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