Пример #1
0
static status_t
CreateShared()
{
	gPd->sharedArea = create_area("VMware shared", (void **)&gPd->si,
		B_ANY_KERNEL_ADDRESS, ROUND_TO_PAGE_SIZE(sizeof(SharedInfo)),
		B_FULL_LOCK, 0);
	if (gPd->sharedArea < B_OK) {
		TRACE("failed to create shared area\n");
		return gPd->sharedArea;
	}
	TRACE("shared area created\n");

	memset(gPd->si, 0, sizeof(SharedInfo));
	return B_OK;
}
Пример #2
0
static status_t
InitDevice(DeviceInfo& di)
{
	// Perform initialization and mapping of the device, and return B_OK if
	// sucessful;  else, return error code.

	// Get the table of VESA modes that the chip supports.  Note that we will
	// need this table only for chips that are currently connected to a laptop
	// display or a monitor connected via a DVI interface.

	size_t vesaModeTableSize = 0;
	VesaMode* vesaModes = (VesaMode*)get_boot_item(VESA_MODES_BOOT_INFO,
		&vesaModeTableSize);

	size_t sharedSize = (sizeof(SharedInfo) + 7) & ~7;

	// Create the area for shared info with NO user-space read or write
	// permissions, to prevent accidental damage.

	di.sharedArea = create_area("ATI shared info",
		(void**) &(di.sharedInfo),
		B_ANY_KERNEL_ADDRESS,
		ROUND_TO_PAGE_SIZE(sharedSize + vesaModeTableSize),
		B_FULL_LOCK, 0);
	if (di.sharedArea < 0)
		return di.sharedArea;	// return error code

	SharedInfo& si = *(di.sharedInfo);

	memset(&si, 0, sharedSize);

	if (vesaModes != NULL) {
		si.vesaModeTableOffset = sharedSize;
		si.vesaModeCount = vesaModeTableSize / sizeof(VesaMode);

		memcpy((uint8*)&si + si.vesaModeTableOffset, vesaModes,
			vesaModeTableSize);
	}

	pci_info& pciInfo = di.pciInfo;

	si.vendorID = pciInfo.vendor_id;
	si.deviceID = pciInfo.device_id;
	si.revision = pciInfo.revision;
	si.chipType = di.pChipInfo->chipType;
	strcpy(si.chipName, di.pChipInfo->chipName);

	TRACE("Chip revision: 0x%x\n", si.revision);

	// 264GT has two chip versions.  If version is non-zero, chip is 264GTB.

	if (si.chipType == MACH64_264GT && si.revision & 0x7)
		si.chipType = MACH64_264GTB;

	// 264VT has two chip versions.  If version is non-zero, chip is 264VTB.

	if (si.chipType == MACH64_264VT && si.revision & 0x7)
		si.chipType = MACH64_264VTB;

	status_t status = MapDevice(di);

	// If device mapped without any error, get the bios parameters from the
	// chip's BIOS ROM.

	if (status >= 0) {
		if (MACH64_FAMILY(si.chipType)) {
			uint8 clockType;
			Mach64_GetBiosParameters(di, clockType);

			// All chips supported by this driver should have an internal clock.
			// If the clock is not an internal clock, the video chip is not
			// supported.

			if (clockType != M64_CLOCK_INTERNAL) {
				TRACE("Video chip clock type %d not supported\n", clockType);
				status = B_UNSUPPORTED;
			}
		}
		else if (RAGE128_FAMILY(si.chipType))
			Rage128_GetBiosParameters(di);
	}

	if (status < 0) {
		delete_area(di.sharedArea);
		di.sharedArea = -1;
		di.sharedInfo = NULL;
		return status;		// return error code
	}

	InitInterruptHandler(di);

	TRACE("Interrupt assigned:  %s\n", si.bInterruptAssigned ? "yes" : "no");
	return B_OK;
}
Пример #3
0
status_t
intel_extreme_init(intel_info &info)
{
    CALLED();
    info.aperture = gGART->map_aperture(info.pci->bus, info.pci->device,
                                        info.pci->function, 0, &info.aperture_base);
    if (info.aperture < B_OK) {
        ERROR("error: could not map GART aperture!\n");
        return info.aperture;
    }

    AreaKeeper sharedCreator;
    info.shared_area = sharedCreator.Create("intel extreme shared info",
                                            (void**)&info.shared_info, B_ANY_KERNEL_ADDRESS,
                                            ROUND_TO_PAGE_SIZE(sizeof(intel_shared_info)) + 3 * B_PAGE_SIZE,
                                            B_FULL_LOCK, 0);
    if (info.shared_area < B_OK) {
        ERROR("error: could not create shared area!\n");
        gGART->unmap_aperture(info.aperture);
        return info.shared_area;
    }

    memset((void*)info.shared_info, 0, sizeof(intel_shared_info));

    int fbIndex = 0;
    int mmioIndex = 1;
    if (info.device_type.InFamily(INTEL_TYPE_9xx)) {
        // For some reason Intel saw the need to change the order of the
        // mappings with the introduction of the i9xx family
        mmioIndex = 0;
        fbIndex = 2;
    }

    // evaluate driver settings, if any

    bool hardwareCursor;
    read_settings(hardwareCursor);

    // memory mapped I/O

    // TODO: registers are mapped twice (by us and intel_gart), maybe we
    // can share it between the drivers

    AreaKeeper mmioMapper;
    info.registers_area = mmioMapper.Map("intel extreme mmio",
                                         info.pci->u.h0.base_registers[mmioIndex],
                                         info.pci->u.h0.base_register_sizes[mmioIndex],
                                         B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
                                         (void**)&info.registers);
    if (mmioMapper.InitCheck() < B_OK) {
        ERROR("error: could not map memory I/O!\n");
        gGART->unmap_aperture(info.aperture);
        return info.registers_area;
    }

    uint32* blocks = info.shared_info->register_blocks;
    blocks[REGISTER_BLOCK(REGS_FLAT)] = 0;

    // setup the register blocks for the different architectures
    if (info.device_type.HasPlatformControlHub()) {
        // PCH based platforms (IronLake and up)
        blocks[REGISTER_BLOCK(REGS_NORTH_SHARED)]
            = PCH_NORTH_SHARED_REGISTER_BASE;
        blocks[REGISTER_BLOCK(REGS_NORTH_PIPE_AND_PORT)]
            = PCH_NORTH_PIPE_AND_PORT_REGISTER_BASE;
        blocks[REGISTER_BLOCK(REGS_NORTH_PLANE_CONTROL)]
            = PCH_NORTH_PLANE_CONTROL_REGISTER_BASE;
        blocks[REGISTER_BLOCK(REGS_SOUTH_SHARED)]
            = PCH_SOUTH_SHARED_REGISTER_BASE;
        blocks[REGISTER_BLOCK(REGS_SOUTH_TRANSCODER_PORT)]
            = PCH_SOUTH_TRANSCODER_AND_PORT_REGISTER_BASE;
    } else {
        // (G)MCH/ICH based platforms
        blocks[REGISTER_BLOCK(REGS_NORTH_SHARED)]
            = MCH_SHARED_REGISTER_BASE;
        blocks[REGISTER_BLOCK(REGS_NORTH_PIPE_AND_PORT)]
            = MCH_PIPE_AND_PORT_REGISTER_BASE;
        blocks[REGISTER_BLOCK(REGS_NORTH_PLANE_CONTROL)]
            = MCH_PLANE_CONTROL_REGISTER_BASE;
        blocks[REGISTER_BLOCK(REGS_SOUTH_SHARED)]
            = ICH_SHARED_REGISTER_BASE;
        blocks[REGISTER_BLOCK(REGS_SOUTH_TRANSCODER_PORT)]
            = ICH_PORT_REGISTER_BASE;
    }

    // make sure bus master, memory-mapped I/O, and frame buffer is enabled
    set_pci_config(info.pci, PCI_command, 2, get_pci_config(info.pci,
                   PCI_command, 2) | PCI_command_io | PCI_command_memory
                   | PCI_command_master);

    // reserve ring buffer memory (currently, this memory is placed in
    // the graphics memory), but this could bring us problems with
    // write combining...

    ring_buffer &primary = info.shared_info->primary_ring_buffer;
    if (intel_allocate_memory(info, 16 * B_PAGE_SIZE, 0, 0,
                              (addr_t*)&primary.base) == B_OK) {
        primary.register_base = INTEL_PRIMARY_RING_BUFFER;
        primary.size = 16 * B_PAGE_SIZE;
        primary.offset = (addr_t)primary.base - info.aperture_base;
    }

    // Enable clock gating
    intel_en_gating(info);

    // Enable automatic gpu downclocking if we can to save power
    intel_en_downclock(info);

    // no errors, so keep areas and mappings
    sharedCreator.Detach();
    mmioMapper.Detach();

    aperture_info apertureInfo;
    gGART->get_aperture_info(info.aperture, &apertureInfo);

    info.shared_info->registers_area = info.registers_area;
    info.shared_info->graphics_memory = (uint8*)info.aperture_base;
    info.shared_info->physical_graphics_memory = apertureInfo.physical_base;
    info.shared_info->graphics_memory_size = apertureInfo.size;
    info.shared_info->frame_buffer = 0;
    info.shared_info->dpms_mode = B_DPMS_ON;

    info.shared_info->got_vbt = get_lvds_mode_from_bios(
                                    &info.shared_info->current_mode);
    /* at least 855gm can't drive more than one head at time */
    if (info.device_type.InFamily(INTEL_TYPE_8xx))
        info.shared_info->single_head_locked = 1;

    if (info.device_type.InFamily(INTEL_TYPE_9xx)) {
        info.shared_info->pll_info.reference_frequency = 96000;	// 96 kHz
        info.shared_info->pll_info.max_frequency = 400000;
        // 400 MHz RAM DAC speed
        info.shared_info->pll_info.min_frequency = 20000;		// 20 MHz
    } else {
        info.shared_info->pll_info.reference_frequency = 48000;	// 48 kHz
        info.shared_info->pll_info.max_frequency = 350000;
        // 350 MHz RAM DAC speed
        info.shared_info->pll_info.min_frequency = 25000;		// 25 MHz
    }

    info.shared_info->pll_info.divisor_register = INTEL_DISPLAY_A_PLL_DIVISOR_0;

    info.shared_info->device_type = info.device_type;
#ifdef __HAIKU__
    strlcpy(info.shared_info->device_identifier, info.device_identifier,
            sizeof(info.shared_info->device_identifier));
#else
    strcpy(info.shared_info->device_identifier, info.device_identifier);
#endif

    // setup overlay registers

    status_t status = intel_allocate_memory(info, B_PAGE_SIZE, 0,
                                            intel_uses_physical_overlay(*info.shared_info)
                                            ? B_APERTURE_NEED_PHYSICAL : 0,
                                            (addr_t*)&info.overlay_registers,
                                            &info.shared_info->physical_overlay_registers);
    if (status == B_OK) {
        info.shared_info->overlay_offset = (addr_t)info.overlay_registers
                                           - info.aperture_base;
        init_overlay_registers(info.overlay_registers);
    } else {
        ERROR("error: could not allocate overlay memory! %s\n",
              strerror(status));
    }

    // Allocate hardware status page and the cursor memory

    if (intel_allocate_memory(info, B_PAGE_SIZE, 0, B_APERTURE_NEED_PHYSICAL,
                              (addr_t*)info.shared_info->status_page,
                              &info.shared_info->physical_status_page) == B_OK) {
        // TODO: set status page
    }
    if (hardwareCursor) {
        intel_allocate_memory(info, B_PAGE_SIZE, 0, B_APERTURE_NEED_PHYSICAL,
                              (addr_t*)&info.shared_info->cursor_memory,
                              &info.shared_info->physical_cursor_memory);
    }

    init_interrupt_handler(info);

    TRACE("%s: completed successfully!\n", __func__);
    return B_OK;
}
Пример #4
0
status_t
device_open(const char *name, uint32 flags, void **cookie)
{
	struct sis_info *info;
	area_id area;
	int id;

	// verify device access (we only allow one user at a time)
	{
		char *thisName;
		int32 mask;

		// search for device name
		for (id = 0; (thisName = gDeviceNames[id]) != NULL; id++) {
			if (!strcmp(name, thisName))
				break;
		}
		if (!thisName)
			return EINVAL;
	
		// check if device is already open
		mask = 1L << id;
		if (atomic_or(&gDeviceOpenMask, mask) & mask)
			return B_BUSY;
	}

	// allocate internal device structure
	if ((area = create_area(DEVICE_NAME " private data", cookie,
							B_ANY_KERNEL_ADDRESS,
							ROUND_TO_PAGE_SIZE(sizeof(struct sis_info)),
							B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA)) < B_OK) {
		gDeviceOpenMask &= ~(1L << id);
		return B_NO_MEMORY;
	}
	info = (struct sis_info *)*cookie;
	memset(info, 0, sizeof(struct sis_info));

	info->cookieMagic = SiS_COOKIE_MAGIC;
	info->thisArea = area;
	info->id = id;
	info->pciInfo = pciInfo[id];
	info->registers = (addr_t)pciInfo[id]->u.h0.base_registers[0];

	if (sis900_getMACAddress(info))
		dprintf(DEVICE_NAME ": MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",
			  info->address.ebyte[0], info->address.ebyte[1], info->address.ebyte[2],
			  info->address.ebyte[3], info->address.ebyte[4], info->address.ebyte[5]);
	else
		dprintf(DEVICE_NAME ": could not get MAC address\n");

	readSettings(info);

	if (createSemaphores(info) == B_OK) {
		status_t status = sis900_initPHYs(info);
		if (status == B_OK) {
			TRACE((DEVICE_NAME ": MII status = %d\n", mdio_read(info, MII_STATUS)));

			//sis900_configFIFOs(info);
			sis900_reset(info);

			// install & enable interrupts
			install_io_interrupt_handler(info->pciInfo->u.h0.interrupt_line,
				sis900_interrupt, info, 0);
			sis900_enableInterrupts(info);

			sis900_setRxFilter(info);
			sis900_createRings(info);

			// enable receiver's state machine
			write32(info->registers + SiS900_MAC_COMMAND, SiS900_MAC_CMD_Rx_ENABLE);

			// check link mode & add timer (once every second)
			sis900_checkMode(info);
			add_timer(&info->timer, sis900_timer, 1000000LL, B_PERIODIC_TIMER);	

			return B_OK;
		}
		dprintf(DEVICE_NAME ": could not initialize MII PHY: %s\n", strerror(status));
		deleteSemaphores(info);
	} else
		dprintf(DEVICE_NAME ": could not create semaphores.\n");

	gDeviceOpenMask &= ~(1L << id);
	delete_area(area);

	return B_ERROR;
}
Пример #5
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;
}
Пример #6
0
status_t
vesa_init(vesa_info& info)
{
	frame_buffer_boot_info* bufferInfo
		= (frame_buffer_boot_info*)get_boot_item(FRAME_BUFFER_BOOT_INFO, NULL);
	if (bufferInfo == NULL)
		return B_ERROR;

	info.vbe_capabilities = bufferInfo->vesa_capabilities;
	info.complete_frame_buffer_mapped = false;

	// Find out which PCI device we belong to, so that we know its frame buffer
	// size
	find_graphics_card(bufferInfo->physical_frame_buffer,
		info.physical_frame_buffer, info.physical_frame_buffer_size);

	size_t modesSize = 0;
	vesa_mode* modes = (vesa_mode*)get_boot_item(VESA_MODES_BOOT_INFO,
		&modesSize);
	info.modes = modes;

	size_t sharedSize = (sizeof(vesa_shared_info) + 7) & ~7;

	info.shared_area = create_area("vesa shared info",
		(void**)&info.shared_info, B_ANY_KERNEL_ADDRESS,
		ROUND_TO_PAGE_SIZE(sharedSize + modesSize), B_FULL_LOCK,
		B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_USER_CLONEABLE_AREA);
	if (info.shared_area < 0)
		return info.shared_area;

	vesa_shared_info& sharedInfo = *info.shared_info;

	memset(&sharedInfo, 0, sizeof(vesa_shared_info));

	if (modes != NULL) {
		sharedInfo.vesa_mode_offset = sharedSize;
		sharedInfo.vesa_mode_count = modesSize / sizeof(vesa_mode);

		memcpy((uint8*)&sharedInfo + sharedSize, modes, modesSize);
	}

	sharedInfo.frame_buffer_area = bufferInfo->area;

	remap_frame_buffer(info, bufferInfo->physical_frame_buffer,
		bufferInfo->width, bufferInfo->height, bufferInfo->depth,
		bufferInfo->bytes_per_row, true);
		// Does not matter if this fails - the frame buffer was already mapped
		// before.

	sharedInfo.current_mode.virtual_width = bufferInfo->width;
	sharedInfo.current_mode.virtual_height = bufferInfo->height;
	sharedInfo.current_mode.space = get_color_space_for_depth(
		bufferInfo->depth);

	edid1_info* edidInfo = (edid1_info*)get_boot_item(VESA_EDID_BOOT_INFO,
		NULL);
	if (edidInfo != NULL) {
		sharedInfo.has_edid = true;
		memcpy(&sharedInfo.edid_info, edidInfo, sizeof(edid1_info));
	}

	vbe_get_dpms_capabilities(info.vbe_dpms_capabilities,
		sharedInfo.dpms_capabilities);
	if (bufferInfo->depth <= 8)
		vbe_set_bits_per_gun(info, 8);

	dprintf(DEVICE_NAME ": vesa_init() completed successfully!\n");
	return B_OK;
}