pcatpcirootbridge.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,017 行 · 第 1/3 页
C
1,017 行
// Memory Ranges, and Prefetchable Memory Ranges the device is decoding
//
if ((PciConfigurationHeader.Hdr.HeaderType & HEADER_LAYOUT_CODE) == HEADER_TYPE_DEVICE) {
Status = PcatPciRootBridgeParseBars (
PrivateData,
PciConfigurationHeader.Hdr.Command,
PrimaryBusIndex,
Device,
Function
);
}
//
// See if the PCI device is an IDE controller
//
if (PciConfigurationHeader.Hdr.ClassCode[2] == 0x01 &&
PciConfigurationHeader.Hdr.ClassCode[1] == 0x01 ) {
if (PciConfigurationHeader.Hdr.ClassCode[0] & 0x80) {
PrivateData->Attributes |= EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO;
PrivateData->Attributes |= EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO;
}
if (PciConfigurationHeader.Hdr.ClassCode[0] & 0x01) {
PrivateData->Attributes |= EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO;
}
if (PciConfigurationHeader.Hdr.ClassCode[0] & 0x04) {
PrivateData->Attributes |= EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO;
}
}
//
// See if the PCI device is a legacy VGA controller
//
if (PciConfigurationHeader.Hdr.ClassCode[2] == 0x00 &&
PciConfigurationHeader.Hdr.ClassCode[1] == 0x01 ) {
PrivateData->Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;
PrivateData->Attributes |= EFI_PCI_ATTRIBUTE_VGA_MEMORY;
PrivateData->Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO;
}
//
// See if the PCI device is a standard VGA controller
//
if (PciConfigurationHeader.Hdr.ClassCode[2] == 0x03 &&
PciConfigurationHeader.Hdr.ClassCode[1] == 0x00 ) {
PrivateData->Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;
PrivateData->Attributes |= EFI_PCI_ATTRIBUTE_VGA_MEMORY;
PrivateData->Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO;
}
//
// See if the PCI Device is a PCI - ISA or PCI - EISA
// or ISA_POSITIVIE_DECODE Bridge device
//
if (PciConfigurationHeader.Hdr.ClassCode[2] == 0x06) {
if (PciConfigurationHeader.Hdr.ClassCode[1] == 0x01 ||
PciConfigurationHeader.Hdr.ClassCode[1] == 0x02 ||
PciConfigurationHeader.Hdr.ClassCode[1] == 0x80 ) {
PrivateData->Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO;
PrivateData->Attributes |= EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO;
if (PrivateData->MemBase > 0xa0000) {
PrivateData->MemBase = 0xa0000;
}
if (PrivateData->MemLimit < 0xbffff) {
PrivateData->MemLimit = 0xbffff;
}
}
}
}
//
// If this device is not a multi function device, then skip the rest of this PCI device
//
if (Function == 0 && !(PciConfigurationHeader.Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION)) {
break;
}
}
}
//
// After scanning all the PCI devices on the PCI root bridge's primary bus, update the
// Primary Bus Number for the next PCI root bridge to be this PCI root bridge's subordinate
// bus number + 1.
//
PrimaryBusIndex = PrivateData->SubordinateBus + 1;
//
// If at least one PCI device was found on the primary bus of this PCI root bridge, then the PCI root bridge
// exists.
//
if (NumberOfPciDevices > 0) {
//
// Adjust the I/O range used for bounds checking for the legacy decoding attributed
//
if (PrivateData->Attributes & 0x7f) {
PrivateData->IoBase = 0;
if (PrivateData->IoLimit < 0xffff) {
PrivateData->IoLimit = 0xffff;
}
}
//
// Adjust the Memory range used for bounds checking for the legacy decoding attributed
//
if (PrivateData->Attributes & EFI_PCI_ATTRIBUTE_VGA_MEMORY) {
if (PrivateData->MemBase > 0xa0000) {
PrivateData->MemBase = 0xa0000;
}
if (PrivateData->MemLimit < 0xbffff) {
PrivateData->MemLimit = 0xbffff;
}
}
//
// Build ACPI descriptors for the resources on the PCI Root Bridge
//
Status = ConstructConfiguration(PrivateData);
ASSERT_EFI_ERROR (Status);
//
// Create the handle for this PCI Root Bridge
//
Status = gBS->InstallMultipleProtocolInterfaces (
&PrivateData->Handle,
&gEfiDevicePathProtocolGuid,
PrivateData->DevicePath,
&gEfiPciRootBridgeIoProtocolGuid,
&PrivateData->Io,
NULL
);
ASSERT_EFI_ERROR (Status);
//
// Contruct DeviceIoProtocol
//
Status = DeviceIoConstructor (
PrivateData->Handle,
&PrivateData->Io,
PrivateData->DevicePath,
(UINT16)PrivateData->PrimaryBus,
(UINT16)PrivateData->SubordinateBus
);
ASSERT_EFI_ERROR (Status);
//
// Scan this PCI Root Bridge for PCI Option ROMs and add them to the PCI Option ROM Table
//
Status = ScanPciRootBridgeForRoms(&PrivateData->Io);
//
// Increment the index for the next PCI Root Bridge
//
PciRootBridgeIndex++;
} else {
//
// If no PCI Root Bridges were found on the current PCI segment, then exit
//
if (NumberOfPciRootBridges == 0) {
Status = EFI_SUCCESS;
goto Done;
}
}
//
// If the PrimaryBusIndex is greater than the maximum allowable PCI bus number, then
// the PCI Segment Number is incremented, and the next segment is searched starting at Bus #0
// Otherwise, the search is continued on the next PCI Root Bridge
//
if (PrimaryBusIndex > PCI_MAX_BUS) {
PciSegmentIndex++;
NumberOfPciRootBridges = 0;
PrimaryBusIndex = 0;
} else {
NumberOfPciRootBridges++;
}
}
return EFI_SUCCESS;
Done:
//
// Clean up memory allocated for the PCI Root Bridge that was searched but not created.
//
if (PrivateData) {
if (PrivateData->DevicePath) {
gBS->FreePool(PrivateData->DevicePath);
}
gBS->FreePool (PrivateData);
}
//
// If no PCI Root Bridges were discovered, then return the error condition from scanning the
// first PCI Root Bridge
//
if (PciRootBridgeIndex == 0) {
return Status;
}
return EFI_SUCCESS;
}
EFI_STATUS
ConstructConfiguration(
IN OUT PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
EFI_STATUS Status;
UINT8 NumConfig;
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration;
EFI_ACPI_END_TAG_DESCRIPTOR *ConfigurationEnd;
NumConfig = 0;
PrivateData->Configuration = NULL;
if (PrivateData->SubordinateBus >= PrivateData->PrimaryBus) {
NumConfig++;
}
if (PrivateData->IoLimit >= PrivateData->IoBase) {
NumConfig++;
}
if (PrivateData->Mem32Limit >= PrivateData->Mem32Base) {
NumConfig++;
}
if (PrivateData->Pmem32Limit >= PrivateData->Pmem32Base) {
NumConfig++;
}
if (PrivateData->Mem64Limit >= PrivateData->Mem64Base) {
NumConfig++;
}
if (PrivateData->Pmem64Limit >= PrivateData->Pmem64Base) {
NumConfig++;
}
if ( NumConfig == 0 ) {
//
// If there is no resource request
//
Status = gBS->AllocatePool (
EfiBootServicesData,
sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR),
&PrivateData->Configuration
);
if (EFI_ERROR (Status )) {
return Status;
}
Configuration = PrivateData->Configuration;
EfiZeroMem (
Configuration,
sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)
);
Configuration->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
Configuration->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
Configuration++;
ConfigurationEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *)(Configuration);
ConfigurationEnd->Desc = ACPI_END_TAG_DESCRIPTOR;
ConfigurationEnd->Checksum = 0;
}
//
// If there is at least one type of resource request,
// allocate a acpi resource node
//
Status = gBS->AllocatePool (
EfiBootServicesData,
sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR),
&PrivateData->Configuration
);
if (EFI_ERROR (Status )) {
return Status;
}
Configuration = PrivateData->Configuration;
EfiZeroMem (
Configuration,
sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)
);
if (PrivateData->SubordinateBus >= PrivateData->PrimaryBus) {
Configuration->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
Configuration->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
Configuration->ResType = ACPI_ADDRESS_SPACE_TYPE_BUS;
Configuration->SpecificFlag = 0;
Configuration->AddrRangeMin = PrivateData->PrimaryBus;
Configuration->AddrRangeMax = PrivateData->SubordinateBus;
Configuration->AddrLen = Configuration->AddrRangeMax - Configuration->AddrRangeMin + 1;
Configuration++;
}
//
// Deal with io aperture
//
if (PrivateData->IoLimit >= PrivateData->IoBase) {
Configuration->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
Configuration->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
Configuration->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;
Configuration->SpecificFlag = 1; //non ISA range
Configuration->AddrRangeMin = PrivateData->IoBase;
Configuration->AddrRangeMax = PrivateData->IoLimit;
Configuration->AddrLen = Configuration->AddrRangeMax - Configuration->AddrRangeMin + 1;
Configuration++;
}
//
// Deal with mem32 aperture
//
if (PrivateData->Mem32Limit >= PrivateData->Mem32Base) {
Configuration->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
Configuration->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
Configuration->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
Configuration->SpecificFlag = 0; //Nonprefechable
Configuration->AddrSpaceGranularity = 32; //32 bit
Configuration->AddrRangeMin = PrivateData->Mem32Base;
Configuration->AddrRangeMax = PrivateData->Mem32Limit;
Configuration->AddrLen = Configuration->AddrRangeMax - Configuration->AddrRangeMin + 1;
Configuration++;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?