]> git.proxmox.com Git - mirror_edk2.git/blob - IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/DmarTable.c
BaseTools:Add import in FvImageSection
[mirror_edk2.git] / IntelSiliconPkg / Feature / VTd / IntelVTdPmrPei / DmarTable.c
1 /** @file
2
3 Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
5
6 **/
7
8 #include <Uefi.h>
9 #include <PiPei.h>
10 #include <Library/BaseLib.h>
11 #include <Library/BaseMemoryLib.h>
12 #include <Library/DebugLib.h>
13 #include <Library/HobLib.h>
14 #include <IndustryStandard/Vtd.h>
15 #include <Ppi/VtdInfo.h>
16
17 #include "IntelVTdPmrPei.h"
18
19 /**
20 Dump DMAR DeviceScopeEntry.
21
22 @param[in] DmarDeviceScopeEntry DMAR DeviceScopeEntry
23 **/
24 VOID
25 DumpDmarDeviceScopeEntry (
26 IN EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDeviceScopeEntry
27 )
28 {
29 UINTN PciPathNumber;
30 UINTN PciPathIndex;
31 EFI_ACPI_DMAR_PCI_PATH *PciPath;
32
33 if (DmarDeviceScopeEntry == NULL) {
34 return;
35 }
36
37 DEBUG ((DEBUG_INFO,
38 " *************************************************************************\n"
39 ));
40 DEBUG ((DEBUG_INFO,
41 " * DMA-Remapping Device Scope Entry Structure *\n"
42 ));
43 DEBUG ((DEBUG_INFO,
44 " *************************************************************************\n"
45 ));
46 DEBUG ((DEBUG_INFO,
47 (sizeof(UINTN) == sizeof(UINT64)) ?
48 " DMAR Device Scope Entry address ...................... 0x%016lx\n" :
49 " DMAR Device Scope Entry address ...................... 0x%08x\n",
50 DmarDeviceScopeEntry
51 ));
52 DEBUG ((DEBUG_INFO,
53 " Device Scope Entry Type ............................ 0x%02x\n",
54 DmarDeviceScopeEntry->Type
55 ));
56 switch (DmarDeviceScopeEntry->Type) {
57 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT:
58 DEBUG ((DEBUG_INFO,
59 " PCI Endpoint Device\n"
60 ));
61 break;
62 case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE:
63 DEBUG ((DEBUG_INFO,
64 " PCI Sub-hierachy\n"
65 ));
66 break;
67 default:
68 break;
69 }
70 DEBUG ((DEBUG_INFO,
71 " Length ............................................. 0x%02x\n",
72 DmarDeviceScopeEntry->Length
73 ));
74 DEBUG ((DEBUG_INFO,
75 " Enumeration ID ..................................... 0x%02x\n",
76 DmarDeviceScopeEntry->EnumerationId
77 ));
78 DEBUG ((DEBUG_INFO,
79 " Starting Bus Number ................................ 0x%02x\n",
80 DmarDeviceScopeEntry->StartBusNumber
81 ));
82
83 PciPathNumber = (DmarDeviceScopeEntry->Length - sizeof(EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER)) / sizeof(EFI_ACPI_DMAR_PCI_PATH);
84 PciPath = (EFI_ACPI_DMAR_PCI_PATH *)(DmarDeviceScopeEntry + 1);
85 for (PciPathIndex = 0; PciPathIndex < PciPathNumber; PciPathIndex++) {
86 DEBUG ((DEBUG_INFO,
87 " Device ............................................. 0x%02x\n",
88 PciPath[PciPathIndex].Device
89 ));
90 DEBUG ((DEBUG_INFO,
91 " Function ........................................... 0x%02x\n",
92 PciPath[PciPathIndex].Function
93 ));
94 }
95
96 DEBUG ((DEBUG_INFO,
97 " *************************************************************************\n\n"
98 ));
99
100 return;
101 }
102
103 /**
104 Dump DMAR RMRR table.
105
106 @param[in] Rmrr DMAR RMRR table
107 **/
108 VOID
109 DumpDmarRmrr (
110 IN EFI_ACPI_DMAR_RMRR_HEADER *Rmrr
111 )
112 {
113 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDeviceScopeEntry;
114 INTN RmrrLen;
115
116 if (Rmrr == NULL) {
117 return;
118 }
119
120 DEBUG ((DEBUG_INFO,
121 " ***************************************************************************\n"
122 ));
123 DEBUG ((DEBUG_INFO,
124 " * Reserved Memory Region Reporting Structure *\n"
125 ));
126 DEBUG ((DEBUG_INFO,
127 " ***************************************************************************\n"
128 ));
129 DEBUG ((DEBUG_INFO,
130 (sizeof(UINTN) == sizeof(UINT64)) ?
131 " RMRR address ........................................... 0x%016lx\n" :
132 " RMRR address ........................................... 0x%08x\n",
133 Rmrr
134 ));
135 DEBUG ((DEBUG_INFO,
136 " Type ................................................. 0x%04x\n",
137 Rmrr->Header.Type
138 ));
139 DEBUG ((DEBUG_INFO,
140 " Length ............................................... 0x%04x\n",
141 Rmrr->Header.Length
142 ));
143 DEBUG ((DEBUG_INFO,
144 " Segment Number ....................................... 0x%04x\n",
145 Rmrr->SegmentNumber
146 ));
147 DEBUG ((DEBUG_INFO,
148 " Reserved Memory Region Base Address .................. 0x%016lx\n",
149 Rmrr->ReservedMemoryRegionBaseAddress
150 ));
151 DEBUG ((DEBUG_INFO,
152 " Reserved Memory Region Limit Address ................. 0x%016lx\n",
153 Rmrr->ReservedMemoryRegionLimitAddress
154 ));
155
156 RmrrLen = Rmrr->Header.Length - sizeof(EFI_ACPI_DMAR_RMRR_HEADER);
157 DmarDeviceScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)(Rmrr + 1);
158 while (RmrrLen > 0) {
159 DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry);
160 RmrrLen -= DmarDeviceScopeEntry->Length;
161 DmarDeviceScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)DmarDeviceScopeEntry + DmarDeviceScopeEntry->Length);
162 }
163
164 DEBUG ((DEBUG_INFO,
165 " ***************************************************************************\n\n"
166 ));
167
168 return;
169 }
170
171 /**
172 Dump DMAR DRHD table.
173
174 @param[in] Drhd DMAR DRHD table
175 **/
176 VOID
177 DumpDmarDrhd (
178 IN EFI_ACPI_DMAR_DRHD_HEADER *Drhd
179 )
180 {
181 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDeviceScopeEntry;
182 INTN DrhdLen;
183
184 if (Drhd == NULL) {
185 return;
186 }
187
188 DEBUG ((DEBUG_INFO,
189 " ***************************************************************************\n"
190 ));
191 DEBUG ((DEBUG_INFO,
192 " * DMA-Remapping Hardware Definition Structure *\n"
193 ));
194 DEBUG ((DEBUG_INFO,
195 " ***************************************************************************\n"
196 ));
197 DEBUG ((DEBUG_INFO,
198 (sizeof(UINTN) == sizeof(UINT64)) ?
199 " DRHD address ........................................... 0x%016lx\n" :
200 " DRHD address ........................................... 0x%08x\n",
201 Drhd
202 ));
203 DEBUG ((DEBUG_INFO,
204 " Type ................................................. 0x%04x\n",
205 Drhd->Header.Type
206 ));
207 DEBUG ((DEBUG_INFO,
208 " Length ............................................... 0x%04x\n",
209 Drhd->Header.Length
210 ));
211 DEBUG ((DEBUG_INFO,
212 " Flags ................................................ 0x%02x\n",
213 Drhd->Flags
214 ));
215 DEBUG ((DEBUG_INFO,
216 " INCLUDE_PCI_ALL .................................... 0x%02x\n",
217 Drhd->Flags & EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL
218 ));
219 DEBUG ((DEBUG_INFO,
220 " Segment Number ....................................... 0x%04x\n",
221 Drhd->SegmentNumber
222 ));
223 DEBUG ((DEBUG_INFO,
224 " Register Base Address ................................ 0x%016lx\n",
225 Drhd->RegisterBaseAddress
226 ));
227
228 DrhdLen = Drhd->Header.Length - sizeof(EFI_ACPI_DMAR_DRHD_HEADER);
229 DmarDeviceScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)(Drhd + 1);
230 while (DrhdLen > 0) {
231 DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry);
232 DrhdLen -= DmarDeviceScopeEntry->Length;
233 DmarDeviceScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)DmarDeviceScopeEntry + DmarDeviceScopeEntry->Length);
234 }
235
236 DEBUG ((DEBUG_INFO,
237 " ***************************************************************************\n\n"
238 ));
239
240 return;
241 }
242
243 /**
244 Dump DMAR ACPI table.
245
246 @param[in] Dmar DMAR ACPI table
247 **/
248 VOID
249 DumpAcpiDMAR (
250 IN EFI_ACPI_DMAR_HEADER *Dmar
251 )
252 {
253 EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
254 INTN DmarLen;
255
256 if (Dmar == NULL) {
257 return;
258 }
259
260 //
261 // Dump Dmar table
262 //
263 DEBUG ((DEBUG_INFO,
264 "*****************************************************************************\n"
265 ));
266 DEBUG ((DEBUG_INFO,
267 "* DMAR Table *\n"
268 ));
269 DEBUG ((DEBUG_INFO,
270 "*****************************************************************************\n"
271 ));
272
273 DEBUG ((DEBUG_INFO,
274 (sizeof(UINTN) == sizeof(UINT64)) ?
275 "DMAR address ............................................. 0x%016lx\n" :
276 "DMAR address ............................................. 0x%08x\n",
277 Dmar
278 ));
279
280 DEBUG ((DEBUG_INFO,
281 " Table Contents:\n"
282 ));
283 DEBUG ((DEBUG_INFO,
284 " Host Address Width ................................... 0x%02x\n",
285 Dmar->HostAddressWidth
286 ));
287 DEBUG ((DEBUG_INFO,
288 " Flags ................................................ 0x%02x\n",
289 Dmar->Flags
290 ));
291 DEBUG ((DEBUG_INFO,
292 " INTR_REMAP ......................................... 0x%02x\n",
293 Dmar->Flags & EFI_ACPI_DMAR_FLAGS_INTR_REMAP
294 ));
295 DEBUG ((DEBUG_INFO,
296 " X2APIC_OPT_OUT_SET ................................. 0x%02x\n",
297 Dmar->Flags & EFI_ACPI_DMAR_FLAGS_X2APIC_OPT_OUT
298 ));
299 DEBUG ((DEBUG_INFO,
300 " DMA_CTRL_PLATFORM_OPT_IN_FLAG ...................... 0x%02x\n",
301 Dmar->Flags & EFI_ACPI_DMAR_FLAGS_DMA_CTRL_PLATFORM_OPT_IN_FLAG
302 ));
303
304 DmarLen = Dmar->Header.Length - sizeof(EFI_ACPI_DMAR_HEADER);
305 DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)(Dmar + 1);
306 while (DmarLen > 0) {
307 switch (DmarHeader->Type) {
308 case EFI_ACPI_DMAR_TYPE_DRHD:
309 DumpDmarDrhd ((EFI_ACPI_DMAR_DRHD_HEADER *)DmarHeader);
310 break;
311 case EFI_ACPI_DMAR_TYPE_RMRR:
312 DumpDmarRmrr ((EFI_ACPI_DMAR_RMRR_HEADER *)DmarHeader);
313 break;
314 default:
315 break;
316 }
317 DmarLen -= DmarHeader->Length;
318 DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)DmarHeader + DmarHeader->Length);
319 }
320
321 DEBUG ((DEBUG_INFO,
322 "*****************************************************************************\n\n"
323 ));
324
325 return;
326 }
327
328 /**
329 Get VTd engine number.
330
331 @param[in] AcpiDmarTable DMAR ACPI table
332
333 @return the VTd engine number.
334 **/
335 UINTN
336 GetVtdEngineNumber (
337 IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
338 )
339 {
340 EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
341 UINTN VtdIndex;
342
343 VtdIndex = 0;
344 DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)(AcpiDmarTable + 1));
345 while ((UINTN)DmarHeader < (UINTN)AcpiDmarTable + AcpiDmarTable->Header.Length) {
346 switch (DmarHeader->Type) {
347 case EFI_ACPI_DMAR_TYPE_DRHD:
348 VtdIndex++;
349 break;
350 default:
351 break;
352 }
353 DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)DmarHeader + DmarHeader->Length);
354 }
355 return VtdIndex ;
356 }
357
358 /**
359 Process DMAR DHRD table.
360
361 @param[in] VTdInfo The VTd engine context information.
362 @param[in] VtdIndex The index of VTd engine.
363 @param[in] DmarDrhd The DRHD table.
364 **/
365 VOID
366 ProcessDhrd (
367 IN VTD_INFO *VTdInfo,
368 IN UINTN VtdIndex,
369 IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd
370 )
371 {
372 DEBUG ((DEBUG_INFO," VTD (%d) BaseAddress - 0x%016lx\n", VtdIndex, DmarDrhd->RegisterBaseAddress));
373 VTdInfo->VTdEngineAddress[VtdIndex] = DmarDrhd->RegisterBaseAddress;
374 }
375
376 /**
377 Parse DMAR DRHD table.
378
379 @param[in] AcpiDmarTable DMAR ACPI table
380
381 @return EFI_SUCCESS The DMAR DRHD table is parsed.
382 **/
383 EFI_STATUS
384 ParseDmarAcpiTableDrhd (
385 IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
386 )
387 {
388 EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
389 UINTN VtdUnitNumber;
390 UINTN VtdIndex;
391 VTD_INFO *VTdInfo;
392
393 VtdUnitNumber = GetVtdEngineNumber (AcpiDmarTable);
394 if (VtdUnitNumber == 0) {
395 return EFI_UNSUPPORTED;
396 }
397
398 VTdInfo = BuildGuidHob (&mVTdInfoGuid, sizeof(VTD_INFO) + (VtdUnitNumber - 1) * sizeof(UINT64));
399 ASSERT(VTdInfo != NULL);
400 if (VTdInfo == NULL) {
401 return EFI_OUT_OF_RESOURCES;
402 }
403
404 //
405 // Initialize the engine mask to all.
406 //
407 VTdInfo->AcpiDmarTable = AcpiDmarTable;
408 VTdInfo->EngineMask = LShiftU64 (1, VtdUnitNumber) - 1;
409 VTdInfo->HostAddressWidth = AcpiDmarTable->HostAddressWidth;
410 VTdInfo->VTdEngineCount = VtdUnitNumber;
411
412 VtdIndex = 0;
413 DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)(AcpiDmarTable + 1));
414 while ((UINTN)DmarHeader < (UINTN)AcpiDmarTable + AcpiDmarTable->Header.Length) {
415 switch (DmarHeader->Type) {
416 case EFI_ACPI_DMAR_TYPE_DRHD:
417 ASSERT (VtdIndex < VtdUnitNumber);
418 ProcessDhrd (VTdInfo, VtdIndex, (EFI_ACPI_DMAR_DRHD_HEADER *)DmarHeader);
419 VtdIndex++;
420
421 break;
422
423 default:
424 break;
425 }
426 DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)DmarHeader + DmarHeader->Length);
427 }
428 ASSERT (VtdIndex == VtdUnitNumber);
429
430 return EFI_SUCCESS;
431 }
432
433 /**
434 Return the VTd engine index according to the Segment and DevScopeEntry.
435
436 @param AcpiDmarTable DMAR ACPI table
437 @param Segment The segment of the VTd engine
438 @param DevScopeEntry The DevScopeEntry of the VTd engine
439
440 @return The VTd engine index according to the Segment and DevScopeEntry.
441 @retval -1 The VTd engine is not found.
442 **/
443 UINTN
444 GetVTdEngineFromDevScopeEntry (
445 IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable,
446 IN UINT16 Segment,
447 IN EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DevScopeEntry
448 )
449 {
450 EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
451 UINTN VtdIndex;
452 EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd;
453 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *ThisDevScopeEntry;
454
455 VtdIndex = 0;
456 DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)(AcpiDmarTable + 1));
457 while ((UINTN)DmarHeader < (UINTN)AcpiDmarTable + AcpiDmarTable->Header.Length) {
458 switch (DmarHeader->Type) {
459 case EFI_ACPI_DMAR_TYPE_DRHD:
460 DmarDrhd = (EFI_ACPI_DMAR_DRHD_HEADER *)DmarHeader;
461 if (DmarDrhd->SegmentNumber != Segment) {
462 // Mismatch
463 break;
464 }
465 if ((DmarDrhd->Header.Length == sizeof(EFI_ACPI_DMAR_DRHD_HEADER)) ||
466 ((DmarDrhd->Flags & EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL) != 0)) {
467 // No DevScopeEntry
468 // Do not handle PCI_ALL
469 break;
470 }
471 ThisDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)(DmarDrhd + 1));
472 while ((UINTN)ThisDevScopeEntry < (UINTN)DmarDrhd + DmarDrhd->Header.Length) {
473 if ((ThisDevScopeEntry->Length == DevScopeEntry->Length) &&
474 (CompareMem (ThisDevScopeEntry, DevScopeEntry, DevScopeEntry->Length) == 0)) {
475 return VtdIndex;
476 }
477 ThisDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)ThisDevScopeEntry + ThisDevScopeEntry->Length);
478 }
479 break;
480 default:
481 break;
482 }
483 DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)DmarHeader + DmarHeader->Length);
484 }
485 return (UINTN)-1;
486 }
487
488 /**
489 Process DMAR RMRR table.
490
491 @param[in] VTdInfo The VTd engine context information.
492 @param[in] DmarRmrr The RMRR table.
493 **/
494 VOID
495 ProcessRmrr (
496 IN VTD_INFO *VTdInfo,
497 IN EFI_ACPI_DMAR_RMRR_HEADER *DmarRmrr
498 )
499 {
500 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDevScopeEntry;
501 UINTN VTdIndex;
502 UINT64 RmrrMask;
503 UINTN LowBottom;
504 UINTN LowTop;
505 UINTN HighBottom;
506 UINT64 HighTop;
507 EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
508
509 AcpiDmarTable = VTdInfo->AcpiDmarTable;
510
511 DEBUG ((DEBUG_INFO," RMRR (Base 0x%016lx, Limit 0x%016lx)\n", DmarRmrr->ReservedMemoryRegionBaseAddress, DmarRmrr->ReservedMemoryRegionLimitAddress));
512
513 if ((DmarRmrr->ReservedMemoryRegionBaseAddress == 0) ||
514 (DmarRmrr->ReservedMemoryRegionLimitAddress == 0)) {
515 return ;
516 }
517
518 DmarDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)(DmarRmrr + 1));
519 while ((UINTN)DmarDevScopeEntry < (UINTN)DmarRmrr + DmarRmrr->Header.Length) {
520 ASSERT (DmarDevScopeEntry->Type == EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT);
521
522 VTdIndex = GetVTdEngineFromDevScopeEntry (AcpiDmarTable, DmarRmrr->SegmentNumber, DmarDevScopeEntry);
523 if (VTdIndex != (UINTN)-1) {
524 RmrrMask = LShiftU64 (1, VTdIndex);
525
526 LowBottom = 0;
527 LowTop = (UINTN)DmarRmrr->ReservedMemoryRegionBaseAddress;
528 HighBottom = (UINTN)DmarRmrr->ReservedMemoryRegionLimitAddress + 1;
529 HighTop = LShiftU64 (1, VTdInfo->HostAddressWidth + 1);
530
531 SetDmaProtectedRange (
532 VTdInfo,
533 RmrrMask,
534 0,
535 (UINT32)(LowTop - LowBottom),
536 HighBottom,
537 HighTop - HighBottom
538 );
539
540 //
541 // Remove the engine from the engine mask.
542 // The assumption is that any other PEI driver does not access
543 // the device covered by this engine.
544 //
545 VTdInfo->EngineMask = VTdInfo->EngineMask & (~RmrrMask);
546 }
547
548 DmarDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)DmarDevScopeEntry + DmarDevScopeEntry->Length);
549 }
550 }
551
552 /**
553 Parse DMAR DRHD table.
554
555 @param[in] VTdInfo The VTd engine context information.
556 **/
557 VOID
558 ParseDmarAcpiTableRmrr (
559 IN VTD_INFO *VTdInfo
560 )
561 {
562 EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
563 EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
564
565 AcpiDmarTable = VTdInfo->AcpiDmarTable;
566
567 DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)(AcpiDmarTable + 1));
568 while ((UINTN)DmarHeader < (UINTN)AcpiDmarTable + AcpiDmarTable->Header.Length) {
569 switch (DmarHeader->Type) {
570 case EFI_ACPI_DMAR_TYPE_RMRR:
571 ProcessRmrr (VTdInfo, (EFI_ACPI_DMAR_RMRR_HEADER *)DmarHeader);
572 break;
573 default:
574 break;
575 }
576 DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)DmarHeader + DmarHeader->Length);
577 }
578 }