1 | /** @file
|
---|
2 | PCI Host Bridge Library instance for pci-ecam-generic DT nodes
|
---|
3 |
|
---|
4 | Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
|
---|
5 |
|
---|
6 | SPDX-License-Identifier: BSD-2-Clause-Patent
|
---|
7 |
|
---|
8 | **/
|
---|
9 | #include <PiDxe.h>
|
---|
10 | #include <Library/BaseMemoryLib.h>
|
---|
11 | #include <Library/DebugLib.h>
|
---|
12 | #include <Library/DevicePathLib.h>
|
---|
13 | #include <Library/DxeServicesTableLib.h>
|
---|
14 | #include <Library/MemoryAllocationLib.h>
|
---|
15 | #include <Library/PcdLib.h>
|
---|
16 | #include <Library/PciHostBridgeLib.h>
|
---|
17 | #include <Library/PciHostBridgeUtilityLib.h>
|
---|
18 | #include <Library/UefiBootServicesTableLib.h>
|
---|
19 |
|
---|
20 | #include <Protocol/FdtClient.h>
|
---|
21 | #include <Protocol/PciRootBridgeIo.h>
|
---|
22 | #include <Protocol/PciHostBridgeResourceAllocation.h>
|
---|
23 |
|
---|
24 | //
|
---|
25 | // We expect the "ranges" property of "pci-host-ecam-generic" to consist of
|
---|
26 | // records like this.
|
---|
27 | //
|
---|
28 | #pragma pack (1)
|
---|
29 | typedef struct {
|
---|
30 | UINT32 Type;
|
---|
31 | UINT64 ChildBase;
|
---|
32 | UINT64 CpuBase;
|
---|
33 | UINT64 Size;
|
---|
34 | } DTB_PCI_HOST_RANGE_RECORD;
|
---|
35 | #pragma pack ()
|
---|
36 |
|
---|
37 | #define DTB_PCI_HOST_RANGE_RELOCATABLE BIT31
|
---|
38 | #define DTB_PCI_HOST_RANGE_PREFETCHABLE BIT30
|
---|
39 | #define DTB_PCI_HOST_RANGE_ALIASED BIT29
|
---|
40 | #define DTB_PCI_HOST_RANGE_MMIO32 BIT25
|
---|
41 | #define DTB_PCI_HOST_RANGE_MMIO64 (BIT25 | BIT24)
|
---|
42 | #define DTB_PCI_HOST_RANGE_IO BIT24
|
---|
43 | #define DTB_PCI_HOST_RANGE_TYPEMASK (BIT31 | BIT30 | BIT29 | BIT25 | BIT24)
|
---|
44 |
|
---|
45 | STATIC
|
---|
46 | EFI_STATUS
|
---|
47 | MapGcdMmioSpace (
|
---|
48 | IN UINT64 Base,
|
---|
49 | IN UINT64 Size
|
---|
50 | )
|
---|
51 | {
|
---|
52 | EFI_STATUS Status;
|
---|
53 |
|
---|
54 | Status = gDS->AddMemorySpace (
|
---|
55 | EfiGcdMemoryTypeMemoryMappedIo,
|
---|
56 | Base,
|
---|
57 | Size,
|
---|
58 | EFI_MEMORY_UC
|
---|
59 | );
|
---|
60 | if (EFI_ERROR (Status)) {
|
---|
61 | DEBUG ((
|
---|
62 | DEBUG_ERROR,
|
---|
63 | "%a: failed to add GCD memory space for region [0x%Lx+0x%Lx)\n",
|
---|
64 | __func__,
|
---|
65 | Base,
|
---|
66 | Size
|
---|
67 | ));
|
---|
68 | return Status;
|
---|
69 | }
|
---|
70 |
|
---|
71 | Status = gDS->SetMemorySpaceAttributes (Base, Size, EFI_MEMORY_UC);
|
---|
72 | if (EFI_ERROR (Status)) {
|
---|
73 | DEBUG ((
|
---|
74 | DEBUG_ERROR,
|
---|
75 | "%a: failed to set memory space attributes for region [0x%Lx+0x%Lx)\n",
|
---|
76 | __func__,
|
---|
77 | Base,
|
---|
78 | Size
|
---|
79 | ));
|
---|
80 | }
|
---|
81 |
|
---|
82 | return Status;
|
---|
83 | }
|
---|
84 |
|
---|
85 | STATIC
|
---|
86 | EFI_STATUS
|
---|
87 | ProcessPciHost (
|
---|
88 | OUT UINT64 *IoBase,
|
---|
89 | OUT UINT64 *IoSize,
|
---|
90 | OUT UINT64 *Mmio32Base,
|
---|
91 | OUT UINT64 *Mmio32Size,
|
---|
92 | OUT UINT64 *Mmio64Base,
|
---|
93 | OUT UINT64 *Mmio64Size,
|
---|
94 | OUT UINT32 *BusMin,
|
---|
95 | OUT UINT32 *BusMax
|
---|
96 | )
|
---|
97 | {
|
---|
98 | FDT_CLIENT_PROTOCOL *FdtClient;
|
---|
99 | INT32 Node;
|
---|
100 | UINT64 ConfigBase, ConfigSize;
|
---|
101 | CONST VOID *Prop;
|
---|
102 | UINT32 Len;
|
---|
103 | UINT32 RecordIdx;
|
---|
104 | EFI_STATUS Status;
|
---|
105 | UINT64 IoTranslation;
|
---|
106 | UINT64 Mmio32Translation;
|
---|
107 | UINT64 Mmio64Translation;
|
---|
108 |
|
---|
109 | //
|
---|
110 | // The following output arguments are initialized only in
|
---|
111 | // order to suppress '-Werror=maybe-uninitialized' warnings
|
---|
112 | // *incorrectly* emitted by some gcc versions.
|
---|
113 | //
|
---|
114 | *IoBase = 0;
|
---|
115 | *Mmio32Base = 0;
|
---|
116 | *Mmio64Base = MAX_UINT64;
|
---|
117 | *BusMin = 0;
|
---|
118 | *BusMax = 0;
|
---|
119 |
|
---|
120 | //
|
---|
121 | // *IoSize, *Mmio##Size and IoTranslation are initialized to zero because the
|
---|
122 | // logic below requires it. However, since they are also affected by the issue
|
---|
123 | // reported above, they are initialized early.
|
---|
124 | //
|
---|
125 | *IoSize = 0;
|
---|
126 | *Mmio32Size = 0;
|
---|
127 | *Mmio64Size = 0;
|
---|
128 | IoTranslation = 0;
|
---|
129 |
|
---|
130 | Status = gBS->LocateProtocol (
|
---|
131 | &gFdtClientProtocolGuid,
|
---|
132 | NULL,
|
---|
133 | (VOID **)&FdtClient
|
---|
134 | );
|
---|
135 | ASSERT_EFI_ERROR (Status);
|
---|
136 |
|
---|
137 | Status = FdtClient->FindCompatibleNode (
|
---|
138 | FdtClient,
|
---|
139 | "pci-host-ecam-generic",
|
---|
140 | &Node
|
---|
141 | );
|
---|
142 | if (EFI_ERROR (Status)) {
|
---|
143 | DEBUG ((
|
---|
144 | DEBUG_INFO,
|
---|
145 | "%a: No 'pci-host-ecam-generic' compatible DT node found\n",
|
---|
146 | __func__
|
---|
147 | ));
|
---|
148 | return EFI_NOT_FOUND;
|
---|
149 | }
|
---|
150 |
|
---|
151 | DEBUG_CODE (
|
---|
152 | INT32 Tmp;
|
---|
153 |
|
---|
154 | //
|
---|
155 | // A DT can legally describe multiple PCI host bridges, but we are not
|
---|
156 | // equipped to deal with that. So assert that there is only one.
|
---|
157 | //
|
---|
158 | Status = FdtClient->FindNextCompatibleNode (
|
---|
159 | FdtClient,
|
---|
160 | "pci-host-ecam-generic",
|
---|
161 | Node,
|
---|
162 | &Tmp
|
---|
163 | );
|
---|
164 | ASSERT (Status == EFI_NOT_FOUND);
|
---|
165 | );
|
---|
166 |
|
---|
167 | Status = FdtClient->GetNodeProperty (FdtClient, Node, "reg", &Prop, &Len);
|
---|
168 | if (EFI_ERROR (Status) || (Len != 2 * sizeof (UINT64))) {
|
---|
169 | DEBUG ((
|
---|
170 | DEBUG_ERROR,
|
---|
171 | "%a: 'reg' property not found or invalid\n",
|
---|
172 | __func__
|
---|
173 | ));
|
---|
174 | return EFI_PROTOCOL_ERROR;
|
---|
175 | }
|
---|
176 |
|
---|
177 | //
|
---|
178 | // Fetch the ECAM window.
|
---|
179 | //
|
---|
180 | ConfigBase = SwapBytes64 (((CONST UINT64 *)Prop)[0]);
|
---|
181 | ConfigSize = SwapBytes64 (((CONST UINT64 *)Prop)[1]);
|
---|
182 |
|
---|
183 | //
|
---|
184 | // Fetch the bus range (note: inclusive).
|
---|
185 | //
|
---|
186 | Status = FdtClient->GetNodeProperty (
|
---|
187 | FdtClient,
|
---|
188 | Node,
|
---|
189 | "bus-range",
|
---|
190 | &Prop,
|
---|
191 | &Len
|
---|
192 | );
|
---|
193 | if (EFI_ERROR (Status) || (Len != 2 * sizeof (UINT32))) {
|
---|
194 | DEBUG ((
|
---|
195 | DEBUG_ERROR,
|
---|
196 | "%a: 'bus-range' not found or invalid\n",
|
---|
197 | __func__
|
---|
198 | ));
|
---|
199 | return EFI_PROTOCOL_ERROR;
|
---|
200 | }
|
---|
201 |
|
---|
202 | *BusMin = SwapBytes32 (((CONST UINT32 *)Prop)[0]);
|
---|
203 | *BusMax = SwapBytes32 (((CONST UINT32 *)Prop)[1]);
|
---|
204 |
|
---|
205 | //
|
---|
206 | // Sanity check: the config space must accommodate all 4K register bytes of
|
---|
207 | // all 8 functions of all 32 devices of all buses.
|
---|
208 | //
|
---|
209 | if ((*BusMax < *BusMin) || (*BusMax - *BusMin == MAX_UINT32) ||
|
---|
210 | (DivU64x32 (ConfigSize, SIZE_4KB * 8 * 32) < *BusMax - *BusMin + 1))
|
---|
211 | {
|
---|
212 | DEBUG ((
|
---|
213 | DEBUG_ERROR,
|
---|
214 | "%a: invalid 'bus-range' and/or 'reg'\n",
|
---|
215 | __func__
|
---|
216 | ));
|
---|
217 | return EFI_PROTOCOL_ERROR;
|
---|
218 | }
|
---|
219 |
|
---|
220 | //
|
---|
221 | // Iterate over "ranges".
|
---|
222 | //
|
---|
223 | Status = FdtClient->GetNodeProperty (FdtClient, Node, "ranges", &Prop, &Len);
|
---|
224 | if (EFI_ERROR (Status) || (Len == 0) ||
|
---|
225 | (Len % sizeof (DTB_PCI_HOST_RANGE_RECORD) != 0))
|
---|
226 | {
|
---|
227 | DEBUG ((DEBUG_ERROR, "%a: 'ranges' not found or invalid\n", __func__));
|
---|
228 | return EFI_PROTOCOL_ERROR;
|
---|
229 | }
|
---|
230 |
|
---|
231 | for (RecordIdx = 0; RecordIdx < Len / sizeof (DTB_PCI_HOST_RANGE_RECORD);
|
---|
232 | ++RecordIdx)
|
---|
233 | {
|
---|
234 | CONST DTB_PCI_HOST_RANGE_RECORD *Record;
|
---|
235 |
|
---|
236 | Record = (CONST DTB_PCI_HOST_RANGE_RECORD *)Prop + RecordIdx;
|
---|
237 | switch (SwapBytes32 (Record->Type) & DTB_PCI_HOST_RANGE_TYPEMASK) {
|
---|
238 | case DTB_PCI_HOST_RANGE_IO:
|
---|
239 | *IoBase = SwapBytes64 (Record->ChildBase);
|
---|
240 | *IoSize = SwapBytes64 (Record->Size);
|
---|
241 | IoTranslation = SwapBytes64 (Record->CpuBase) - *IoBase;
|
---|
242 |
|
---|
243 | ASSERT (PcdGet64 (PcdPciIoTranslation) == IoTranslation);
|
---|
244 | break;
|
---|
245 |
|
---|
246 | case DTB_PCI_HOST_RANGE_MMIO32:
|
---|
247 | *Mmio32Base = SwapBytes64 (Record->ChildBase);
|
---|
248 | *Mmio32Size = SwapBytes64 (Record->Size);
|
---|
249 | Mmio32Translation = SwapBytes64 (Record->CpuBase) - *Mmio32Base;
|
---|
250 |
|
---|
251 | if ((*Mmio32Base > MAX_UINT32) || (*Mmio32Size > MAX_UINT32) ||
|
---|
252 | (*Mmio32Base + *Mmio32Size > SIZE_4GB))
|
---|
253 | {
|
---|
254 | DEBUG ((DEBUG_ERROR, "%a: MMIO32 space invalid\n", __func__));
|
---|
255 | return EFI_PROTOCOL_ERROR;
|
---|
256 | }
|
---|
257 |
|
---|
258 | ASSERT (PcdGet64 (PcdPciMmio32Translation) == Mmio32Translation);
|
---|
259 |
|
---|
260 | if (Mmio32Translation != 0) {
|
---|
261 | DEBUG ((
|
---|
262 | DEBUG_ERROR,
|
---|
263 | "%a: unsupported nonzero MMIO32 translation "
|
---|
264 | "0x%Lx\n",
|
---|
265 | __func__,
|
---|
266 | Mmio32Translation
|
---|
267 | ));
|
---|
268 | return EFI_UNSUPPORTED;
|
---|
269 | }
|
---|
270 |
|
---|
271 | break;
|
---|
272 |
|
---|
273 | case DTB_PCI_HOST_RANGE_MMIO64:
|
---|
274 | *Mmio64Base = SwapBytes64 (Record->ChildBase);
|
---|
275 | *Mmio64Size = SwapBytes64 (Record->Size);
|
---|
276 | Mmio64Translation = SwapBytes64 (Record->CpuBase) - *Mmio64Base;
|
---|
277 |
|
---|
278 | ASSERT (PcdGet64 (PcdPciMmio64Translation) == Mmio64Translation);
|
---|
279 |
|
---|
280 | if (Mmio64Translation != 0) {
|
---|
281 | DEBUG ((
|
---|
282 | DEBUG_ERROR,
|
---|
283 | "%a: unsupported nonzero MMIO64 translation "
|
---|
284 | "0x%Lx\n",
|
---|
285 | __func__,
|
---|
286 | Mmio64Translation
|
---|
287 | ));
|
---|
288 | return EFI_UNSUPPORTED;
|
---|
289 | }
|
---|
290 |
|
---|
291 | break;
|
---|
292 | }
|
---|
293 | }
|
---|
294 |
|
---|
295 | if (*Mmio32Size == 0) {
|
---|
296 | DEBUG ((DEBUG_ERROR, "%a: MMIO32 space empty\n", __func__));
|
---|
297 | return EFI_PROTOCOL_ERROR;
|
---|
298 | }
|
---|
299 |
|
---|
300 | //
|
---|
301 | // The dynamic PCD PcdPciExpressBaseAddress should have already been set,
|
---|
302 | // and should match the value we found in the DT node.
|
---|
303 | //
|
---|
304 | ASSERT (PcdGet64 (PcdPciExpressBaseAddress) == ConfigBase);
|
---|
305 |
|
---|
306 | DEBUG ((
|
---|
307 | DEBUG_INFO,
|
---|
308 | "%a: Config[0x%Lx+0x%Lx) Bus[0x%x..0x%x] "
|
---|
309 | "Io[0x%Lx+0x%Lx)@0x%Lx Mem32[0x%Lx+0x%Lx)@0x0 Mem64[0x%Lx+0x%Lx)@0x0\n",
|
---|
310 | __func__,
|
---|
311 | ConfigBase,
|
---|
312 | ConfigSize,
|
---|
313 | *BusMin,
|
---|
314 | *BusMax,
|
---|
315 | *IoBase,
|
---|
316 | *IoSize,
|
---|
317 | IoTranslation,
|
---|
318 | *Mmio32Base,
|
---|
319 | *Mmio32Size,
|
---|
320 | *Mmio64Base,
|
---|
321 | *Mmio64Size
|
---|
322 | ));
|
---|
323 |
|
---|
324 | // Map the ECAM space in the GCD memory map
|
---|
325 | Status = MapGcdMmioSpace (ConfigBase, ConfigSize);
|
---|
326 | ASSERT_EFI_ERROR (Status);
|
---|
327 | if (EFI_ERROR (Status)) {
|
---|
328 | return Status;
|
---|
329 | }
|
---|
330 |
|
---|
331 | if (*IoSize != 0) {
|
---|
332 | //
|
---|
333 | // Map the MMIO window that provides I/O access - the PCI host bridge code
|
---|
334 | // is not aware of this translation and so it will only map the I/O view
|
---|
335 | // in the GCD I/O map.
|
---|
336 | //
|
---|
337 | Status = MapGcdMmioSpace (*IoBase + IoTranslation, *IoSize);
|
---|
338 | ASSERT_EFI_ERROR (Status);
|
---|
339 | }
|
---|
340 |
|
---|
341 | return Status;
|
---|
342 | }
|
---|
343 |
|
---|
344 | /**
|
---|
345 | Return all the root bridge instances in an array.
|
---|
346 |
|
---|
347 | @param Count Return the count of root bridge instances.
|
---|
348 |
|
---|
349 | @return All the root bridge instances in an array.
|
---|
350 | The array should be passed into PciHostBridgeFreeRootBridges()
|
---|
351 | when it's not used.
|
---|
352 | **/
|
---|
353 | PCI_ROOT_BRIDGE *
|
---|
354 | EFIAPI
|
---|
355 | PciHostBridgeGetRootBridges (
|
---|
356 | UINTN *Count
|
---|
357 | )
|
---|
358 | {
|
---|
359 | UINT64 IoBase, IoSize;
|
---|
360 | UINT64 Mmio32Base, Mmio32Size;
|
---|
361 | UINT64 Mmio64Base, Mmio64Size;
|
---|
362 | UINT32 BusMin, BusMax;
|
---|
363 | EFI_STATUS Status;
|
---|
364 | UINT64 Attributes;
|
---|
365 | UINT64 AllocationAttributes;
|
---|
366 | PCI_ROOT_BRIDGE_APERTURE Io;
|
---|
367 | PCI_ROOT_BRIDGE_APERTURE Mem;
|
---|
368 | PCI_ROOT_BRIDGE_APERTURE MemAbove4G;
|
---|
369 | PCI_ROOT_BRIDGE_APERTURE PMem;
|
---|
370 | PCI_ROOT_BRIDGE_APERTURE PMemAbove4G;
|
---|
371 |
|
---|
372 | if (PcdGet64 (PcdPciExpressBaseAddress) == 0) {
|
---|
373 | DEBUG ((DEBUG_INFO, "%a: PCI host bridge not present\n", __func__));
|
---|
374 |
|
---|
375 | *Count = 0;
|
---|
376 | return NULL;
|
---|
377 | }
|
---|
378 |
|
---|
379 | Status = ProcessPciHost (
|
---|
380 | &IoBase,
|
---|
381 | &IoSize,
|
---|
382 | &Mmio32Base,
|
---|
383 | &Mmio32Size,
|
---|
384 | &Mmio64Base,
|
---|
385 | &Mmio64Size,
|
---|
386 | &BusMin,
|
---|
387 | &BusMax
|
---|
388 | );
|
---|
389 | if (EFI_ERROR (Status)) {
|
---|
390 | DEBUG ((
|
---|
391 | DEBUG_ERROR,
|
---|
392 | "%a: failed to discover PCI host bridge: %r\n",
|
---|
393 | __func__,
|
---|
394 | Status
|
---|
395 | ));
|
---|
396 | *Count = 0;
|
---|
397 | return NULL;
|
---|
398 | }
|
---|
399 |
|
---|
400 | ZeroMem (&Io, sizeof (Io));
|
---|
401 | ZeroMem (&Mem, sizeof (Mem));
|
---|
402 | ZeroMem (&MemAbove4G, sizeof (MemAbove4G));
|
---|
403 | ZeroMem (&PMem, sizeof (PMem));
|
---|
404 | ZeroMem (&PMemAbove4G, sizeof (PMemAbove4G));
|
---|
405 |
|
---|
406 | Attributes = EFI_PCI_ATTRIBUTE_ISA_IO_16 |
|
---|
407 | EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO |
|
---|
408 | EFI_PCI_ATTRIBUTE_VGA_IO_16 |
|
---|
409 | EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
|
---|
410 |
|
---|
411 | AllocationAttributes = EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM;
|
---|
412 |
|
---|
413 | if (IoSize != 0) {
|
---|
414 | Io.Base = IoBase;
|
---|
415 | Io.Limit = IoBase + IoSize - 1;
|
---|
416 | } else {
|
---|
417 | Io.Base = MAX_UINT64;
|
---|
418 | Io.Limit = 0;
|
---|
419 | }
|
---|
420 |
|
---|
421 | Mem.Base = Mmio32Base;
|
---|
422 | Mem.Limit = Mmio32Base + Mmio32Size - 1;
|
---|
423 |
|
---|
424 | if ((sizeof (UINTN) == sizeof (UINT64)) && (Mmio64Size != 0)) {
|
---|
425 | MemAbove4G.Base = Mmio64Base;
|
---|
426 | MemAbove4G.Limit = Mmio64Base + Mmio64Size - 1;
|
---|
427 | AllocationAttributes |= EFI_PCI_HOST_BRIDGE_MEM64_DECODE;
|
---|
428 | } else {
|
---|
429 | //
|
---|
430 | // UEFI mandates a 1:1 virtual-to-physical mapping, so on a 32-bit
|
---|
431 | // architecture such as ARM, we will not be able to access 64-bit MMIO
|
---|
432 | // BARs unless they are allocated below 4 GB. So ignore the range above
|
---|
433 | // 4 GB in this case.
|
---|
434 | //
|
---|
435 | MemAbove4G.Base = MAX_UINT64;
|
---|
436 | MemAbove4G.Limit = 0;
|
---|
437 | }
|
---|
438 |
|
---|
439 | //
|
---|
440 | // No separate ranges for prefetchable and non-prefetchable BARs
|
---|
441 | //
|
---|
442 | PMem.Base = MAX_UINT64;
|
---|
443 | PMem.Limit = 0;
|
---|
444 | PMemAbove4G.Base = MAX_UINT64;
|
---|
445 | PMemAbove4G.Limit = 0;
|
---|
446 |
|
---|
447 | return PciHostBridgeUtilityGetRootBridges (
|
---|
448 | Count,
|
---|
449 | Attributes,
|
---|
450 | AllocationAttributes,
|
---|
451 | TRUE,
|
---|
452 | FALSE,
|
---|
453 | BusMin,
|
---|
454 | BusMax,
|
---|
455 | &Io,
|
---|
456 | &Mem,
|
---|
457 | &MemAbove4G,
|
---|
458 | &PMem,
|
---|
459 | &PMemAbove4G
|
---|
460 | );
|
---|
461 | }
|
---|
462 |
|
---|
463 | /**
|
---|
464 | Free the root bridge instances array returned from
|
---|
465 | PciHostBridgeGetRootBridges().
|
---|
466 |
|
---|
467 | @param Bridges The root bridge instances array.
|
---|
468 | @param Count The count of the array.
|
---|
469 | **/
|
---|
470 | VOID
|
---|
471 | EFIAPI
|
---|
472 | PciHostBridgeFreeRootBridges (
|
---|
473 | PCI_ROOT_BRIDGE *Bridges,
|
---|
474 | UINTN Count
|
---|
475 | )
|
---|
476 | {
|
---|
477 | PciHostBridgeUtilityFreeRootBridges (Bridges, Count);
|
---|
478 | }
|
---|
479 |
|
---|
480 | /**
|
---|
481 | Inform the platform that the resource conflict happens.
|
---|
482 |
|
---|
483 | @param HostBridgeHandle Handle of the Host Bridge.
|
---|
484 | @param Configuration Pointer to PCI I/O and PCI memory resource
|
---|
485 | descriptors. The Configuration contains the resources
|
---|
486 | for all the root bridges. The resource for each root
|
---|
487 | bridge is terminated with END descriptor and an
|
---|
488 | additional END is appended indicating the end of the
|
---|
489 | entire resources. The resource descriptor field
|
---|
490 | values follow the description in
|
---|
491 | EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
|
---|
492 | .SubmitResources().
|
---|
493 | **/
|
---|
494 | VOID
|
---|
495 | EFIAPI
|
---|
496 | PciHostBridgeResourceConflict (
|
---|
497 | EFI_HANDLE HostBridgeHandle,
|
---|
498 | VOID *Configuration
|
---|
499 | )
|
---|
500 | {
|
---|
501 | PciHostBridgeUtilityResourceConflict (Configuration);
|
---|
502 | }
|
---|