Example #1
0
static VOID NTAPI
XenGfxFreeResources(PXENGFX_DEVICE_EXTENSION pXenGfxExtension)
{
    XenGfxReleaseFrameBuffer(pXenGfxExtension);

    pXenGfxExtension->pGartBaseReg = NULL;
    pXenGfxExtension->pGartMappingReg = NULL;

    if (pXenGfxExtension->pModes != NULL) {
        XenGfxReleaseModes(pXenGfxExtension->pModes);
        pXenGfxExtension->pModes = NULL;
    }

    if (pXenGfxExtension->pEdid != NULL) {
        XenGfxFreeContiguousPages(pXenGfxExtension->pEdid, 1);
        pXenGfxExtension->pEdid = NULL;
    }

    if (pXenGfxExtension->pXgfxRegBase != NULL) {
        VideoPortFreeDeviceBase(pXenGfxExtension, pXenGfxExtension->pXgfxRegBase);
        pXenGfxExtension->pGart = NULL;
        pXenGfxExtension->pVCrtc0 = NULL;
        pXenGfxExtension->pGlobal = NULL;
        pXenGfxExtension->pXgfxRegBase = NULL;
        pXenGfxExtension->pGartBaseReg = NULL;
        pXenGfxExtension->pGartMappingReg = NULL;
    }
}
Example #2
0
PUCHAR detectVideoBoard()
{
    // If this call succeeds, pVideoProIo will be valid upon return.  The
    // calling function will have to execute a VideoPortFreeDeviceBase().

  #if 1
    return 0;
  #else
    ULONG videoProPorts[3] = {0x240, 0x300, 0x340};
    PUCHAR  pVideoProIo;
    byte  i;
   
    for (i = 0; i < 3; i++)
    {
        // Get access to ports before trying to map I/O configuration space.
        VideoProAccessRange.RangeStart.LowPart = (ULONG)videoProPorts[i];

        if (VideoPortVerifyAccessRanges(pMgaDeviceExtension,
                                        1,
                                        &VideoProAccessRange) == NO_ERROR &&
        (pVideoProIo = VideoPortGetDeviceBase(pMgaDeviceExtension,
                               VideoProAccessRange.RangeStart,
                               VideoProAccessRange.RangeLength,
                               VideoProAccessRange.RangeInIoSpace)) != NULL)
        {
            if ( (inp(pVideoProIo+2) & 0xe0) == 0x40 )
            {
                // pVideoProIo will be freed later by the calling routine.
                return pVideoProIo;
            }
            VideoPortFreeDeviceBase(pMgaDeviceExtension,pVideoProIo);
        }
    }
    return 0;
  #endif
}
Example #3
0
VP_STATUS
DGXFindAdapter(
    PVOID HwDeviceExtension,
    PVOID HwContext,
    PWSTR ArgumentString,
    PVIDEO_PORT_CONFIG_INFO ConfigInfo,
    PUCHAR Again
    )

/*++

Routine Description:

    This routine is called to determine if the adapter for this driver
    is present in the system.
    If it is present, the function fills out some information describing
    the adapter.

Arguments:

    HwDeviceExtension - Supplies the miniport driver's adapter storage. This
        storage is initialized to zero before this call.

    HwContext - Supplies the context value which was passed to
        VideoPortInitialize().

    ArgumentString - Suuplies a NULL terminated ASCII string. This string
        originates from the user.

    ConfigInfo - Returns the configuration information structure which is
        filled by the miniport driver. This structure is initialized with
        any knwon configuration information (such as SystemIoBusNumber) by
        the port driver. Where possible, drivers should have one set of
        defaults which do not require any supplied configuration information.

    Again - Indicates if the miniport driver wants the port driver to call
        its VIDEO_HW_FIND_ADAPTER function again with a new device extension
        and the same config info. This is used by the miniport drivers which
        can search for several adapters on a bus.

Return Value:

    This routine must return:

    NO_ERROR - Indicates a host adapter was found and the
        configuration information was successfully determined.

    ERROR_INVALID_PARAMETER - Indicates an adapter was found but there was an
        error obtaining the configuration information. If possible an error
        should be logged.

    ERROR_DEV_NOT_EXIST - Indicates no host adapter was found for the
        supplied configuration information.

--*/

