Home | History | Annotate | Download | only in PciHostBridgeDxe
      1 /**
      2  * Copyright (c) 2014, AppliedMicro Corp. All rights reserved.
      3  * Copyright (c) 2016, Hisilicon Limited. All rights reserved.
      4  * Copyright (c) 2016, Linaro Limited. All rights reserved.
      5  *
      6  * This program and the accompanying materials
      7  * are licensed and made available under the terms and conditions of the BSD License
      8  * which accompanies this distribution.  The full text of the license may be found at
      9  * http://opensource.org/licenses/bsd-license.php
     10  *
     11  * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13  *
     14  **/
     15 
     16 #include <Uefi.h>
     17 #include <Protocol/EmbeddedGpio.h>
     18 #include <Guid/EventGroup.h>
     19 #include <Library/UefiBootServicesTableLib.h>
     20 #include <Library/UefiRuntimeServicesTableLib.h>
     21 #include <Library/OemMiscLib.h>
     22 
     23 #include "PciHostBridge.h"
     24 
     25 UINTN RootBridgeNumber[PCIE_MAX_HOSTBRIDGE] = { PCIE_MAX_ROOTBRIDGE,PCIE_MAX_ROOTBRIDGE };
     26 
     27 UINT64 RootBridgeAttribute[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_ROOTBRIDGE] = {
     28     { //Host Bridge0
     29             EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
     30             EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
     31             EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
     32             EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
     33             EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
     34             EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
     35             EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
     36             EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
     37     },
     38     { //Host Bridge1
     39             EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
     40             EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
     41             EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
     42             EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
     43             EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
     44             EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
     45             EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
     46             EFI_PCI_HOST_BRIDGE_MEM64_DECODE,
     47     }
     48     };
     49 
     50 EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath[PCIE_MAX_HOSTBRIDGE][PCIE_MAX_ROOTBRIDGE] = {
     51   { //Host Bridge0
     52   /* Port 0 */
     53     {
     54       {
     55         {
     56           ACPI_DEVICE_PATH,
     57           ACPI_DP,
     58           {
     59             (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
     60             (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
     61           }
     62         },
     63         EISA_PNP_ID(0x0A03),
     64         0
     65       },
     66 
     67       {
     68         END_DEVICE_PATH_TYPE,
     69         END_ENTIRE_DEVICE_PATH_SUBTYPE,
     70         {
     71           END_DEVICE_PATH_LENGTH,
     72           0
     73         }
     74       }
     75     },
     76   /* Port 1 */
     77     {
     78       {
     79         {
     80           ACPI_DEVICE_PATH,
     81           ACPI_DP,
     82           {
     83             (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
     84             (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
     85           }
     86         },
     87         EISA_PNP_ID(0x0A04),
     88         0
     89       },
     90 
     91       {
     92         END_DEVICE_PATH_TYPE,
     93         END_ENTIRE_DEVICE_PATH_SUBTYPE,
     94         {
     95           END_DEVICE_PATH_LENGTH,
     96           0
     97         }
     98       }
     99     },
    100   /* Port 2 */
    101     {
    102       {
    103         {
    104           ACPI_DEVICE_PATH,
    105           ACPI_DP,
    106           {
    107             (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
    108             (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
    109           }
    110         },
    111         EISA_PNP_ID(0x0A05),
    112         0
    113       },
    114 
    115       {
    116         END_DEVICE_PATH_TYPE,
    117         END_ENTIRE_DEVICE_PATH_SUBTYPE,
    118         {
    119           END_DEVICE_PATH_LENGTH,
    120           0
    121         }
    122       }
    123     },
    124   /* Port 3 */
    125     {
    126       {
    127         {
    128           ACPI_DEVICE_PATH,
    129           ACPI_DP,
    130           {
    131             (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
    132             (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
    133           }
    134         },
    135         EISA_PNP_ID(0x0A06),
    136         0
    137       },
    138 
    139       {
    140         END_DEVICE_PATH_TYPE,
    141         END_ENTIRE_DEVICE_PATH_SUBTYPE,
    142         {
    143           END_DEVICE_PATH_LENGTH,
    144           0
    145         }
    146       }
    147     },
    148     /* Port 4 */
    149     {
    150       {
    151         {
    152           ACPI_DEVICE_PATH,
    153           ACPI_DP,
    154           {
    155             (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
    156             (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
    157           }
    158         },
    159         EISA_PNP_ID(0x0A07),
    160         0
    161       },
    162 
    163       {
    164         END_DEVICE_PATH_TYPE,
    165         END_ENTIRE_DEVICE_PATH_SUBTYPE,
    166         {
    167           END_DEVICE_PATH_LENGTH,
    168           0
    169         }
    170       }
    171     },
    172     /* Port 5 */
    173     {
    174       {
    175         {
    176           ACPI_DEVICE_PATH,
    177           ACPI_DP,
    178           {
    179             (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
    180             (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
    181           }
    182         },
    183         EISA_PNP_ID(0x0A08),
    184         0
    185       },
    186 
    187       {
    188         END_DEVICE_PATH_TYPE,
    189         END_ENTIRE_DEVICE_PATH_SUBTYPE,
    190         {
    191           END_DEVICE_PATH_LENGTH,
    192           0
    193         }
    194       }
    195     },
    196     /* Port 6 */
    197     {
    198       {
    199         {
    200           ACPI_DEVICE_PATH,
    201           ACPI_DP,
    202           {
    203             (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
    204             (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
    205           }
    206         },
    207         EISA_PNP_ID(0x0A09),
    208         0
    209       },
    210 
    211       {
    212         END_DEVICE_PATH_TYPE,
    213         END_ENTIRE_DEVICE_PATH_SUBTYPE,
    214         {
    215           END_DEVICE_PATH_LENGTH,
    216           0
    217         }
    218       }
    219     },
    220     /* Port 7 */
    221     {
    222       {
    223         {
    224           ACPI_DEVICE_PATH,
    225           ACPI_DP,
    226           {
    227             (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
    228             (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
    229           }
    230         },
    231         EISA_PNP_ID(0x0A0A),
    232         0
    233       },
    234 
    235       {
    236         END_DEVICE_PATH_TYPE,
    237         END_ENTIRE_DEVICE_PATH_SUBTYPE,
    238         {
    239           END_DEVICE_PATH_LENGTH,
    240           0
    241         }
    242       }
    243     }
    244 },
    245 { // Host Bridge1
    246   /* Port 0 */
    247     {
    248       {
    249         {
    250           ACPI_DEVICE_PATH,
    251           ACPI_DP,
    252           {
    253             (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
    254             (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
    255           }
    256         },
    257         EISA_PNP_ID(0x0A0B),
    258         0
    259       },
    260 
    261       {
    262         END_DEVICE_PATH_TYPE,
    263         END_ENTIRE_DEVICE_PATH_SUBTYPE,
    264         {
    265           END_DEVICE_PATH_LENGTH,
    266           0
    267         }
    268       }
    269     },
    270   /* Port 1 */
    271     {
    272       {
    273         {
    274           ACPI_DEVICE_PATH,
    275           ACPI_DP,
    276           {
    277             (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
    278             (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
    279           }
    280         },
    281         EISA_PNP_ID(0x0A0C),
    282         0
    283       },
    284 
    285       {
    286         END_DEVICE_PATH_TYPE,
    287         END_ENTIRE_DEVICE_PATH_SUBTYPE,
    288         {
    289           END_DEVICE_PATH_LENGTH,
    290           0
    291         }
    292       }
    293     },
    294   /* Port 2 */
    295     {
    296       {
    297         {
    298           ACPI_DEVICE_PATH,
    299           ACPI_DP,
    300           {
    301             (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
    302             (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
    303           }
    304         },
    305         EISA_PNP_ID(0x0A0D),
    306         0
    307       },
    308 
    309       {
    310         END_DEVICE_PATH_TYPE,
    311         END_ENTIRE_DEVICE_PATH_SUBTYPE,
    312         {
    313           END_DEVICE_PATH_LENGTH,
    314           0
    315         }
    316       }
    317     },
    318   /* Port 3 */
    319     {
    320       {
    321         {
    322           ACPI_DEVICE_PATH,
    323           ACPI_DP,
    324           {
    325             (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
    326             (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
    327           }
    328         },
    329         EISA_PNP_ID(0x0A0E),
    330         0
    331       },
    332 
    333       {
    334         END_DEVICE_PATH_TYPE,
    335         END_ENTIRE_DEVICE_PATH_SUBTYPE,
    336         {
    337           END_DEVICE_PATH_LENGTH,
    338           0
    339         }
    340       }
    341     },
    342    /* Port 4 */
    343     {
    344       {
    345         {
    346           ACPI_DEVICE_PATH,
    347           ACPI_DP,
    348           {
    349             (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
    350             (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
    351           }
    352         },
    353         EISA_PNP_ID(0x0A0F),
    354         0
    355       },
    356 
    357       {
    358         END_DEVICE_PATH_TYPE,
    359         END_ENTIRE_DEVICE_PATH_SUBTYPE,
    360         {
    361           END_DEVICE_PATH_LENGTH,
    362           0
    363         }
    364       }
    365     },
    366     /* Port 5 */
    367     {
    368       {
    369         {
    370           ACPI_DEVICE_PATH,
    371           ACPI_DP,
    372           {
    373             (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
    374             (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
    375           }
    376         },
    377         EISA_PNP_ID(0x0A10),
    378         0
    379       },
    380 
    381       {
    382         END_DEVICE_PATH_TYPE,
    383         END_ENTIRE_DEVICE_PATH_SUBTYPE,
    384         {
    385           END_DEVICE_PATH_LENGTH,
    386           0
    387         }
    388       }
    389     },
    390     /* Port 6 */
    391     {
    392       {
    393         {
    394           ACPI_DEVICE_PATH,
    395           ACPI_DP,
    396           {
    397             (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
    398             (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
    399           }
    400         },
    401         EISA_PNP_ID(0x0A11),
    402         0
    403       },
    404 
    405       {
    406         END_DEVICE_PATH_TYPE,
    407         END_ENTIRE_DEVICE_PATH_SUBTYPE,
    408         {
    409           END_DEVICE_PATH_LENGTH,
    410           0
    411         }
    412       }
    413     },
    414     /* Port 7 */
    415     {
    416       {
    417         {
    418           ACPI_DEVICE_PATH,
    419           ACPI_DP,
    420           {
    421             (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
    422             (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
    423           }
    424         },
    425         EISA_PNP_ID(0x0A12),
    426         0
    427       },
    428 
    429       {
    430         END_DEVICE_PATH_TYPE,
    431         END_ENTIRE_DEVICE_PATH_SUBTYPE,
    432         {
    433           END_DEVICE_PATH_LENGTH,
    434           0
    435         }
    436       }
    437     }
    438   }
    439 };
    440 
    441 EFI_HANDLE mDriverImageHandle;
    442 
    443 PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate = {
    444   PCI_HOST_BRIDGE_SIGNATURE,  // Signature
    445   NULL,                       // HostBridgeHandle
    446   0,                          // RootBridgeNumber
    447   {NULL, NULL},               // Head
    448   FALSE,                      // ResourceSubiteed
    449   TRUE,                       // CanRestarted
    450   {
    451     NotifyPhase,
    452     GetNextRootBridge,
    453     GetAttributes,
    454     StartBusEnumeration,
    455     SetBusNumbers,
    456     SubmitResources,
    457     GetProposedResources,
    458     PreprocessController
    459   }
    460 };
    461 
    462 /**
    463   Entry point of this driver
    464 
    465   @param ImageHandle     Handle of driver image
    466   @param SystemTable     Point to EFI_SYSTEM_TABLE
    467 
    468   @retval EFI_OUT_OF_RESOURCES  Can not allocate memory resource
    469   @retval EFI_DEVICE_ERROR      Can not install the protocol instance
    470   @retval EFI_SUCCESS           Success to initialize the Pci host bridge.
    471 **/
    472 EFI_STATUS
    473 EFIAPI
    474 InitializePciHostBridge (
    475   IN EFI_HANDLE        ImageHandle,
    476   IN EFI_SYSTEM_TABLE  *SystemTable
    477   )
    478 {
    479   EFI_STATUS                  Status;
    480   UINTN                       Loop1;
    481   UINTN                       Loop2;
    482   PCI_HOST_BRIDGE_INSTANCE    *HostBridge = NULL;
    483   PCI_ROOT_BRIDGE_INSTANCE    *PrivateData;
    484   UINT32       PcieRootBridgeMask;
    485 
    486   if (!OemIsMpBoot())
    487   {
    488     PcieRootBridgeMask = PcdGet32(PcdPcieRootBridgeMask);
    489   }
    490   else
    491   {
    492     PcieRootBridgeMask = PcdGet32(PcdPcieRootBridgeMask2P);
    493   }
    494 
    495   mDriverImageHandle = ImageHandle;
    496   //
    497   // Create Host Bridge Device Handle
    498   //
    499   //Each Host Bridge have 8 Root Bridges max, every bits of 0xFF(8 bit) stands for the according PCIe Port
    500   //is enable or not
    501   for (Loop1 = 0; Loop1 < PCIE_MAX_HOSTBRIDGE; Loop1++) {
    502     if (((PcieRootBridgeMask >> (PCIE_MAX_ROOTBRIDGE * Loop1)) & 0xFF ) == 0) {
    503       continue;
    504     }
    505 
    506 
    507     HostBridge = AllocateCopyPool (sizeof(PCI_HOST_BRIDGE_INSTANCE), &mPciHostBridgeInstanceTemplate);
    508     if (HostBridge == NULL) {
    509       return EFI_OUT_OF_RESOURCES;
    510     }
    511 
    512     HostBridge->RootBridgeNumber = RootBridgeNumber[Loop1];
    513     InitializeListHead (&HostBridge->Head);
    514 
    515     Status = gBS->InstallMultipleProtocolInterfaces (
    516                   &HostBridge->HostBridgeHandle,
    517                   &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc,
    518                   NULL
    519                   );
    520     if (EFI_ERROR (Status)) {
    521       FreePool (HostBridge);
    522       return EFI_DEVICE_ERROR;
    523     }
    524 
    525     //
    526     // Create Root Bridge Device Handle in this Host Bridge
    527     //
    528     for (Loop2 = 0; Loop2 < HostBridge->RootBridgeNumber; Loop2++) {
    529       if (!(((PcieRootBridgeMask >> (PCIE_MAX_ROOTBRIDGE * Loop1)) >> Loop2 ) & 0x01)) {
    530         continue;
    531       }
    532 
    533       PrivateData = AllocateZeroPool (sizeof(PCI_ROOT_BRIDGE_INSTANCE));
    534       if (PrivateData == NULL) {
    535         FreePool (HostBridge);
    536         return EFI_OUT_OF_RESOURCES;
    537       }
    538       PrivateData->Port = Loop2;
    539       PrivateData->SocType = PcdGet32(Pcdsoctype);
    540       PrivateData->Signature = PCI_ROOT_BRIDGE_SIGNATURE;
    541       PrivateData->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath[Loop1][Loop2];
    542 
    543       (VOID)RootBridgeConstructor (
    544            &PrivateData->Io,
    545            HostBridge->HostBridgeHandle,
    546            RootBridgeAttribute[Loop1][Loop2],
    547            &mResAppeture[Loop1][Loop2],
    548            Loop1
    549       );
    550 
    551       Status = gBS->InstallMultipleProtocolInterfaces(
    552                       &PrivateData->Handle,
    553                       &gEfiDevicePathProtocolGuid,      PrivateData->DevicePath,
    554                       &gEfiPciRootBridgeIoProtocolGuid, &PrivateData->Io,
    555                       NULL
    556                       );
    557       if (EFI_ERROR (Status)) {
    558         (VOID)gBS->UninstallMultipleProtocolInterfaces (
    559                 HostBridge->HostBridgeHandle,
    560                 &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc,
    561                 NULL
    562                 );
    563         FreePool(PrivateData);
    564         FreePool (HostBridge);
    565         return EFI_DEVICE_ERROR;
    566       }
    567       // PCI  Memory Space
    568       Status = gDS->AddMemorySpace (
    569              EfiGcdMemoryTypeMemoryMappedIo,
    570              mResAppeture[Loop1][Loop2] .MemBase,
    571              mResAppeture[Loop1][Loop2] .MemLimit -mResAppeture[Loop1][Loop2] .MemBase + 1,
    572              0
    573       );
    574       if (EFI_ERROR (Status)) {
    575         DEBUG((EFI_D_ERROR,"PCIE AddMemorySpace Error\n"));
    576       }
    577       InsertTailList (&HostBridge->Head, &PrivateData->Link);
    578     }
    579   }
    580 
    581   return EFI_SUCCESS;
    582 }
    583 
    584 EFI_STATUS
    585 EFIAPI
    586 NotifyAllocateMemResources(
    587  IN PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance,
    588  IN PCI_RESOURCE_TYPE                     Index,
    589  IN OUT UINT64                            *AllocatedLenMem
    590 )
    591 {
    592   EFI_PHYSICAL_ADDRESS                  BaseAddress;
    593   EFI_STATUS                            ReturnStatus;
    594   UINT64                                AddrLen;
    595   UINTN                                 BitsOfAlignment;
    596 
    597   AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
    598   PCIE_DEBUG("Addrlen:%llx\n", AddrLen);
    599   // Get the number of '1' in Alignment.
    600   BitsOfAlignment = (UINTN) (HighBitSet64 (RootBridgeInstance->ResAllocNode[Index].Alignment) + 1);
    601 
    602   BaseAddress = (RootBridgeInstance->MemBase + *AllocatedLenMem +
    603                        RootBridgeInstance->ResAllocNode[Index].Alignment)
    604                         & ~(RootBridgeInstance->ResAllocNode[Index].Alignment);
    605   if ((BaseAddress + AddrLen - 1) > RootBridgeInstance->MemLimit) {
    606           ReturnStatus = EFI_OUT_OF_RESOURCES;
    607           RootBridgeInstance->ResAllocNode[Index].Length = 0;
    608           return ReturnStatus;
    609   }
    610 
    611   PCIE_DEBUG("(P)Mem32/64 request memory at:%llx\n", BaseAddress);
    612   ReturnStatus = gDS->AllocateMemorySpace (
    613                      EfiGcdAllocateAddress,
    614                      EfiGcdMemoryTypeMemoryMappedIo,
    615                      BitsOfAlignment,
    616                      AddrLen,
    617                      &BaseAddress,
    618                      mDriverImageHandle,
    619                      NULL
    620                  );
    621 
    622   if (!EFI_ERROR (ReturnStatus)) {
    623      // We were able to allocate the PCI memory
    624      RootBridgeInstance->ResAllocNode[Index].Base   = (UINTN)BaseAddress;
    625      RootBridgeInstance->ResAllocNode[Index].Status = ResAllocated;
    626      *AllocatedLenMem += AddrLen;
    627      PCIE_DEBUG("(P)Mem32/64 resource allocated:%llx\n", BaseAddress);
    628 
    629   } else {
    630       // Not able to allocate enough PCI memory
    631       if (ReturnStatus != EFI_OUT_OF_RESOURCES) {
    632         RootBridgeInstance->ResAllocNode[Index].Length = 0;
    633       }
    634     }
    635   return ReturnStatus;
    636 }
    637 
    638 EFI_STATUS
    639 EFIAPI
    640 NotifyAllocateResources(
    641  IN PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance
    642 )
    643 {
    644   EFI_STATUS                            ReturnStatus;
    645   LIST_ENTRY                            *List;
    646   PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
    647   PCI_RESOURCE_TYPE                     Index;
    648 
    649   ReturnStatus = EFI_SUCCESS;
    650   List = HostBridgeInstance->Head.ForwardLink;
    651 
    652   while (List != &HostBridgeInstance->Head) {
    653     RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
    654 
    655     UINT64 AllocatedLenMem = 0;
    656     for (Index = TypeIo; Index < TypeBus; Index++) {
    657       if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
    658         if(Index == TypeIo) {
    659           PCIE_DEBUG("NOT SUPPOER IO RESOURCES ON THIS PLATFORM\n");
    660         } else if ((Index >= TypeMem32) && (Index <= TypePMem64)) {
    661           ReturnStatus = NotifyAllocateMemResources(RootBridgeInstance,Index,&AllocatedLenMem);
    662         } else {
    663                ASSERT (FALSE);
    664         }
    665       }
    666     }
    667 
    668     List = List->ForwardLink;
    669   }
    670 
    671   return ReturnStatus;
    672 }
    673 
    674 EFI_STATUS
    675 EFIAPI
    676 NotifyFreeResources(
    677   IN PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance
    678 )
    679 {
    680   EFI_STATUS                            ReturnStatus;
    681   LIST_ENTRY                            *List;
    682   PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
    683   PCI_RESOURCE_TYPE                     Index;
    684   UINT64                                AddrLen;
    685   EFI_PHYSICAL_ADDRESS                  BaseAddress;
    686 
    687   ReturnStatus = EFI_SUCCESS;
    688   List = HostBridgeInstance->Head.ForwardLink;
    689   while (List != &HostBridgeInstance->Head) {
    690     RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
    691     for (Index = TypeIo; Index < TypeBus; Index++) {
    692       if (RootBridgeInstance->ResAllocNode[Index].Status == ResAllocated) {
    693         AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
    694         BaseAddress = RootBridgeInstance->ResAllocNode[Index].Base;
    695 
    696         if(Index <= TypePMem64){
    697           ReturnStatus = gDS->FreeMemorySpace (BaseAddress, AddrLen);
    698         }else{
    699           ASSERT (FALSE);
    700         }
    701 
    702         RootBridgeInstance->ResAllocNode[Index].Type      = Index;
    703         RootBridgeInstance->ResAllocNode[Index].Base      = 0;
    704         RootBridgeInstance->ResAllocNode[Index].Length    = 0;
    705         RootBridgeInstance->ResAllocNode[Index].Status    = ResNone;
    706       }
    707     }
    708 
    709     List = List->ForwardLink;
    710   }
    711 
    712   HostBridgeInstance->ResourceSubmited = FALSE;
    713   HostBridgeInstance->CanRestarted     = TRUE;
    714   return ReturnStatus;
    715 
    716 }
    717 
    718 VOID
    719 EFIAPI
    720 NotifyBeginEnumeration(
    721   IN PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance
    722 )
    723 {
    724   LIST_ENTRY                            *List;
    725   PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
    726   PCI_RESOURCE_TYPE                     Index;
    727 
    728   //
    729   // Reset the Each Root Bridge
    730   //
    731   List = HostBridgeInstance->Head.ForwardLink;
    732 
    733   while (List != &HostBridgeInstance->Head) {
    734     RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
    735     for (Index = TypeIo; Index < TypeMax; Index++) {
    736       RootBridgeInstance->ResAllocNode[Index].Type      = Index;
    737       RootBridgeInstance->ResAllocNode[Index].Base      = 0;
    738       RootBridgeInstance->ResAllocNode[Index].Length    = 0;
    739       RootBridgeInstance->ResAllocNode[Index].Status    = ResNone;
    740     }
    741 
    742     List = List->ForwardLink;
    743   }
    744 
    745   HostBridgeInstance->ResourceSubmited = FALSE;
    746   HostBridgeInstance->CanRestarted     = TRUE;
    747 }
    748 
    749 /**
    750    These are the notifications from the PCI bus driver that it is about to enter a certain
    751    phase of the PCI enumeration process.
    752 
    753    This member function can be used to notify the host bridge driver to perform specific actions,
    754    including any chipset-specific initialization, so that the chipset is ready to enter the next phase.
    755    Eight notification points are defined at this time. See belows:
    756    EfiPciHostBridgeBeginEnumeration       Resets the host bridge PCI apertures and internal data
    757                                           structures. The PCI enumerator should issue this notification
    758                                           before starting a fresh enumeration process. Enumeration cannot
    759                                           be restarted after sending any other notification such as
    760                                           EfiPciHostBridgeBeginBusAllocation.
    761    EfiPciHostBridgeBeginBusAllocation     The bus allocation phase is about to begin. No specific action is
    762                                           required here. This notification can be used to perform any
    763                                           chipset-specific programming.
    764    EfiPciHostBridgeEndBusAllocation       The bus allocation and bus programming phase is complete. No
    765                                           specific action is required here. This notification can be used to
    766                                           perform any chipset-specific programming.
    767    EfiPciHostBridgeBeginResourceAllocation
    768                                           The resource allocation phase is about to begin. No specific
    769                                           action is required here. This notification can be used to perform
    770                                           any chipset-specific programming.
    771    EfiPciHostBridgeAllocateResources      Allocates resources per previously submitted requests for all the PCI
    772                                           root bridges. These resource settings are returned on the next call to
    773                                           GetProposedResources(). Before calling NotifyPhase() with a Phase of
    774                                           EfiPciHostBridgeAllocateResource, the PCI bus enumerator is responsible
    775                                           for gathering I/O and memory requests for
    776                                           all the PCI root bridges and submitting these requests using
    777                                           SubmitResources(). This function pads the resource amount
    778                                           to suit the root bridge hardware, takes care of dependencies between
    779                                           the PCI root bridges, and calls the Global Coherency Domain (GCD)
    780                                           with the allocation request. In the case of padding, the allocated range
    781                                           could be bigger than what was requested.
    782    EfiPciHostBridgeSetResources           Programs the host bridge hardware to decode previously allocated
    783                                           resources (proposed resources) for all the PCI root bridges. After the
    784                                           hardware is programmed, reassigning resources will not be supported.
    785                                           The bus settings are not affected.
    786    EfiPciHostBridgeFreeResources          Deallocates resources that were previously allocated for all the PCI
    787                                           root bridges and resets the I/O and memory apertures to their initial
    788                                           state. The bus settings are not affected. If the request to allocate
    789                                           resources fails, the PCI enumerator can use this notification to
    790                                           deallocate previous resources, adjust the requests, and retry
    791                                           allocation.
    792    EfiPciHostBridgeEndResourceAllocation  The resource allocation phase is completed. No specific action is
    793                                           required here. This notification can be used to perform any chipsetspecific
    794                                           programming.
    795 
    796    @param[in] This                The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
    797    @param[in] Phase               The phase during enumeration
    798 
    799    @retval EFI_NOT_READY          This phase cannot be entered at this time. For example, this error
    800                                   is valid for a Phase of EfiPciHostBridgeAllocateResources if
    801                                   SubmitResources() has not been called for one or more
    802                                   PCI root bridges before this call
    803    @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error. This error is valid
    804                                   for a Phase of EfiPciHostBridgeSetResources.
    805    @retval EFI_INVALID_PARAMETER  Invalid phase parameter
    806    @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
    807                                   This error is valid for a Phase of EfiPciHostBridgeAllocateResources if the
    808                                   previously submitted resource requests cannot be fulfilled or
    809                                   were only partially fulfilled.
    810    @retval EFI_SUCCESS            The notification was accepted without any errors.
    811 
    812 **/
    813 EFI_STATUS
    814 EFIAPI
    815 NotifyPhase(
    816   IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
    817   IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE    Phase
    818   )
    819 {
    820   PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
    821   EFI_STATUS                            ReturnStatus;
    822 
    823   HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
    824   ReturnStatus = EFI_SUCCESS;
    825 
    826   switch (Phase) {
    827 
    828   case EfiPciHostBridgeBeginEnumeration:
    829   PCIE_DEBUG("Case EfiPciHostBridgeBeginEnumeration\n");
    830     if (HostBridgeInstance->CanRestarted) {
    831       NotifyBeginEnumeration(HostBridgeInstance);
    832     } else {
    833       //
    834       // Can not restart
    835       //
    836       return EFI_NOT_READY;
    837     }
    838     break;
    839 
    840   case EfiPciHostBridgeEndEnumeration:
    841     PCIE_DEBUG("Case EfiPciHostBridgeEndEnumeration\n");
    842     break;
    843 
    844   case EfiPciHostBridgeBeginBusAllocation:
    845     PCIE_DEBUG("Case EfiPciHostBridgeBeginBusAllocation\n");
    846     //
    847     // No specific action is required here, can perform any chipset specific programing
    848     //
    849 
    850     HostBridgeInstance->CanRestarted = FALSE;
    851     break;
    852 
    853   case EfiPciHostBridgeEndBusAllocation:
    854     PCIE_DEBUG("Case EfiPciHostBridgeEndBusAllocation\n");
    855     //
    856     // No specific action is required here, can perform any chipset specific programing
    857     //
    858     break;
    859 
    860   case EfiPciHostBridgeBeginResourceAllocation:
    861     PCIE_DEBUG("Case EfiPciHostBridgeBeginResourceAllocation\n");
    862     //
    863     // No specific action is required here, can perform any chipset specific programing
    864     //
    865     break;
    866 
    867   case EfiPciHostBridgeAllocateResources:
    868     PCIE_DEBUG("Case EfiPciHostBridgeAllocateResources\n");
    869 
    870     if (HostBridgeInstance->ResourceSubmited) {
    871       //
    872       // Take care of the resource dependencies between the root bridges
    873       //
    874      ReturnStatus = NotifyAllocateResources(HostBridgeInstance);
    875     } else {
    876       return EFI_NOT_READY;
    877     }
    878     //break;
    879 
    880   case EfiPciHostBridgeSetResources:
    881     PCIE_DEBUG("Case EfiPciHostBridgeSetResources\n");
    882     break;
    883 
    884   case EfiPciHostBridgeFreeResources:
    885     PCIE_DEBUG("Case EfiPciHostBridgeFreeResources\n");
    886 
    887     ReturnStatus = NotifyFreeResources(HostBridgeInstance);
    888     break;
    889 
    890   case EfiPciHostBridgeEndResourceAllocation:
    891     PCIE_DEBUG("Case EfiPciHostBridgeEndResourceAllocation\n");
    892     HostBridgeInstance->CanRestarted = FALSE;
    893     break;
    894 
    895   default:
    896     return EFI_INVALID_PARAMETER;
    897   }
    898 
    899   return ReturnStatus;
    900 }
    901 
    902 /**
    903    Return the device handle of the next PCI root bridge that is associated with this Host Bridge.
    904 
    905    This function is called multiple times to retrieve the device handles of all the PCI root bridges that
    906    are associated with this PCI host bridge. Each PCI host bridge is associated with one or more PCI
    907    root bridges. On each call, the handle that was returned by the previous call is passed into the
    908    interface, and on output the interface returns the device handle of the next PCI root bridge. The
    909    caller can use the handle to obtain the instance of the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
    910    for that root bridge. When there are no more PCI root bridges to report, the interface returns
    911    EFI_NOT_FOUND. A PCI enumerator must enumerate the PCI root bridges in the order that they
    912    are returned by this function.
    913    For D945 implementation, there is only one root bridge in PCI host bridge.
    914 
    915    @param[in]       This              The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
    916    @param[in, out]  RootBridgeHandle  Returns the device handle of the next PCI root bridge.
    917 
    918    @retval EFI_SUCCESS            If parameter RootBridgeHandle = NULL, then return the first Rootbridge handle of the
    919                                   specific Host bridge and return EFI_SUCCESS.
    920    @retval EFI_NOT_FOUND          Can not find the any more root bridge in specific host bridge.
    921    @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not an EFI_HANDLE that was
    922                                   returned on a previous call to GetNextRootBridge().
    923 **/
    924 EFI_STATUS
    925 EFIAPI
    926 GetNextRootBridge(
    927   IN       EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
    928   IN OUT   EFI_HANDLE                                       *RootBridgeHandle
    929   )
    930 {
    931   BOOLEAN                               NoRootBridge;
    932   LIST_ENTRY                            *List;
    933   PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
    934   PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
    935 
    936   NoRootBridge = TRUE;
    937   HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
    938   List = HostBridgeInstance->Head.ForwardLink;
    939 
    940 
    941   while (List != &HostBridgeInstance->Head) {
    942     NoRootBridge = FALSE;
    943     RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
    944     if (*RootBridgeHandle == NULL) {
    945       //
    946       // Return the first Root Bridge Handle of the Host Bridge
    947       //
    948       *RootBridgeHandle = RootBridgeInstance->Handle;
    949       return EFI_SUCCESS;
    950     } else {
    951       if (*RootBridgeHandle == RootBridgeInstance->Handle) {
    952         //
    953         // Get next if have
    954         //
    955         List = List->ForwardLink;
    956         if (List!=&HostBridgeInstance->Head) {
    957           RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
    958           *RootBridgeHandle = RootBridgeInstance->Handle;
    959           return EFI_SUCCESS;
    960         } else {
    961           return EFI_NOT_FOUND;
    962         }
    963       }
    964     }
    965 
    966     List = List->ForwardLink;
    967   } //end while
    968 
    969   if (NoRootBridge) {
    970     return EFI_NOT_FOUND;
    971   } else {
    972     return EFI_INVALID_PARAMETER;
    973   }
    974 }
    975 
    976 /**
    977    Returns the allocation attributes of a PCI root bridge.
    978 
    979    The function returns the allocation attributes of a specific PCI root bridge. The attributes can vary
    980    from one PCI root bridge to another. These attributes are different from the decode-related
    981    attributes that are returned by the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The
    982    RootBridgeHandle parameter is used to specify the instance of the PCI root bridge. The device
    983    handles of all the root bridges that are associated with this host bridge must be obtained by calling
    984    GetNextRootBridge(). The attributes are static in the sense that they do not change during or
    985    after the enumeration process. The hardware may provide mechanisms to change the attributes on
    986    the fly, but such changes must be completed before EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is
    987    installed. The permitted values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in
    988    "Related Definitions" below. The caller uses these attributes to combine multiple resource requests.
    989    For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI bus enumerator needs to
    990    include requests for the prefetchable memory in the nonprefetchable memory pool and not request any
    991    prefetchable memory.
    992       Attribute                                 Description
    993    ------------------------------------         ----------------------------------------------------------------------
    994    EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM         If this bit is set, then the PCI root bridge does not support separate
    995                                                 windows for nonprefetchable and prefetchable memory. A PCI bus
    996                                                 driver needs to include requests for prefetchable memory in the
    997                                                 nonprefetchable memory pool.
    998 
    999    EFI_PCI_HOST_BRIDGE_MEM64_DECODE             If this bit is set, then the PCI root bridge supports 64-bit memory
   1000                                                 windows. If this bit is not set, the PCI bus driver needs to include
   1001                                                 requests for a 64-bit memory address in the corresponding 32-bit
   1002                                                 memory pool.
   1003 
   1004    @param[in]   This               The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
   1005    @param[in]   RootBridgeHandle   The device handle of the PCI root bridge in which the caller is interested. Type
   1006                                    EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
   1007    @param[out]  Attributes         The pointer to attribte of root bridge, it is output parameter
   1008 
   1009    @retval EFI_INVALID_PARAMETER   Attribute pointer is NULL
   1010    @retval EFI_INVALID_PARAMETER   RootBridgehandle is invalid.
   1011    @retval EFI_SUCCESS             Success to get attribute of interested root bridge.
   1012 
   1013 **/
   1014 EFI_STATUS
   1015 EFIAPI
   1016 GetAttributes(
   1017   IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
   1018   IN  EFI_HANDLE                                       RootBridgeHandle,
   1019   OUT UINT64                                           *Attributes
   1020   )
   1021 {
   1022   LIST_ENTRY                            *List;
   1023   PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
   1024   PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
   1025 
   1026   if (Attributes == NULL) {
   1027     return EFI_INVALID_PARAMETER;
   1028   }
   1029 
   1030   HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
   1031   List = HostBridgeInstance->Head.ForwardLink;
   1032 
   1033   while (List != &HostBridgeInstance->Head) {
   1034     RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
   1035     if (RootBridgeHandle == RootBridgeInstance->Handle) {
   1036       *Attributes = RootBridgeInstance->RootBridgeAttrib;
   1037       return EFI_SUCCESS;
   1038     }
   1039 
   1040     List = List->ForwardLink;
   1041   }
   1042 
   1043   //
   1044   // RootBridgeHandle is not an EFI_HANDLE
   1045   // that was returned on a previous call to GetNextRootBridge()
   1046   //
   1047   return EFI_INVALID_PARAMETER;
   1048 }
   1049 
   1050 /**
   1051    Sets up the specified PCI root bridge for the bus enumeration process.
   1052 
   1053    This member function sets up the root bridge for bus enumeration and returns the PCI bus range
   1054    over which the search should be performed in ACPI 2.0 resource descriptor format.
   1055 
   1056    @param[in]   This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
   1057    @param[in]   RootBridgeHandle  The PCI Root Bridge to be set up.
   1058    @param[out]  Configuration     Pointer to the pointer to the PCI bus resource descriptor.
   1059 
   1060    @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle
   1061    @retval EFI_OUT_OF_RESOURCES  Fail to allocate ACPI resource descriptor tag.
   1062    @retval EFI_SUCCESS           Sucess to allocate ACPI resource descriptor.
   1063 
   1064 **/
   1065 EFI_STATUS
   1066 EFIAPI
   1067 StartBusEnumeration(
   1068   IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
   1069   IN  EFI_HANDLE                                       RootBridgeHandle,
   1070   OUT VOID                                             **Configuration
   1071   )
   1072 {
   1073   LIST_ENTRY                            *List;
   1074   PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
   1075   PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
   1076   VOID                                  *Buffer;
   1077   UINT8                                 *Temp;
   1078   UINT64                                BusStart;
   1079   UINT64                                BusEnd;
   1080 
   1081   HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
   1082   List = HostBridgeInstance->Head.ForwardLink;
   1083 
   1084   while (List != &HostBridgeInstance->Head) {
   1085     RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
   1086     if (RootBridgeHandle == RootBridgeInstance->Handle) {
   1087       //
   1088       // Set up the Root Bridge for Bus Enumeration
   1089       //
   1090       BusStart = RootBridgeInstance->BusBase;
   1091       BusEnd   = RootBridgeInstance->BusLimit;
   1092       //
   1093       // Program the Hardware(if needed) if error return EFI_DEVICE_ERROR
   1094       //
   1095 
   1096       Buffer = AllocatePool (sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof(EFI_ACPI_END_TAG_DESCRIPTOR));
   1097       if (Buffer == NULL) {
   1098         return EFI_OUT_OF_RESOURCES;
   1099       }
   1100 
   1101       Temp = (UINT8 *)Buffer;
   1102 
   1103       ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->Desc = 0x8A;
   1104       ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->Len  = 0x2B;
   1105       ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->ResType = 2;
   1106       ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->GenFlag = 0;
   1107       ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->SpecificFlag = 0;
   1108       ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrSpaceGranularity = 0;
   1109       ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrRangeMin = BusStart;
   1110       ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrRangeMax = 0;
   1111       ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrTranslationOffset = 0;
   1112       ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrLen = BusEnd - BusStart + 1;
   1113 
   1114       Temp = Temp + sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
   1115       ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Desc = 0x79;
   1116       ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Checksum = 0x0;
   1117 
   1118       *Configuration = Buffer;
   1119       return EFI_SUCCESS;
   1120     }
   1121     List = List->ForwardLink;
   1122   }
   1123 
   1124   return EFI_INVALID_PARAMETER;
   1125 }
   1126 
   1127 /**
   1128    Programs the PCI root bridge hardware so that it decodes the specified PCI bus range.
   1129 
   1130    This member function programs the specified PCI root bridge to decode the bus range that is
   1131    specified by the input parameter Configuration.
   1132    The bus range information is specified in terms of the ACPI 2.0 resource descriptor format.
   1133 
   1134    @param[in] This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
   1135    @param[in] RootBridgeHandle  The PCI Root Bridge whose bus range is to be programmed
   1136    @param[in] Configuration     The pointer to the PCI bus resource descriptor
   1137 
   1138    @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
   1139    @retval EFI_INVALID_PARAMETER  Configuration is NULL.
   1140    @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
   1141    @retval EFI_INVALID_PARAMETER  Configuration does not include a valid ACPI 2.0 bus resource descriptor.
   1142    @retval EFI_INVALID_PARAMETER  Configuration includes valid ACPI 2.0 resource descriptors other than
   1143                                   bus descriptors.
   1144    @retval EFI_INVALID_PARAMETER  Configuration contains one or more invalid ACPI resource descriptors.
   1145    @retval EFI_INVALID_PARAMETER  "Address Range Minimum" is invalid for this root bridge.
   1146    @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this root bridge.
   1147    @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
   1148    @retval EFI_SUCCESS            The bus range for the PCI root bridge was programmed.
   1149 
   1150 **/
   1151 EFI_STATUS
   1152 EFIAPI
   1153 SetBusNumbers(
   1154   IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
   1155   IN EFI_HANDLE                                       RootBridgeHandle,
   1156   IN VOID                                             *Configuration
   1157   )
   1158 {
   1159   LIST_ENTRY                            *List;
   1160   PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
   1161   PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
   1162   UINT8                                 *Ptr;
   1163   UINTN                                 BusStart;
   1164   UINTN                                 BusEnd;
   1165   UINTN                                 BusLen;
   1166 
   1167   if (Configuration == NULL) {
   1168     return EFI_INVALID_PARAMETER;
   1169   }
   1170 
   1171   Ptr = Configuration;
   1172 
   1173   //
   1174   // Check the Configuration is valid
   1175   //
   1176   if(*Ptr != ACPI_ADDRESS_SPACE_DESCRIPTOR) {
   1177     return EFI_INVALID_PARAMETER;
   1178   }
   1179 
   1180   if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->ResType != 2) {
   1181     return EFI_INVALID_PARAMETER;
   1182   }
   1183 
   1184   Ptr += sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
   1185   if (*Ptr != ACPI_END_TAG_DESCRIPTOR) {
   1186     return EFI_INVALID_PARAMETER;
   1187   }
   1188 
   1189   HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
   1190   List = HostBridgeInstance->Head.ForwardLink;
   1191 
   1192   Ptr = Configuration;
   1193 
   1194   while (List != &HostBridgeInstance->Head) {
   1195     RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
   1196     if (RootBridgeHandle == RootBridgeInstance->Handle) {
   1197       BusStart = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrRangeMin;
   1198       BusLen = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrLen;
   1199       BusEnd = BusStart + BusLen - 1;
   1200 
   1201       if (BusStart > BusEnd) {
   1202         return EFI_INVALID_PARAMETER;
   1203       }
   1204 
   1205       if ((BusStart < RootBridgeInstance->BusBase) || (BusEnd > RootBridgeInstance->BusLimit)) {
   1206         return EFI_INVALID_PARAMETER;
   1207       }
   1208 
   1209       //
   1210       // Update the Bus Range
   1211       //
   1212       RootBridgeInstance->ResAllocNode[TypeBus].Base   = BusStart;
   1213       RootBridgeInstance->ResAllocNode[TypeBus].Length = BusLen;
   1214       RootBridgeInstance->ResAllocNode[TypeBus].Status = ResAllocated;
   1215 
   1216       //
   1217       // Program the Root Bridge Hardware
   1218       //
   1219 
   1220       return EFI_SUCCESS;
   1221     }
   1222 
   1223     List = List->ForwardLink;
   1224   }
   1225 
   1226   return EFI_INVALID_PARAMETER;
   1227 }
   1228 
   1229 VOID
   1230 EFIAPI
   1231 SubmitGetResourceType(
   1232  IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     *Ptr,
   1233  OUT   UINT64*                            Index
   1234 )
   1235 {
   1236   switch (Ptr->ResType) {
   1237     case 0:
   1238       if (Ptr->AddrSpaceGranularity == 32) {
   1239         if (Ptr->SpecificFlag == 0x06)
   1240           *Index = TypePMem32;
   1241         else
   1242           *Index = TypeMem32;
   1243       }
   1244 
   1245       if (Ptr->AddrSpaceGranularity == 64) {
   1246         if (Ptr->SpecificFlag == 0x06)
   1247           *Index = TypePMem64;
   1248         else
   1249           *Index = TypeMem64;
   1250       }
   1251       break;
   1252 
   1253     case 1:
   1254       *Index = TypeIo;
   1255       break;
   1256 
   1257     default:
   1258       break;
   1259   };
   1260 
   1261 }
   1262 
   1263 /**
   1264    Submits the I/O and memory resource requirements for the specified PCI root bridge.
   1265 
   1266    This function is used to submit all the I/O and memory resources that are required by the specified
   1267    PCI root bridge. The input parameter Configuration is used to specify the following:
   1268    - The various types of resources that are required
   1269    - The associated lengths in terms of ACPI 2.0 resource descriptor format
   1270 
   1271    @param[in] This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
   1272    @param[in] RootBridgeHandle  The PCI root bridge whose I/O and memory resource requirements are being submitted.
   1273    @param[in] Configuration     The pointer to the PCI I/O and PCI memory resource descriptor.
   1274 
   1275    @retval EFI_SUCCESS            The I/O and memory resource requests for a PCI root bridge were accepted.
   1276    @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
   1277    @retval EFI_INVALID_PARAMETER  Configuration is NULL.
   1278    @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
   1279    @retval EFI_INVALID_PARAMETER  Configuration includes requests for one or more resource types that are
   1280                                   not supported by this PCI root bridge. This error will happen if the caller
   1281                                   did not combine resources according to Attributes that were returned by
   1282                                   GetAllocAttributes().
   1283    @retval EFI_INVALID_PARAMETER  Address Range Maximum" is invalid.
   1284    @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this PCI root bridge.
   1285    @retval EFI_INVALID_PARAMETER  "Address Space Granularity" is invalid for this PCI root bridge.
   1286 
   1287 **/
   1288 EFI_STATUS
   1289 EFIAPI
   1290 SubmitResources(
   1291   IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
   1292   IN EFI_HANDLE                                       RootBridgeHandle,
   1293   IN VOID                                             *Configuration
   1294   )
   1295 {
   1296   LIST_ENTRY                            *List;
   1297   PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
   1298   PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
   1299   UINT8                                 *Temp;
   1300   EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     *Ptr;
   1301   UINT64                                AddrLen;
   1302   UINT64                                Alignment;
   1303   UINTN                                 Index;
   1304 
   1305   PCIE_DEBUG("In SubmitResources\n");
   1306   //
   1307   // Check the input parameter: Configuration
   1308   //
   1309   if (Configuration == NULL)
   1310     return EFI_INVALID_PARAMETER;
   1311 
   1312   HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
   1313   List = HostBridgeInstance->Head.ForwardLink;
   1314 
   1315   Temp = (UINT8 *)Configuration;
   1316   while ( *Temp == 0x8A)
   1317     Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) ;
   1318 
   1319   if (*Temp != 0x79)
   1320     return EFI_INVALID_PARAMETER;
   1321 
   1322   Temp = (UINT8 *)Configuration;
   1323   while (List != &HostBridgeInstance->Head) {
   1324     RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
   1325     if (RootBridgeHandle == RootBridgeInstance->Handle) {
   1326       while ( *Temp == 0x8A) {
   1327         Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp ;
   1328         PCIE_DEBUG("Ptr->ResType:%d\n", Ptr->ResType);
   1329         PCIE_DEBUG("Ptr->Addrlen:%llx\n", Ptr->AddrLen);
   1330         PCIE_DEBUG("Ptr->AddrRangeMax:%llx\n", Ptr->AddrRangeMax);
   1331         PCIE_DEBUG("Ptr->AddrRangeMin:%llx\n", Ptr->AddrRangeMin);
   1332         PCIE_DEBUG("Ptr->SpecificFlag:%llx\n", Ptr->SpecificFlag);
   1333         PCIE_DEBUG("Ptr->AddrSpaceGranularity:%d\n", Ptr->AddrSpaceGranularity);
   1334         PCIE_DEBUG("RootBridgeInstance->RootBridgeAttrib:%llx\n", RootBridgeInstance->RootBridgeAttrib);
   1335         //
   1336         // Check address range alignment
   1337         //
   1338         if (Ptr->AddrRangeMax != (GetPowerOfTwo64 (Ptr->AddrRangeMax + 1) - 1)) {
   1339           return EFI_INVALID_PARAMETER;
   1340         }
   1341         Index = 0;
   1342         SubmitGetResourceType(Ptr,&Index);
   1343         AddrLen = (UINTN) Ptr->AddrLen;
   1344         Alignment = (UINTN) Ptr->AddrRangeMax;
   1345         RootBridgeInstance->ResAllocNode[Index].Length  = AddrLen;
   1346         RootBridgeInstance->ResAllocNode[Index].Alignment = Alignment;
   1347         RootBridgeInstance->ResAllocNode[Index].Status  = ResRequested;
   1348         HostBridgeInstance->ResourceSubmited = TRUE;
   1349 
   1350         Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) ;
   1351       }
   1352 
   1353       return EFI_SUCCESS;
   1354     }
   1355 
   1356     List = List->ForwardLink;
   1357   }
   1358   return EFI_INVALID_PARAMETER;
   1359 }
   1360 
   1361 /**
   1362    Returns the proposed resource settings for the specified PCI root bridge.
   1363 
   1364    This member function returns the proposed resource settings for the specified PCI root bridge. The
   1365    proposed resource settings are prepared when NotifyPhase() is called with a Phase of
   1366    EfiPciHostBridgeAllocateResources. The output parameter Configuration
   1367    specifies the following:
   1368    - The various types of resources, excluding bus resources, that are allocated
   1369    - The associated lengths in terms of ACPI 2.0 resource descriptor format
   1370 
   1371    @param[in]  This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
   1372    @param[in]  RootBridgeHandle  The PCI root bridge handle. Type EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
   1373    @param[out] Configuration     The pointer to the pointer to the PCI I/O and memory resource descriptor.
   1374 
   1375    @retval EFI_SUCCESS            The requested parameters were returned.
   1376    @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
   1377    @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
   1378    @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
   1379 
   1380 **/
   1381 EFI_STATUS
   1382 EFIAPI
   1383 SetResource(
   1384   PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance,
   1385   VOID                                  *Buffer
   1386 
   1387 )
   1388 {
   1389   UINTN                                 Index;
   1390   UINT8                                 *Temp;
   1391   EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     *Ptr;
   1392   UINT64                                ResStatus;
   1393 
   1394   Temp = Buffer;
   1395 
   1396   for (Index = 0; Index < TypeBus; Index ++)
   1397   {
   1398     if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
   1399       Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp ;
   1400       ResStatus = RootBridgeInstance->ResAllocNode[Index].Status;
   1401 
   1402       switch (Index) {
   1403 
   1404       case TypeIo:
   1405         //
   1406         // Io
   1407         //
   1408         Ptr->Desc = 0x8A;
   1409         Ptr->Len  = 0x2B;
   1410         Ptr->ResType = 1;
   1411         Ptr->GenFlag = 0;
   1412         Ptr->SpecificFlag = 0;
   1413         /* This is PCIE Device Bus which start address is the low 32bit of mem base*/
   1414         Ptr->AddrRangeMin = (RootBridgeInstance->ResAllocNode[Index].Base - RootBridgeInstance->MemBase) +
   1415                             (RootBridgeInstance->MemBase & 0xFFFFFFFF);
   1416         Ptr->AddrRangeMax = 0;
   1417         Ptr->AddrTranslationOffset = \
   1418              (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
   1419         Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
   1420         break;
   1421 
   1422       case TypeMem32:
   1423         //
   1424         // Memory 32
   1425         //
   1426         Ptr->Desc = 0x8A;
   1427         Ptr->Len  = 0x2B;
   1428         Ptr->ResType = 0;
   1429         Ptr->GenFlag = 0;
   1430         Ptr->SpecificFlag = 0;
   1431         Ptr->AddrSpaceGranularity = 32;
   1432         /* This is PCIE Device Bus which start address is the low 32bit of mem base*/
   1433         Ptr->AddrRangeMin = (RootBridgeInstance->ResAllocNode[Index].Base - RootBridgeInstance->MemBase) +
   1434                              (RootBridgeInstance->MemBase & 0xFFFFFFFF);
   1435         Ptr->AddrRangeMax = 0;
   1436         Ptr->AddrTranslationOffset = \
   1437              (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
   1438         Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
   1439         break;
   1440 
   1441       case TypePMem32:
   1442         //
   1443         // Prefetch memory 32
   1444         //
   1445         Ptr->Desc = 0x8A;
   1446         Ptr->Len  = 0x2B;
   1447         Ptr->ResType = 0;
   1448         Ptr->GenFlag = 0;
   1449         Ptr->SpecificFlag = 6;
   1450         Ptr->AddrSpaceGranularity = 32;
   1451         /* This is PCIE Device Bus which start address is the low 32bit of mem base*/
   1452         Ptr->AddrRangeMin = (RootBridgeInstance->ResAllocNode[Index].Base - RootBridgeInstance->MemBase) +
   1453                              (RootBridgeInstance->MemBase & 0xFFFFFFFF);
   1454         Ptr->AddrRangeMax = 0;
   1455         Ptr->AddrTranslationOffset = \
   1456              (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
   1457         Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
   1458         break;
   1459 
   1460       case TypeMem64:
   1461         //
   1462         // Memory 64
   1463         //
   1464         Ptr->Desc = 0x8A;
   1465         Ptr->Len  = 0x2B;
   1466         Ptr->ResType = 0;
   1467         Ptr->GenFlag = 0;
   1468         Ptr->SpecificFlag = 0;
   1469         Ptr->AddrSpaceGranularity = 64;
   1470         /* This is PCIE Device Bus which start address is the low 32bit of mem base*/
   1471         Ptr->AddrRangeMin = (RootBridgeInstance->ResAllocNode[Index].Base - RootBridgeInstance->MemBase) +
   1472                              (RootBridgeInstance->MemBase & 0xFFFFFFFFFFFFFFFF);
   1473         Ptr->AddrRangeMax = 0;
   1474         Ptr->AddrTranslationOffset = \
   1475              (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
   1476         Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
   1477         break;
   1478 
   1479       case TypePMem64:
   1480         //
   1481         // Prefetch memory 64
   1482         //
   1483         Ptr->Desc = 0x8A;
   1484         Ptr->Len  = 0x2B;
   1485         Ptr->ResType = 0;
   1486         Ptr->GenFlag = 0;
   1487         Ptr->SpecificFlag = 6;
   1488         Ptr->AddrSpaceGranularity = 64;
   1489         /* This is PCIE Device Bus which start address is the low 32bit of mem base*/
   1490         Ptr->AddrRangeMin = (RootBridgeInstance->ResAllocNode[Index].Base - RootBridgeInstance->MemBase) +
   1491                              (RootBridgeInstance->MemBase & 0xFFFFFFFFFFFFFFFF);
   1492         Ptr->AddrRangeMax = 0;
   1493         Ptr->AddrTranslationOffset = \
   1494              (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
   1495         Ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
   1496         break;
   1497       };
   1498       PCIE_DEBUG("Ptr->ResType:%d\n", Ptr->ResType);
   1499       PCIE_DEBUG("Ptr->Addrlen:%llx\n", Ptr->AddrLen);
   1500       PCIE_DEBUG("Ptr->AddrRangeMax:%llx\n", Ptr->AddrRangeMax);
   1501       PCIE_DEBUG("Ptr->AddrRangeMin:%llx\n", Ptr->AddrRangeMin);
   1502       PCIE_DEBUG("Ptr->SpecificFlag:%llx\n", Ptr->SpecificFlag);
   1503       PCIE_DEBUG("Ptr->AddrTranslationOffset:%d\n", Ptr->AddrTranslationOffset);
   1504       PCIE_DEBUG("Ptr->AddrSpaceGranularity:%d\n", Ptr->AddrSpaceGranularity);
   1505 
   1506       Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
   1507     }
   1508   }
   1509   ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Desc = 0x79;
   1510   ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Checksum = 0x0;
   1511 
   1512   return EFI_SUCCESS;
   1513 }
   1514 /**
   1515    Returns the proposed resource settings for the specified PCI root bridge.
   1516 
   1517    This member function returns the proposed resource settings for the specified PCI root bridge. The
   1518    proposed resource settings are prepared when NotifyPhase() is called with a Phase of
   1519    EfiPciHostBridgeAllocateResources. The output parameter Configuration
   1520    specifies the following:
   1521    - The various types of resources, excluding bus resources, that are allocated
   1522    - The associated lengths in terms of ACPI 2.0 resource descriptor format
   1523 
   1524    @param[in]  This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
   1525    @param[in]  RootBridgeHandle  The PCI root bridge handle. Type EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
   1526    @param[out] Configuration     The pointer to the pointer to the PCI I/O and memory resource descriptor.
   1527 
   1528    @retval EFI_SUCCESS            The requested parameters were returned.
   1529    @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
   1530    @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
   1531    @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
   1532 
   1533 **/
   1534 EFI_STATUS
   1535 EFIAPI
   1536 GetProposedResources(
   1537   IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
   1538   IN  EFI_HANDLE                                       RootBridgeHandle,
   1539   OUT VOID                                             **Configuration
   1540   )
   1541 {
   1542   LIST_ENTRY                            *List;
   1543   PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
   1544   PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
   1545   UINTN                                 Index;
   1546   UINTN                                 Number;
   1547   VOID                                  *Buffer;
   1548 
   1549   Buffer = NULL;
   1550   Number = 0;
   1551 
   1552   PCIE_DEBUG("In GetProposedResources\n");
   1553   //
   1554   // Get the Host Bridge Instance from the resource allocation protocol
   1555   //
   1556   HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
   1557   List = HostBridgeInstance->Head.ForwardLink;
   1558 
   1559   //
   1560   // Enumerate the root bridges in this host bridge
   1561   //
   1562   while (List != &HostBridgeInstance->Head) {
   1563     RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
   1564     if (RootBridgeHandle == RootBridgeInstance->Handle) {
   1565       for (Index = 0; Index < TypeBus; Index ++) {
   1566         if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
   1567           Number ++;
   1568         }
   1569       }
   1570 
   1571       Buffer = AllocateZeroPool (Number * sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof(EFI_ACPI_END_TAG_DESCRIPTOR));
   1572       if (Buffer == NULL) {
   1573         return EFI_OUT_OF_RESOURCES;
   1574       }
   1575 
   1576       (VOID)SetResource(RootBridgeInstance,Buffer);
   1577 
   1578       *Configuration = Buffer;
   1579 
   1580       return EFI_SUCCESS;
   1581     }
   1582 
   1583     List = List->ForwardLink;
   1584   }
   1585 
   1586   return EFI_INVALID_PARAMETER;
   1587 }
   1588 
   1589 /**
   1590    Provides the hooks from the PCI bus driver to every PCI controller (device/function) at various
   1591    stages of the PCI enumeration process that allow the host bridge driver to preinitialize individual
   1592    PCI controllers before enumeration.
   1593 
   1594    This function is called during the PCI enumeration process. No specific action is expected from this
   1595    member function. It allows the host bridge driver to preinitialize individual PCI controllers before
   1596    enumeration.
   1597 
   1598    @param This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
   1599    @param RootBridgeHandle  The associated PCI root bridge handle. Type EFI_HANDLE is defined in
   1600                             InstallProtocolInterface() in the UEFI 2.0 Specification.
   1601    @param PciAddress        The address of the PCI device on the PCI bus. This address can be passed to the
   1602                             EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to access the PCI
   1603                             configuration space of the device. See Table 12-1 in the UEFI 2.0 Specification for
   1604                             the definition of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.
   1605    @param Phase             The phase of the PCI device enumeration.
   1606 
   1607    @retval EFI_SUCCESS              The requested parameters were returned.
   1608    @retval EFI_INVALID_PARAMETER    RootBridgeHandle is not a valid root bridge handle.
   1609    @retval EFI_INVALID_PARAMETER    Phase is not a valid phase that is defined in
   1610                                     EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.
   1611    @retval EFI_DEVICE_ERROR         Programming failed due to a hardware error. The PCI enumerator should
   1612                                     not enumerate this device, including its child devices if it is a PCI-to-PCI
   1613                                     bridge.
   1614 
   1615 **/
   1616 EFI_STATUS
   1617 EFIAPI
   1618 PreprocessController (
   1619   IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL          *This,
   1620   IN  EFI_HANDLE                                                RootBridgeHandle,
   1621   IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS               PciAddress,
   1622   IN  EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE              Phase
   1623   )
   1624 {
   1625   PCI_HOST_BRIDGE_INSTANCE              *HostBridgeInstance;
   1626   PCI_ROOT_BRIDGE_INSTANCE              *RootBridgeInstance;
   1627   LIST_ENTRY                            *List;
   1628 
   1629   HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
   1630   List = HostBridgeInstance->Head.ForwardLink;
   1631 
   1632   //
   1633   // Enumerate the root bridges in this host bridge
   1634   //
   1635   while (List != &HostBridgeInstance->Head) {
   1636     RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
   1637     if (RootBridgeHandle == RootBridgeInstance->Handle) {
   1638       break;
   1639     }
   1640     List = List->ForwardLink;
   1641   }
   1642   if (List == &HostBridgeInstance->Head) {
   1643     return EFI_INVALID_PARAMETER;
   1644   }
   1645 
   1646   if ((UINT32)Phase > EfiPciBeforeResourceCollection) {
   1647     return EFI_INVALID_PARAMETER;
   1648   }
   1649 
   1650   return EFI_SUCCESS;
   1651 }
   1652