• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   Library instance of PciHostBridgeLib library class for coreboot.
3 
4   Copyright (C) 2016, Red Hat, Inc.
5   Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
6 
7   This program and the accompanying materials are licensed and made available
8   under the terms and conditions of the BSD License which accompanies this
9   distribution.  The full text of the license may be found at
10   http://opensource.org/licenses/bsd-license.php.
11 
12   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
13   WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 
15 **/
16 #include <PiDxe.h>
17 
18 #include <IndustryStandard/Pci.h>
19 #include <Protocol/PciHostBridgeResourceAllocation.h>
20 #include <Protocol/PciRootBridgeIo.h>
21 
22 #include <Library/BaseMemoryLib.h>
23 #include <Library/DebugLib.h>
24 #include <Library/DevicePathLib.h>
25 #include <Library/MemoryAllocationLib.h>
26 #include <Library/PciHostBridgeLib.h>
27 #include <Library/PciLib.h>
28 
29 #include "PciHostBridge.h"
30 
31 STATIC
32 CONST
33 CB_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate = {
34   {
35     {
36       ACPI_DEVICE_PATH,
37       ACPI_DP,
38       {
39         (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
40         (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
41       }
42     },
43     EISA_PNP_ID(0x0A03), // HID
44     0                    // UID
45   },
46 
47   {
48     END_DEVICE_PATH_TYPE,
49     END_ENTIRE_DEVICE_PATH_SUBTYPE,
50     {
51       END_DEVICE_PATH_LENGTH,
52       0
53     }
54   }
55 };
56 
57 
58 /**
59   Initialize a PCI_ROOT_BRIDGE structure.
60 
61   @param[in]  Supports         Supported attributes.
62 
63   @param[in]  Attributes       Initial attributes.
64 
65   @param[in]  AllocAttributes  Allocation attributes.
66 
67   @param[in]  RootBusNumber    The bus number to store in RootBus.
68 
69   @param[in]  MaxSubBusNumber  The inclusive maximum bus number that can be
70                                assigned to any subordinate bus found behind any
71                                PCI bridge hanging off this root bus.
72 
73                                The caller is repsonsible for ensuring that
74                                RootBusNumber <= MaxSubBusNumber. If
75                                RootBusNumber equals MaxSubBusNumber, then the
76                                root bus has no room for subordinate buses.
77 
78   @param[in]  Io               IO aperture.
79 
80   @param[in]  Mem              MMIO aperture.
81 
82   @param[in]  MemAbove4G       MMIO aperture above 4G.
83 
84   @param[in]  PMem             Prefetchable MMIO aperture.
85 
86   @param[in]  PMemAbove4G      Prefetchable MMIO aperture above 4G.
87 
88   @param[out] RootBus          The PCI_ROOT_BRIDGE structure (allocated by the
89                                caller) that should be filled in by this
90                                function.
91 
92   @retval EFI_SUCCESS           Initialization successful. A device path
93                                 consisting of an ACPI device path node, with
94                                 UID = RootBusNumber, has been allocated and
95                                 linked into RootBus.
96 
97   @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
98 **/
99 EFI_STATUS
InitRootBridge(IN UINT64 Supports,IN UINT64 Attributes,IN UINT64 AllocAttributes,IN UINT8 RootBusNumber,IN UINT8 MaxSubBusNumber,IN PCI_ROOT_BRIDGE_APERTURE * Io,IN PCI_ROOT_BRIDGE_APERTURE * Mem,IN PCI_ROOT_BRIDGE_APERTURE * MemAbove4G,IN PCI_ROOT_BRIDGE_APERTURE * PMem,IN PCI_ROOT_BRIDGE_APERTURE * PMemAbove4G,OUT PCI_ROOT_BRIDGE * RootBus)100 InitRootBridge (
101   IN  UINT64                   Supports,
102   IN  UINT64                   Attributes,
103   IN  UINT64                   AllocAttributes,
104   IN  UINT8                    RootBusNumber,
105   IN  UINT8                    MaxSubBusNumber,
106   IN  PCI_ROOT_BRIDGE_APERTURE *Io,
107   IN  PCI_ROOT_BRIDGE_APERTURE *Mem,
108   IN  PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,
109   IN  PCI_ROOT_BRIDGE_APERTURE *PMem,
110   IN  PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G,
111   OUT PCI_ROOT_BRIDGE          *RootBus
112 )
113 {
114   CB_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath;
115 
116   //
117   // Be safe if other fields are added to PCI_ROOT_BRIDGE later.
118   //
119   ZeroMem (RootBus, sizeof *RootBus);
120 
121   RootBus->Segment = 0;
122 
123   RootBus->Supports   = Supports;
124   RootBus->Attributes = Attributes;
125 
126   RootBus->DmaAbove4G = FALSE;
127 
128   RootBus->AllocationAttributes = AllocAttributes;
129   RootBus->Bus.Base  = RootBusNumber;
130   RootBus->Bus.Limit = MaxSubBusNumber;
131   CopyMem (&RootBus->Io, Io, sizeof (*Io));
132   CopyMem (&RootBus->Mem, Mem, sizeof (*Mem));
133   CopyMem (&RootBus->MemAbove4G, MemAbove4G, sizeof (*MemAbove4G));
134   CopyMem (&RootBus->PMem, PMem, sizeof (*PMem));
135   CopyMem (&RootBus->PMemAbove4G, PMemAbove4G, sizeof (*PMemAbove4G));
136 
137   RootBus->NoExtendedConfigSpace = FALSE;
138 
139   DevicePath = AllocateCopyPool (sizeof (mRootBridgeDevicePathTemplate),
140                                  &mRootBridgeDevicePathTemplate);
141   if (DevicePath == NULL) {
142     DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES));
143     return EFI_OUT_OF_RESOURCES;
144   }
145   DevicePath->AcpiDevicePath.UID = RootBusNumber;
146   RootBus->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;
147 
148   DEBUG ((EFI_D_INFO,
149           "%a: populated root bus %d, with room for %d subordinate bus(es)\n",
150           __FUNCTION__, RootBusNumber, MaxSubBusNumber - RootBusNumber));
151   return EFI_SUCCESS;
152 }
153 
154 
155 /**
156   Return all the root bridge instances in an array.
157 
158   @param Count  Return the count of root bridge instances.
159 
160   @return All the root bridge instances in an array.
161           The array should be passed into PciHostBridgeFreeRootBridges()
162           when it's not used.
163 **/
164 PCI_ROOT_BRIDGE *
165 EFIAPI
PciHostBridgeGetRootBridges(UINTN * Count)166 PciHostBridgeGetRootBridges (
167   UINTN *Count
168 )
169 {
170   return ScanForRootBridges (Count);
171 }
172 
173 
174 /**
175   Free the root bridge instances array returned from
176   PciHostBridgeGetRootBridges().
177 
178   @param  The root bridge instances array.
179   @param  The count of the array.
180 **/
181 VOID
182 EFIAPI
PciHostBridgeFreeRootBridges(PCI_ROOT_BRIDGE * Bridges,UINTN Count)183 PciHostBridgeFreeRootBridges (
184   PCI_ROOT_BRIDGE *Bridges,
185   UINTN           Count
186 )
187 {
188   if (Bridges == NULL && Count == 0) {
189     return;
190   }
191   ASSERT (Bridges != NULL && Count > 0);
192 
193   do {
194     --Count;
195     FreePool (Bridges[Count].DevicePath);
196   } while (Count > 0);
197 
198   FreePool (Bridges);
199 }
200 
201 
202 /**
203   Inform the platform that the resource conflict happens.
204 
205   @param HostBridgeHandle Handle of the Host Bridge.
206   @param Configuration    Pointer to PCI I/O and PCI memory resource
207                           descriptors. The Configuration contains the resources
208                           for all the root bridges. The resource for each root
209                           bridge is terminated with END descriptor and an
210                           additional END is appended indicating the end of the
211                           entire resources. The resource descriptor field
212                           values follow the description in
213                           EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
214                           .SubmitResources().
215 **/
216 VOID
217 EFIAPI
PciHostBridgeResourceConflict(EFI_HANDLE HostBridgeHandle,VOID * Configuration)218 PciHostBridgeResourceConflict (
219   EFI_HANDLE                        HostBridgeHandle,
220   VOID                              *Configuration
221 )
222 {
223   //
224   // coreboot UEFI Payload does not do PCI enumeration and should not call this
225   // library interface.
226   //
227   ASSERT (FALSE);
228 }
229