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; } } } }
/* 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; }
/* 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; }
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); }
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); }