{

#define NUM_ACCESS_RANGES  5

    PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
    PVOID *pVirtAddr;
    ULONG i;
    USHORT temp;
    PUSHORT port;
    VP_STATUS status;
    PWSTR pwszChip= NULL;    // chip name
    ULONG cbChip= 0;         // length of chip name
    PWSTR pwszDac= NULL;     // DAC name
    ULONG cbDac= 0;          // length of DAC name
    ULONG cbMemSize;         // size of video memory

    VIDEO_ACCESS_RANGE accessRange[NUM_ACCESS_RANGES] = {
        {0X00000061, 0x00000000, 0x00000001, 1, 1, 0},   // DGX I
        {0X00006CA8, 0x00000000, 0x00000001, 1, 1, 0},   // DGX I
        {0X00006C80, 0x00000000, 0x00000009, 1, 1, 0},   // DGX I & II
        {0X00000CAC, 0x00000000, 0x00000004, 1, 1, 0},   // front panel
        {0x20000000, 0x00000000, 0x00400000, 0, 1, 0}    // Frame buf & dac
    };

    //
    // Make sure the size of the structure is at least as large as what we
    // are expecting (check version of the config info structure).
    //

    if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO)) {

        return ERROR_INVALID_PARAMETER;

    }

    //
    // Check to see if there is a hardware resource conflict.
    //

    status = VideoPortVerifyAccessRanges(HwDeviceExtension,
                                         NUM_ACCESS_RANGES,
                                         accessRange);

    if (status != NO_ERROR) {

        return status;

    }

    //
    // Clear out the Emulator entries and the state size since this driver
    // does not support them.
    //

    ConfigInfo->NumEmulatorAccessEntries = 0;
    ConfigInfo->EmulatorAccessEntries = NULL;
    ConfigInfo->EmulatorAccessEntriesContext = 0;

    ConfigInfo->HardwareStateSize = 0;

    ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart = 0x00000000;
    ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0x00000000;
    ConfigInfo->VdmPhysicalVideoMemoryLength = 0x00000000;

    //
    // Frame buffer information
    //

    hwDeviceExtension->FrameLength = DELL_DGX_LEN;
    hwDeviceExtension->PhysicalFrameAddress.HighPart = 0;
    hwDeviceExtension->PhysicalFrameAddress.LowPart = DELL_DGX_BASE;


    //
    // Map all of our ranges into system virtual address space.
    // IMPORTANT !!!
    // This is dependant on the order of the virtual addresses in the
    // HwDeviceExtensionto be the same as the order of the entries in the
    // access range structure.
    //

    pVirtAddr = &hwDeviceExtension->DGX1Misc;

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

        if ( (*pVirtAddr = VideoPortGetDeviceBase(hwDeviceExtension,
                               accessRange[i].RangeStart,
                               accessRange[i].RangeLength,
                               accessRange[i].RangeInIoSpace)) == NULL) {

            return ERROR_INVALID_PARAMETER;

        }

        pVirtAddr++;
    }

    //
    // Are we really on a Dell DGX machine? If so which one?
    //

    hwDeviceExtension->ModelNumber = 0;

    port = (PUSHORT) hwDeviceExtension->DGXControlPorts;
    temp = VideoPortReadPortUshort(port++);

    if (temp == DELL_DGX_ID_LOW) {

        temp = VideoPortReadPortUshort(port);

        if (temp == DELL_DGX_1_ID_HIGH) {

            hwDeviceExtension->ModelNumber = 1;
            pwszChip= CHIPNAME1;
            cbChip= sizeof(CHIPNAME1);

        }

        if (temp == DELL_DGX_2_ID_HIGH) {

            hwDeviceExtension->ModelNumber = 2;
            pwszChip= CHIPNAME2;
            cbChip= sizeof(CHIPNAME2);

        }
    }

    if (hwDeviceExtension->ModelNumber == 0) {

        //
        // If we did not find the chip, free all the resources we allocated.
        //

        pVirtAddr = &hwDeviceExtension->DGX1Misc;

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

            VideoPortFreeDeviceBase(hwDeviceExtension, *pVirtAddr);
            pVirtAddr++;
        }

        return ERROR_DEV_NOT_EXIST;
    }

    //
    // Initialize the current mode number.
    //

    hwDeviceExtension->CurrentModeNumber = 0;

    //
    // Setup All the valid modes.
    //

    hwDeviceExtension->NumValidModes = 0;

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

        DGXModes[i].modeInformation.ModeIndex = i;

        DGXModes[i].bValid = TRUE;
        hwDeviceExtension->NumValidModes++;

    }

    //
    // Indicate we do not wish to be called over
    //

    *Again = 0;

    //
    // Init Front panel Display
    //

    DevSetPanel(HwDeviceExtension, PANEL_MESSAGE);

    //
    // Set hardware information strings in registry
    //

    VideoPortSetRegistryParameters(HwDeviceExtension,
                                   L"HardwareInformation.ChipType",
                                   pwszChip,
                                   cbChip );

    pwszDac= DELL_DGX_DACNAME;
    cbDac= sizeof( DELL_DGX_DACNAME );
    VideoPortSetRegistryParameters(HwDeviceExtension,
                                   L"HardwareInformation.DacType",
                                   pwszDac,
                                   cbDac );

    cbMemSize= DELL_DGX_LEN;
    VideoPortSetRegistryParameters(HwDeviceExtension,
                                   L"HardwareInformation.MemorySize",
                                   &cbMemSize,
                                   sizeof(ULONG) );
    //
    // Indicate a successful completion status.
    //

    return NO_ERROR;

} // end DGXFindAdapter()
Example #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);
}
Example #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);

}
Example #6
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 );
}