Home | History | Annotate | Download | only in AmdStyxPciHostBridgeLib
      1 /** @file
      2   PCI Host Bridge Library instance for AMD Seattle SOC
      3 
      4   Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
      5 
      6   This program and the accompanying materials are licensed and made available
      7   under the terms and conditions of the BSD License which accompanies this
      8   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, WITHOUT
     12   WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 #include <PiDxe.h>
     16 #include <Library/PciHostBridgeLib.h>
     17 #include <Library/DebugLib.h>
     18 #include <Library/DevicePathLib.h>
     19 #include <Library/MemoryAllocationLib.h>
     20 #include <Library/PcdLib.h>
     21 
     22 #include <Protocol/PciRootBridgeIo.h>
     23 #include <Protocol/PciHostBridgeResourceAllocation.h>
     24 
     25 #pragma pack(1)
     26 typedef struct {
     27   ACPI_HID_DEVICE_PATH     AcpiDevicePath;
     28   EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
     29 } EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
     30 #pragma pack ()
     31 
     32 STATIC EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath = {
     33   {
     34     {
     35       ACPI_DEVICE_PATH,
     36       ACPI_DP,
     37       {
     38         (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
     39         (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
     40       }
     41     },
     42     EISA_PNP_ID(0x0A08), // PCI Express
     43     0
     44   },
     45 
     46   {
     47     END_DEVICE_PATH_TYPE,
     48     END_ENTIRE_DEVICE_PATH_SUBTYPE,
     49     {
     50       END_DEVICE_PATH_LENGTH,
     51       0
     52     }
     53   }
     54 };
     55 
     56 GLOBAL_REMOVE_IF_UNREFERENCED
     57 CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {
     58   L"Mem", L"I/O", L"Bus"
     59 };
     60 
     61 /**
     62   Return all the root bridge instances in an array.
     63 
     64   @param Count  Return the count of root bridge instances.
     65 
     66   @return All the root bridge instances in an array.
     67           The array should be passed into PciHostBridgeFreeRootBridges()
     68           when it's not used.
     69 **/
     70 PCI_ROOT_BRIDGE *
     71 EFIAPI
     72 PciHostBridgeGetRootBridges (
     73   UINTN *Count
     74   )
     75 {
     76   PCI_ROOT_BRIDGE     *RootBridge;
     77 
     78   *Count = 1;
     79   RootBridge = AllocateZeroPool (*Count * sizeof *RootBridge);
     80 
     81   RootBridge->Segment     = 0;
     82 
     83   RootBridge->Supports    = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO |
     84                             EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO |
     85                             EFI_PCI_ATTRIBUTE_ISA_IO_16 |
     86                             EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO |
     87                             EFI_PCI_ATTRIBUTE_VGA_MEMORY |
     88                             EFI_PCI_ATTRIBUTE_VGA_IO_16  |
     89                             EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
     90   RootBridge->Attributes  = RootBridge->Supports;
     91 
     92   RootBridge->DmaAbove4G  = TRUE;
     93 
     94   RootBridge->AllocationAttributes  = EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM |
     95                                       EFI_PCI_HOST_BRIDGE_MEM64_DECODE ;
     96 
     97   RootBridge->Bus.Base              = PcdGet32 (PcdPciBusMin);
     98   RootBridge->Bus.Limit             = PcdGet32 (PcdPciBusMax);
     99   RootBridge->Io.Base               = PcdGet64 (PcdPciIoBase);
    100   RootBridge->Io.Limit              = PcdGet64 (PcdPciIoBase) + PcdGet64 (PcdPciIoSize) - 1;
    101   RootBridge->Mem.Base              = PcdGet32 (PcdPciMmio32Base);
    102   RootBridge->Mem.Limit             = PcdGet32 (PcdPciMmio32Base) + PcdGet32 (PcdPciMmio32Size) - 1;
    103   RootBridge->MemAbove4G.Base       = PcdGet64 (PcdPciMmio64Base);
    104   RootBridge->MemAbove4G.Limit      = PcdGet64 (PcdPciMmio64Base) + PcdGet64 (PcdPciMmio64Size) - 1;
    105 
    106   //
    107   // No separate ranges for prefetchable and non-prefetchable BARs
    108   //
    109   RootBridge->PMem.Base             = MAX_UINT64;
    110   RootBridge->PMem.Limit            = 0;
    111   RootBridge->PMemAbove4G.Base      = MAX_UINT64;
    112   RootBridge->PMemAbove4G.Limit     = 0;
    113 
    114   ASSERT (FixedPcdGet64 (PcdPciMmio32Translation) == 0);
    115   ASSERT (FixedPcdGet64 (PcdPciMmio64Translation) == 0);
    116 
    117   RootBridge->NoExtendedConfigSpace = FALSE;
    118 
    119   RootBridge->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)&mEfiPciRootBridgeDevicePath;
    120 
    121   return RootBridge;
    122 }
    123 
    124 /**
    125   Free the root bridge instances array returned from PciHostBridgeGetRootBridges().
    126 
    127   @param Bridges The root bridge instances array.
    128   @param Count   The count of the array.
    129 **/
    130 VOID
    131 EFIAPI
    132 PciHostBridgeFreeRootBridges (
    133   PCI_ROOT_BRIDGE *Bridges,
    134   UINTN           Count
    135   )
    136 {
    137   FreePool (Bridges);
    138 }
    139 
    140 /**
    141   Inform the platform that the resource conflict happens.
    142 
    143   @param HostBridgeHandle Handle of the Host Bridge.
    144   @param Configuration    Pointer to PCI I/O and PCI memory resource
    145                           descriptors. The Configuration contains the resources
    146                           for all the root bridges. The resource for each root
    147                           bridge is terminated with END descriptor and an
    148                           additional END is appended indicating the end of the
    149                           entire resources. The resource descriptor field
    150                           values follow the description in
    151                           EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
    152                           .SubmitResources().
    153 **/
    154 VOID
    155 EFIAPI
    156 PciHostBridgeResourceConflict (
    157   EFI_HANDLE                        HostBridgeHandle,
    158   VOID                              *Configuration
    159   )
    160 {
    161   EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
    162   UINTN                             RootBridgeIndex;
    163   DEBUG ((EFI_D_ERROR, "PciHostBridge: Resource conflict happens!\n"));
    164 
    165   RootBridgeIndex = 0;
    166   Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
    167   while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
    168     DEBUG ((EFI_D_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++));
    169     for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
    170       ASSERT (Descriptor->ResType <
    171               (sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr) /
    172                sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr[0])
    173                )
    174               );
    175       DEBUG ((EFI_D_ERROR, " %s: Length/Alignment = 0x%lx / 0x%lx\n",
    176               mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType],
    177               Descriptor->AddrLen, Descriptor->AddrRangeMax
    178               ));
    179       if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
    180         DEBUG ((EFI_D_ERROR, "     Granularity/SpecificFlag = %ld / %02x%s\n",
    181                 Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag,
    182                 ((Descriptor->SpecificFlag &
    183                   EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE
    184                   ) != 0) ? L" (Prefetchable)" : L""
    185                 ));
    186       }
    187     }
    188     //
    189     // Skip the END descriptor for root bridge
    190     //
    191     ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR);
    192     Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)(
    193                    (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1
    194                    );
    195   }
    196 }
    197