Beispiel #1
0
ULONG
NTAPI
DriverEntry(IN PVOID Context1,
            IN PVOID Context2)
{
    VIDEO_HW_INITIALIZATION_DATA InitData;

    /* Zero initialization structure and array of extensions, one per screen */
    DPRINT1("VMX-SVGAII Loading...\n");
    VideoPortZeroMemory(VmxDeviceExtensionArray, sizeof(VmxDeviceExtensionArray));
    VideoPortZeroMemory(&InitData, sizeof(InitData));

    /* Setup the initialization structure with VideoPort */
    InitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
    InitData.HwFindAdapter = VmxFindAdapter;
    InitData.HwInitialize = VmxInitialize;
    InitData.HwInterrupt = VmxInterrupt;
    InitData.HwStartIO = VmxStartIO;
    InitData.HwResetHw = VmxResetHw;
    InitData.HwGetPowerState = VmxGetPowerState;
    InitData.HwSetPowerState = VmxSetPowerState;
    InitData.HwGetVideoChildDescriptor = VmxGetVideoChildDescriptor;
    InitData.AdapterInterfaceType = PCIBus;
    InitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
    InitData.HwDeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
    return VideoPortInitialize(Context1, Context2, &InitData, NULL);
}
Beispiel #2
0
VP_STATUS NTAPI
VBEGetPowerState(
   PVOID HwDeviceExtension,
   ULONG HwId,
   PVIDEO_POWER_MANAGEMENT VideoPowerControl)
{
   INT10_BIOS_ARGUMENTS BiosRegisters;
   PVBE_DEVICE_EXTENSION VBEDeviceExtension =
     (PVBE_DEVICE_EXTENSION)HwDeviceExtension;

   if (HwId != DISPLAY_ADAPTER_HW_ID ||
       VideoPowerControl->Length < sizeof(VIDEO_POWER_MANAGEMENT))
      return ERROR_INVALID_FUNCTION;

   /*
    * Get general power support information.
    */

   VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
   BiosRegisters.Eax = VBE_POWER_MANAGEMENT_EXTENSIONS;
   BiosRegisters.Ebx = 0;
   BiosRegisters.Edi = 0;
   BiosRegisters.SegEs = 0;
   VBEDeviceExtension->Int10Interface.Int10CallBios(
      VBEDeviceExtension->Int10Interface.Context,
      &BiosRegisters);

   if ( VBE_GETRETURNCODE(BiosRegisters.Eax) == VBE_NOT_SUPPORTED)
      return ERROR_DEV_NOT_EXIST;
   if (VBE_GETRETURNCODE(BiosRegisters.Eax) != VBE_SUCCESS)
      return ERROR_INVALID_FUNCTION;

   /*
    * Get current power state.
    */

   VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
   BiosRegisters.Eax = VBE_POWER_MANAGEMENT_EXTENSIONS;
   BiosRegisters.Ebx = 0x2;
   BiosRegisters.Edi = 0;
   BiosRegisters.SegEs = 0;
   VBEDeviceExtension->Int10Interface.Int10CallBios(
      VBEDeviceExtension->Int10Interface.Context,
      &BiosRegisters);

   if (VBE_GETRETURNCODE(BiosRegisters.Eax) == VBE_SUCCESS)
   {
      VideoPowerControl->DPMSVersion = BiosRegisters.Ebx & 0xFF;
      switch (BiosRegisters.Ebx >> 8)
      {
         case 0: VideoPowerControl->PowerState = VideoPowerOn; break;
         case 1: VideoPowerControl->PowerState = VideoPowerStandBy; break;
         case 2: VideoPowerControl->PowerState = VideoPowerSuspend; break;
         case 4: VideoPowerControl->PowerState = VideoPowerOff; break;
         case 5: VideoPowerControl->PowerState = VideoPowerOn; break;
         default: VideoPowerControl->PowerState = VideoPowerUnspecified;
      }

      return NO_ERROR;
   }
Beispiel #3
0
ULONG NTAPI
DriverEntry(IN PVOID Context1, IN PVOID Context2)
{
  VIDEO_HW_INITIALIZATION_DATA InitData;

  VideoPortZeroMemory(&InitData, sizeof(InitData));
  InitData.AdapterInterfaceType = PCIBus;
  InitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
  InitData.HwFindAdapter = XboxVmpFindAdapter;
  InitData.HwInitialize = XboxVmpInitialize;
  InitData.HwStartIO = XboxVmpStartIO;
  InitData.HwResetHw = XboxVmpResetHw;
  InitData.HwGetPowerState = XboxVmpGetPowerState;
  InitData.HwSetPowerState = XboxVmpSetPowerState;
  InitData.HwDeviceExtensionSize = sizeof(XBOXVMP_DEVICE_EXTENSION);

  return VideoPortInitialize(Context1, Context2, &InitData, NULL);
}
Beispiel #4
0
ULONG NTAPI
DriverEntry(IN PVOID Context1, IN PVOID Context2)
{
   VIDEO_HW_INITIALIZATION_DATA InitData;

   VideoPortZeroMemory(&InitData, sizeof(InitData));
   InitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
   InitData.HwFindAdapter = VBEFindAdapter;
   InitData.HwInitialize = VBEInitialize;
   InitData.HwStartIO = VBEStartIO;
   InitData.HwResetHw = VBEResetHw;
   InitData.HwGetPowerState = VBEGetPowerState;
   InitData.HwSetPowerState = VBESetPowerState;
   InitData.HwGetVideoChildDescriptor = VBEGetVideoChildDescriptor;
   InitData.HwDeviceExtensionSize = sizeof(VBE_DEVICE_EXTENSION);

   return VideoPortInitialize(Context1, Context2, &InitData, NULL);
}
Beispiel #5
0
VOID
VgaSizeMemory(
    PHW_DEVICE_EXTENSION HwDeviceExtension
    )
/*++

Routine Description:

    This routine determines the amount of VideoMemory on the adapter.

Arguments:

    HwDeviceExtension - Pointer to the miniport driver's device extension.


Return Value:

    None.

--*/
{

#ifdef INT10_MODE_SET

    VIDEO_X86_BIOS_ARGUMENTS biosArguments;

    VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
    biosArguments.Eax = 0x6f07;

    if (VideoPortInt10(HwDeviceExtension, &biosArguments) == NO_ERROR) {

        //
        // int 10 function 6f07 returns al = 6f, ah = # of 256K byte segments
        // high bit of ah = 1 if vram, 0 if dram
        //

        biosArguments.Eax &= 0x7f00;  // Strip off unused bits

        HwDeviceExtension->AdapterMemorySize = ((biosArguments.Eax >> 8) << 18);

    } else
Beispiel #6
0
ULONG NTAPI
DriverEntry(IN PVOID Context1,
            IN PVOID Context2)
{
    VIDEO_HW_INITIALIZATION_DATA  InitData;

    VideoPortZeroMemory(&InitData, sizeof InitData);

    InitData.HwInitDataSize = sizeof(InitData);
    /* FIXME: Fill in InitData members  */
    InitData.StartingDeviceNumber = 0;

    /*  Export driver entry points...  */
    InitData.HwFindAdapter = VGAFindAdapter;
    InitData.HwInitialize = VGAInitialize;
    InitData.HwStartIO = VGAStartIO;
    /* InitData.HwInterrupt = VGAInterrupt;  */
    InitData.HwResetHw = VGAResetHw;
    /* InitData.HwTimer = VGATimer;  */

    return  VideoPortInitialize(Context1, Context2, &InitData, NULL);
}
/* 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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
ULONG
DriverEntry (
    PVOID Context1,
    PVOID Context2
    )

/*++

Routine Description:

    Installable driver initialization entry point.
    This entry point is called directly by the I/O system.

Arguments:

    Context1 - First context value passed by the operating system. This is
        the value with which the miniport driver calls VideoPortInitialize().

    Context2 - Second context value passed by the operating system. This is
        the value with which the miniport driver calls VideoPortInitialize().

Return Value:

    Status from VideoPortInitialize()

--*/

{

    VIDEO_HW_INITIALIZATION_DATA hwInitData;

    //
    // Zero out structure.
    //

    VideoPortZeroMemory(&hwInitData, sizeof(VIDEO_HW_INITIALIZATION_DATA));

    //
    // Specify sizes of structure and extension.
    //

    hwInitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);

    //
    // Set entry points.
    //

    hwInitData.HwFindAdapter = DGXFindAdapter;
    hwInitData.HwInitialize = DGXInitialize;
    hwInitData.HwInterrupt = NULL;
    hwInitData.HwStartIO = DGXStartIO;

    //
    // Determine the size we require for the device extension.
    //

    hwInitData.HwDeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);

    //
    // Always start with parameters for device0 in this case.
    //

//    hwInitData.StartingDeviceNumber = 0;

    //
    // This device only supports the internal bus type. So return the status
    // value directly to the operating system.
    //

    hwInitData.AdapterInterfaceType = Eisa;

    return VideoPortInitialize(Context1,
                               Context2,
                               &hwInitData,
                               NULL);

} // end DriverEntry()
Beispiel #10
0
ULONG
DriverEntry (
    PVOID Context1,
    PVOID Context2
    )

