Exemple #1
0
VOID FASTCALL
VBESortModes(PVBE_DEVICE_EXTENSION DeviceExtension)
{
   BOOLEAN Finished = FALSE;
   ULONG Pos;
   int Result;
   VBE_MODEINFO TempModeInfo;
   USHORT TempModeNumber;

   while (!Finished)
   {
      Finished = TRUE;
      for (Pos = 0; Pos < DeviceExtension->ModeCount - 1; Pos++)
      {
         Result = VBESortModesCallback(
            DeviceExtension->ModeInfo + Pos,
            DeviceExtension->ModeInfo + Pos + 1);
         if (Result > 0)
         {
            Finished = FALSE;

            VideoPortMoveMemory(
               &TempModeInfo,
               DeviceExtension->ModeInfo + Pos,
               sizeof(VBE_MODEINFO));
            TempModeNumber = DeviceExtension->ModeNumbers[Pos];

            VideoPortMoveMemory(
               DeviceExtension->ModeInfo + Pos,
               DeviceExtension->ModeInfo + Pos + 1,
               sizeof(VBE_MODEINFO));
            DeviceExtension->ModeNumbers[Pos] =
               DeviceExtension->ModeNumbers[Pos + 1];

            VideoPortMoveMemory(
               DeviceExtension->ModeInfo + Pos + 1,
               &TempModeInfo,
               sizeof(VBE_MODEINFO));
            DeviceExtension->ModeNumbers[Pos + 1] = TempModeNumber;
         }
      }
   }
}
Exemple #2
0
/* Called for IOCTL_VIDEO_QUERY_AVAIL_MODES.
 * Returns information about supported video modes.
 */
BOOLEAN VBoxMPQueryAvailModes(PVBOXMP_DEVEXT pExt, PVIDEO_MODE_INFORMATION pModes, PSTATUS_BLOCK pStatus)
{
    LOGF_ENTER();

    ULONG ulSize = VBoxMPXpdmGetVideoModesCount()*sizeof(VIDEO_MODE_INFORMATION);
    pStatus->Information = ulSize;
    VideoPortMoveMemory(pModes, VBoxMPCmnGetVideoModeInfo(0), ulSize);

    LOGF_LEAVE();
    return TRUE;
}
Exemple #3
0
/* Called for IOCTL_VIDEO_QUERY_CURRENT_MODE.
 * Returns information about current video mode.
 */
BOOLEAN VBoxMPQueryCurrentMode(PVBOXMP_DEVEXT pExt, PVIDEO_MODE_INFORMATION pModeInfo, PSTATUS_BLOCK pStatus)
{
    LOGF_ENTER();

    pStatus->Information = sizeof(VIDEO_MODE_INFORMATION);

    VideoPortMoveMemory(pModeInfo, VBoxMPXpdmCurrentVideoMode(pExt), sizeof(VIDEO_MODE_INFORMATION));

    LOGF_LEAVE();
    return TRUE;
}
Exemple #4
0
BOOLEAN
ViperGetBaseAddr(
    PHW_DEVICE_EXTENSION HwDeviceExtension
    )

