ULONG NTAPI VmxReadUlong(IN PHW_DEVICE_EXTENSION DeviceExtension, IN ULONG Index) { /* Program the index first, then read the value */ VideoPortWritePortUlong(DeviceExtension->IndexPort, Index); return VideoPortReadPortUlong(DeviceExtension->ValuePort); }
/* 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; }
/* 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; }