/* Checks if we have a device supported by our driver and initialize * our driver/card specific information. * In particular we obtain VM monitors configuration and configure related structures. */ static VP_STATUS VBoxDrvFindAdapter(IN PVOID HwDeviceExtension, IN PVOID HwContext, IN PWSTR ArgumentString, IN OUT PVIDEO_PORT_CONFIG_INFO ConfigInfo, OUT PUCHAR Again) { RT_NOREF(HwContext, ArgumentString, Again); PVBOXMP_DEVEXT pExt = (PVBOXMP_DEVEXT) HwDeviceExtension; VP_STATUS rc; USHORT DispiId; ULONG cbVRAM = VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES; PHYSICAL_ADDRESS phVRAM = {0}; ULONG ulApertureSize = 0; PAGED_CODE(); LOGF_ENTER(); /* Init video port api */ VBoxSetupVideoPortAPI(pExt, ConfigInfo); VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID); VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID2); DispiId = VideoPortReadPortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA); if (DispiId != VBE_DISPI_ID2) { WARN(("VBE card not found, returning ERROR_DEV_NOT_EXIST")); return ERROR_DEV_NOT_EXIST; } LOG(("found the VBE card")); /* * Query the adapter's memory size. It's a bit of a hack, we just read * an ULONG from the data port without setting an index before. */ cbVRAM = VideoPortReadPortUlong((PULONG)VBE_DISPI_IOPORT_DATA); /* Write hw information to registry, so that it's visible in windows property dialog */ rc = VideoPortSetRegistryParameters(pExt, L"HardwareInformation.ChipType", g_wszVBoxChipType, sizeof(g_wszVBoxChipType)); VBOXMP_WARN_VPS(rc); rc = VideoPortSetRegistryParameters(pExt, L"HardwareInformation.DacType", g_wszVBoxDACType, sizeof(g_wszVBoxDACType)); VBOXMP_WARN_VPS(rc); rc = VideoPortSetRegistryParameters(pExt, L"HardwareInformation.MemorySize", &cbVRAM, sizeof(ULONG)); VBOXMP_WARN_VPS(rc); rc = VideoPortSetRegistryParameters(pExt, L"HardwareInformation.AdapterString", g_wszVBoxAdapterString, sizeof(g_wszVBoxAdapterString)); VBOXMP_WARN_VPS(rc); rc = VideoPortSetRegistryParameters(pExt, L"HardwareInformation.BiosString", g_wszVBoxBiosString, sizeof(g_wszVBoxBiosString)); VBOXMP_WARN_VPS(rc); /* Call VideoPortGetAccessRanges to ensure interrupt info in ConfigInfo gets set up * and to get LFB aperture data. */ { VIDEO_ACCESS_RANGE tmpRanges[4]; ULONG slot = 0; VideoPortZeroMemory(tmpRanges, sizeof(tmpRanges)); if (VBoxQueryWinVersion(NULL) == WINVERSION_NT4) { /* NT crashes if either of 'vendorId, 'deviceId' or 'slot' parameters is NULL, * and needs PCI ids for a successful VideoPortGetAccessRanges call. */ ULONG vendorId = 0x80EE; ULONG deviceId = 0xBEEF; rc = VideoPortGetAccessRanges(pExt, 0, NULL, RT_ELEMENTS(tmpRanges), tmpRanges, &vendorId, &deviceId, &slot); } else { rc = VideoPortGetAccessRanges(pExt, 0, NULL, RT_ELEMENTS(tmpRanges), tmpRanges, NULL, NULL, &slot); } VBOXMP_WARN_VPS(rc); if (rc != NO_ERROR) { return rc; } /* The first non-IO range is the framebuffer. We require that information. */ for (int iRange = 0; iRange < RT_ELEMENTS(tmpRanges); ++iRange) { if (!tmpRanges[iRange].RangeInIoSpace) { phVRAM = tmpRanges[iRange].RangeStart; ulApertureSize = tmpRanges[iRange].RangeLength; break; } } } /* Initialize VBoxGuest library, which is used for requests which go through VMMDev. */ rc = VbglR0InitClient(); VBOXMP_WARN_VPS(rc); /* Preinitialize the primary extension. */ pExt->pNext = NULL; pExt->pPrimary = pExt; pExt->iDevice = 0; pExt->ulFrameBufferOffset = 0; pExt->ulFrameBufferSize = 0; pExt->u.primary.ulVbvaEnabled = 0; VideoPortZeroMemory(&pExt->areaDisplay, sizeof(HGSMIAREA)); /* Guest supports only HGSMI, the old VBVA via VMMDev is not supported. Old * code will be ifdef'ed and later removed. * The host will however support both old and new interface to keep compatibility * with old guest additions. */ VBoxSetupDisplaysHGSMI(&pExt->u.primary.commonInfo, phVRAM, ulApertureSize, cbVRAM, 0); /* Check if the chip restricts horizontal resolution or not. * Must be done after VBoxSetupDisplaysHGSMI, because it initializes the common structure. */ VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID); VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_ANYX); DispiId = VideoPortReadPortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA); if (DispiId == VBE_DISPI_ID_ANYX) VBoxCommonFromDeviceExt(pExt)->fAnyX = TRUE; else VBoxCommonFromDeviceExt(pExt)->fAnyX = FALSE; if (pExt->u.primary.commonInfo.bHGSMI) { LOGREL(("using HGSMI")); VBoxCreateDisplays(pExt, ConfigInfo); } /** @todo pretend success to make the driver work. */ rc = NO_ERROR; LOGF_LEAVE(); VBOXMP_WARN_VPS(rc); return rc; }
VP_STATUS DGXFindAdapter( PVOID HwDeviceExtension, PVOID HwContext, PWSTR ArgumentString, PVIDEO_PORT_CONFIG_INFO ConfigInfo, PUCHAR Again ) /*++ Routine Description: This routine is called to determine if the adapter for this driver is present in the system. If it is present, the function fills out some information describing the adapter. Arguments: HwDeviceExtension - Supplies the miniport driver's adapter storage. This storage is initialized to zero before this call. HwContext - Supplies the context value which was passed to VideoPortInitialize(). ArgumentString - Suuplies a NULL terminated ASCII string. This string originates from the user. ConfigInfo - Returns the configuration information structure which is filled by the miniport driver. This structure is initialized with any knwon configuration information (such as SystemIoBusNumber) by the port driver. Where possible, drivers should have one set of defaults which do not require any supplied configuration information. Again - Indicates if the miniport driver wants the port driver to call its VIDEO_HW_FIND_ADAPTER function again with a new device extension and the same config info. This is used by the miniport drivers which can search for several adapters on a bus. Return Value: This routine must return: NO_ERROR - Indicates a host adapter was found and the configuration information was successfully determined. ERROR_INVALID_PARAMETER - Indicates an adapter was found but there was an error obtaining the configuration information. If possible an error should be logged. ERROR_DEV_NOT_EXIST - Indicates no host adapter was found for the supplied configuration information. --*/ { #define NUM_ACCESS_RANGES 5 PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension; PVOID *pVirtAddr; ULONG i; USHORT temp; PUSHORT port; VP_STATUS status; PWSTR pwszChip= NULL; // chip name ULONG cbChip= 0; // length of chip name PWSTR pwszDac= NULL; // DAC name ULONG cbDac= 0; // length of DAC name ULONG cbMemSize; // size of video memory VIDEO_ACCESS_RANGE accessRange[NUM_ACCESS_RANGES] = { {0X00000061, 0x00000000, 0x00000001, 1, 1, 0}, // DGX I {0X00006CA8, 0x00000000, 0x00000001, 1, 1, 0}, // DGX I {0X00006C80, 0x00000000, 0x00000009, 1, 1, 0}, // DGX I & II {0X00000CAC, 0x00000000, 0x00000004, 1, 1, 0}, // front panel {0x20000000, 0x00000000, 0x00400000, 0, 1, 0} // Frame buf & dac }; // // Make sure the size of the structure is at least as large as what we // are expecting (check version of the config info structure). // if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO)) { return ERROR_INVALID_PARAMETER; } // // Check to see if there is a hardware resource conflict. // status = VideoPortVerifyAccessRanges(HwDeviceExtension, NUM_ACCESS_RANGES, accessRange); if (status != NO_ERROR) { return status; } // // Clear out the Emulator entries and the state size since this driver // does not support them. // ConfigInfo->NumEmulatorAccessEntries = 0; ConfigInfo->EmulatorAccessEntries = NULL; ConfigInfo->EmulatorAccessEntriesContext = 0; ConfigInfo->HardwareStateSize = 0; ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart = 0x00000000; ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0x00000000; ConfigInfo->VdmPhysicalVideoMemoryLength = 0x00000000; // // Frame buffer information // hwDeviceExtension->FrameLength = DELL_DGX_LEN; hwDeviceExtension->PhysicalFrameAddress.HighPart = 0; hwDeviceExtension->PhysicalFrameAddress.LowPart = DELL_DGX_BASE; // // Map all of our ranges into system virtual address space. // IMPORTANT !!! // This is dependant on the order of the virtual addresses in the // HwDeviceExtensionto be the same as the order of the entries in the // access range structure. // pVirtAddr = &hwDeviceExtension->DGX1Misc; for (i=0 ; i <NUM_ACCESS_RANGES ; i++ ) { if ( (*pVirtAddr = VideoPortGetDeviceBase(hwDeviceExtension, accessRange[i].RangeStart, accessRange[i].RangeLength, accessRange[i].RangeInIoSpace)) == NULL) { return ERROR_INVALID_PARAMETER; } pVirtAddr++; } // // Are we really on a Dell DGX machine? If so which one? // hwDeviceExtension->ModelNumber = 0; port = (PUSHORT) hwDeviceExtension->DGXControlPorts; temp = VideoPortReadPortUshort(port++); if (temp == DELL_DGX_ID_LOW) { temp = VideoPortReadPortUshort(port); if (temp == DELL_DGX_1_ID_HIGH) { hwDeviceExtension->ModelNumber = 1; pwszChip= CHIPNAME1; cbChip= sizeof(CHIPNAME1); } if (temp == DELL_DGX_2_ID_HIGH) { hwDeviceExtension->ModelNumber = 2; pwszChip= CHIPNAME2; cbChip= sizeof(CHIPNAME2); } } if (hwDeviceExtension->ModelNumber == 0) { // // If we did not find the chip, free all the resources we allocated. // pVirtAddr = &hwDeviceExtension->DGX1Misc; for (i=0 ; i <NUM_ACCESS_RANGES ; i++) { VideoPortFreeDeviceBase(hwDeviceExtension, *pVirtAddr); pVirtAddr++; } return ERROR_DEV_NOT_EXIST; } // // Initialize the current mode number. // hwDeviceExtension->CurrentModeNumber = 0; // // Setup All the valid modes. // hwDeviceExtension->NumValidModes = 0; for (i=0; i < NumDGXModes; i++) { DGXModes[i].modeInformation.ModeIndex = i; DGXModes[i].bValid = TRUE; hwDeviceExtension->NumValidModes++; } // // Indicate we do not wish to be called over // *Again = 0; // // Init Front panel Display // DevSetPanel(HwDeviceExtension, PANEL_MESSAGE); // // Set hardware information strings in registry // VideoPortSetRegistryParameters(HwDeviceExtension, L"HardwareInformation.ChipType", pwszChip, cbChip ); pwszDac= DELL_DGX_DACNAME; cbDac= sizeof( DELL_DGX_DACNAME ); VideoPortSetRegistryParameters(HwDeviceExtension, L"HardwareInformation.DacType", pwszDac, cbDac ); cbMemSize= DELL_DGX_LEN; VideoPortSetRegistryParameters(HwDeviceExtension, L"HardwareInformation.MemorySize", &cbMemSize, sizeof(ULONG) ); // // Indicate a successful completion status. // return NO_ERROR; } // end DGXFindAdapter()
VP_STATUS NTAPI VmxFindAdapter(IN PVOID HwDeviceExtension, IN PVOID HwContext, IN PWSTR ArgumentString, IN OUT PVIDEO_PORT_CONFIG_INFO ConfigInfo, OUT PUCHAR Again) { VP_STATUS Status; PHW_DEVICE_EXTENSION DeviceExtension = HwDeviceExtension; DPRINT1("VMX searching for adapter\n"); /* Zero out the fields */ VideoPortZeroMemory(DeviceExtension, sizeof(HW_DEVICE_EXTENSION)); /* Validate the Config Info */ if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO)) { /* Incorrect OS version? */ DPRINT1("Invalid configuration info\n"); return ERROR_INVALID_PARAMETER; } /* Initialize the device extension and find the adapter */ Status = VmxInitDevice(DeviceExtension); DPRINT1("Init status: %lx\n", Status); if (Status != NO_ERROR) return ERROR_DEV_NOT_EXIST; /* Save this adapter extension */ VmxDeviceExtensionArray[0] = DeviceExtension; /* Create the sync event */ VideoPortCreateEvent(DeviceExtension, NOTIFICATION_EVENT, NULL, &DeviceExtension->SyncEvent); /* Check for multi-monitor configuration */ if (VmxIsMultiMon(DeviceExtension)) { /* Let's not go so far */ UNIMPLEMENTED; while (TRUE); } /* Zero the frame buffer */ VideoPortZeroMemory((PVOID)DeviceExtension->FrameBuffer.LowPart, DeviceExtension->VramSize.LowPart); /* Initialize the video modes */ VmxInitModes(DeviceExtension); /* Setup registry keys */ VideoPortSetRegistryParameters(DeviceExtension, L"HardwareInformation.ChipType", AdapterString, sizeof(AdapterString)); VideoPortSetRegistryParameters(DeviceExtension, L"HardwareInformation.DacType", AdapterString, sizeof(AdapterString)); VideoPortSetRegistryParameters(DeviceExtension, L"HardwareInformation.MemorySize", &DeviceExtension->VramSize.LowPart, sizeof(ULONG)); VideoPortSetRegistryParameters(DeviceExtension, L"HardwareInformation.AdapterString", AdapterString, sizeof(AdapterString)); VideoPortSetRegistryParameters(DeviceExtension, L"HardwareInformation.BiosString", AdapterString, sizeof(AdapterString)); /* No VDM support */ ConfigInfo->NumEmulatorAccessEntries = 0; ConfigInfo->EmulatorAccessEntries = 0; ConfigInfo->EmulatorAccessEntriesContext = 0; ConfigInfo->HardwareStateSize = 0; ConfigInfo->VdmPhysicalVideoMemoryAddress.QuadPart = 0; ConfigInfo->VdmPhysicalVideoMemoryLength = 0; /* Write that this is Windows XP or higher */ VmxWriteUlong(DeviceExtension, SVGA_REG_GUEST_ID, 0x5000 | 0x08); return NO_ERROR; }
VP_STATUS VBoxMPCmnRegSetDword(IN VBOXMPCMNREGISTRY Reg, PWSTR pName, uint32_t Val) { return VideoPortSetRegistryParameters(Reg, pName, &Val, sizeof(Val)); }
/* Checks if we have a device supported by our driver and initialize * our driver/card specific information. * In particular we obtain VM monitors configuration and configure related structures. */ static VP_STATUS VBoxDrvFindAdapter(IN PVOID HwDeviceExtension, IN PVOID HwContext, IN PWSTR ArgumentString, IN OUT PVIDEO_PORT_CONFIG_INFO ConfigInfo, OUT PUCHAR Again) { PVBOXMP_DEVEXT pExt = (PVBOXMP_DEVEXT) HwDeviceExtension; VP_STATUS rc; USHORT DispiId; ULONG AdapterMemorySize = VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES; PAGED_CODE(); LOGF_ENTER(); /* Init video port api */ VBoxSetupVideoPortAPI(pExt, ConfigInfo); VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID); VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID2); DispiId = VideoPortReadPortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA); if (DispiId != VBE_DISPI_ID2) { WARN(("VBE card not found, returning ERROR_DEV_NOT_EXIST")); return ERROR_DEV_NOT_EXIST; } LOG(("found the VBE card")); /* * Query the adapter's memory size. It's a bit of a hack, we just read * an ULONG from the data port without setting an index before. */ AdapterMemorySize = VideoPortReadPortUlong((PULONG)VBE_DISPI_IOPORT_DATA); /* Write hw information to registry, so that it's visible in windows property dialog */ rc = VideoPortSetRegistryParameters(pExt, L"HardwareInformation.ChipType", VBoxChipType, sizeof(VBoxChipType)); VBOXMP_WARN_VPS(rc); rc = VideoPortSetRegistryParameters(pExt, L"HardwareInformation.DacType", VBoxDACType, sizeof(VBoxDACType)); VBOXMP_WARN_VPS(rc); rc = VideoPortSetRegistryParameters(pExt, L"HardwareInformation.MemorySize", &AdapterMemorySize, sizeof(ULONG)); VBOXMP_WARN_VPS(rc); rc = VideoPortSetRegistryParameters(pExt, L"HardwareInformation.AdapterString", VBoxAdapterString, sizeof(VBoxAdapterString)); VBOXMP_WARN_VPS(rc); rc = VideoPortSetRegistryParameters(pExt, L"HardwareInformation.BiosString", VBoxBiosString, sizeof(VBoxBiosString)); VBOXMP_WARN_VPS(rc); /* Call VideoPortGetAccessRanges to ensure interrupt info in ConfigInfo gets set up */ { VIDEO_ACCESS_RANGE tmpRanges[4]; ULONG slot = 0; VideoPortZeroMemory(tmpRanges, sizeof(tmpRanges)); if (VBoxQueryWinVersion() == WINNT4) { /* NT crashes if either of 'vendorId, 'deviceId' or 'slot' parameters is NULL, * and needs PCI ids for a successful VideoPortGetAccessRanges call. */ ULONG vendorId = 0x80EE; ULONG deviceId = 0xBEEF; rc = VideoPortGetAccessRanges(pExt, 0, NULL, RT_ELEMENTS(tmpRanges), tmpRanges, &vendorId, &deviceId, &slot); } else { rc = VideoPortGetAccessRanges(pExt, 0, NULL, RT_ELEMENTS(tmpRanges), tmpRanges, NULL, NULL, &slot); } VBOXMP_WARN_VPS(rc); } /* Initialize VBoxGuest library, which is used for requests which go through VMMDev. */ rc = VbglInit(); VBOXMP_WARN_VPS(rc); /* Preinitialize the primary extension. */ pExt->pNext = NULL; pExt->pPrimary = pExt; pExt->iDevice = 0; pExt->ulFrameBufferOffset = 0; pExt->ulFrameBufferSize = 0; pExt->u.primary.ulVbvaEnabled = 0; VideoPortZeroMemory(&pExt->areaDisplay, sizeof(HGSMIAREA)); /* Guest supports only HGSMI, the old VBVA via VMMDev is not supported. Old * code will be ifdef'ed and later removed. * The host will however support both old and new interface to keep compatibility * with old guest additions. */ VBoxSetupDisplaysHGSMI(&pExt->u.primary.commonInfo, AdapterMemorySize, 0); if (pExt->u.primary.commonInfo.bHGSMI) { LOGREL(("using HGSMI")); VBoxCreateDisplays(pExt, ConfigInfo); } /** @todo pretend success to make the driver work. */ rc = NO_ERROR; LOGF_LEAVE(); VBOXMP_WARN_VPS(rc); return rc; }
/* Determine whether the supported adapter is present. Note that this * function is not allowed to change the state of the adapter! */ VP_STATUS HwVidFindAdapter( PVOID HwDevExt, PVOID HwContext, PWSTR ArgumentString, PVIDEO_PORT_CONFIG_INFO ConfigInfo, PUCHAR Again ) { PHW_DEV_EXT pExt = HwDevExt; PVOID *pVirtAddr; ULONG i; INT chip_id; VP_STATUS status; ULONG cbVramSize; PWSTR pwszDesc; ULONG cbDesc; #ifdef USE_GETACCESSRANGES VIDEO_ACCESS_RANGE pciAccessRanges[NUM_PCI_RANGES]; USHORT usVendorId = BOXV_PCI_VEN; USHORT usDeviceId = BOXV_PCI_DEV; ULONG ulSlot = 0; #endif //@todo: The framebuffer address should not be hardcoded for non-PCI access #define NUM_ACCESS_RANGES 2 VIDEO_ACCESS_RANGE accessRanges[NUM_ACCESS_RANGES] = { /* StartLo StartHi Len IO Vis Shr */ { 0x000001CE, 0x00000000, 0x00000002, 1, 1, 0 }, /* I/O ports */ { 0xE0000000, 0x00000000, 0x00400000, 0, 1, 0 } /* Framebuffer */ }; VideoDebugPrint( (1, "videomp: HwVidFindAdapter\n") ); /* Fail if the passed structure is smaller than the NT 3.1 version. */ if( ConfigInfo->Length < offsetof( VIDEO_PORT_CONFIG_INFO, DmaChannel ) ) { return( ERROR_INVALID_PARAMETER ); } /* Sadly, VideoPortGetAccessRanges was not present in NT 3.1. There is no * reasonably simple way to dynamically import port driver routines on * newer versions, so we'll just do without. */ #ifdef USE_GETACCESSRANGES /* If PCI is supported, query the bus for resource mappings. */ if( ConfigInfo->AdapterInterfaceType == PCIBus ) { /* Ask for bus specific access ranges. */ VideoPortZeroMemory( pciAccessRanges, sizeof( pciAccessRanges ) ); status = VideoPortGetAccessRanges( HwDevExt, 0, NULL, NUM_PCI_RANGES, pciAccessRanges, &usVendorId, &usDeviceId, &ulSlot ); if( status == NO_ERROR ) { VideoDebugPrint( (1, "videomp: Found adapter in PCI slot %d\n", ulSlot) ); pExt->ulSlot = ulSlot; /* The framebuffer is in the first slot of the PCI ranges. Copy * the data into the access ranges we're going to request. */ accessRanges[1].RangeStart = pciAccessRanges[0].RangeStart; accessRanges[1].RangeLength = pciAccessRanges[0].RangeLength; } else { /* On NT versions without PCI support, we won't even attempt this. * So if we tried to query the PCI device and failed to find it, * it really isn't there and we have to give up. */ VideoDebugPrint( (1, "videomp: PCI adapter not found\n") ); return( ERROR_DEV_NOT_EXIST ); } } #endif /* Some versions of vga.sys trap accesses to ports 0x1CE-0x1CF used on * old ATI cards. On Windows 2000 and later we can report legacy * resources to resolve this conflict. On NT 4 and older, we use a hack * and claim other, non-conflicting ports. */ if( PortVersion < VP_VER_W2K ) accessRanges[0].RangeStart = RtlConvertUlongToLargeInteger( 0x1CC ); /* Check for a conflict in case someone else claimed our resources. */ status = VideoPortVerifyAccessRanges( HwDevExt, NUM_ACCESS_RANGES, accessRanges ); if( status != NO_ERROR ) { return( status ); } /* Indicate no emulator support. */ ConfigInfo->NumEmulatorAccessEntries = 0; ConfigInfo->EmulatorAccessEntries = NULL; ConfigInfo->EmulatorAccessEntriesContext = 0; ConfigInfo->HardwareStateSize = 0; ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart = 0; ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0; ConfigInfo->VdmPhysicalVideoMemoryLength = 0; /* Describe the framebuffer. We claimed the range already. */ pExt->PhysicalFrameAddress = accessRanges[1].RangeStart; /* * Map all memory and I/O ranges into system virtual address space. * NB: The virtual addresses in the HwDevExt must match the number * and type of AccessRange entries. */ pVirtAddr = &pExt->IoPorts; /* Attempt to claim and map the memory and I/O address ranges. */ for( i = 0; i < NUM_ACCESS_RANGES; ++i, ++pVirtAddr ) { *pVirtAddr = VideoPortGetDeviceBase( pExt, accessRanges[i].RangeStart, accessRanges[i].RangeLength, accessRanges[i].RangeInIoSpace ); if( *pVirtAddr == NULL ) { return( ERROR_INVALID_PARAMETER ); } } /* Verify that supported hardware is present. */ chip_id = BOXV_detect( pExt, &pExt->FramebufLen ); if( !chip_id ) { /* If supported hardware was not found, free allocated resources. */ pVirtAddr = &pExt->IoPorts; for( i = 0; i < NUM_ACCESS_RANGES; ++i, ++pVirtAddr ) VideoPortFreeDeviceBase( pExt, *pVirtAddr ); return( ERROR_DEV_NOT_EXIST ); } /* We need to access VGA and other I/O ports. Fortunately the HAL doesn't * care at all how the I/O ports are or aren't mapped on x86 platforms. */ pExt->IOAddrVGA = NULL; /* Only support one attached monitor. */ pExt->NumMonitors = 1; /* Set up mode information. */ pExt->CurrentModeNumber = 0; pExt->NumValidModes = 0; for( i = 0; i < ulAllModes; ++i ) { vmpValidateMode( &VideoModes[i], pExt->FramebufLen ); if( VideoModes[i].bValid ) ++pExt->NumValidModes; } /* Only one adapter supported, no need to call us again. */ *Again = 0; /* Report the hardware names via registry. */ #define TEMP_CHIP_NAME L"bochs Mk II" pwszDesc = TEMP_CHIP_NAME; cbDesc = sizeof( TEMP_CHIP_NAME ); VideoPortSetRegistryParameters( pExt, L"HardwareInformation.ChipType", pwszDesc, cbDesc ); #define TEMP_DAC_NAME L"Integrated DAC" pwszDesc = TEMP_DAC_NAME; cbDesc = sizeof( TEMP_DAC_NAME ); VideoPortSetRegistryParameters( pExt, L"HardwareInformation.DacType", pwszDesc, cbDesc ); #define TEMP_ADAPTER_NAME L"VirtualBox/bochs" pwszDesc = TEMP_ADAPTER_NAME; cbDesc = sizeof( TEMP_ADAPTER_NAME ); VideoPortSetRegistryParameters( pExt, L"HardwareInformation.AdapterString", pwszDesc, cbDesc ); cbVramSize = pExt->FramebufLen; VideoPortSetRegistryParameters( pExt, L"HardwareInformation.MemorySize", &cbVramSize, sizeof( ULONG ) ); /* All is well. */ return( NO_ERROR ); }