TianoCore EDK2 master
Loading...
Searching...
No Matches
PciSegmentInfoLibAcpiBoardInfo.c
Go to the documentation of this file.
1
12#include <PiDxe.h>
14
15#include <Library/HobLib.h>
17#include <Library/DebugLib.h>
19#include <Library/PciLib.h>
21#include <Library/PcdLib.h>
24
25static PCI_SEGMENT_INFO *mPciSegments;
26static UINTN mCount;
27
37VOID
39 IN UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo,
40 IN UPL_PCI_SEGMENT_INFO_HOB *UplSegmentInfo,
41 OUT UINTN *NumberOfRootBridges
42 )
43{
44 UINTN Size;
45 UINT8 Index;
46
47 if (PciRootBridgeInfo == NULL) {
48 mPciSegments = NULL;
49 return;
50 }
51
52 *NumberOfRootBridges = PciRootBridgeInfo->Count;
53
54 Size = PciRootBridgeInfo->Count * sizeof (PCI_SEGMENT_INFO);
55 mPciSegments = (PCI_SEGMENT_INFO *)AllocatePool (Size);
56 ASSERT (mPciSegments != NULL);
57 ZeroMem (mPciSegments, PciRootBridgeInfo->Count * sizeof (PCI_SEGMENT_INFO));
58
59 //
60 // Create all root bridges with PciRootBridgeInfoHob
61 //
62 for (Index = 0; Index < PciRootBridgeInfo->Count; Index++) {
63 if (UplSegmentInfo->SegmentInfo[Index].SegmentNumber == (UINT16)(PciRootBridgeInfo->RootBridge[Index].Segment)) {
64 mPciSegments[Index].BaseAddress = UplSegmentInfo->SegmentInfo[Index].BaseAddress;
65 }
66
67 mPciSegments[Index].SegmentNumber = (UINT16)(PciRootBridgeInfo->RootBridge[Index].Segment);
68 mPciSegments[Index].StartBusNumber = (UINT8)PciRootBridgeInfo->RootBridge[Index].Bus.Base;
69 mPciSegments[Index].EndBusNumber = (UINT8)PciRootBridgeInfo->RootBridge[Index].Bus.Limit;
70 }
71
72 return;
73}
74
82VOID
84 OUT UINTN *NumberOfRootBridges
85 )
86{
87 EFI_HOB_GUID_TYPE *GuidHob;
88 ACPI_BOARD_INFO *AcpiBoardInfo;
89
90 *NumberOfRootBridges = 1;
91 // old model relies on gUefiAcpiBoardInfoGuid and hardcoded values for single segment only.
92 // This is only for backward compatibility, new platforms should adopt new model even in single segment cases.
93 //
94 mPciSegments = (PCI_SEGMENT_INFO *)AllocatePool (sizeof (PCI_SEGMENT_INFO));
95 ASSERT (mPciSegments != NULL);
97 ASSERT (GuidHob != NULL);
98 if (GuidHob != NULL) {
99 AcpiBoardInfo = (ACPI_BOARD_INFO *)GET_GUID_HOB_DATA (GuidHob);
100 mPciSegments->SegmentNumber = 0;
101 mPciSegments->BaseAddress = AcpiBoardInfo->PcieBaseAddress;
102 mPciSegments->StartBusNumber = 0;
103 mPciSegments->EndBusNumber = 0xFF;
104 }
105}
106
114 VOID
115 )
116{
117 UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo;
118 EFI_HOB_GUID_TYPE *GuidHob;
120
121 //
122 // Find Universal Payload PCI Root Bridge Info hob
123 //
124 GuidHob = GetFirstGuidHob (&gUniversalPayloadPciRootBridgeInfoGuid);
125 if ((GuidHob == NULL) || (sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER) > GET_GUID_HOB_DATA_SIZE (GuidHob))) {
126 return NULL;
127 }
128
129 GenericHeader = (UNIVERSAL_PAYLOAD_GENERIC_HEADER *)GET_GUID_HOB_DATA (GuidHob);
130 if (GenericHeader->Length > GET_GUID_HOB_DATA_SIZE (GuidHob)) {
131 return NULL;
132 }
133
134 if ((GenericHeader->Revision != UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION) || (GenericHeader->Length < sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES))) {
135 return NULL;
136 }
137
138 //
139 // UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES structure is used when Revision equals to UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION
140 //
141 PciRootBridgeInfo = (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *)GET_GUID_HOB_DATA (GuidHob);
142 if (PciRootBridgeInfo->Count <= (GET_GUID_HOB_DATA_SIZE (GuidHob) - sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES)) / sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE)) {
143 return PciRootBridgeInfo;
144 }
145
146 return NULL;
147}
148
156 VOID
157 )
158{
159 UPL_PCI_SEGMENT_INFO_HOB *UplSegmentInfo;
160 EFI_HOB_GUID_TYPE *GuidHob;
162
163 //
164 // Find Universal Payload Segment Info hob
165 //
167 if ((GuidHob == NULL) || (sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER) > GET_GUID_HOB_DATA_SIZE (GuidHob))) {
168 return NULL;
169 }
170
171 GenericHeader = (UNIVERSAL_PAYLOAD_GENERIC_HEADER *)GET_GUID_HOB_DATA (GuidHob);
172 if (GenericHeader->Length > GET_GUID_HOB_DATA_SIZE (GuidHob)) {
173 return NULL;
174 }
175
176 if ((GenericHeader->Revision != UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION) || (GenericHeader->Length < sizeof (UPL_PCI_SEGMENT_INFO_HOB))) {
177 return NULL;
178 }
179
180 //
181 // UPL_PCI_SEGMENT_INFO_HOB structure is used when Revision equals to UPL_PCI_SEGMENT_INFO_HOB_REVISION
182 //
183 UplSegmentInfo = (UPL_PCI_SEGMENT_INFO_HOB *)GET_GUID_HOB_DATA (GuidHob);
184 if (UplSegmentInfo->Count <= (GET_GUID_HOB_DATA_SIZE (GuidHob) - sizeof (UPL_PCI_SEGMENT_INFO_HOB)) / sizeof (UPL_SEGMENT_INFO)) {
185 return UplSegmentInfo;
186 }
187
188 return NULL;
189}
190
201EFIAPI
203 UINTN *Count
204 )
205{
206 UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo;
207 UPL_PCI_SEGMENT_INFO_HOB *UplSegmentInfo;
208
209 if (mPciSegments != NULL) {
210 *Count = mCount;
211 return mPciSegments;
212 }
213
214 UplSegmentInfo = Get_UPLSegInfo ();
215
216 if (UplSegmentInfo == NULL) {
218 } else {
219 PciRootBridgeInfo = Get_RBInfo ();
220 if (PciRootBridgeInfo == NULL) {
221 return 0;
222 }
223
224 RetrieveMultiSegmentInfoFromHob (PciRootBridgeInfo, UplSegmentInfo, Count);
225 }
226
227 mCount = *Count;
228 return mPciSegments;
229}
UINT64 UINTN
EFI_GUID gUefiAcpiBoardInfoGuid
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
Definition: HobLib.c:215
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define NULL
Definition: Base.h:319
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
EFI_GUID gUplPciSegmentInfoHobGuid
VOID RetrieveSegmentInfoFromHob(OUT UINTN *NumberOfRootBridges)
UPL_PCI_SEGMENT_INFO_HOB * Get_UPLSegInfo(VOID)
UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES * Get_RBInfo(VOID)
PCI_SEGMENT_INFO *EFIAPI GetPciSegmentInfo(UINTN *Count)
VOID RetrieveMultiSegmentInfoFromHob(IN UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo, IN UPL_PCI_SEGMENT_INFO_HOB *UplSegmentInfo, OUT UINTN *NumberOfRootBridges)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
UINT8 StartBusNumber
Start BUS number, for verifying the PCI Segment address.
UINT8 EndBusNumber
End BUS number, for verifying the PCI Segment address.
UINT64 BaseAddress
ECAM Base address.
UINT16 SegmentNumber
Segment number.