/*++

Routine Description:

    Installable driver initialization entry point.
    This entry point is called directly by the I/O system.

Arguments:

    Context1 - First context value passed by the operating system. This is
        the value with which the miniport driver calls VideoPortInitialize().

    Context2 - Second context value passed by the operating system. This is
        the value with which the miniport driver calls VideoPortInitialize().

Return Value:

    Status from VideoPortInitialize()

--*/

{
    VIDEO_HW_INITIALIZATION_DATA hwInitData;
    ULONG initializationStatus;
    ULONG status;

    //
    // Zero out structure.
    //

    VideoPortZeroMemory(&hwInitData, sizeof(VIDEO_HW_INITIALIZATION_DATA));

    //
    // Specify sizes of structure and extension.
    //

    hwInitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);

    //
    // Set entry points.
    //

    hwInitData.HwFindAdapter = A8514FindAdapter;
    hwInitData.HwInitialize = A8514Initialize;
    hwInitData.HwInterrupt = NULL;
    hwInitData.HwStartIO = A8514StartIO;

    //
    // Determine the size we require for the device extension.
    //

    hwInitData.HwDeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);

    //
    // This device only supports many bus types.
    //

    hwInitData.AdapterInterfaceType = Isa;

    initializationStatus = VideoPortInitialize(Context1,
                                               Context2,
                                               &hwInitData,
                                               NULL);

    hwInitData.AdapterInterfaceType = Eisa;

    status = VideoPortInitialize(Context1,
                                     Context2,
                                     &hwInitData,
                                     NULL);

    if (initializationStatus > status) {
        initializationStatus = status;
    }

    hwInitData.AdapterInterfaceType = MicroChannel;

    status = VideoPortInitialize(Context1,
                                 Context2,
                                 &hwInitData,
                                 NULL);

    if (initializationStatus > status) {
        initializationStatus = status;
    }

    return initializationStatus;

} // end DriverEntry()
Beispiel #11
0
VP_STATUS
NTAPI
VbeSetColorLookup(IN PHW_DEVICE_EXTENSION VgaExtension,
                  IN PVIDEO_CLUT ClutBuffer)
{
    PVBE_COLOR_REGISTER VesaClut;
    INT10_BIOS_ARGUMENTS BiosArguments;
    PVOID Context;
    ULONG Entries;
    ULONG BufferSize = 4 * 1024;
    USHORT TrampolineMemorySegment, TrampolineMemoryOffset;
    VP_STATUS Status;
    USHORT i;
    PVIDEOMODE CurrentMode = VgaExtension->CurrentMode;

    Entries = ClutBuffer->NumEntries;
    
    VideoDebugPrint((0, "Setting %lu entries.\n", Entries));
    
    /* 
     * For Vga compatible modes, write them directly.
     * Otherwise, the LGPL VGABIOS (used in bochs) fails!
     * It is also said that this way is faster.
     */
    if(!CurrentMode->NonVgaMode)
    {
        for (i=ClutBuffer->FirstEntry; i<ClutBuffer->FirstEntry + Entries; i++)
        {
            VideoPortWritePortUchar((PUCHAR)0x03c8, i);
            VideoPortWritePortUchar((PUCHAR)0x03c9, ClutBuffer->LookupTable[i].RgbArray.Red);
            VideoPortWritePortUchar((PUCHAR)0x03c9, ClutBuffer->LookupTable[i].RgbArray.Green);
            VideoPortWritePortUchar((PUCHAR)0x03c9, ClutBuffer->LookupTable[i].RgbArray.Blue);
        }
        return NO_ERROR;
    }

    /* Allocate INT10 context/buffer */
    VesaClut = VideoPortAllocatePool(VgaExtension, 1, sizeof(ULONG) * Entries, ' agV');
    if (!VesaClut) return ERROR_INVALID_PARAMETER;
    if (!VgaExtension->Int10Interface.Size) return ERROR_INVALID_PARAMETER;
    Context = VgaExtension->Int10Interface.Context;
    Status = VgaExtension->Int10Interface.Int10AllocateBuffer(Context,
                                                            &TrampolineMemorySegment,
                                                            &TrampolineMemoryOffset,
                                                            &BufferSize);
    if (Status != NO_ERROR) return ERROR_INVALID_PARAMETER;

    /* VESA has color registers backward! */
    for (i = 0; i < Entries; i++)
    {
        VesaClut[i].Blue = ClutBuffer->LookupTable[i].RgbArray.Blue;
        VesaClut[i].Green = ClutBuffer->LookupTable[i].RgbArray.Green;
        VesaClut[i].Red = ClutBuffer->LookupTable[i].RgbArray.Red;
        VesaClut[i].Pad = 0;
    }
    Status = VgaExtension->Int10Interface.Int10WriteMemory(Context,
                                                         TrampolineMemorySegment,
                                                         TrampolineMemoryOffset,
                                                         VesaClut,
                                                         Entries * sizeof(ULONG));
    if (Status != NO_ERROR) return ERROR_INVALID_PARAMETER;

    /* Write the palette */
    VideoPortZeroMemory(&BiosArguments, sizeof(BiosArguments));
    BiosArguments.Ebx = 0;
    BiosArguments.Ecx = Entries;
    BiosArguments.Edx = ClutBuffer->FirstEntry;
    BiosArguments.Edi = TrampolineMemoryOffset;
    BiosArguments.SegEs = TrampolineMemorySegment;
    BiosArguments.Eax = VBE_SET_GET_PALETTE_DATA;
    Status = VgaExtension->Int10Interface.Int10CallBios(Context, &BiosArguments);
    if (Status != NO_ERROR) return ERROR_INVALID_PARAMETER;
    VideoPortFreePool(VgaExtension, VesaClut);
    VideoDebugPrint((Error, "VBE Status: %lx\n", BiosArguments.Eax));
    if (VBE_GETRETURNCODE(BiosArguments.Eax) == VBE_SUCCESS)
        return NO_ERROR;
    return ERROR_INVALID_PARAMETER;
}
Beispiel #12
0
ULONG
DriverEntry (
    PVOID Context1,
    PVOID Context2
    )

