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 + -
显示快捷键?