/*++

Routine Description:

    Perform board detection and if present return the P9000 base address.

Arguments:

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

Return Value:

TRUE    - Board found, P9 and Frame buffer address info was placed in
the device extension.

FALSE   - Board not found.

--*/
{
    VP_STATUS           status;
    SHORT               i;
    ULONG               ulBiosAddr;
    BOOLEAN             bValid = FALSE;

    VIDEO_ACCESS_RANGE  BiosAccessRange =
     {
        VGA_BIOS_ADDR,                      // Low address
        0x00000000,                     // Hi address
        VGA_BIOS_LEN,                           // length
        0,                              // Is range in i/o space?
        1,                              // Range should be visible
        1                               // Range should be shareable
     };

    if (HwDeviceExtension->MachineType == SIEMENS_P9100_VLB)
          return FALSE;

    //
    // Determine if a Viper card is installed by scanning the VGA BIOS ROM
    // memory space.
    //

    //
    // Map in the BIOS' memory space. If it can't be mapped,
    // return an error.
    //

    if (HwDeviceExtension->MachineType == SIEMENS)
    {
        BiosAccessRange.RangeStart.LowPart += 0x10000000L;
    }

    if (VideoPortVerifyAccessRanges(HwDeviceExtension,
                                    1,
                                    &BiosAccessRange) != NO_ERROR)
    {
        return(FALSE);
    }

    if ((ulBiosAddr = (ULONG)
        VideoPortGetDeviceBase(HwDeviceExtension,
                               BiosAccessRange.RangeStart,
                               BiosAccessRange.RangeLength,
                               FALSE)) == 0)
    {
        return(FALSE);
    }

    if (!VideoPortScanRom(HwDeviceExtension,
                         (PUCHAR) ulBiosAddr,
                         VGA_BIOS_LEN,
                         VIPER_VL_ID_STR))
    {
        VideoPortFreeDeviceBase(HwDeviceExtension, (PVOID) ulBiosAddr);
        return(FALSE);
    }

#ifdef REJECT_ON_BIOS_VERSION

    if (bRejectOnBiosVersion(HwDeviceExtension, (PUCHAR) ulBiosAddr, VGA_BIOS_LEN))
       return (FALSE);

#endif // REJECT_ON_BIOS_VERSION

    VideoPortFreeDeviceBase(HwDeviceExtension, (PVOID) ulBiosAddr);

    //
    // For now, pretend we have a Weitek 5x86 VGA. Later we may call the
    // Viper BIOS to determine which type of BIOS is installed.
    //

    HwDeviceExtension->AdapterDesc.bWtk5x86 = TRUE;

    //
    // Copy the DAC register access ranges to the global access range
    // structure.
    //

    VideoPortMoveMemory(&DriverAccessRanges[NUM_DRIVER_ACCESS_RANGES],
                            VLDefDACRegRange,
                            HwDeviceExtension->Dac.cDacRegs *
                            sizeof(VIDEO_ACCESS_RANGE));

    //
    // A value for the P9 base address may have beens found in the registry,
    // and it is now stored in the device extension. Ensure the address
    // value is valid for the Viper card. Then use it to compute
    // the starting address of the P9000 registers and frame buffer,
    // and store it in the device extension.
    //

    for (i = 0; i < NumMemRanges; i++)
    {
        if (HwDeviceExtension->P9PhysAddr.LowPart ==
            ViperMemRange[i].BaseMemAddr.LowPart)
        {
            bValid = TRUE;
            break;
        }
    }

    //
    // If the address value is invalid, or was not found in the registry,
    // use the default.
    //

    if (!bValid)
    {
        HwDeviceExtension->P9PhysAddr.LowPart = MemBase;
    }

    return(TRUE);
}
Exemple #5
0
BOOLEAN
PciGetBaseAddr(
    PHW_DEVICE_EXTENSION HwDeviceExtension
    )