/*++

Routine Description:

    Installable driver initialization entry point.
    This entry point is called directly by the I/O system.

Arguments:

    Context1 - First context value passed by the operating system. This is
        the value with which the miniport driver calls VideoPortInitialize().

    Context2 - Second context value passed by the operating system. This is
        the value with which the miniport driver calls VideoPortInitialize().

Return Value:

    Status from VideoPortInitialize()

--*/

{

    VIDEO_HW_INITIALIZATION_DATA hwInitData;
    ULONG status;
    ULONG initializationStatus;

    //
    // Zero out structure.
    //

    VideoPortZeroMemory(&hwInitData, sizeof(VIDEO_HW_INITIALIZATION_DATA));

    //
    // Specify sizes of structure and extension.
    //

    hwInitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);

    //
    // Set entry points.
    //

    hwInitData.HwFindAdapter = SimFindAdapter;
    hwInitData.HwInitialize = SimInitialize;
    hwInitData.HwInterrupt = NULL;
    hwInitData.HwStartIO = SimStartIO;

    //
    // Determine the size we require for the device extension.
    //

    hwInitData.HwDeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);

    //
    // Always start with parameters for device0 in this case.
    //

//    hwInitData.StartingDeviceNumber = 0;

    //
    // Once all the relevant information has been stored, call the video
    // port driver to do the initialization.
    // For this device we will repeat this call three times, for ISA, EISA
    // and MCA.
    // We will return the minimum of all return values.
    //

    hwInitData.AdapterInterfaceType = Isa;

    initializationStatus = VideoPortInitialize(Context1,
                                               Context2,
                                               &hwInitData,
                                               &DeviceCount);

    hwInitData.AdapterInterfaceType = Eisa;

    status = VideoPortInitialize(Context1,
                                 Context2,
                                 &hwInitData,
                                 &DeviceCount);

    if (initializationStatus > status) {
        initializationStatus = status;
    }

    hwInitData.AdapterInterfaceType = MicroChannel;

    status = VideoPortInitialize(Context1,
                                 Context2,
                                 &hwInitData,
                                 &DeviceCount);

    if (initializationStatus > status) {
        initializationStatus = status;
    }

    hwInitData.AdapterInterfaceType = Internal;

    status = VideoPortInitialize(Context1,
                                 Context2,
                                 &hwInitData,
                                 &DeviceCount);

    if (initializationStatus > status) {
        initializationStatus = status;
    }

    hwInitData.AdapterInterfaceType = PCIBus;

    status = VideoPortInitialize(Context1,
                                 Context2,
                                 &hwInitData,
                                 &DeviceCount);

    if (initializationStatus > status) {
        initializationStatus = status;
    }

    return initializationStatus;

} // end DriverEntry()
Beispiel #13
0
VOID
VgaValidateModes(
    PHW_DEVICE_EXTENSION HwDeviceExtension
    )

