@@ -17,6 +17,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
1717
1818**/
1919
20+ #include <Library/BaseLib.h>
2021#include <Library/DebugLib.h>
2122#include <Library/UefiLib.h>
2223#include <Library/UnitTestLib.h>
@@ -66,8 +67,9 @@ CheckExcludedRegions (
6667 UINTN EfiDescriptorSize ;
6768 UINT32 EfiDescriptorVersion ;
6869 EFI_ACPI_DESCRIPTION_HEADER * IortTable ;
69- RMRListNode * Head ;
70- RMRListNode * Current ;
70+ LIST_ENTRY RmrList ;
71+ LIST_ENTRY * Link ;
72+ RMR_LIST_NODE * RmrEntry ;
7173 BOOLEAN Found ;
7274 BOOLEAN FoundInMemoryMap ;
7375 UINT32 FoundMemoryType ;
@@ -83,15 +85,14 @@ CheckExcludedRegions (
8385 //
8486 // Step 2: Get the RMR (Reserved Memory Range) nodes from IORT Table
8587 //
86- Head = GetIortAcpiTableRmrList (IortTable );
87- if (Head == NULL ) {
88+ InitializeListHead (& RmrList );
89+ Status = GetIortAcpiTableRmrList (IortTable , & RmrList );
90+ UT_ASSERT_NOT_EFI_ERROR (Status );
91+ if (IsListEmpty (& RmrList )) {
8892 UT_LOG_INFO ("No RMRs Found in IORT\n" );
89- DEBUG ((DEBUG_INFO , "%a: No RMRs Found in IORT\n" , __func__ ));
9093 return UNIT_TEST_PASSED ;
9194 }
9295
93- Current = Head ;
94-
9596 //
9697 // Step 3: Get the EFI memory map.
9798 //
@@ -118,7 +119,6 @@ CheckExcludedRegions (
118119 UT_ASSERT_NOT_EFI_ERROR (Status );
119120 } else {
120121 UT_LOG_ERROR ("GetMemoryMap Failed\n" );
121- DEBUG ((DEBUG_ERROR , "%a: GetMemoryMap Failed\n" , __func__ ));
122122 TestStatus = UNIT_TEST_ERROR_TEST_FAILED ;
123123 UT_ASSERT_STATUS_EQUAL (Status , TestStatus );
124124 return UNIT_TEST_ERROR_TEST_FAILED ;
@@ -131,19 +131,22 @@ CheckExcludedRegions (
131131 EfiMemoryMapEnd = (EFI_MEMORY_DESCRIPTOR * )((UINT8 * )EfiMemoryMap + EfiMemoryMapSize );
132132 TestStatus = UNIT_TEST_PASSED ;
133133
134- while (Current != NULL ) {
134+ for (Link = GetFirstNode (& RmrList );
135+ !IsNull (& RmrList , Link );
136+ Link = GetNextNode (& RmrList , Link ))
137+ {
138+ RmrEntry = RMR_LIST_NODE_FROM_LINK (Link );
135139 Found = FALSE;
136140 FoundInMemoryMap = FALSE;
137141 FoundMemoryType = 0 ;
138142 EfiMemNext = EfiMemoryMap ;
139143
140- UT_LOG_INFO ("Checking RMR region: Base=0x%lX, Length=0x%lX\n" , Current -> BaseAddress , Current -> Length );
141- DEBUG ((DEBUG_INFO , "%a: Checking RMR region: Base=0x%lX, Length=0x%lX\n" , __func__ , Current -> BaseAddress , Current -> Length ));
144+ UT_LOG_INFO ("Checking RMR region: Base=0x%lX, Length=0x%lX\n" , RmrEntry -> BaseAddress , RmrEntry -> Length );
142145
143146 while (EfiMemNext < EfiMemoryMapEnd ) {
144147 // Check if memory range fully encompasses RMR
145- if ((EfiMemNext -> PhysicalStart <= Current -> BaseAddress ) &&
146- ((EfiMemNext -> PhysicalStart + (EFI_PAGE_SIZE * EfiMemNext -> NumberOfPages )) >= (Current -> BaseAddress + Current -> Length )))
148+ if ((EfiMemNext -> PhysicalStart <= RmrEntry -> BaseAddress ) &&
149+ ((EfiMemNext -> PhysicalStart + (EFI_PAGE_SIZE * EfiMemNext -> NumberOfPages )) >= (RmrEntry -> BaseAddress + RmrEntry -> Length )))
147150 {
148151 FoundInMemoryMap = TRUE;
149152 FoundMemoryType = EfiMemNext -> Type ;
@@ -154,14 +157,6 @@ CheckExcludedRegions (
154157 EFI_PAGE_SIZE * EfiMemNext -> NumberOfPages ,
155158 EfiMemNext -> Type
156159 );
157- DEBUG ((
158- DEBUG_INFO ,
159- "%a: Found encompassing memory range: Base=0x%lX, Length=0x%lX, Type=%d\n" ,
160- __func__ ,
161- EfiMemNext -> PhysicalStart ,
162- EFI_PAGE_SIZE * EfiMemNext -> NumberOfPages ,
163- EfiMemNext -> Type
164- ));
165160
166161 if ((EfiMemNext -> Type == EfiReservedMemoryType ) ||
167162 (EfiMemNext -> Type == EfiRuntimeServicesData ))
@@ -183,42 +178,34 @@ CheckExcludedRegions (
183178 if (!FoundInMemoryMap ) {
184179 UT_LOG_INFO (
185180 "RMR region Base=0x%lX, Length=0x%lX was NOT found in the UEFI memory map\n" ,
186- Current -> BaseAddress ,
187- Current -> Length
181+ RmrEntry -> BaseAddress ,
182+ RmrEntry -> Length
188183 );
189- DEBUG ((
190- DEBUG_INFO ,
191- "%a: RMR region Base=0x%lX, Length=0x%lX was NOT found in the UEFI memory map\n" ,
192- __func__ ,
193- Current -> BaseAddress ,
194- Current -> Length
195- ));
196184 TestStatus = UNIT_TEST_ERROR_TEST_FAILED ;
197185 }
198186
199187 if (!Found ) {
200188 UT_LOG_ERROR (
201189 "RMR between 0x%lX and 0x%lX NOT found with an acceptable memory type (Reserved or RuntimeServicesData)! Memory type found: %d\n" ,
202- Current -> BaseAddress ,
203- Current -> BaseAddress + Current -> Length ,
190+ RmrEntry -> BaseAddress ,
191+ RmrEntry -> BaseAddress + RmrEntry -> Length ,
204192 FoundMemoryType
205193 );
206- DEBUG ((
207- DEBUG_ERROR ,
208- "%a: RMR between 0x%lX and 0x%lX NOT found with an acceptable memory type (Reserved or RuntimeServicesData)! Memory type found: %d\n" ,
209- __func__ ,
210- Current -> BaseAddress ,
211- Current -> BaseAddress + Current -> Length ,
212- FoundMemoryType
213- ));
214194 TestStatus = UNIT_TEST_ERROR_TEST_FAILED ;
215195 }
216-
217- Current = Current -> Next ;
218196 }
219197
220198 UT_LOG_INFO ("%a: Result=%d (%a)\n" , __func__ , TestStatus , (TestStatus == UNIT_TEST_PASSED ) ? "PASSED" : "FAILED" );
221- DEBUG ((DEBUG_INFO , "%a: Result=%d (%a)\n" , __func__ , TestStatus , (TestStatus == UNIT_TEST_PASSED ) ? "PASSED" : "FAILED" ));
199+
200+ //
201+ // Free every RMR entry appended by GetIortAcpiTableRmrList.
202+ //
203+ while (!IsListEmpty (& RmrList )) {
204+ Link = GetFirstNode (& RmrList );
205+ RmrEntry = RMR_LIST_NODE_FROM_LINK (Link );
206+ RemoveEntryList (Link );
207+ FreePool (RmrEntry );
208+ }
222209
223210 UT_ASSERT_STATUS_EQUAL (TestStatus , UNIT_TEST_PASSED );
224211 return TestStatus ;
@@ -287,7 +274,6 @@ CheckIOMMUEnabled (
287274 //
288275 UT_ASSERT_TRUE (SmmuCount > 0 );
289276 UT_LOG_INFO ("Found %d SMMUv3 units in IORT\n" , SmmuCount );
290- DEBUG ((DEBUG_INFO , "%a: Found %d SMMUv3 units in IORT\n" , __func__ , SmmuCount ));
291277
292278 TestStatus = UNIT_TEST_PASSED ;
293279
@@ -302,21 +288,18 @@ CheckIOMMUEnabled (
302288 //
303289 for (Iterator = 0 ; Iterator < SmmuCount ; Iterator ++ ) {
304290 UT_LOG_INFO ("Checking SMMUv3 at base address 0x%lX\n" , SmmuBaseAddresses [Iterator ]);
305- DEBUG ((DEBUG_INFO , "%a: Checking SMMUv3 at base address 0x%lX\n" , __func__ , SmmuBaseAddresses [Iterator ]));
306291
307292 //
308293 // Read CR0 register
309294 //
310295 Cr0Value = MmioRead32 ((UINTN )(SmmuBaseAddresses [Iterator ] + SMMU_CR0 ));
311296 UT_LOG_INFO ("CR0 Register Value: 0x%X\n" , Cr0Value );
312- DEBUG ((DEBUG_INFO , "%a: CR0 Register Value: 0x%X\n" , __func__ , Cr0Value ));
313297
314298 //
315299 // Check SMMUEN bit (bit 0)
316300 //
317301 SmmuEnBit = Cr0Value & SMMU_CR0_SMMUEN ;
318302 UT_LOG_INFO ("SMMUEN bit: %d\n" , SmmuEnBit );
319- DEBUG ((DEBUG_INFO , "%a: SMMUEN bit: %d\n" , __func__ , SmmuEnBit ));
320303 if (SmmuEnBit == 0 ) {
321304 //
322305 // SMMU translation is not enabled. The SMMU is still DMA-safe if it is
@@ -325,20 +308,17 @@ CheckIOMMUEnabled (
325308 GbpaValue = MmioRead32 ((UINTN )(SmmuBaseAddresses [Iterator ] + SMMU_GBPA ));
326309 AbortBit = GbpaValue & SMMU_GBPA_ABORT ;
327310 UT_LOG_INFO ("GBPA Register Value: 0x%X, ABORT bit: %d\n" , GbpaValue , AbortBit ? 1 : 0 );
328- DEBUG ((DEBUG_INFO , "%a: GBPA Register Value: 0x%X, ABORT bit: %d\n" , __func__ , GbpaValue , AbortBit ? 1 : 0 ));
329311
330312 if (AbortBit != 0 ) {
331313 //
332314 // Global abort is set: all DMA is aborted, so this SMMU is DMA-safe.
333315 // Skip the remaining translation-related checks for this SMMU.
334316 //
335317 UT_LOG_INFO ("SMMUEN is disabled but global abort (GBPA.ABORT) is set for SMMUv3 at base address 0x%lX. SMMU is DMA-safe.\n" , SmmuBaseAddresses [Iterator ]);
336- DEBUG ((DEBUG_INFO , "%a: SMMUEN is disabled but global abort (GBPA.ABORT) is set for SMMUv3 at base address 0x%lX. SMMU is DMA-safe.\n" , __func__ , SmmuBaseAddresses [Iterator ]));
337318 continue ;
338319 }
339320
340321 UT_LOG_ERROR ("SMMUEN bit is disabled and global abort is not set for SMMUv3 at base address 0x%lX\n" , SmmuBaseAddresses [Iterator ]);
341- DEBUG ((DEBUG_ERROR , "%a: SMMUEN bit is disabled and global abort is not set for SMMUv3 at base address 0x%lX\n" , __func__ , SmmuBaseAddresses [Iterator ]));
342322 TestStatus = UNIT_TEST_ERROR_TEST_FAILED ;
343323 continue ;
344324 }
@@ -348,10 +328,8 @@ CheckIOMMUEnabled (
348328 //
349329 CmdQEnBit = Cr0Value & SMMU_CR0_CMDQEN ;
350330 UT_LOG_INFO ("CMDQEN bit: %d\n" , CmdQEnBit ? 1 : 0 );
351- DEBUG ((DEBUG_INFO , "%a: CMDQEN bit: %d\n" , __func__ , CmdQEnBit ? 1 : 0 ));
352331 if (CmdQEnBit == 0 ) {
353332 UT_LOG_ERROR ("CMDQEN bit is disabled for SMMUv3 at base address 0x%lX\n" , SmmuBaseAddresses [Iterator ]);
354- DEBUG ((DEBUG_ERROR , "%a: CMDQEN bit is disabled for SMMUv3 at base address 0x%lX\n" , __func__ , SmmuBaseAddresses [Iterator ]));
355333 TestStatus = UNIT_TEST_ERROR_TEST_FAILED ;
356334 }
357335
@@ -360,10 +338,8 @@ CheckIOMMUEnabled (
360338 //
361339 EvtQEnBit = Cr0Value & SMMU_CR0_EVTQEN ;
362340 UT_LOG_INFO ("EVTQEN bit: %d\n" , EvtQEnBit ? 1 : 0 );
363- DEBUG ((DEBUG_INFO , "%a: EVTQEN bit: %d\n" , __func__ , EvtQEnBit ? 1 : 0 ));
364341 if (EvtQEnBit == 0 ) {
365342 UT_LOG_ERROR ("EVTQEN bit is disabled for SMMUv3 at base address 0x%lX\n" , SmmuBaseAddresses [Iterator ]);
366- DEBUG ((DEBUG_ERROR , "%a: EVTQEN bit is disabled for SMMUv3 at base address 0x%lX\n" , __func__ , SmmuBaseAddresses [Iterator ]));
367343 TestStatus = UNIT_TEST_ERROR_TEST_FAILED ;
368344 }
369345
@@ -373,15 +349,12 @@ CheckIOMMUEnabled (
373349 //
374350 StrTabBase = MmioRead64 ((UINTN )(SmmuBaseAddresses [Iterator ] + SMMU_STRTAB_BASE ));
375351 UT_LOG_INFO ("STRTAB_BASE Register Value: 0x%lX\n" , StrTabBase );
376- DEBUG ((DEBUG_INFO , "%a: STRTAB_BASE Register Value: 0x%lX\n" , __func__ , StrTabBase ));
377352
378353 // Extract the address portion by masking out lower 6 bits (bits [5:0] are reserved/config)
379354 StrTabBaseAddr = StrTabBase & ~SMMU_STRTAB_BASE_ADDR_MASK ;
380355 UT_LOG_INFO ("STRTAB_BASE Address: 0x%lX\n" , StrTabBaseAddr );
381- DEBUG ((DEBUG_INFO , "%a: STRTAB_BASE Address: 0x%lX\n" , __func__ , StrTabBaseAddr ));
382356 if (StrTabBaseAddr == 0 ) {
383357 UT_LOG_ERROR ("STRTAB_BASE is NULL for SMMUv3 at base address 0x%lX\n" , SmmuBaseAddresses [Iterator ]);
384- DEBUG ((DEBUG_ERROR , "%a: STRTAB_BASE is NULL for SMMUv3 at base address 0x%lX\n" , __func__ , SmmuBaseAddresses [Iterator ]));
385358 TestStatus = UNIT_TEST_ERROR_TEST_FAILED ;
386359 }
387360
@@ -390,16 +363,17 @@ CheckIOMMUEnabled (
390363 //
391364 GError = MmioRead32 ((UINTN )(SmmuBaseAddresses [Iterator ] + SMMU_GERROR ));
392365 UT_LOG_INFO ("GERROR Register Value: 0x%X\n" , GError );
393- DEBUG ((DEBUG_INFO , "%a: GERROR Register Value: 0x%X\n" , __func__ , GError ));
394366 if (GError != 0 ) {
395367 UT_LOG_ERROR ("GERROR register is non-zero for SMMUv3 at base address 0x%lX\n" , SmmuBaseAddresses [Iterator ]);
396- DEBUG ((DEBUG_ERROR , "%a: GERROR register is non-zero for SMMUv3 at base address 0x%lX\n" , __func__ , SmmuBaseAddresses [Iterator ]));
397368 TestStatus = UNIT_TEST_ERROR_TEST_FAILED ;
398369 }
399370 }
400371
401372 UT_LOG_INFO ("%a: Result=%d (%a)\n" , __func__ , TestStatus , (TestStatus == UNIT_TEST_PASSED ) ? "PASSED" : "FAILED" );
402- DEBUG ((DEBUG_INFO , "%a: Result=%d (%a)\n" , __func__ , TestStatus , (TestStatus == UNIT_TEST_PASSED ) ? "PASSED" : "FAILED" ));
373+
374+ // Free the SMMU base address array allocated by ParseIortAcpiTableSmmu.
375+ FreePool (SmmuBaseAddresses );
376+ SmmuBaseAddresses = NULL ;
403377
404378 UT_ASSERT_STATUS_EQUAL (TestStatus , UNIT_TEST_PASSED );
405379 return TestStatus ;
0 commit comments