Ejemplo n.º 1
0
/*!	Remaps the frame buffer if necessary; if we've already mapped the complete
	frame buffer, there is no need to map it again.
*/
static status_t
remap_frame_buffer(vesa_info& info, addr_t physicalBase, uint32 width,
	uint32 height, int8 depth, uint32 bytesPerRow, bool initializing)
{
	vesa_shared_info& sharedInfo = *info.shared_info;
	addr_t frameBuffer = info.frame_buffer;

	if (!info.complete_frame_buffer_mapped) {
		addr_t base = physicalBase;
		size_t size = bytesPerRow * height;
		bool remap = !initializing;

		if (info.physical_frame_buffer_size != 0) {
			// we can map the complete frame buffer
			base = info.physical_frame_buffer;
			size = info.physical_frame_buffer_size;
			remap = true;
		}

		if (remap) {
			area_id area = map_physical_memory("vesa frame buffer", base,
				size, B_ANY_KERNEL_ADDRESS, B_READ_AREA | B_WRITE_AREA,
				(void**)&frameBuffer);
			if (area < 0)
				return area;

			if (initializing) {
				// We need to manually update the kernel's frame buffer address,
				// since this frame buffer remapping has not been issued by the
				// app_server (which would otherwise take care of this)
				frame_buffer_update(frameBuffer, width, height, depth,
					bytesPerRow);
			}

			delete_area(info.shared_info->frame_buffer_area);

			info.frame_buffer = frameBuffer;
			sharedInfo.frame_buffer_area = area;

			// Turn on write combining for the area
			vm_set_area_memory_type(area, base, B_MTR_WC);

			if (info.physical_frame_buffer_size != 0)
				info.complete_frame_buffer_mapped = true;
		}
	}

	if (info.complete_frame_buffer_mapped)
		frameBuffer += physicalBase - info.physical_frame_buffer;

	// Update shared frame buffer information
	sharedInfo.frame_buffer = (uint8*)frameBuffer;
	sharedInfo.physical_frame_buffer = (uint8*)physicalBase;
	sharedInfo.bytes_per_row = bytesPerRow;

	return B_OK;
}
Ejemplo n.º 2
0
status_t init_driver()
{
    LogFlowFunc(("init_driver\n"));

    gLock.Init("VBoxVideo driver lock");

    uint32 pciIndex = 0;

    while (gPCI->get_nth_pci_info(pciIndex, &gDeviceInfo.pciInfo) == B_OK)
    {
        if (gDeviceInfo.pciInfo.vendor_id == VENDOR_ID && gDeviceInfo.pciInfo.device_id == DEVICE_ID)
        {
            sprintf(gDeviceInfo.name, "graphics/" DEVICE_FORMAT,
                    gDeviceInfo.pciInfo.vendor_id, gDeviceInfo.pciInfo.device_id,
                    gDeviceInfo.pciInfo.bus, gDeviceInfo.pciInfo.device, gDeviceInfo.pciInfo.function);
            TRACE("found device %s\n", gDeviceInfo.name);

            gCanHasDevice = true;
            gDeviceInfo.openCount = 0;

            size_t sharedSize = (sizeof(SharedInfo) + 7) & ~7;
            gDeviceInfo.sharedArea = create_area("vboxvideo shared info",
                                                 (void **)&gDeviceInfo.sharedInfo, B_ANY_KERNEL_ADDRESS,
                                                 ROUND_TO_PAGE_SIZE(sharedSize), B_FULL_LOCK,
                                                 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_USER_CLONEABLE_AREA);

            uint16_t width, height, vwidth, bpp, flags;
            VBoxVideoGetModeRegisters(&width, &height, &vwidth, &bpp, &flags);

            gDeviceInfo.sharedInfo->currentMode.space = get_color_space_for_depth(bpp);
            gDeviceInfo.sharedInfo->currentMode.virtual_width = width;
            gDeviceInfo.sharedInfo->currentMode.virtual_height = height;
            gDeviceInfo.sharedInfo->currentMode.h_display_start = 0;
            gDeviceInfo.sharedInfo->currentMode.v_display_start = 0;
            gDeviceInfo.sharedInfo->currentMode.flags = 0;
            gDeviceInfo.sharedInfo->currentMode.timing.h_display = width;
            gDeviceInfo.sharedInfo->currentMode.timing.v_display = height;
            /* Not used, but this makes a reasonable-sounding refresh rate show in screen prefs: */
            gDeviceInfo.sharedInfo->currentMode.timing.h_total = 1000;
            gDeviceInfo.sharedInfo->currentMode.timing.v_total = 1;
            gDeviceInfo.sharedInfo->currentMode.timing.pixel_clock = 850;

            /* Map the PCI memory space */
            uint32 command_reg = gPCI->read_pci_config(gDeviceInfo.pciInfo.bus,
                                                       gDeviceInfo.pciInfo.device, gDeviceInfo.pciInfo.function,  PCI_command, 2);
            command_reg |= PCI_command_io | PCI_command_memory | PCI_command_master;
            gPCI->write_pci_config(gDeviceInfo.pciInfo.bus, gDeviceInfo.pciInfo.device,
                                   gDeviceInfo.pciInfo.function, PCI_command, 2, command_reg);

            gDeviceInfo.sharedInfo->framebufferArea = map_physical_memory("vboxvideo framebuffer",
                                                      (phys_addr_t)gDeviceInfo.pciInfo.u.h0.base_registers[0],
                                                      gDeviceInfo.pciInfo.u.h0.base_register_sizes[0], B_ANY_KERNEL_BLOCK_ADDRESS,
                                                      B_READ_AREA | B_WRITE_AREA, &(gDeviceInfo.sharedInfo->framebuffer));
            vm_set_area_memory_type(gDeviceInfo.sharedInfo->framebufferArea,
                                    (phys_addr_t)gDeviceInfo.pciInfo.u.h0.base_registers[0], B_MTR_WC);
            break;
        }

        pciIndex++;
    }

    return B_OK;
}