/*++

Routine Description:

    Determines which modes are valid and which are not.

Arguments:

    HwDeviceExtension - Pointer to the miniport driver's device extension.

Return Value:

    None.

--*/
{

    ULONG i;
    VIDEO_X86_BIOS_ARGUMENTS biosArguments;
    ULONG   ulAvailMemory;                      // Available memory on the card.

    /***********************************************************************
    ***   On the AVGA cards, the amount of memory is hardcoded           ***
    ***   in the BIOS.  To determine the amount of memory available      ***
    ***   on the card, we need to perform an INT 10 bios call.           ***
    ***********************************************************************/

    VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));

    /***********************************************************************
    ***   To find out if we only have 256Kb of RAM on the board we need  ***
    ***   to determine if 640x480x256 color modes are supported.         ***
    ***   If the mode is supported, we have at least 512kb of RAM.       ***
    ***   To determine if this mode is supported we need to perform      ***
    ***   An INT 10 call to get the video environment.                   ***
    ***                         AH = BFh ; AL = 03h ; BX = 00h                          ***
    ***   Then we need to test bit 6.  If it is set, the mode is         ***
    ***   supported and we have at least 512Kb on the board.             ***
    ***********************************************************************/

    biosArguments.Eax = 0xBF03;
    VideoPortInt10(HwDeviceExtension, &biosArguments);
    VideoDebugPrint((2,"AVGA.SYS: biosArguments.Ecx = %x\n",biosArguments.Ecx));
    VideoDebugPrint((2,"AVGA.SYS: VgaValidateModes - "));

    if (biosArguments.Ecx & 0x40) {

        VideoDebugPrint((2,"512Kb RAM on the board.\n"));
        ulAvailMemory = 0x80000;

    } else {

        VideoDebugPrint((2,"256Kb RAM on the board.\n"));
        ulAvailMemory = 0x40000;
    }

    //
    // Store the number of modes into the buffer.
    //

    HwDeviceExtension->NumAvailableModes = 0;

    for (i = 0; i < NUM_VIDEO_MODES; i++) {

        if (ModesVGA[i].sbytes > ulAvailMemory) {   // Does the card have

            ModesVGA[i].ValidMode = FALSE;          // enough memory to support
            continue;                               // this mode ?

        }

        if ((HwDeviceExtension->DisplayType == PANEL) &&
            (ModesVGA[i].hres == 800)) {

            VideoDebugPrint((2,"AVGA.sys: VgaValidateModes - 800x600 mode with PANEL = %x\n",i));
            ModesVGA[i].ValidMode = FALSE;

        } else {

            VideoDebugPrint((2,"AVGA.sys: VgaValidateModes - Valid Mode %x\n",i));
            ModesVGA[i].ValidMode = TRUE;
            HwDeviceExtension->NumAvailableModes ++;

        }
    }

    VideoDebugPrint((2,"AVGA.sys: VgaValidateModes - NumMode = %x.\n",
                     HwDeviceExtension->NumAvailableModes));

}
Beispiel #14
0
/* Standard NT driver initialization entry point. */
ULONG DriverEntry( PVOID Context1, PVOID Context2 )
{
    VIDEO_HW_INITIALIZATION_DATA    hwInitData;
    ULONG                           status;

    VideoDebugPrint( (1, "videomp: DriverEntry\n") );

    /* Prepare the initialization structure. */
    VideoPortZeroMemory( &hwInitData, sizeof( VIDEO_HW_INITIALIZATION_DATA ) );
    hwInitData.HwInitDataSize = sizeof( VIDEO_HW_INITIALIZATION_DATA );

    /* Set up driver callbacks. */
    hwInitData.HwFindAdapter = HwVidFindAdapter;
    hwInitData.HwInitialize  = HwVidInitialize;
    hwInitData.HwStartIO     = HwVidStartIO;
    /* There's no interrupt or timer callback. */
    hwInitData.HwInterrupt   = NULL;
    hwInitData.HwTimer       = NULL;
    hwInitData.HwResetHw     = HwVidResetHw;

    /* Power and child device management callbacks were added in NT 5.0. */
    hwInitData.HwGetPowerState           = HwGetPowerState;
    hwInitData.HwSetPowerState           = HwSetPowerState;
    hwInitData.HwGetVideoChildDescriptor = HwGetChildDesc;

    /* Report legacy resources. */
    hwInitData.HwLegacyResourceList  = LegacyRanges;
    hwInitData.HwLegacyResourceCount = ulNumLegacyRanges;

    /* Report the device extension size. */
    hwInitData.HwDeviceExtensionSize = sizeof( HW_DEV_EXT );

    /* Refer to the CurrentControlSet\Services\xxx\Device0 registry key. */
    hwInitData.StartingDeviceNumber = 0;

    /* Later NT versions support PCI; recent versions ignore this entirely */
    hwInitData.AdapterInterfaceType = PCIBus;

    /* The PsGetVersion function was not available in NT 3.x. We therefore 
     * implement a poor man's version detection by successively reducing the
     * HwInitDataSize until the video miniport (we hope) accepts it.
     */
    do {
        /* First try with NT 5.1 (Windows XP) structure size. */
        VideoDebugPrint( (1, "videomp: Trying DDI 5.1 HwInitDataSize\n") );
        hwInitData.HwInitDataSize = SIZE_OF_WXP_VIDEO_HW_INITIALIZATION_DATA;
        PortVersion = VP_VER_XP;
        status = VideoPortInitialize( Context1, Context2, &hwInitData, NULL );
        if( status != STATUS_REVISION_MISMATCH ) {
            /* If status is anything other than a version mismatch, don't
             * try calling VideoPortInitialize again. The call may have
             * succeeded, or it failed for some reason whe can't easily fix.
             */
            break;
        }

        /* Try the NT 5.0 (Windows 2000) structure size. */
        VideoDebugPrint( (1, "videomp: Trying DDI 5.0 HwInitDataSize\n") );
        hwInitData.HwInitDataSize = SIZE_OF_W2K_VIDEO_HW_INITIALIZATION_DATA;
        PortVersion = VP_VER_W2K;
        status = VideoPortInitialize( Context1, Context2, &hwInitData, NULL );
        if( status != STATUS_REVISION_MISMATCH ) {
            break;
        }

        /* Try the NT 4.0 (and also NT 3.51) structure size. */
        VideoDebugPrint( (1, "videomp: Trying DDI 4.0 HwInitDataSize\n") );
        hwInitData.HwInitDataSize = SIZE_OF_NT4_VIDEO_HW_INITIALIZATION_DATA;
        PortVersion = VP_VER_NT4;
        status = VideoPortInitialize( Context1, Context2, &hwInitData, NULL );
        if( status != STATUS_REVISION_MISMATCH ) {
            break;
        }

        /* Try the original NT 3.1/3.5 HwInitDataSize. No PCI support. */
        VideoDebugPrint( (1, "videomp: Trying DDI 3.1 HwInitDataSize\n") );
        hwInitData.HwInitDataSize = offsetof( VIDEO_HW_INITIALIZATION_DATA, HwResetHw );
        hwInitData.AdapterInterfaceType = Isa;
        PortVersion = VP_VER_NT31;
        status = VideoPortInitialize( Context1, Context2, &hwInitData, NULL );
    } while( 0 );
    VideoDebugPrint( (1, "videomp: VideoPortInitialize rc=%08x\n", status ) );
    return( status );
}
/* Video Miniport Driver entry point */
ULONG DriverEntry(IN PVOID Context1, IN PVOID Context2)
{
    PAGED_CODE();

    int irc = RTR0Init(0);
    if (RT_FAILURE(irc))
    {
        LogRel(("VBoxMP::failed to init IPRT (rc=%#x)", irc));
        return ERROR_INVALID_FUNCTION;
    }

    LOGF_ENTER();

    LOGREL(("VBox XPDM Driver for Windows version %d.%d.%dr%d, %d bit; Built %s %s",
            VBOX_VERSION_MAJOR, VBOX_VERSION_MINOR, VBOX_VERSION_BUILD, VBOX_SVN_REV,
            (sizeof (void*) << 3), __DATE__, __TIME__));

    VIDEO_HW_INITIALIZATION_DATA vhwData;

    /*Zero the structure*/
    VideoPortZeroMemory(&vhwData, sizeof(vhwData));

    /*Required driver callbacks*/
    vhwData.HwFindAdapter    = VBoxDrvFindAdapter;
    vhwData.HwInitialize     = VBoxDrvInitialize;
    vhwData.HwStartIO        = VBoxDrvStartIO;
    vhwData.HwSetPowerState  = VBoxDrvSetPowerState;
    vhwData.HwGetPowerState  = VBoxDrvGetPowerState;
    vhwData.HwGetVideoChildDescriptor = VBoxDrvGetVideoChildDescriptor;

    /*Optional callbacks*/
    vhwData.HwResetHw     = VBoxDrvResetHW;
#ifdef VBOX_WITH_VIDEOHWACCEL
    vhwData.HwInterrupt   = VBoxDrvInterrupt;
#endif

    /*Our private storage space*/
    vhwData.HwDeviceExtensionSize = sizeof(VBOXMP_DEVEXT);

    /*Claim legacy VGA resource ranges*/
    vhwData.HwLegacyResourceList  = g_aVBoxLegacyVGAResources;
    vhwData.HwLegacyResourceCount = RT_ELEMENTS(g_aVBoxLegacyVGAResources);

    /*Size of this structure changes between windows/ddk versions,
     *so we query current version and report the expected size
     *to allow our driver to be loaded.
     */
    switch (VBoxQueryWinVersion(NULL))
    {
        case WINVERSION_NT4:
            LOG(("WINVERSION_NT4"));
            vhwData.HwInitDataSize = SIZE_OF_NT4_VIDEO_HW_INITIALIZATION_DATA;
            break;
        case WINVERSION_2K:
            LOG(("WINVERSION_2K"));
            vhwData.HwInitDataSize = SIZE_OF_W2K_VIDEO_HW_INITIALIZATION_DATA;
            break;
        default:
            vhwData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
            break;
    }

    /*Even though msdn claims that this field is ignored and should remain zero-initialized,
      windows NT4 SP0 dies without the following line.
     */
    vhwData.AdapterInterfaceType = PCIBus;

    /*Allocate system resources*/
    ULONG rc = VideoPortInitialize(Context1, Context2, &vhwData, NULL);
    if (rc != NO_ERROR)
        LOG(("VideoPortInitialize failed with %#x", rc));

    LOGF_LEAVE();
    return rc;
}
Beispiel #16
0
/* 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 );
}
Beispiel #17
0
BOOLEAN NTAPI
VBEInitialize(PVOID HwDeviceExtension)
{
   INT10_BIOS_ARGUMENTS BiosRegisters;
   VP_STATUS Status;
   PVBE_DEVICE_EXTENSION VBEDeviceExtension =
     (PVBE_DEVICE_EXTENSION)HwDeviceExtension;
   ULONG Length;
   ULONG ModeCount;
   ULONG SuitableModeCount;
   USHORT ModeTemp;
   ULONG CurrentMode;
   PVBE_MODEINFO VbeModeInfo;

   /*
    * Get the Int 10 interface that we will use for allocating real
    * mode memory and calling the video BIOS.
    */

   VBEDeviceExtension->Int10Interface.Version = VIDEO_PORT_INT10_INTERFACE_VERSION_1;
   VBEDeviceExtension->Int10Interface.Size = sizeof(VIDEO_PORT_INT10_INTERFACE);
   Status = VideoPortQueryServices(
      HwDeviceExtension,
      VideoPortServicesInt10,
      (PINTERFACE)&VBEDeviceExtension->Int10Interface);

   if (Status != NO_ERROR)
   {
      VideoPortDebugPrint(Error, "Failed to get Int 10 service functions (Status %x)\n", Status);
      return FALSE;
   }

   /*
    * Allocate a bit of memory that will be later used for VBE transport
    * buffer. This memory must be accessible from V86 mode so it must fit
    * in the first megabyte of physical memory.
    */

   Length = 0x400;
   Status = VBEDeviceExtension->Int10Interface.Int10AllocateBuffer(
      VBEDeviceExtension->Int10Interface.Context,
      &VBEDeviceExtension->TrampolineMemorySegment,
      &VBEDeviceExtension->TrampolineMemoryOffset,
      &Length);

   if (Status != NO_ERROR)
   {
      VideoPortDebugPrint(Error, "Failed to allocate virtual memory (Status %x)\n", Status);
      return FALSE;
   }

   /*
    * Get the VBE general information.
    */

   VBEDeviceExtension->Int10Interface.Int10WriteMemory(
      VBEDeviceExtension->Int10Interface.Context,
      VBEDeviceExtension->TrampolineMemorySegment,
      VBEDeviceExtension->TrampolineMemoryOffset,
      "VBE2",
      4);

   VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
   BiosRegisters.Eax = VBE_GET_CONTROLLER_INFORMATION;
   BiosRegisters.Edi = VBEDeviceExtension->TrampolineMemoryOffset;
   BiosRegisters.SegEs = VBEDeviceExtension->TrampolineMemorySegment;
   VBEDeviceExtension->Int10Interface.Int10CallBios(
      VBEDeviceExtension->Int10Interface.Context,
      &BiosRegisters);

   if (VBE_GETRETURNCODE(BiosRegisters.Eax) == VBE_SUCCESS)
   {
      VBEDeviceExtension->Int10Interface.Int10ReadMemory(
         VBEDeviceExtension->Int10Interface.Context,
         VBEDeviceExtension->TrampolineMemorySegment,
         VBEDeviceExtension->TrampolineMemoryOffset,
         &VBEDeviceExtension->VbeInfo,
         sizeof(VBEDeviceExtension->VbeInfo));

      /* Verify the VBE signature. */
      if (VideoPortCompareMemory(VBEDeviceExtension->VbeInfo.Signature, "VESA", 4) != 4)
      {
         VideoPortDebugPrint(Error, "No VBE BIOS present\n");
         return FALSE;
      }

      VideoPortDebugPrint(Trace, "VBE BIOS Present (%d.%d, %8ld Kb)\n",
         VBEDeviceExtension->VbeInfo.Version / 0x100,
         VBEDeviceExtension->VbeInfo.Version & 0xFF,
         VBEDeviceExtension->VbeInfo.TotalMemory * 64);

#ifdef VBE12_SUPPORT
      if (VBEDeviceExtension->VbeInfo.Version < 0x102)
#else
      if (VBEDeviceExtension->VbeInfo.Version < 0x200)
#endif
      {
         VideoPortDebugPrint(Error, "VBE BIOS present, but incompatible version %d.%d\n",
                             VBEDeviceExtension->VbeInfo.Version / 0x100,
                             VBEDeviceExtension->VbeInfo.Version & 0xFF);
         return FALSE;
      }
   }
   else
   {
      VideoPortDebugPrint(Error, "No VBE BIOS found.\n");
      return FALSE;
   }

   /*
    * Build a mode list here that can be later used by
    * IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES and IOCTL_VIDEO_QUERY_AVAIL_MODES
    * calls.
    */

   /*
    * Get the number of supported video modes.
    *
    * No need to be map the memory. It's either in the video BIOS memory or
    * in our trampoline memory. In either case the memory is already mapped.
    */

   for (ModeCount = 0; ; ModeCount++)
   {
      /* Read the VBE mode number. */
      VBEDeviceExtension->Int10Interface.Int10ReadMemory(
         VBEDeviceExtension->Int10Interface.Context,
         HIWORD(VBEDeviceExtension->VbeInfo.VideoModePtr),
         LOWORD(VBEDeviceExtension->VbeInfo.VideoModePtr) + (ModeCount << 1),
         &ModeTemp,
         sizeof(ModeTemp));

      /* End of list? */
      if (ModeTemp == 0xFFFF || ModeTemp == 0)
         break;
   }

   /*
    * Allocate space for video modes information.
    */

   VBEDeviceExtension->ModeInfo =
      VideoPortAllocatePool(HwDeviceExtension, VpPagedPool, ModeCount * sizeof(VBE_MODEINFO), TAG_VBE);
   VBEDeviceExtension->ModeNumbers =
      VideoPortAllocatePool(HwDeviceExtension, VpPagedPool, ModeCount * sizeof(USHORT), TAG_VBE);

   /*
    * Get the actual mode infos.
    */

   for (CurrentMode = 0, SuitableModeCount = 0;
        CurrentMode < ModeCount;
        CurrentMode++)
   {
      /* Read the VBE mode number. */
      VBEDeviceExtension->Int10Interface.Int10ReadMemory(
         VBEDeviceExtension->Int10Interface.Context,
         HIWORD(VBEDeviceExtension->VbeInfo.VideoModePtr),
         LOWORD(VBEDeviceExtension->VbeInfo.VideoModePtr) + (CurrentMode << 1),
         &ModeTemp,
         sizeof(ModeTemp));

      /* Call VBE BIOS to read the mode info. */
      VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
      BiosRegisters.Eax = VBE_GET_MODE_INFORMATION;
      BiosRegisters.Ecx = ModeTemp;
      BiosRegisters.Edi = VBEDeviceExtension->TrampolineMemoryOffset + 0x200;
      BiosRegisters.SegEs = VBEDeviceExtension->TrampolineMemorySegment;
      VBEDeviceExtension->Int10Interface.Int10CallBios(
         VBEDeviceExtension->Int10Interface.Context,
         &BiosRegisters);

      /* Read the VBE mode info. */
      VBEDeviceExtension->Int10Interface.Int10ReadMemory(
         VBEDeviceExtension->Int10Interface.Context,
         VBEDeviceExtension->TrampolineMemorySegment,
         VBEDeviceExtension->TrampolineMemoryOffset + 0x200,
         VBEDeviceExtension->ModeInfo + SuitableModeCount,
         sizeof(VBE_MODEINFO));

      VbeModeInfo = VBEDeviceExtension->ModeInfo + SuitableModeCount;

      /* Is this mode acceptable? */
      if (VBE_GETRETURNCODE(BiosRegisters.Eax) == VBE_SUCCESS &&
          VbeModeInfo->XResolution >= 640 &&
          VbeModeInfo->YResolution >= 480 &&
          (VbeModeInfo->MemoryModel == VBE_MEMORYMODEL_PACKEDPIXEL ||
           VbeModeInfo->MemoryModel == VBE_MEMORYMODEL_DIRECTCOLOR) &&
          VbeModeInfo->PhysBasePtr != 0)
      {
         if (VbeModeInfo->ModeAttributes & VBE_MODEATTR_LINEAR)
         {
            /* Bit 15 14 13 12 | 11 10 9 8 | 7 6 5 4 | 3 2 1 0 */
             // if (ModeTemp & 0x4000)
             //{
                VBEDeviceExtension->ModeNumbers[SuitableModeCount] = ModeTemp | 0x4000;
                SuitableModeCount++;
             //}
         }
#ifdef VBE12_SUPPORT
         else
         {
            VBEDeviceExtension->ModeNumbers[SuitableModeCount] = ModeTemp;
            SuitableModeCount++;
         }
#endif
      }
   }


   if (SuitableModeCount == 0)
   {

      VideoPortDebugPrint(Warn, "VBEMP: No video modes supported\n");
      return FALSE;
   }

   VBEDeviceExtension->ModeCount = SuitableModeCount;

   /*
    * Sort the video mode list according to resolution and bits per pixel.
    */

   VBESortModes(VBEDeviceExtension);

   /*
    * Print the supported video modes.
    */

   for (CurrentMode = 0;
        CurrentMode < SuitableModeCount;
        CurrentMode++)
   {
      VideoPortDebugPrint(Trace, "%dx%dx%d\n",
         VBEDeviceExtension->ModeInfo[CurrentMode].XResolution,
         VBEDeviceExtension->ModeInfo[CurrentMode].YResolution,
         VBEDeviceExtension->ModeInfo[CurrentMode].BitsPerPixel);
   }

   /*
    * Enumerate our children.
    */
   VideoPortEnumerateChildren(HwDeviceExtension, NULL);

   return TRUE;
}
Beispiel #18
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;
}
Beispiel #19
0
VP_STATUS
VgaSetMode(
    PHW_DEVICE_EXTENSION HwDeviceExtension,
    PVIDEO_MODE Mode,
    ULONG ModeSize
    )

