2 Pci Host Bridge driver:
3 Provides the basic interfaces to abstract a PCI Host Bridge Resource Allocation
5 Copyright (c) 2008 - 2009, Intel Corporation<BR> All rights
6 reserved. This program and the accompanying materials are
7 licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "PciHostBridge.h"
19 // Support 64 K IO space
21 #define RES_IO_BASE 0x1000
22 #define RES_IO_LIMIT 0xFFFF
24 // Support 4G address space
26 #define RES_MEM_BASE_1 0xF8000000
27 #define RES_MEM_LIMIT_1 (0xFEC00000 - 1)
30 // Hard code: Root Bridge Number within the host bridge
31 // Root Bridge's attribute
32 // Root Bridge's device path
33 // Root Bridge's resource appeture
35 UINTN RootBridgeNumber
[1] = { 1 };
37 UINT64 RootBridgeAttribute
[1][1] = { EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
};
39 EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath
[1][1] = {
43 (UINT8
) (sizeof(ACPI_HID_DEVICE_PATH
)),
44 (UINT8
) ((sizeof(ACPI_HID_DEVICE_PATH
)) >> 8),
48 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
49 END_DEVICE_PATH_LENGTH
,
54 PCI_ROOT_BRIDGE_RESOURCE_APPETURE mResAppeture
[1][1] = {
55 {0, 0, 0, 0xffffffff, 0, 1 << 16}
58 EFI_HANDLE mDriverImageHandle
;
60 PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate
= {
61 PCI_HOST_BRIDGE_SIGNATURE
, // Signature
62 NULL
, // HostBridgeHandle
63 0, // RootBridgeNumber
65 FALSE
, // ResourceSubiteed
84 InitializePciHostBridge (
85 IN EFI_HANDLE ImageHandle
,
86 IN EFI_SYSTEM_TABLE
*SystemTable
91 Entry point of this driver
106 PCI_HOST_BRIDGE_INSTANCE
*HostBridge
;
107 PCI_ROOT_BRIDGE_INSTANCE
*PrivateData
;
108 IN EFI_PHYSICAL_ADDRESS BaseAddress
;
111 mDriverImageHandle
= ImageHandle
;
114 // Create Host Bridge Device Handle
116 for (Loop1
= 0; Loop1
< HOST_BRIDGE_NUMBER
; Loop1
++) {
117 HostBridge
= AllocateCopyPool (sizeof(PCI_HOST_BRIDGE_INSTANCE
), &mPciHostBridgeInstanceTemplate
);
118 if (HostBridge
== NULL
) {
119 return EFI_OUT_OF_RESOURCES
;
122 HostBridge
->RootBridgeNumber
= RootBridgeNumber
[Loop1
];
123 InitializeListHead (&HostBridge
->Head
);
125 Status
= gBS
->InstallMultipleProtocolInterfaces (
126 &HostBridge
->HostBridgeHandle
,
127 &gEfiPciHostBridgeResourceAllocationProtocolGuid
, &HostBridge
->ResAlloc
,
130 if (EFI_ERROR (Status
)) {
131 FreePool (HostBridge
);
132 return EFI_DEVICE_ERROR
;
136 // Create Root Bridge Device Handle in this Host Bridge
139 for (Loop2
= 0; Loop2
< HostBridge
->RootBridgeNumber
; Loop2
++) {
140 PrivateData
= AllocateZeroPool (sizeof(PCI_ROOT_BRIDGE_INSTANCE
));
141 if (PrivateData
== NULL
) {
142 return EFI_OUT_OF_RESOURCES
;
145 PrivateData
->Signature
= PCI_ROOT_BRIDGE_SIGNATURE
;
146 PrivateData
->DevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*)&mEfiPciRootBridgeDevicePath
[Loop1
][Loop2
];
148 RootBridgeConstructor (
150 HostBridge
->HostBridgeHandle
,
151 RootBridgeAttribute
[Loop1
][Loop2
],
152 &mResAppeture
[Loop1
][Loop2
]
155 Status
= gBS
->InstallMultipleProtocolInterfaces(
156 &PrivateData
->Handle
,
157 &gEfiDevicePathProtocolGuid
, PrivateData
->DevicePath
,
158 &gEfiPciRootBridgeIoProtocolGuid
, &PrivateData
->Io
,
161 if (EFI_ERROR (Status
)) {
162 FreePool(PrivateData
);
163 return EFI_DEVICE_ERROR
;
166 InsertTailList (&HostBridge
->Head
, &PrivateData
->Link
);
170 Status
= gDS
->AddIoSpace (
173 RES_IO_LIMIT
- RES_IO_BASE
+ 1
176 // PCI memory space from 3.75Gbytes->(4GBytes - BIOSFWH local APIC etc)
177 Status
= gDS
->AddMemorySpace (
178 EfiGcdMemoryTypeMemoryMappedIo
,
180 (RES_MEM_LIMIT_1
- RES_MEM_BASE_1
+ 1),
184 BaseAddress
= 0x80000000;
185 Length
= RES_MEM_BASE_1
- BaseAddress
;
186 Status
= gDS
->AddMemorySpace (
187 EfiGcdMemoryTypeMemoryMappedIo
,
200 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
201 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
206 Enter a certain phase of the PCI enumeration process
209 This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance
210 Phase -- The phase during enumeration
216 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
217 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
218 PCI_RESOURCE_TYPE Index
;
220 EFI_PHYSICAL_ADDRESS BaseAddress
;
222 UINTN BitsOfAlignment
;
224 EFI_STATUS ReturnStatus
;
226 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
230 case EfiPciHostBridgeBeginEnumeration
:
231 if (HostBridgeInstance
->CanRestarted
) {
233 // Reset the Each Root Bridge
235 List
= HostBridgeInstance
->Head
.ForwardLink
;
237 while (List
!= &HostBridgeInstance
->Head
) {
238 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
239 for (Index
= TypeIo
; Index
< TypeMax
; Index
++) {
240 RootBridgeInstance
->ResAllocNode
[Index
].Type
= Index
;
241 RootBridgeInstance
->ResAllocNode
[Index
].Base
= 0;
242 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
243 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResNone
;
246 List
= List
->ForwardLink
;
249 HostBridgeInstance
->ResourceSubmited
= FALSE
;
250 HostBridgeInstance
->CanRestarted
= TRUE
;
255 return EFI_NOT_READY
;
259 case EfiPciHostBridgeBeginBusAllocation
:
261 // No specific action is required here, can perform any chipset specific programing
263 HostBridgeInstance
->CanRestarted
= FALSE
;
267 case EfiPciHostBridgeEndBusAllocation
:
269 // No specific action is required here, can perform any chipset specific programing
271 //HostBridgeInstance->CanRestarted = FALSE;
275 case EfiPciHostBridgeBeginResourceAllocation
:
277 // No specific action is required here, can perform any chipset specific programing
279 //HostBridgeInstance->CanRestarted = FALSE;
283 case EfiPciHostBridgeAllocateResources
:
284 ReturnStatus
= EFI_SUCCESS
;
285 if (HostBridgeInstance
->ResourceSubmited
) {
287 // Take care of the resource dependencies between the root bridges
289 List
= HostBridgeInstance
->Head
.ForwardLink
;
291 while (List
!= &HostBridgeInstance
->Head
) {
292 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
293 for (Index
= TypeIo
; Index
< TypeBus
; Index
++) {
294 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
296 AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
299 // Get the number of '1' in Alignment.
301 BitsOfAlignment
= HighBitSet64 (RootBridgeInstance
->ResAllocNode
[Index
].Alignment
) + 1;
307 // It is impossible for this chipset to align 0xFFFF for IO16
310 if (BitsOfAlignment
>= 16) {
314 Status
= gDS
->AllocateIoSpace (
315 EfiGcdAllocateAnySearchBottomUp
,
324 if (!EFI_ERROR (Status
)) {
325 RootBridgeInstance
->ResAllocNode
[Index
].Base
= (UINTN
)BaseAddress
;
326 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResAllocated
;
328 ReturnStatus
= Status
;
329 if (Status
!= EFI_OUT_OF_RESOURCES
) {
330 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
339 // It is impossible for this chipset to align 0xFFFFFFFF for Mem32
343 if (BitsOfAlignment
>= 32) {
347 Status
= gDS
->AllocateMemorySpace (
348 EfiGcdAllocateAnySearchBottomUp
,
349 EfiGcdMemoryTypeMemoryMappedIo
,
357 if (!EFI_ERROR (Status
)) {
358 // We were able to allocate the PCI memory
359 RootBridgeInstance
->ResAllocNode
[Index
].Base
= (UINTN
)BaseAddress
;
360 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResAllocated
;
363 // Not able to allocate enough PCI memory
364 ReturnStatus
= Status
;
366 if (Status
!= EFI_OUT_OF_RESOURCES
) {
367 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
376 ReturnStatus
= EFI_ABORTED
;
385 List
= List
->ForwardLink
;
391 return EFI_NOT_READY
;
395 case EfiPciHostBridgeSetResources
:
398 case EfiPciHostBridgeFreeResources
:
399 ReturnStatus
= EFI_SUCCESS
;
400 List
= HostBridgeInstance
->Head
.ForwardLink
;
401 while (List
!= &HostBridgeInstance
->Head
) {
402 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
403 for (Index
= TypeIo
; Index
< TypeBus
; Index
++) {
404 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
== ResAllocated
) {
405 AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
406 BaseAddress
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
410 Status
= gDS
->FreeIoSpace (BaseAddress
, AddrLen
);
411 if (EFI_ERROR (Status
)) {
412 ReturnStatus
= Status
;
417 Status
= gDS
->FreeMemorySpace (BaseAddress
, AddrLen
);
418 if (EFI_ERROR (Status
)) {
419 ReturnStatus
= Status
;
437 RootBridgeInstance
->ResAllocNode
[Index
].Type
= Index
;
438 RootBridgeInstance
->ResAllocNode
[Index
].Base
= 0;
439 RootBridgeInstance
->ResAllocNode
[Index
].Length
= 0;
440 RootBridgeInstance
->ResAllocNode
[Index
].Status
= ResNone
;
444 List
= List
->ForwardLink
;
447 HostBridgeInstance
->ResourceSubmited
= FALSE
;
448 HostBridgeInstance
->CanRestarted
= TRUE
;
452 case EfiPciHostBridgeEndResourceAllocation
:
453 HostBridgeInstance
->CanRestarted
= FALSE
;
457 return EFI_INVALID_PARAMETER
;
466 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
467 IN OUT EFI_HANDLE
*RootBridgeHandle
472 Return the device handle of the next PCI root bridge that is associated with
476 This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
477 RootBridgeHandle -- Returns the device handle of the next PCI Root Bridge.
478 On input, it holds the RootBridgeHandle returned by the most
479 recent call to GetNextRootBridge().The handle for the first
480 PCI Root Bridge is returned if RootBridgeHandle is NULL on input
486 BOOLEAN NoRootBridge
;
488 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
489 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
492 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
493 List
= HostBridgeInstance
->Head
.ForwardLink
;
496 while (List
!= &HostBridgeInstance
->Head
) {
497 NoRootBridge
= FALSE
;
498 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
499 if (*RootBridgeHandle
== NULL
) {
501 // Return the first Root Bridge Handle of the Host Bridge
503 *RootBridgeHandle
= RootBridgeInstance
->Handle
;
506 if (*RootBridgeHandle
== RootBridgeInstance
->Handle
) {
510 List
= List
->ForwardLink
;
511 if (List
!=&HostBridgeInstance
->Head
) {
512 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
513 *RootBridgeHandle
= RootBridgeInstance
->Handle
;
516 return EFI_NOT_FOUND
;
521 List
= List
->ForwardLink
;
525 return EFI_NOT_FOUND
;
527 return EFI_INVALID_PARAMETER
;
534 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
535 IN EFI_HANDLE RootBridgeHandle
,
536 OUT UINT64
*Attributes
541 Returns the attributes of a PCI Root Bridge.
544 This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
545 RootBridgeHandle -- The device handle of the PCI Root Bridge
546 that the caller is interested in
547 Attribute -- The pointer to attributes of the PCI Root Bridge
554 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
555 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
557 if (Attributes
== NULL
) {
558 return EFI_INVALID_PARAMETER
;
561 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
562 List
= HostBridgeInstance
->Head
.ForwardLink
;
564 while (List
!= &HostBridgeInstance
->Head
) {
565 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
566 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
567 *Attributes
= RootBridgeInstance
->RootBridgeAttrib
;
570 List
= List
->ForwardLink
;
574 // RootBridgeHandle is not an EFI_HANDLE
575 // that was returned on a previous call to GetNextRootBridge()
577 return EFI_INVALID_PARAMETER
;
583 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
584 IN EFI_HANDLE RootBridgeHandle
,
585 OUT VOID
**Configuration
590 This is the request from the PCI enumerator to set up
591 the specified PCI Root Bridge for bus enumeration process.
594 This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
595 RootBridgeHandle -- The PCI Root Bridge to be set up
596 Configuration -- Pointer to the pointer to the PCI bus resource descriptor
603 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
604 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
610 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
611 List
= HostBridgeInstance
->Head
.ForwardLink
;
613 while (List
!= &HostBridgeInstance
->Head
) {
614 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
615 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
617 // Set up the Root Bridge for Bus Enumeration
619 BusStart
= RootBridgeInstance
->BusBase
;
620 BusEnd
= RootBridgeInstance
->BusLimit
;
622 // Program the Hardware(if needed) if error return EFI_DEVICE_ERROR
625 Buffer
= AllocatePool (sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) + sizeof(EFI_ACPI_END_TAG_DESCRIPTOR
));
626 if (Buffer
== NULL
) {
627 return EFI_OUT_OF_RESOURCES
;
630 Temp
= (UINT8
*)Buffer
;
632 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->Desc
= 0x8A;
633 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->Len
= 0x2B;
634 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->ResType
= 2;
635 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->GenFlag
= 0;
636 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->SpecificFlag
= 0;
637 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrSpaceGranularity
= 0;
638 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrRangeMin
= BusStart
;
639 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrRangeMax
= 0;
640 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrTranslationOffset
= 0;
641 ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Temp
)->AddrLen
= BusEnd
- BusStart
+ 1;
643 Temp
= Temp
+ sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
644 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Desc
= 0x79;
645 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Checksum
= 0x0;
647 *Configuration
= Buffer
;
650 List
= List
->ForwardLink
;
653 return EFI_INVALID_PARAMETER
;
659 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
660 IN EFI_HANDLE RootBridgeHandle
,
661 IN VOID
*Configuration
666 This function programs the PCI Root Bridge hardware so that
667 it decodes the specified PCI bus range
670 This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
671 RootBridgeHandle -- The PCI Root Bridge whose bus range is to be programmed
672 Configuration -- The pointer to the PCI bus resource descriptor
679 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
680 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
686 if (Configuration
== NULL
) {
687 return EFI_INVALID_PARAMETER
;
693 // Check the Configuration is valid
695 if(*Ptr
!= ACPI_ADDRESS_SPACE_DESCRIPTOR
) {
696 return EFI_INVALID_PARAMETER
;
699 if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Ptr
)->ResType
!= 2) {
700 return EFI_INVALID_PARAMETER
;
703 Ptr
+= sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
704 if (*Ptr
!= ACPI_END_TAG_DESCRIPTOR
) {
705 return EFI_INVALID_PARAMETER
;
708 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
709 List
= HostBridgeInstance
->Head
.ForwardLink
;
713 while (List
!= &HostBridgeInstance
->Head
) {
714 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
715 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
716 BusStart
= (UINTN
)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Ptr
)->AddrRangeMin
;
717 BusLen
= (UINTN
)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*)Ptr
)->AddrLen
;
718 BusEnd
= BusStart
+ BusLen
- 1;
720 if (BusStart
> BusEnd
) {
721 return EFI_INVALID_PARAMETER
;
724 if ((BusStart
< RootBridgeInstance
->BusBase
) || (BusEnd
> RootBridgeInstance
->BusLimit
)) {
725 return EFI_INVALID_PARAMETER
;
729 // Update the Bus Range
731 RootBridgeInstance
->ResAllocNode
[TypeBus
].Base
= BusStart
;
732 RootBridgeInstance
->ResAllocNode
[TypeBus
].Length
= BusLen
;
733 RootBridgeInstance
->ResAllocNode
[TypeBus
].Status
= ResAllocated
;
736 // Program the Root Bridge Hardware
742 List
= List
->ForwardLink
;
745 return EFI_INVALID_PARAMETER
;
752 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
753 IN EFI_HANDLE RootBridgeHandle
,
754 IN VOID
*Configuration
759 Submits the I/O and memory resource requirements for the specified PCI Root Bridge
762 This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
763 RootBridgeHandle -- The PCI Root Bridge whose I/O and memory resource requirements
765 Configuration -- The pointer to the PCI I/O and PCI memory resource descriptor
771 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
772 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
774 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*ptr
;
779 // Check the input parameter: Configuration
781 if (Configuration
== NULL
) {
782 return EFI_INVALID_PARAMETER
;
785 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
786 List
= HostBridgeInstance
->Head
.ForwardLink
;
788 Temp
= (UINT8
*)Configuration
;
789 while ( *Temp
== 0x8A) {
790 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) ;
793 return EFI_INVALID_PARAMETER
;
796 Temp
= (UINT8
*)Configuration
;
797 while (List
!= &HostBridgeInstance
->Head
) {
798 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
799 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
800 while ( *Temp
== 0x8A) {
801 ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
;
804 // Check Address Length
806 if (ptr
->AddrLen
> 0xffffffff) {
807 return EFI_INVALID_PARAMETER
;
811 // Check address range alignment
813 if (ptr
->AddrRangeMax
>= 0xffffffff || ptr
->AddrRangeMax
!= (GetPowerOfTwo64 (ptr
->AddrRangeMax
+ 1) - 1)) {
814 return EFI_INVALID_PARAMETER
;
817 switch (ptr
->ResType
) {
822 // Check invalid Address Sapce Granularity
824 if (ptr
->AddrSpaceGranularity
!= 32) {
825 return EFI_INVALID_PARAMETER
;
829 // check the memory resource request is supported by PCI root bridge
831 if (RootBridgeInstance
->RootBridgeAttrib
== EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
&&
832 ptr
->SpecificFlag
== 0x06) {
833 return EFI_INVALID_PARAMETER
;
836 AddrLen
= ptr
->AddrLen
;
837 Alignment
= ptr
->AddrRangeMax
;
838 if (ptr
->AddrSpaceGranularity
== 32) {
839 if (ptr
->SpecificFlag
== 0x06) {
843 RootBridgeInstance
->ResAllocNode
[TypePMem32
].Status
= ResSubmitted
;
845 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Length
= AddrLen
;
846 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Alignment
= Alignment
;
847 RootBridgeInstance
->ResAllocNode
[TypeMem32
].Status
= ResRequested
;
848 HostBridgeInstance
->ResourceSubmited
= TRUE
;
852 if (ptr
->AddrSpaceGranularity
== 64) {
853 if (ptr
->SpecificFlag
== 0x06) {
854 RootBridgeInstance
->ResAllocNode
[TypePMem64
].Status
= ResSubmitted
;
856 RootBridgeInstance
->ResAllocNode
[TypeMem64
].Status
= ResSubmitted
;
862 AddrLen
= (UINTN
)ptr
->AddrLen
;
863 Alignment
= (UINTN
)ptr
->AddrRangeMax
;
864 RootBridgeInstance
->ResAllocNode
[TypeIo
].Length
= AddrLen
;
865 RootBridgeInstance
->ResAllocNode
[TypeIo
].Alignment
= Alignment
;
866 RootBridgeInstance
->ResAllocNode
[TypeIo
].Status
= ResRequested
;
867 HostBridgeInstance
->ResourceSubmited
= TRUE
;
874 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) ;
880 List
= List
->ForwardLink
;
883 return EFI_INVALID_PARAMETER
;
888 GetProposedResources(
889 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
890 IN EFI_HANDLE RootBridgeHandle
,
891 OUT VOID
**Configuration
896 This function returns the proposed resource settings for the specified
900 This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
901 RootBridgeHandle -- The PCI Root Bridge handle
902 Configuration -- The pointer to the pointer to the PCI I/O
903 and memory resource descriptor
910 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
911 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
916 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*ptr
;
922 // Get the Host Bridge Instance from the resource allocation protocol
924 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
925 List
= HostBridgeInstance
->Head
.ForwardLink
;
928 // Enumerate the root bridges in this host bridge
930 while (List
!= &HostBridgeInstance
->Head
) {
931 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
932 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
933 for (Index
= 0; Index
< TypeBus
; Index
++) {
934 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
940 return EFI_INVALID_PARAMETER
;
943 Buffer
= AllocateZeroPool (Number
* sizeof(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) + sizeof(EFI_ACPI_END_TAG_DESCRIPTOR
));
944 if (Buffer
== NULL
) {
945 return EFI_OUT_OF_RESOURCES
;
949 for (Index
= 0; Index
< TypeBus
; Index
++) {
950 if (RootBridgeInstance
->ResAllocNode
[Index
].Status
!= ResNone
) {
951 ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
;
952 ResStatus
= RootBridgeInstance
->ResAllocNode
[Index
].Status
;
964 ptr
->SpecificFlag
= 0;
965 ptr
->AddrRangeMin
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
966 ptr
->AddrRangeMax
= 0;
967 ptr
->AddrTranslationOffset
= \
968 (ResStatus
== ResAllocated
) ? EFI_RESOURCE_SATISFIED
: EFI_RESOURCE_LESS
;
969 ptr
->AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
980 ptr
->SpecificFlag
= 0;
981 ptr
->AddrSpaceGranularity
= 32;
982 ptr
->AddrRangeMin
= RootBridgeInstance
->ResAllocNode
[Index
].Base
;
983 ptr
->AddrRangeMax
= 0;
984 ptr
->AddrTranslationOffset
= \
985 (ResStatus
== ResAllocated
) ? EFI_RESOURCE_SATISFIED
: EFI_RESOURCE_LESS
;
986 ptr
->AddrLen
= RootBridgeInstance
->ResAllocNode
[Index
].Length
;
991 // Prefetch memory 32
997 ptr
->SpecificFlag
= 6;
998 ptr
->AddrSpaceGranularity
= 32;
999 ptr
->AddrRangeMin
= 0;
1000 ptr
->AddrRangeMax
= 0;
1001 ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1013 ptr
->SpecificFlag
= 0;
1014 ptr
->AddrSpaceGranularity
= 64;
1015 ptr
->AddrRangeMin
= 0;
1016 ptr
->AddrRangeMax
= 0;
1017 ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1023 // Prefetch memory 64
1029 ptr
->SpecificFlag
= 6;
1030 ptr
->AddrSpaceGranularity
= 64;
1031 ptr
->AddrRangeMin
= 0;
1032 ptr
->AddrRangeMax
= 0;
1033 ptr
->AddrTranslationOffset
= EFI_RESOURCE_NONEXISTENT
;
1038 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
1042 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Desc
= 0x79;
1043 ((EFI_ACPI_END_TAG_DESCRIPTOR
*)Temp
)->Checksum
= 0x0;
1045 *Configuration
= Buffer
;
1050 List
= List
->ForwardLink
;
1053 return EFI_INVALID_PARAMETER
;
1058 UpdateRootBridgeAttributes (
1059 IN PCI_ROOT_BRIDGE_INSTANCE
*RootBridge
,
1060 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress
1064 PCI_TYPE01 PciConfigurationHeader
;
1068 // Read the PCI Configuration Header for the device
1070 Status
= RootBridge
->Io
.Pci
.Read (
1076 PciAddress
.Function
,
1079 sizeof (PciConfigurationHeader
) / sizeof (UINT16
),
1080 &PciConfigurationHeader
1082 if (EFI_ERROR (Status
)) {
1086 Attributes
= RootBridge
->Attributes
;
1089 // Look for devices with the VGA Palette Snoop enabled in the COMMAND register of the PCI Config Header
1091 if (PciConfigurationHeader
.Hdr
.Command
& 0x20) {
1092 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO
;
1096 // If the device is a PCI-PCI Bridge, then look at the Subordinate Bus Number
1098 if (IS_PCI_BRIDGE(&PciConfigurationHeader
)) {
1100 // Look at the PPB Configuration for legacy decoding attributes
1102 if (PciConfigurationHeader
.Bridge
.BridgeControl
& 0x04) {
1103 Attributes
|= EFI_PCI_ATTRIBUTE_ISA_IO
;
1104 Attributes
|= EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO
;
1106 if (PciConfigurationHeader
.Bridge
.BridgeControl
& 0x08) {
1107 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO
;
1108 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_MEMORY
;
1109 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_IO
;
1113 // See if the PCI device is an IDE controller
1115 if (PciConfigurationHeader
.Hdr
.ClassCode
[2] == 0x01 &&
1116 PciConfigurationHeader
.Hdr
.ClassCode
[1] == 0x01 ) {
1117 if (PciConfigurationHeader
.Hdr
.ClassCode
[0] & 0x80) {
1118 Attributes
|= EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO
;
1119 Attributes
|= EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO
;
1121 if (PciConfigurationHeader
.Hdr
.ClassCode
[0] & 0x01) {
1122 Attributes
|= EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO
;
1124 if (PciConfigurationHeader
.Hdr
.ClassCode
[0] & 0x04) {
1125 Attributes
|= EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO
;
1130 // See if the PCI device is a legacy VGA controller
1132 if (PciConfigurationHeader
.Hdr
.ClassCode
[2] == 0x00 &&
1133 PciConfigurationHeader
.Hdr
.ClassCode
[1] == 0x01 ) {
1134 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO
;
1135 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_MEMORY
;
1136 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_IO
;
1140 // See if the PCI device is a standard VGA controller
1142 if (PciConfigurationHeader
.Hdr
.ClassCode
[2] == 0x03 &&
1143 PciConfigurationHeader
.Hdr
.ClassCode
[1] == 0x00 ) {
1144 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO
;
1145 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_MEMORY
;
1146 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_IO
;
1150 RootBridge
->Attributes
= Attributes
;
1151 RootBridge
->Supports
= Attributes
;
1156 PreprocessController (
1157 IN
struct _EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*This
,
1158 IN EFI_HANDLE RootBridgeHandle
,
1159 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress
,
1160 IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase
1164 Routine Description:
1165 This function is called for all the PCI controllers that the PCI
1166 bus driver finds. Can be used to Preprogram the controller.
1169 This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
1170 RootBridgeHandle -- The PCI Root Bridge handle
1171 PciBusAddress -- Address of the controller on the PCI bus
1172 Phase -- The Phase during resource allocation
1178 PCI_HOST_BRIDGE_INSTANCE
*HostBridgeInstance
;
1179 PCI_ROOT_BRIDGE_INSTANCE
*RootBridgeInstance
;
1182 HostBridgeInstance
= INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This
);
1183 List
= HostBridgeInstance
->Head
.ForwardLink
;
1186 // Enumerate the root bridges in this host bridge
1188 while (List
!= &HostBridgeInstance
->Head
) {
1189 RootBridgeInstance
= DRIVER_INSTANCE_FROM_LIST_ENTRY (List
);
1190 if (RootBridgeHandle
== RootBridgeInstance
->Handle
) {
1191 UpdateRootBridgeAttributes (
1197 List
= List
->ForwardLink
;
1200 return EFI_INVALID_PARAMETER
;