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