/*++

Routine Description:

    This routine sets the vga into the requested mode.

Arguments:

    HwDeviceExtension - Pointer to the miniport driver's device extension.

    Mode - Pointer to the structure containing the information about the
        font to be set.

    ModeSize - Length of the input buffer supplied by the user.

Return Value:

    ERROR_INSUFFICIENT_BUFFER if the input buffer was not large enough
        for the input data.

    ERROR_INVALID_PARAMETER if the mode number is invalid.

    NO_ERROR if the operation completed successfully.

--*/

{

    PVIDEOMODE pRequestedMode;
    VP_STATUS status;

#ifdef INT10_MODE_SET
    VIDEO_X86_BIOS_ARGUMENTS biosArguments;
#endif

    //
    // Check if the size of the data in the input buffer is large enough.
    //

    if (ModeSize < sizeof(VIDEO_MODE)) {

        return ERROR_INSUFFICIENT_BUFFER;

    }

    //
    // Extract the clear memory bit.
    //

    if (Mode->RequestedMode & VIDEO_MODE_NO_ZERO_MEMORY) {

        Mode->RequestedMode &= ~VIDEO_MODE_NO_ZERO_MEMORY;

    }  else {

        VgaZeroVideoMemory(HwDeviceExtension);

    }

    //
    // Check to see if we are requesting a valid mode
    //

    if ( (Mode->RequestedMode >= NumVideoModes) ||
         (!ModesVGA[Mode->RequestedMode].ValidMode) ) {

        return ERROR_INVALID_PARAMETER;

    }

    pRequestedMode = &ModesVGA[Mode->RequestedMode];

#ifdef INT10_MODE_SET

    VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));

    biosArguments.Ebx = pRequestedMode->Int10ModeNumber;

    if (biosArguments.Ebx != 0) {

        biosArguments.Eax = 0x6f05;

        status = VideoPortInt10(HwDeviceExtension, &biosArguments);

        if (status != NO_ERROR) {

            return status;

        }
    }