/*++

Routine Description:

    Perform board detection and if present return the P9 base address.

Arguments:

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

Return Value:

TRUE    - Board found, P9 and Frame buffer address info was placed in
the device extension. PCI extended base address was placed in the
device extension.

FALSE   - Board not found.

--*/
{

    VIDEO_ACCESS_RANGE  PciAccessRange;
    PVIDEO_ACCESS_RANGE DefaultDACRegRange;
    ULONG               ulTempAddr;
    ULONG               ulBiosAddr;
    ULONG               ulBoardAddr;
    ULONG               ulTemp;
    LONG                i;
    VP_STATUS           status;

    ULONG               wcpID;

    //
    // Only the viper p9000 works on the Siemens boxes
    //

    if (HwDeviceExtension->MachineType == SIEMENS
    ||  HwDeviceExtension->MachineType == SIEMENS_P9100_VLB)
    {
        return FALSE;
    }

    //
    // See if the PCI HAL can locate a Weitek 9001 PCI Board.
    //

    //
    // First check for a P9100
    //

    if (PciFindDevice(HwDeviceExtension,
                      WTK_9100_ID,
                      WTK_VENDOR_ID,
                      &HwDeviceExtension->PciSlotNum))
    {
        wcpID = P9100_ID;
        HwDeviceExtension->usBusType = PCI;

        // Just a hack to get things working.
        // NOTE: !!! WE should really do the detection.

        HwDeviceExtension->p91State.bVideoPowerEnabled = FALSE;

        // Now make sure we are looking for a P9100, if were not
        // then fail.

        if (HwDeviceExtension->P9CoprocInfo.CoprocId != P9100_ID)
        {
            return(FALSE);
        }

#ifdef	_MIPS_
                //
                // SNI platform recognition and specific stuff
                //
        {

        extern VP_STATUS                GetCPUIdCallback(
               PVOID                    HwDeviceExtension,
               PVOID                    Context,
               VIDEO_DEVICE_DATA_TYPE   DeviceDataType,
               PVOID                    Identifier,
               ULONG                    IdentifierLength,
               PVOID                    ConfigurationData,
               ULONG                    ConfigurationDataLength,
               PVOID                    ComponentInformation,
               ULONG                    ComponentInformationLength
		);
        if(VideoPortIsCpu(L"RM200PCI")
        || VideoPortIsCpu(L"RM300PCI")
        || VideoPortIsCpu(L"RM300PCI MP")
        || VideoPortIsCpu(L"RM400PCI")
        || VideoPortIsCpu(L"RM4x0PCI"))
                {
                // adjust the VGA physical address with the E/ISA I/O space
                DriverAccessRanges[1].RangeStart.LowPart += 0x14000000 ;
                        HwDeviceExtension->MachineType = SIEMENS_P9100_PCi;
                }
        }
#endif
    }
    else if (PciFindDevice(HwDeviceExtension,
                      WTK_9001_ID,
                      WTK_VENDOR_ID,
                      &HwDeviceExtension->PciSlotNum))
    {
        wcpID = P9000_ID;

        // Now make sure we are looking for a P9000, if were not
        // then fail.

        if (HwDeviceExtension->P9CoprocInfo.CoprocId != P9000_ID)
        {
            return(FALSE);
        }

        //
        // Read the config space to determine if
        // this is Rev 1 or 2. This will determine at which addresses
        // the DAC registers are mapped.
        //

        if (!VideoPortGetBusData(HwDeviceExtension,
                                 PCIConfiguration,
                                 HwDeviceExtension->PciSlotNum,
                                 &ulTemp,
                                 P9001_REV_ID,
                                 sizeof(ulTemp)))
        {
            return(FALSE);
        }

        //
        // Got the 9001 rev id. Choose the appropriate table of DAC register
        // addresses.
        //

        switch((UCHAR) (ulTemp))
        {
            case 1 :
                //
                // This is a Rev 1 9001, which uses the standard VL DAC
                // Addresses. All known rev 1 implementations use the
                // Weitek 5286 VGA chip.
                //

                DefaultDACRegRange = VLDefDACRegRange;
                HwDeviceExtension->AdapterDesc.bWtk5x86 = TRUE;
                break;

            case 2 :
            default:
                //
                // This is a Rev 2 9001. Set up the table of DAC register
                // offsets accordingly.
                //

                DefaultDACRegRange = Pci9001DefDACRegRange;

                //
                // A Rev 2 9001 is present. Get the BIOS ROM address from the
                // PCI configuration space so we can do a ROM scan to
                // determine if this is a Viper PCI adapter.
                //

                PciAccessRange.RangeStart.LowPart = 0;
                PciAccessRange.RangeStart.HighPart = 0;

                if (VideoPortGetBusData(HwDeviceExtension,
                                        PCIConfiguration,
                                        HwDeviceExtension->PciSlotNum,
                                        &PciAccessRange.RangeStart.LowPart,
                                        P9001_BIOS_BASE_ADDR,
                                        sizeof(ULONG)) == 0)
                {
                    return FALSE;
                }

                if (PciAccessRange.RangeStart.LowPart)
                {
                    //
                    // We found an address for the BIOS.  Verify it.
                    //
                    // Set up the access range so we can map out the BIOS ROM
                    // space. This will allow us to scan the ROM and detect the
                    // presence of a Viper PCI adapter.
                    //

                    PciAccessRange.RangeInIoSpace = FALSE;
                    PciAccessRange.RangeVisible = TRUE;
                    PciAccessRange.RangeShareable = TRUE;
                    PciAccessRange.RangeLength = BIOS_RANGE_LEN;

                    //
                    // Check to see if another miniport driver has allocated the
                    // BIOS' memory space.
                    //

                    if (VideoPortVerifyAccessRanges(HwDeviceExtension,
                                                    1L,
                                                    &PciAccessRange) != NO_ERROR)
                    {
                        PciAccessRange.RangeStart.LowPart = 0;
                    }
                }


                if (PciAccessRange.RangeStart.LowPart == 0)
                {
                    //
                    // The Adapter has not been enabled, so we need to map the
                    // BIOS address.
                    //

                    IO_RESOURCE_DESCRIPTOR ioResource = {
                        IO_RESOURCE_PREFERRED,
                        CmResourceTypeMemory,
                        CmResourceShareDeviceExclusive,
                        0,
                        CM_RESOURCE_MEMORY_READ_WRITE,
                        0,
                        {
                          BIOS_RANGE_LEN,    // Length
                          BIOS_RANGE_LEN,    // Alignment
                          { 0x10000000, 0 }, // Minimum start address
                          { 0xefffffff, 0}   // Maximum end address
                        }
                    };

                    status = VideoPortGetAccessRanges(HwDeviceExtension,
                                                      1,
                                                      &ioResource,
                                                      1,
                                                      &PciAccessRange,
                                                      NULL,
                                                      NULL,
                                                      &HwDeviceExtension->PciSlotNum);

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

                //
                // Map in the BIOS' memory space. If it can't be mapped,
                // return an error.
                //

                if ((ulBiosAddr = (ULONG)
                        VideoPortGetDeviceBase(HwDeviceExtension,
                                               PciAccessRange.RangeStart,
                                               PciAccessRange.RangeLength,
                                               PciAccessRange.RangeInIoSpace)) == 0)
                {
                    return(FALSE);
                }

                //
                // Enable the Adapter BIOS.
                //

                ulTemp = PciAccessRange.RangeStart.LowPart | PCI_BIOS_ENB;

                VideoPortSetBusData(HwDeviceExtension,
                                    PCIConfiguration,
                                    HwDeviceExtension->PciSlotNum,
                                    &ulTemp,
                                    P9001_BIOS_BASE_ADDR,
                                    sizeof(ULONG));

                if (VideoPortScanRom(HwDeviceExtension,
                                     (PUCHAR) ulBiosAddr,
                                     BIOS_RANGE_LEN,
                                     VIPER_ID_STR))
                {
                    //
                    // A Viper PCI is present, use the Viper set mode,
                    // enable/disable video function pointers, and clk
                    // divisor values. Also, Viper PCI does not
                    // use a Weitek VGA.
                    //

                    HwDeviceExtension->AdapterDesc.OEMSetMode = ViperSetMode;
                    HwDeviceExtension->AdapterDesc.P9EnableVideo =
                        ViperPciP9Enable;
                    HwDeviceExtension->AdapterDesc.P9DisableVideo =
                        ViperPciP9Disable;
                    HwDeviceExtension->AdapterDesc.iClkDiv = 4;
                    HwDeviceExtension->AdapterDesc.bWtk5x86 = FALSE;
                }
                else
                {
                    //
                    // All non-Viper Rev 2 implementations use a Weitek
                    // 5286 VGA chip.
                    //

                    HwDeviceExtension->AdapterDesc.bWtk5x86 = TRUE;

                }

                //
                // Restore the BIOS register to it's original value.
                //

                VideoPortSetBusData(HwDeviceExtension,
                                    PCIConfiguration,
                                    HwDeviceExtension->PciSlotNum,
                                    &ulTempAddr,
                                    P9001_BIOS_BASE_ADDR,
                                    sizeof(ULONG));

                VideoPortFreeDeviceBase(HwDeviceExtension, (PVOID) ulBiosAddr);

                break;
        }

    }
    else if (PciFindDevice(HwDeviceExtension,   // Search for a Weitek 9002.
                           WTK_9002_ID,
                           WTK_VENDOR_ID,
                           &HwDeviceExtension->PciSlotNum))
    {
        wcpID = P9000_ID;

        // Now make sure we are looking for a P9000, if were not
        // then fail.

        if (HwDeviceExtension->P9CoprocInfo.CoprocId != P9000_ID)
        {
            return(FALSE);
        }

        //
        // Found a 9002 board. Set up the table of DAC addresses
        // accordingly.
        //

        DefaultDACRegRange = Pci9002DefDACRegRange;
    }
    else
    {
        //
        // No Weitek PCI devices were found, return an error.
        //

        return(FALSE);
    }

    //
    // Get the base address of the adapter.
    // Some machines rely on the address not changing - if the address changes
    // the machine randomly appears to corrupt memory.
    // So use the pre-configured address if it is available.
    //

    HwDeviceExtension->P9PhysAddr.LowPart = 0;

    VideoPortGetBusData(HwDeviceExtension,
                        PCIConfiguration,
                        HwDeviceExtension->PciSlotNum,
                        &HwDeviceExtension->P9PhysAddr.LowPart,
                        P9001_BASE_ADDR,
                        sizeof(ULONG));

    if (HwDeviceExtension->P9PhysAddr.LowPart == 0)
    {
        IO_RESOURCE_DESCRIPTOR ioResource = {
            IO_RESOURCE_PREFERRED,
            CmResourceTypeMemory,
            CmResourceShareDeviceExclusive,
            0,
            CM_RESOURCE_MEMORY_READ_WRITE,
            0,
            {
              RESERVE_PCI_ADDRESS_SPACE,  // Length
              RESERVE_PCI_ADDRESS_SPACE,  // Alignment
              { 0x10000000, 0 },          // Minimum start address
              { 0xefffffff, 0}            // Maximum end address
            }
        };

        status = VideoPortGetAccessRanges(HwDeviceExtension,
                                          1,
                                          &ioResource,
                                          1,
                                          &PciAccessRange,
                                          NULL,
                                          NULL,
                                          &HwDeviceExtension->PciSlotNum);

        if (status == NO_ERROR)
        {
            HwDeviceExtension->P9PhysAddr = PciAccessRange.RangeStart;

            //
            // Save the physical base address in the PCI config space.
            //

            VideoPortSetBusData(HwDeviceExtension,
                                PCIConfiguration,
                                HwDeviceExtension->PciSlotNum,
                                &HwDeviceExtension->P9PhysAddr.LowPart,
                                P9001_BASE_ADDR,
                                sizeof(ULONG));
        }
    }

    if (HwDeviceExtension->P9PhysAddr.LowPart == 0)
    {
        return(FALSE);
    }

    //
    // The P9100 can access the DAC directly, so no I/O space needs to be
    // allocated for DAC access.
    //

    if (wcpID == P9000_ID)
    {

        //
        // The Adapter has not been enabled, so we need to map the
        // base IO address.
        //

        IO_RESOURCE_DESCRIPTOR ioResource = {
            IO_RESOURCE_PREFERRED,
            CmResourceTypePort,
            CmResourceShareDeviceExclusive,
            0,
            CM_RESOURCE_PORT_IO,
            0,
            {
              P9001_IO_RANGE,    // Length
              P9001_IO_RANGE,    // Alignment
              { 0x00001000, 0 }, // Minimum start address
              { 0x0000ffff, 0}   // Maximum end address
            }
        };

        status = VideoPortGetAccessRanges(HwDeviceExtension,
                                          1,
                                          &ioResource,
                                          1,
                                          &PciAccessRange,
                                          NULL,
                                          NULL,
                                          &HwDeviceExtension->PciSlotNum);

        if (status == NO_ERROR)
        {
            HwDeviceExtension->P9001PhysicalAddress = PciAccessRange.RangeStart;
        }
        else
        {
            return(FALSE);
        }

        //
        // Save the physical base address in the PCI config space.
        //

        ulTemp = HwDeviceExtension->P9001PhysicalAddress.LowPart | 0x01;

        VideoPortSetBusData(HwDeviceExtension,
                            PCIConfiguration,
                            HwDeviceExtension->PciSlotNum,
                            &ulTemp,
                            P9001_REG_BASE,
                            sizeof(ULONG));

        //
        // Compute the actual base address.
        //

        HwDeviceExtension->P9001PhysicalAddress.LowPart &= 0xFFFFFFFE;

        //
        // If this is a 9002 board, map in and read the VGA id register.
        //

        if (DefaultDACRegRange == Pci9002DefDACRegRange)
        {
            //
            // Set up the access range so we can map out the VGA ID register.
            //

            PciAccessRange.RangeInIoSpace = TRUE;
            PciAccessRange.RangeVisible = TRUE;
            PciAccessRange.RangeShareable = TRUE;
            PciAccessRange.RangeLength = 1;

            PciAccessRange.RangeStart = HwDeviceExtension->P9001PhysicalAddress;
            PciAccessRange.RangeStart.LowPart += P9002_VGA_ID;

            //
            // Map in the VGA ID register. If it can't be mapped,
            // we can't determine the VGA type, so just use the default.
            //

            if ((ulBoardAddr = (ULONG)
                    VideoPortGetDeviceBase(HwDeviceExtension,
                                           PciAccessRange.RangeStart,
                                           PciAccessRange.RangeLength,
                                           PciAccessRange.RangeInIoSpace)) != 0)
            {
                HwDeviceExtension->AdapterDesc.bWtk5x86 =
                    (VideoPortReadPortUchar((PUCHAR) ulBoardAddr) & VGA_MSK == WTK_VGA);

                VideoPortFreeDeviceBase(HwDeviceExtension,
                                        (PVOID) ulBoardAddr);
            }
            else
            {
                //
                // Assume this is a 5x86 VGA.
                //

                HwDeviceExtension->AdapterDesc.bWtk5x86 = TRUE;
            }
        }

        //
        // Compute the actual DAC register addresses relative to the PCI
        // base address.
        //

        for (i = 0; i < HwDeviceExtension->Dac.cDacRegs; i++)
        {
            //
            // If this is not a palette addr or data register, and the board
            // is not using the standard VL addresses, compute the register
            // address relative to the register base address.
            //

            if ((i > 3) && (DefaultDACRegRange != VLDefDACRegRange))
            {
                DefaultDACRegRange[i].RangeStart.LowPart +=
                    HwDeviceExtension->P9001PhysicalAddress.LowPart;
            }
        }

        //
        // Copy the DAC register access range into the global list of access
        // ranges.
        //

        VideoPortMoveMemory(&DriverAccessRanges[NUM_DRIVER_ACCESS_RANGES],
                            DefaultDACRegRange,
                            sizeof(VIDEO_ACCESS_RANGE) *
                            HwDeviceExtension->Dac.cDacRegs);

        //
        // This is a hack. Initialize an additional access range to map out
        // the entire 4K range of contiguous IO space starting at PCI_REG_BASE.
        // apparently the 9001 decodes accesses over this entire range rather
        // than the individual register offsets within this range.
        //
        //
        // Set up the access range so we can map the entire 4k IO range.
        //

        PciAccessRange.RangeInIoSpace = TRUE;
        PciAccessRange.RangeVisible = TRUE;
        PciAccessRange.RangeShareable = TRUE;
        PciAccessRange.RangeLength = P9001_IO_RANGE;
        PciAccessRange.RangeStart = HwDeviceExtension->P9001PhysicalAddress;

        VideoPortMoveMemory(&DriverAccessRanges[NUM_DRIVER_ACCESS_RANGES +
                                                NUM_DAC_ACCESS_RANGES],
                            &PciAccessRange,
                            sizeof(VIDEO_ACCESS_RANGE));
    }

    return(TRUE);

}