Пример #1
0
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;
}
Пример #3
0
/* 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;
}