#endif

    //
    // Call the interpreter
    //

    VgaInterpretCmdStream(HwDeviceExtension,
                          pRequestedMode->CmdStrings[HwDeviceExtension->AdapterType]);

#ifdef INT10_MODE_SET
{
    UCHAR temp;
    UCHAR dummy;
    UCHAR bIsColor;

    if (!(pRequestedMode->fbType & VIDEO_MODE_GRAPHICS)) {

            //
            // Fix to make sure we always set the colors in text mode to be
            // intensity, and not flashing
            // For this zero out the Mode Control Regsiter bit 3 (index 0x10
            // of the Attribute controller).
            //

            if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
                    MISC_OUTPUT_REG_READ_PORT) & 0x01) {

                bIsColor = TRUE;

            } else {

                bIsColor = FALSE;

            }

            if (bIsColor) {

                dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
                        INPUT_STATUS_1_COLOR);
            } else {

                dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
                        INPUT_STATUS_1_MONO);
            }

            VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
                    ATT_ADDRESS_PORT, (0x10 | VIDEO_ENABLE));
            temp = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
                    ATT_DATA_READ_PORT);

            temp &= 0xF7;

            if (bIsColor) {

                dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
                        INPUT_STATUS_1_COLOR);
            } else {

                dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
                        INPUT_STATUS_1_MONO);
            }

            VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
                    ATT_ADDRESS_PORT, (0x10 | VIDEO_ENABLE));
            VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
                    ATT_DATA_WRITE_PORT, temp);
    }
}

