Changeset 108794 in vbox for trunk/src/VBox/Devices/EFI/FirmwareNew/UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.c
- Timestamp:
- Mar 31, 2025 11:31:09 AM (2 weeks ago)
- svn:sync-xref-src-repo-rev:
- 168237
- Location:
- trunk/src/VBox/Devices/EFI/FirmwareNew
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/EFI/FirmwareNew
-
Property svn:mergeinfo
changed from (toggle deleted branches)
to (toggle deleted branches)/vendor/edk2/current 103735-103757,103769-103776,129194-164365 /vendor/edk2/current 103735-103757,103769-103776,129194-168232
-
Property svn:mergeinfo
changed from (toggle deleted branches)
-
trunk/src/VBox/Devices/EFI/FirmwareNew/UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.c
r99404 r108794 4 4 5 5 Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> 6 Copyright (c) 2024, Rivos Inc. All rights reserved.<BR> 7 6 8 SPDX-License-Identifier: BSD-2-Clause-Patent 7 9 … … 14 16 #include <Library/PciSegmentInfoLib.h> 15 17 #include <Library/DebugLib.h> 16 17 STATIC PCI_SEGMENT_INFO mPciSegment0 = { 18 0, // Segment number 19 0, // To be fixed later 20 0, // Start bus number 21 255 // End bus number 22 }; 23 24 /** 25 Return an array of PCI_SEGMENT_INFO holding the segment information. 26 27 Note: The returned array/buffer is owned by callee. 28 29 @param Count Return the count of segments. 30 31 @retval A callee owned array holding the segment information. 18 #include <UniversalPayload/PciRootBridges.h> 19 #include <Library/PciLib.h> 20 #include <Library/MemoryAllocationLib.h> 21 #include <Library/PcdLib.h> 22 #include <Library/BaseMemoryLib.h> 23 #include <Guid/PciSegmentInfoGuid.h> 24 25 static PCI_SEGMENT_INFO *mPciSegments; 26 static UINTN mCount; 27 28 /** 29 Find segment info from all root bridges 30 31 @param[in] PciRootBridgeInfo Pointer of Universal Payload PCI Root Bridge Info Hob 32 @param[in] UplSegmentInfo Pointer of Universal UPL Segment Info 33 34 @param[out] NumberOfRootBridges Number of root bridges detected 35 36 **/ 37 VOID 38 RetrieveMultiSegmentInfoFromHob ( 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 IndexForExistingSegments; 46 UINT8 NumberOfExistingSegments; 47 UINT8 IndexForRb; 48 PCI_SEGMENT_INFO *pPciSegments; 49 50 if (PciRootBridgeInfo == NULL) { 51 mPciSegments = NULL; 52 return; 53 } 54 55 IndexForExistingSegments = 0; 56 NumberOfExistingSegments = 0; 57 IndexForRb = 0; 58 Size = PciRootBridgeInfo->Count * sizeof (PCI_SEGMENT_INFO); 59 60 *NumberOfRootBridges = PciRootBridgeInfo->Count; 61 62 pPciSegments = (PCI_SEGMENT_INFO *)AllocatePool (Size); 63 if (pPciSegments == NULL) { 64 ASSERT (pPciSegments != NULL); 65 return; 66 } 67 68 ZeroMem (pPciSegments, PciRootBridgeInfo->Count * sizeof (PCI_SEGMENT_INFO)); 69 70 // 71 // RBs may share the same Segment number, but mPciSegments should not have duplicate segment data. 72 // 1. if RB Segment is same with existing one, update StartBus and EndBus of existing one 73 // 2. if RB Segment is different from all existing ones, add it to the existing Segments data buffer. 74 // pPciSegments is local temporary data buffer that will be freed later (size depends on numbers of RB) 75 // mPciSegments is global data that will be updated with the pPciSegments for caller to utilize. (size depends on numbers of different PciSegments) 76 // 77 NumberOfExistingSegments = 1; 78 pPciSegments[0].BaseAddress = UplSegmentInfo->SegmentInfo[0].BaseAddress; 79 pPciSegments[0].SegmentNumber = (UINT16)(PciRootBridgeInfo->RootBridge[0].Segment); 80 pPciSegments[0].StartBusNumber = (UINT8)PciRootBridgeInfo->RootBridge[0].Bus.Base; 81 pPciSegments[0].EndBusNumber = (UINT8)PciRootBridgeInfo->RootBridge[0].Bus.Limit; 82 for (IndexForRb = 1; IndexForRb < PciRootBridgeInfo->Count; IndexForRb++) { 83 for (IndexForExistingSegments = 0; IndexForExistingSegments < NumberOfExistingSegments; IndexForExistingSegments++) { 84 if (pPciSegments[IndexForExistingSegments].SegmentNumber == PciRootBridgeInfo->RootBridge[IndexForRb].Segment) { 85 if (pPciSegments[IndexForExistingSegments].StartBusNumber > PciRootBridgeInfo->RootBridge[IndexForRb].Bus.Base) { 86 pPciSegments[IndexForExistingSegments].StartBusNumber = (UINT8)PciRootBridgeInfo->RootBridge[IndexForRb].Bus.Base; 87 } 88 89 if (pPciSegments[IndexForExistingSegments].EndBusNumber < PciRootBridgeInfo->RootBridge[IndexForRb].Bus.Limit) { 90 pPciSegments[IndexForExistingSegments].EndBusNumber = (UINT8)PciRootBridgeInfo->RootBridge[IndexForRb].Bus.Limit; 91 } 92 93 break; // breaking after a match found 94 } 95 } 96 97 if (IndexForExistingSegments >= NumberOfExistingSegments) { 98 // 99 // No match found, add it to segments data buffer 100 // 101 pPciSegments[NumberOfExistingSegments].BaseAddress = UplSegmentInfo->SegmentInfo[IndexForRb].BaseAddress; 102 pPciSegments[NumberOfExistingSegments].SegmentNumber = (UINT16)(PciRootBridgeInfo->RootBridge[IndexForRb].Segment); 103 pPciSegments[NumberOfExistingSegments].StartBusNumber = (UINT8)PciRootBridgeInfo->RootBridge[IndexForRb].Bus.Base; 104 pPciSegments[NumberOfExistingSegments].EndBusNumber = (UINT8)PciRootBridgeInfo->RootBridge[IndexForRb].Bus.Limit; 105 NumberOfExistingSegments++; 106 } 107 } 108 109 // 110 // Prepare data for returning to caller 111 // 112 *NumberOfRootBridges = NumberOfExistingSegments; 113 Size = NumberOfExistingSegments * sizeof (PCI_SEGMENT_INFO); 114 mPciSegments = (PCI_SEGMENT_INFO *)AllocatePool (Size); 115 if (mPciSegments == NULL) { 116 ASSERT (FALSE); 117 return; 118 } 119 120 CopyMem (&mPciSegments[0], &pPciSegments[0], Size); 121 if (pPciSegments != NULL) { 122 FreePool (pPciSegments); 123 } 124 125 return; 126 } 127 128 /** 129 Find segment info from all root bridges for legacy systems 130 131 @param[in] PciRootBridgeInfo Pointer of Universal Payload PCI Root Bridge Info Hob 132 @param[out] NumberOfRootBridges Number of root bridges detected 133 134 **/ 135 VOID 136 RetrieveSegmentInfoFromHob ( 137 OUT UINTN *NumberOfRootBridges 138 ) 139 { 140 EFI_HOB_GUID_TYPE *GuidHob; 141 ACPI_BOARD_INFO *AcpiBoardInfo; 142 143 *NumberOfRootBridges = 1; 144 // old model relies on gUefiAcpiBoardInfoGuid and hardcoded values for single segment only. 145 // This is only for backward compatibility, new platforms should adopt new model even in single segment cases. 146 // 147 mPciSegments = (PCI_SEGMENT_INFO *)AllocatePool (sizeof (PCI_SEGMENT_INFO)); 148 ASSERT (mPciSegments != NULL); 149 GuidHob = GetFirstGuidHob (&gUefiAcpiBoardInfoGuid); 150 ASSERT (GuidHob != NULL); 151 if (GuidHob != NULL) { 152 AcpiBoardInfo = (ACPI_BOARD_INFO *)GET_GUID_HOB_DATA (GuidHob); 153 mPciSegments->SegmentNumber = 0; 154 mPciSegments->BaseAddress = AcpiBoardInfo->PcieBaseAddress; 155 mPciSegments->StartBusNumber = 0; 156 mPciSegments->EndBusNumber = 0xFF; 157 } 158 } 159 160 /** 161 Return info for all root bridges 162 163 @return All the root bridge info instances in an array. 164 **/ 165 UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES * 166 Get_RBInfo ( 167 VOID 168 ) 169 { 170 UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo; 171 EFI_HOB_GUID_TYPE *GuidHob; 172 UNIVERSAL_PAYLOAD_GENERIC_HEADER *GenericHeader; 173 174 // 175 // Find Universal Payload PCI Root Bridge Info hob 176 // 177 GuidHob = GetFirstGuidHob (&gUniversalPayloadPciRootBridgeInfoGuid); 178 if ((GuidHob == NULL) || (sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER) > GET_GUID_HOB_DATA_SIZE (GuidHob))) { 179 return NULL; 180 } 181 182 GenericHeader = (UNIVERSAL_PAYLOAD_GENERIC_HEADER *)GET_GUID_HOB_DATA (GuidHob); 183 if (GenericHeader->Length > GET_GUID_HOB_DATA_SIZE (GuidHob)) { 184 return NULL; 185 } 186 187 if ((GenericHeader->Revision != UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION) || (GenericHeader->Length < sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES))) { 188 return NULL; 189 } 190 191 // 192 // UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES structure is used when Revision equals to UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION 193 // 194 PciRootBridgeInfo = (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *)GET_GUID_HOB_DATA (GuidHob); 195 if (PciRootBridgeInfo->Count <= (GET_GUID_HOB_DATA_SIZE (GuidHob) - sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES)) / sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE)) { 196 return PciRootBridgeInfo; 197 } 198 199 return NULL; 200 } 201 202 /** 203 Return info for all root bridge segments 204 205 @return All the segment info instances in an array. 206 **/ 207 UPL_PCI_SEGMENT_INFO_HOB * 208 Get_UPLSegInfo ( 209 VOID 210 ) 211 { 212 UPL_PCI_SEGMENT_INFO_HOB *UplSegmentInfo; 213 EFI_HOB_GUID_TYPE *GuidHob; 214 UNIVERSAL_PAYLOAD_GENERIC_HEADER *GenericHeader; 215 216 // 217 // Find Universal Payload Segment Info hob 218 // 219 GuidHob = GetFirstGuidHob (&gUplPciSegmentInfoHobGuid); 220 if ((GuidHob == NULL) || (sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER) > GET_GUID_HOB_DATA_SIZE (GuidHob))) { 221 return NULL; 222 } 223 224 GenericHeader = (UNIVERSAL_PAYLOAD_GENERIC_HEADER *)GET_GUID_HOB_DATA (GuidHob); 225 if (GenericHeader->Length > GET_GUID_HOB_DATA_SIZE (GuidHob)) { 226 return NULL; 227 } 228 229 if ((GenericHeader->Revision != UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION) || (GenericHeader->Length < sizeof (UPL_PCI_SEGMENT_INFO_HOB))) { 230 return NULL; 231 } 232 233 // 234 // UPL_PCI_SEGMENT_INFO_HOB structure is used when Revision equals to UPL_PCI_SEGMENT_INFO_HOB_REVISION 235 // 236 UplSegmentInfo = (UPL_PCI_SEGMENT_INFO_HOB *)GET_GUID_HOB_DATA (GuidHob); 237 if (UplSegmentInfo->Count <= (GET_GUID_HOB_DATA_SIZE (GuidHob) - sizeof (UPL_PCI_SEGMENT_INFO_HOB)) / sizeof (UPL_SEGMENT_INFO)) { 238 return UplSegmentInfo; 239 } 240 241 return NULL; 242 } 243 244 /** 245 Return all the root bridge instances in an array. 246 247 @param Count Return the count of root bridge instances. 248 249 @return All the root bridge instances in an array. 250 The array should be passed into PciHostBridgeFreeRootBridges() 251 when it's not used. 32 252 **/ 33 253 PCI_SEGMENT_INFO * … … 37 257 ) 38 258 { 39 EFI_HOB_GUID_TYPE *GuidHob; 40 ACPI_BOARD_INFO *AcpiBoardInfo; 41 42 ASSERT (Count != NULL); 43 if (Count == NULL) { 44 return NULL; 45 } 46 47 if (mPciSegment0.BaseAddress == 0) { 48 // 49 // Find the acpi board information guid hob 50 // 51 GuidHob = GetFirstGuidHob (&gUefiAcpiBoardInfoGuid); 52 ASSERT (GuidHob != NULL); 53 54 AcpiBoardInfo = (ACPI_BOARD_INFO *)GET_GUID_HOB_DATA (GuidHob); 55 mPciSegment0.BaseAddress = AcpiBoardInfo->PcieBaseAddress; 56 } 57 58 *Count = 1; 59 return &mPciSegment0; 60 } 259 UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo; 260 UPL_PCI_SEGMENT_INFO_HOB *UplSegmentInfo; 261 262 if (mPciSegments != NULL) { 263 *Count = mCount; 264 return mPciSegments; 265 } 266 267 UplSegmentInfo = Get_UPLSegInfo (); 268 269 if (UplSegmentInfo == NULL) { 270 RetrieveSegmentInfoFromHob (Count); 271 } else { 272 PciRootBridgeInfo = Get_RBInfo (); 273 if (PciRootBridgeInfo == NULL) { 274 return 0; 275 } 276 277 RetrieveMultiSegmentInfoFromHob (PciRootBridgeInfo, UplSegmentInfo, Count); 278 } 279 280 mCount = *Count; 281 return mPciSegments; 282 }
Note:
See TracChangeset
for help on using the changeset viewer.