#endif

    //
    // Update the location of the physical frame buffer within video memory.
    //

    HwDeviceExtension->PhysicalFrameLength =
            MemoryMaps[pRequestedMode->MemMap].MaxSize;

    HwDeviceExtension->PhysicalFrameBase.LowPart =
            MemoryMaps[pRequestedMode->MemMap].Start;

    //
    // Store the new mode value.
    //

    HwDeviceExtension->ModeIndex = Mode->RequestedMode;
    HwDeviceExtension->CurrentMode = pRequestedMode;

    return NO_ERROR;

} //end VgaSetMode()
Beispiel #20
0
/*Query video port for api functions or fill with stubs if those are not supported*/
void VBoxSetupVideoPortAPI(PVBOXMP_DEVEXT pExt, PVIDEO_PORT_CONFIG_INFO pConfigInfo)
{
    VBOXVIDEOPORTPROCS *pAPI = &pExt->u.primary.VideoPortProcs;
    VideoPortZeroMemory(pAPI, sizeof(VBOXVIDEOPORTPROCS));

    if (VBoxQueryWinVersion() <= WINVERSION_NT4)
    {
        /* VideoPortGetProcAddress is available for >= win2k */
        pAPI->pfnWaitForSingleObject = vboxWaitForSingleObjectVoid;
        pAPI->pfnSetEvent = vboxSetEventVoid;
        pAPI->pfnClearEvent = vboxClearEventVoid;
        pAPI->pfnCreateEvent = vboxCreateEventVoid;
        pAPI->pfnDeleteEvent = vboxDeleteEventVoid;
        pAPI->pfnAllocatePool = vboxAllocatePoolVoid;
        pAPI->pfnFreePool = vboxFreePoolVoid;
        pAPI->pfnQueueDpc = vboxQueueDpcVoid;
        pAPI->pfnCreateSecondaryDisplay = vboxCreateSecondaryDisplayVoid;
        return;
    }

    VP_GETPROC(pfnWaitForSingleObject, PFNWAITFORSINGLEOBJECT, "VideoPortWaitForSingleObject");
    VP_GETPROC(pfnSetEvent, PFNSETEVENT, "VideoPortSetEvent");
    VP_GETPROC(pfnClearEvent, PFNCLEAREVENT, "VideoPortClearEvent");
    VP_GETPROC(pfnCreateEvent, PFNCREATEEVENT, "VideoPortCreateEvent");
    VP_GETPROC(pfnDeleteEvent, PFNDELETEEVENT, "VideoPortDeleteEvent");

    if(pAPI->pfnWaitForSingleObject
       && pAPI->pfnSetEvent
       && pAPI->pfnClearEvent
       && pAPI->pfnCreateEvent
       && pAPI->pfnDeleteEvent)
    {
        pAPI->fSupportedTypes |= VBOXVIDEOPORTPROCS_EVENT;
    }
    else
    {
        pAPI->pfnWaitForSingleObject = vboxWaitForSingleObjectVoid;
        pAPI->pfnSetEvent = vboxSetEventVoid;
        pAPI->pfnClearEvent = vboxClearEventVoid;
        pAPI->pfnCreateEvent = vboxCreateEventVoid;
        pAPI->pfnDeleteEvent = vboxDeleteEventVoid;
    }

    VP_GETPROC(pfnAllocatePool, PFNALLOCATEPOOL, "VideoPortAllocatePool");
    VP_GETPROC(pfnFreePool, PFNFREEPOOL, "VideoPortFreePool");

    if(pAPI->pfnAllocatePool
       && pAPI->pfnFreePool)
    {
        pAPI->fSupportedTypes |= VBOXVIDEOPORTPROCS_POOL;
    }
    else
    {
        pAPI->pfnAllocatePool = vboxAllocatePoolVoid;
        pAPI->pfnFreePool = vboxFreePoolVoid;
    }

    VP_GETPROC(pfnQueueDpc, PFNQUEUEDPC, "VideoPortQueueDpc");

    if(pAPI->pfnQueueDpc)
    {
        pAPI->fSupportedTypes |= VBOXVIDEOPORTPROCS_DPC;
    }
    else
    {
        pAPI->pfnQueueDpc = vboxQueueDpcVoid;
    }

    VP_GETPROC(pfnCreateSecondaryDisplay, PFNCREATESECONDARYDISPLAY, "VideoPortCreateSecondaryDisplay");

    if (pAPI->pfnCreateSecondaryDisplay)
    {
        pAPI->fSupportedTypes |= VBOXVIDEOPORTPROCS_CSD;
    }
    else
    {
        pAPI->pfnCreateSecondaryDisplay = vboxCreateSecondaryDisplayVoid;
    }
}
Beispiel #21
0
int VBoxVbvaEnable(PVBOXMP_DEVEXT pExt, BOOLEAN bEnable, VBVAENABLERESULT *pResult)
{
    int rc = VINF_SUCCESS;
    LOGF_ENTER();

    VMMDevMemory *pVMMDevMemory = NULL;

    rc = VbglQueryVMMDevMemory (&pVMMDevMemory);
    if (RT_FAILURE(rc))
    {
        WARN(("VbglQueryVMMDevMemory rc = %#xrc", rc));
        LOGF_LEAVE();
        return rc;
    }

    if (pExt->iDevice>0)
    {
        PVBOXMP_DEVEXT pPrimary = pExt->pPrimary;
        LOGF(("skipping non-primary display %d", pExt->iDevice));

        if (bEnable && pPrimary->u.primary.ulVbvaEnabled && pVMMDevMemory)
        {
            pResult->pVbvaMemory = &pVMMDevMemory->vbvaMemory;
            pResult->pfnFlush    = VBoxVbvaFlush;
            pResult->pvFlush     = pExt;
        }
        else
        {
            VideoPortZeroMemory(&pResult, sizeof(VBVAENABLERESULT));
        }

        LOGF_LEAVE();
        return rc;
    }

    /* Allocate the memory block for VMMDevReq_VideoAccelFlush request. */
    if (pExt->u.primary.pvReqFlush == NULL)
    {
        VMMDevVideoAccelFlush *req = NULL;

        rc = VbglGRAlloc((VMMDevRequestHeader **)&req, sizeof(VMMDevVideoAccelFlush), VMMDevReq_VideoAccelFlush);

        if (RT_SUCCESS(rc))
        {
            pExt->u.primary.pvReqFlush = req;
        }
        else
        {
            WARN(("VbglGRAlloc(VMMDevVideoAccelFlush) rc = %#xrc", rc));
            LOGF_LEAVE();
            return rc;
        }
    }

    ULONG ulEnabled = 0;

    VMMDevVideoAccelEnable *req = NULL;
    rc = VbglGRAlloc((VMMDevRequestHeader **)&req, sizeof(VMMDevVideoAccelEnable), VMMDevReq_VideoAccelEnable);

    if (RT_SUCCESS(rc))
    {
        req->u32Enable    = bEnable;
        req->cbRingBuffer = VBVA_RING_BUFFER_SIZE;
        req->fu32Status   = 0;

        rc = VbglGRPerform(&req->header);
        if (RT_SUCCESS(rc))
        {
            if (req->fu32Status & VBVA_F_STATUS_ACCEPTED)
            {
                LOG(("accepted"));

                /* Initialize the result information and VBVA memory. */
                if (req->fu32Status & VBVA_F_STATUS_ENABLED)
                {
                    pResult->pVbvaMemory = &pVMMDevMemory->vbvaMemory;
                    pResult->pfnFlush    = VBoxVbvaFlush;
                    pResult->pvFlush     = pExt;
                    ulEnabled = 1;
                }
                else
                {
                    VideoPortZeroMemory(&pResult, sizeof(VBVAENABLERESULT));
                }
            }
            else
            {
                LOG(("rejected"));

                /* Disable VBVA for old hosts. */
                req->u32Enable = 0;
                req->cbRingBuffer = VBVA_RING_BUFFER_SIZE;
                req->fu32Status = 0;

                VbglGRPerform(&req->header);

                rc = VERR_NOT_SUPPORTED;
            }
        }
        else
        {
            WARN(("rc = %#xrc", rc));
        }

        VbglGRFree(&req->header);
    }
    else
    {
        WARN(("VbglGRAlloc(VMMDevVideoAccelEnable) rc = %#xrc", rc));
    }

    pExt->u.primary.ulVbvaEnabled = ulEnabled;

    LOGF_LEAVE();
    return rc;
}
Beispiel #22
0
VP_STATUS
VgaSetMode(
    PHW_DEVICE_EXTENSION HwDeviceExtension,
    PVIDEO_MODE Mode,
    ULONG ModeSize
    )

/*++

Routine Description:

    This routine sets the VGA into the requested mode.

Arguments:

    HwDeviceExtension - Pointer to the miniport driver's device extension.

    Mode - Pointer to the structure containing the information about the
        font to be set.

    ModeSize - Length of the input buffer supplied by the user.

Return Value:

    ERROR_INSUFFICIENT_BUFFER if the input buffer was not large enough
        for the input data.

    ERROR_INVALID_PARAMETER if the mode number is invalid.

    NO_ERROR if the operation completed successfully.

--*/

{

   PVIDEOMODE pRequestedMode;
   VP_STATUS status;

   //
   // Check if the size of the data in the input buffer is large enough.
   //

   if (ModeSize < sizeof(VIDEO_MODE)) {

       return ERROR_INSUFFICIENT_BUFFER;

   }

   //
   // Extract the clear memory bit.
   //

   if (Mode->RequestedMode & VIDEO_MODE_NO_ZERO_MEMORY) {

       Mode->RequestedMode &= ~VIDEO_MODE_NO_ZERO_MEMORY;

   }  else {

       VgaZeroVideoMemory(HwDeviceExtension);

   }

   //
   // Check to see if we are requesting a valid mode
   //

   if ((Mode->RequestedMode >= NUM_VIDEO_MODES) ||
       (!ModesVGA[Mode->RequestedMode].ValidMode)) {

       VideoDebugPrint((0,"AVGA.sys: VGASetMode - ERROR_INVALID_PARAMETER.\n"));
       return ERROR_INVALID_PARAMETER;

   }

    pRequestedMode = &ModesVGA[Mode->RequestedMode];
    HwDeviceExtension->ModeIndex = Mode->RequestedMode;


    //
    // Store the new mode value.
    //

    HwDeviceExtension->CurrentMode = pRequestedMode;

#ifdef INT10_MODE_SET
{

    VIDEO_X86_BIOS_ARGUMENTS biosArguments;
    UCHAR temp;
    UCHAR dummy;
    UCHAR bIsColor;

    /***********************************************************************
    ***   There appears to be a problem with some application            ***
    ***   which reset the first 16 palette registers.                    ***
    ***   Since the palette is not reset when going to and               ***
    ***   from text modes by doing a set mode (instead of                ***
    ***   the hardware save restore), some colors might not              ***
    ***   appear as expected in the text modes.  The bios                ***
    ***   calls seem to reload the palette so Andre Vachon               ***
    ***   suggested that we implement an Int10 mode set for the          ***
    ***   text modes.                                                    ***
    ***   To accomplish this, we need to hard code the first             ***
    ***   three modes in modeset.h in the following switch.              ***
    ***   If more text modes are added to modeset.h, their               ***
    ***   index must be added to this switch statement.                  ***
    ***********************************************************************/
    VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
    switch (Mode->RequestedMode) {
       case 0:                               // 720x400
                    /***********************************************************************
          ***   Prepare the card for the VGA mode 3+ instead of the CGA mode 3  ***
                    ***********************************************************************/
         biosArguments.Eax = 0x1202;              // Select Scan line number
          biosArguments.Ebx = 0x0030;             // to be 400 scan lines
          status = VideoPortInt10(HwDeviceExtension, &biosArguments);

          /***********************************************************************
          ***   Set the video mode to BIOS mode 3.                              ***
          ***********************************************************************/
                    VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
          biosArguments.Eax = 0x03;          // bios mode 0x03
          status = VideoPortInt10(HwDeviceExtension, &biosArguments);
          break;
       case 1:                               // 640x350
          /***********************************************************************
          ***   Prepare the card for the EGA mode 3* instead of the CGA mode 3  ***
          ***********************************************************************/
         biosArguments.Eax = 0x1201;              // Select Scan line number
          biosArguments.Ebx = 0x0030;             // to be 350 scan lines
          status = VideoPortInt10(HwDeviceExtension, &biosArguments);

                    /***********************************************************************
          ***   Set the video mode to BIOS mode 3.                              ***
                    ***********************************************************************/
                    VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
          biosArguments.Eax = 0x03;          // bios mode 0x03
          status = VideoPortInt10(HwDeviceExtension, &biosArguments);
          break;

       default:                              // all graphics modes are
                                             // handled by the default case
          biosArguments.Eax = pRequestedMode->Int10ModeNumber;
          status = VideoPortInt10(HwDeviceExtension, &biosArguments);
          break;

    }

    if (status != NO_ERROR) {
        return status;
    }

    //
    // Fix to get 640x350 text mode
    //

    if (!(pRequestedMode->fbType & VIDEO_MODE_GRAPHICS)) {

//        if ((pRequestedMode->hres == 640) &&
//            (pRequestedMode->vres == 350)) {
//
//            VgaInterpretCmdStream(HwDeviceExtension, VGA_TEXT_1);
//
//        } else {

            //
            // Fix to make sure we always set the colors in text mode to be
            // intensity, and not flashing
            // For this zero out the Mode Control Regsiter bit 3 (index 0x10
            // of the Attribute controller).
            //

            if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
                    MISC_OUTPUT_REG_READ_PORT) & 0x01) {

                bIsColor = TRUE;

            } else {

                bIsColor = FALSE;

            }

            if (bIsColor) {

                dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
                        INPUT_STATUS_1_COLOR);
            } else {

                dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
                        INPUT_STATUS_1_MONO);
            }

            VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
                    ATT_ADDRESS_PORT, (0x10 | VIDEO_ENABLE));
            temp = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
                    ATT_DATA_READ_PORT);

            temp &= 0xF7;

            if (bIsColor) {

                dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
                        INPUT_STATUS_1_COLOR);
            } else {

                dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
                        INPUT_STATUS_1_MONO);
            }

            VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
                    ATT_ADDRESS_PORT, (0x10 | VIDEO_ENABLE));
            VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
                    ATT_DATA_WRITE_PORT, temp);
//        }
    }
}
#else
    VgaInterpretCmdStream(HwDeviceExtension, pRequestedMode->CmdStrings);
#endif

    //
    // Update the location of the physical frame buffer within video memory.
    //

    HwDeviceExtension->PhysicalFrameLength =
            MemoryMaps[pRequestedMode->MemMap].MaxSize;

    HwDeviceExtension->PhysicalFrameBase.LowPart =
            MemoryMaps[pRequestedMode->MemMap].Start;

    return NO_ERROR;

} // end VgaSetMode()