]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c
SecurityPkg: Apply uncrustify changes
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / Parsers / Srat / SratParser.c
CommitLineData
a6eaba4d 1/** @file\r
ee4dc24f
RN
2 SRAT table parser\r
3\r
b8504826 4 Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.\r
56ba3746 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
ee4dc24f
RN
6\r
7 @par Reference(s):\r
710ff749 8 - ACPI 6.3 Specification - January 2019\r
ee4dc24f
RN
9**/\r
10\r
11#include <IndustryStandard/Acpi.h>\r
12#include <Library/PrintLib.h>\r
13#include <Library/UefiLib.h>\r
14#include "AcpiParser.h"\r
15#include "AcpiTableParser.h"\r
e18ac66d 16#include "AcpiViewConfig.h"\r
ee4dc24f
RN
17\r
18// Local Variables\r
19STATIC CONST UINT8* SratRAType;\r
20STATIC CONST UINT8* SratRALength;\r
710ff749 21STATIC CONST UINT8* SratDeviceHandleType;\r
ee4dc24f
RN
22STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;\r
23\r
a6eaba4d
DB
24/**\r
25 This function validates the Reserved field in the SRAT table header.\r
ee4dc24f
RN
26\r
27 @param [in] Ptr Pointer to the start of the field data.\r
28 @param [in] Context Pointer to context specific information e.g. this\r
29 could be a pointer to the ACPI table header.\r
a6eaba4d 30**/\r
ee4dc24f
RN
31STATIC\r
32VOID\r
33EFIAPI\r
34ValidateSratReserved (\r
35 IN UINT8* Ptr,\r
36 IN VOID* Context\r
527a3685
KK
37 )\r
38{\r
39 if (*(UINT32*)Ptr != 1) {\r
40 IncrementErrorCount ();\r
41 Print (L"\nERROR: Reserved should be 1 for backward compatibility.\n");\r
42 }\r
43}\r
ee4dc24f 44\r
710ff749
KK
45/**\r
46 This function validates the Device Handle Type field in the Generic Initiator\r
47 Affinity Structure.\r
48\r
49 @param [in] Ptr Pointer to the start of the field data.\r
50 @param [in] Context Pointer to context specific information e.g. this\r
51 could be a pointer to the ACPI table header.\r
52**/\r
53STATIC\r
54VOID\r
55EFIAPI\r
56ValidateSratDeviceHandleType (\r
57 IN UINT8* Ptr,\r
58 IN VOID* Context\r
59 )\r
60{\r
61 UINT8 DeviceHandleType;\r
62\r
63 DeviceHandleType = *Ptr;\r
64\r
65 if (DeviceHandleType > EFI_ACPI_6_3_PCI_DEVICE_HANDLE) {\r
66 IncrementErrorCount ();\r
67 Print (\r
68 L"\nERROR: Invalid Device Handle Type: %d. Must be between 0 and %d.",\r
69 DeviceHandleType,\r
70 EFI_ACPI_6_3_PCI_DEVICE_HANDLE\r
71 );\r
72 }\r
73}\r
74\r
75/**\r
76 This function traces the PCI BDF Number field inside Device Handle - PCI\r
77\r
78 @param [in] Format Format string for tracing the data.\r
79 @param [in] Ptr Pointer to the start of the buffer.\r
80**/\r
81STATIC\r
82VOID\r
83EFIAPI\r
84DumpSratPciBdfNumber (\r
85 IN CONST CHAR16* Format,\r
86 IN UINT8* Ptr\r
87 )\r
88{\r
89 CHAR16 Buffer[OUTPUT_FIELD_COLUMN_WIDTH];\r
90\r
91 Print (L"\n");\r
92\r
93 /*\r
94 The PCI BDF Number subfields are printed in the order specified in the ACPI\r
95 specification. The format of the 16-bit PCI BDF Number field is as follows:\r
96\r
97 +-----+------+------+\r
98 |DEV | FUNC | BUS |\r
99 +-----+------+------+\r
100 |15:11| 10:8 | 7:0 |\r
101 +-----+------+------+\r
102 */\r
103\r
104 // Print PCI Bus Number (Bits 7:0 of Byte 2)\r
105 UnicodeSPrint (\r
106 Buffer,\r
107 sizeof (Buffer),\r
108 L"PCI Bus Number"\r
109 );\r
110 PrintFieldName (4, Buffer);\r
111 Print (\r
112 L"0x%x\n",\r
113 *Ptr\r
114 );\r
115\r
116 Ptr++;\r
117\r
118 // Print PCI Device Number (Bits 7:3 of Byte 3)\r
119 UnicodeSPrint (\r
120 Buffer,\r
121 sizeof (Buffer),\r
122 L"PCI Device Number"\r
123 );\r
124 PrintFieldName (4, Buffer);\r
125 Print (\r
126 L"0x%x\n",\r
127 (*Ptr & (BIT7 | BIT6 | BIT5 | BIT4 | BIT3)) >> 3\r
128 );\r
129\r
130 // PCI Function Number (Bits 2:0 of Byte 3)\r
131 UnicodeSPrint (\r
132 Buffer,\r
133 sizeof (Buffer),\r
134 L"PCI Function Number"\r
135 );\r
136 PrintFieldName (4, Buffer);\r
137 Print (\r
138 L"0x%x\n",\r
139 *Ptr & (BIT2 | BIT1 | BIT0)\r
140 );\r
141}\r
142\r
143/**\r
144 An ACPI_PARSER array describing the Device Handle - ACPI\r
145**/\r
146STATIC CONST ACPI_PARSER SratDeviceHandleAcpiParser[] = {\r
147 {L"ACPI_HID", 8, 0, L"0x%lx", NULL, NULL, NULL, NULL},\r
148 {L"ACPI_UID", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},\r
149 {L"Reserved", 4, 12, L"0x%x", NULL, NULL, NULL, NULL}\r
150};\r
151\r
152/**\r
153 An ACPI_PARSER array describing the Device Handle - PCI\r
154**/\r
155STATIC CONST ACPI_PARSER SratDeviceHandlePciParser[] = {\r
156 {L"PCI Segment", 2, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
157 {L"PCI BDF Number", 2, 2, NULL, DumpSratPciBdfNumber, NULL, NULL, NULL},\r
158 {L"Reserved", 12, 4, L"%x %x %x %x - %x %x %x %x - %x %x %x %x", Dump12Chars,\r
159 NULL, NULL, NULL}\r
160};\r
161\r
162/**\r
163 This function traces the Device Handle field inside Generic Initiator\r
164 Affinity Structure.\r
165\r
166 @param [in] Format Format string for tracing the data.\r
167 @param [in] Ptr Pointer to the start of the buffer.\r
168**/\r
169STATIC\r
170VOID\r
171EFIAPI\r
172DumpSratDeviceHandle (\r
173 IN CONST CHAR16* Format,\r
174 IN UINT8* Ptr\r
175 )\r
176{\r
177 if (SratDeviceHandleType == NULL) {\r
178 IncrementErrorCount ();\r
179 Print (L"\nERROR: Device Handle Type read incorrectly.\n");\r
180 return;\r
181 }\r
182\r
183 Print (L"\n");\r
184\r
185 if (*SratDeviceHandleType == EFI_ACPI_6_3_ACPI_DEVICE_HANDLE) {\r
186 ParseAcpi (\r
187 TRUE,\r
188 2,\r
189 NULL,\r
190 Ptr,\r
191 sizeof (EFI_ACPI_6_3_DEVICE_HANDLE_ACPI),\r
192 PARSER_PARAMS (SratDeviceHandleAcpiParser)\r
193 );\r
194 } else if (*SratDeviceHandleType == EFI_ACPI_6_3_PCI_DEVICE_HANDLE) {\r
195 ParseAcpi (\r
196 TRUE,\r
197 2,\r
198 NULL,\r
199 Ptr,\r
200 sizeof (EFI_ACPI_6_3_DEVICE_HANDLE_PCI),\r
201 PARSER_PARAMS (SratDeviceHandlePciParser)\r
202 );\r
203 }\r
204}\r
205\r
a6eaba4d
DB
206/**\r
207 This function traces the APIC Proximity Domain field.\r
ee4dc24f
RN
208\r
209 @param [in] Format Format string for tracing the data.\r
210 @param [in] Ptr Pointer to the start of the buffer.\r
a6eaba4d 211**/\r
ee4dc24f
RN
212STATIC\r
213VOID\r
7343bc80 214EFIAPI\r
ee4dc24f 215DumpSratApicProximity (\r
527a3685
KK
216 IN CONST CHAR16* Format,\r
217 IN UINT8* Ptr\r
218 )\r
219{\r
220 UINT32 ProximityDomain;\r
221\r
222 ProximityDomain = Ptr[0] | (Ptr[1] << 8) | (Ptr[2] << 16);\r
223\r
224 Print (Format, ProximityDomain);\r
225}\r
ee4dc24f 226\r
a6eaba4d
DB
227/**\r
228 An ACPI_PARSER array describing the SRAT Table.\r
229**/\r
ee4dc24f
RN
230STATIC CONST ACPI_PARSER SratParser[] = {\r
231 PARSE_ACPI_HEADER (&AcpiHdrInfo),\r
232 {L"Reserved", 4, 36, L"0x%x", NULL, NULL, ValidateSratReserved, NULL},\r
233 {L"Reserved", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL}\r
234};\r
235\r
a6eaba4d
DB
236/**\r
237 An ACPI_PARSER array describing the Resource Allocation structure header.\r
238**/\r
ee4dc24f
RN
239STATIC CONST ACPI_PARSER SratResourceAllocationParser[] = {\r
240 {L"Type", 1, 0, NULL, NULL, (VOID**)&SratRAType, NULL, NULL},\r
241 {L"Length", 1, 1, NULL, NULL, (VOID**)&SratRALength, NULL, NULL}\r
242};\r
243\r
a6eaba4d
DB
244/**\r
245 An ACPI_PARSER array describing the GICC Affinity structure.\r
246**/\r
ee4dc24f
RN
247STATIC CONST ACPI_PARSER SratGicCAffinityParser[] = {\r
248 {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
249 {L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},\r
250\r
251 {L"Proximity Domain", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},\r
252 {L"ACPI Processor UID", 4, 6, L"0x%x", NULL, NULL, NULL, NULL},\r
253 {L"Flags", 4, 10, L"0x%x", NULL, NULL, NULL, NULL},\r
254 {L"Clock Domain", 4, 14, L"0x%x", NULL, NULL, NULL, NULL}\r
255};\r
256\r
a6eaba4d
DB
257/**\r
258 An ACPI_PARSER array describing the GIC ITS Affinity structure.\r
259**/\r
ee4dc24f
RN
260STATIC CONST ACPI_PARSER SratGicITSAffinityParser[] = {\r
261 {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
262 {L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},\r
263\r
264 {L"Proximity Domain", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},\r
265 {L"Reserved", 2, 6, L"0x%x", NULL, NULL, NULL, NULL},\r
266 {L"ITS Id", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},\r
267};\r
268\r
710ff749
KK
269/**\r
270 An ACPI_PARSER array describing the Generic Initiator Affinity Structure\r
271**/\r
272STATIC CONST ACPI_PARSER SratGenericInitiatorAffinityParser[] = {\r
273 {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
274 {L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},\r
275\r
276 {L"Reserved", 1, 2, L"0x%x", NULL, NULL, NULL, NULL},\r
277 {L"Device Handle Type", 1, 3, L"%d", NULL, (VOID**)&SratDeviceHandleType,\r
278 ValidateSratDeviceHandleType, NULL},\r
279 {L"Proximity Domain", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},\r
280 {L"Device Handle", 16, 8, L"%s", DumpSratDeviceHandle, NULL, NULL, NULL},\r
281 {L"Flags", 4, 24, L"0x%x", NULL, NULL, NULL, NULL},\r
282 {L"Reserved", 4, 28, L"0x%x", NULL, NULL, NULL, NULL}\r
283};\r
284\r
a6eaba4d
DB
285/**\r
286 An ACPI_PARSER array describing the Memory Affinity structure.\r
287**/\r
ee4dc24f
RN
288STATIC CONST ACPI_PARSER SratMemAffinityParser[] = {\r
289 {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
290 {L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},\r
291\r
292 {L"Proximity Domain", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},\r
293 {L"Reserved", 2, 6, L"0x%x", NULL, NULL, NULL, NULL},\r
294 {L"Base Address Low", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},\r
295 {L"Base Address High", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},\r
296 {L"Length Low", 4, 16, L"0x%x", NULL, NULL, NULL, NULL},\r
297 {L"Length High", 4, 20, L"0x%x", NULL, NULL, NULL, NULL},\r
298 {L"Reserved", 4, 24, L"0x%x", NULL, NULL, NULL, NULL},\r
299 {L"Flags", 4, 28, L"0x%x", NULL, NULL, NULL, NULL},\r
300 {L"Reserved", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL}\r
301};\r
302\r
a6eaba4d
DB
303/**\r
304 An ACPI_PARSER array describing the APIC/SAPIC Affinity structure.\r
305**/\r
ee4dc24f
RN
306STATIC CONST ACPI_PARSER SratApciSapicAffinityParser[] = {\r
307 {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
308 {L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},\r
309\r
310 {L"Proximity Domain [7:0]", 1, 2, L"0x%x", NULL, NULL, NULL, NULL},\r
311 {L"APIC ID", 1, 3, L"0x%x", NULL, NULL, NULL, NULL},\r
312 {L"Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},\r
313 {L"Local SAPIC EID", 1, 8, L"0x%x", NULL, NULL, NULL, NULL},\r
314 {L"Proximity Domain [31:8]", 3, 9, L"0x%x", DumpSratApicProximity,\r
315 NULL, NULL, NULL},\r
316 {L"Clock Domain", 4, 12, L"0x%x", NULL, NULL, NULL, NULL}\r
317};\r
318\r
a6eaba4d
DB
319/**\r
320 An ACPI_PARSER array describing the Processor Local x2APIC Affinity structure.\r
321**/\r
ee4dc24f
RN
322STATIC CONST ACPI_PARSER SratX2ApciAffinityParser[] = {\r
323 {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
324 {L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},\r
325\r
326 {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},\r
327 {L"Proximity Domain", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},\r
328 {L"X2APIC ID", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},\r
329 {L"Flags", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},\r
330 {L"Clock Domain", 4, 16, L"0x%x", NULL, NULL, NULL, NULL},\r
331 {L"Reserved", 4, 20, L"0x%x", NULL, NULL, NULL, NULL}\r
332};\r
333\r
a6eaba4d
DB
334/**\r
335 This function parses the ACPI SRAT table.\r
ee4dc24f
RN
336 When trace is enabled this function parses the SRAT table and\r
337 traces the ACPI table fields.\r
338\r
339 This function parses the following Resource Allocation Structures:\r
340 - Processor Local APIC/SAPIC Affinity Structure\r
341 - Memory Affinity Structure\r
342 - Processor Local x2APIC Affinity Structure\r
343 - GICC Affinity Structure\r
344\r
345 This function also performs validation of the ACPI table fields.\r
346\r
347 @param [in] Trace If TRUE, trace the ACPI fields.\r
348 @param [in] Ptr Pointer to the start of the buffer.\r
349 @param [in] AcpiTableLength Length of the ACPI table.\r
350 @param [in] AcpiTableRevision Revision of the ACPI table.\r
a6eaba4d 351**/\r
ee4dc24f
RN
352VOID\r
353EFIAPI\r
354ParseAcpiSrat (\r
355 IN BOOLEAN Trace,\r
356 IN UINT8* Ptr,\r
357 IN UINT32 AcpiTableLength,\r
358 IN UINT8 AcpiTableRevision\r
359 )\r
360{\r
361 UINT32 Offset;\r
362 UINT8* ResourcePtr;\r
f75c7478
DB
363 UINT32 GicCAffinityIndex;\r
364 UINT32 GicITSAffinityIndex;\r
710ff749 365 UINT32 GenericInitiatorAffinityIndex;\r
f75c7478
DB
366 UINT32 MemoryAffinityIndex;\r
367 UINT32 ApicSapicAffinityIndex;\r
368 UINT32 X2ApicAffinityIndex;\r
ee4dc24f
RN
369 CHAR8 Buffer[80]; // Used for AsciiName param of ParseAcpi\r
370\r
f75c7478
DB
371 GicCAffinityIndex = 0;\r
372 GicITSAffinityIndex = 0;\r
710ff749 373 GenericInitiatorAffinityIndex = 0;\r
f75c7478
DB
374 MemoryAffinityIndex = 0;\r
375 ApicSapicAffinityIndex = 0;\r
376 X2ApicAffinityIndex = 0;\r
377\r
ee4dc24f
RN
378 if (!Trace) {\r
379 return;\r
380 }\r
381\r
382 Offset = ParseAcpi (\r
383 TRUE,\r
384 0,\r
385 "SRAT",\r
386 Ptr,\r
387 AcpiTableLength,\r
388 PARSER_PARAMS (SratParser)\r
389 );\r
748c1efd 390\r
ee4dc24f
RN
391 ResourcePtr = Ptr + Offset;\r
392\r
393 while (Offset < AcpiTableLength) {\r
394 ParseAcpi (\r
395 FALSE,\r
396 0,\r
397 NULL,\r
398 ResourcePtr,\r
48d5d6d5 399 AcpiTableLength - Offset,\r
ee4dc24f
RN
400 PARSER_PARAMS (SratResourceAllocationParser)\r
401 );\r
402\r
ce7b77a7
KK
403 // Check if the values used to control the parsing logic have been\r
404 // successfully read.\r
405 if ((SratRAType == NULL) ||\r
406 (SratRALength == NULL)) {\r
407 IncrementErrorCount ();\r
408 Print (\r
409 L"ERROR: Insufficient remaining table buffer length to read the " \\r
410 L"Static Resource Allocation structure header. Length = %d.\n",\r
411 AcpiTableLength - Offset\r
412 );\r
413 return;\r
414 }\r
415\r
b8504826
KK
416 // Validate Static Resource Allocation Structure length\r
417 if ((*SratRALength == 0) ||\r
418 ((Offset + (*SratRALength)) > AcpiTableLength)) {\r
48d5d6d5
KK
419 IncrementErrorCount ();\r
420 Print (\r
b8504826
KK
421 L"ERROR: Invalid Static Resource Allocation Structure length. " \\r
422 L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",\r
48d5d6d5 423 *SratRALength,\r
b8504826
KK
424 Offset,\r
425 AcpiTableLength\r
48d5d6d5
KK
426 );\r
427 return;\r
428 }\r
429\r
ee4dc24f 430 switch (*SratRAType) {\r
710ff749 431 case EFI_ACPI_6_3_GICC_AFFINITY:\r
ee4dc24f
RN
432 AsciiSPrint (\r
433 Buffer,\r
434 sizeof (Buffer),\r
435 "GICC Affinity Structure [%d]",\r
436 GicCAffinityIndex++\r
437 );\r
438 ParseAcpi (\r
439 TRUE,\r
440 2,\r
441 Buffer,\r
442 ResourcePtr,\r
443 *SratRALength,\r
444 PARSER_PARAMS (SratGicCAffinityParser)\r
445 );\r
446 break;\r
447\r
710ff749 448 case EFI_ACPI_6_3_GIC_ITS_AFFINITY:\r
ee4dc24f
RN
449 AsciiSPrint (\r
450 Buffer,\r
451 sizeof (Buffer),\r
452 "GIC ITS Affinity Structure [%d]",\r
453 GicITSAffinityIndex++\r
454 );\r
455 ParseAcpi (\r
456 TRUE,\r
457 2,\r
458 Buffer,\r
459 ResourcePtr,\r
460 *SratRALength,\r
461 PARSER_PARAMS (SratGicITSAffinityParser)\r
748c1efd 462 );\r
ee4dc24f
RN
463 break;\r
464\r
710ff749
KK
465 case EFI_ACPI_6_3_GENERIC_INITIATOR_AFFINITY:\r
466 AsciiSPrint (\r
467 Buffer,\r
468 sizeof (Buffer),\r
469 "Generic Initiator Affinity Structure [%d]",\r
470 GenericInitiatorAffinityIndex++\r
471 );\r
472 ParseAcpi (\r
473 TRUE,\r
474 2,\r
475 Buffer,\r
476 ResourcePtr,\r
477 *SratRALength,\r
478 PARSER_PARAMS (SratGenericInitiatorAffinityParser)\r
479 );\r
480 break;\r
481\r
482 case EFI_ACPI_6_3_MEMORY_AFFINITY:\r
ee4dc24f
RN
483 AsciiSPrint (\r
484 Buffer,\r
485 sizeof (Buffer),\r
486 "Memory Affinity Structure [%d]",\r
487 MemoryAffinityIndex++\r
488 );\r
489 ParseAcpi (\r
490 TRUE,\r
491 2,\r
492 Buffer,\r
493 ResourcePtr,\r
494 *SratRALength,\r
495 PARSER_PARAMS (SratMemAffinityParser)\r
496 );\r
497 break;\r
498\r
710ff749 499 case EFI_ACPI_6_3_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY:\r
ee4dc24f
RN
500 AsciiSPrint (\r
501 Buffer,\r
502 sizeof (Buffer),\r
503 "APIC/SAPIC Affinity Structure [%d]",\r
504 ApicSapicAffinityIndex++\r
505 );\r
506 ParseAcpi (\r
507 TRUE,\r
508 2,\r
509 Buffer,\r
510 ResourcePtr,\r
511 *SratRALength,\r
512 PARSER_PARAMS (SratApciSapicAffinityParser)\r
513 );\r
514 break;\r
515\r
710ff749 516 case EFI_ACPI_6_3_PROCESSOR_LOCAL_X2APIC_AFFINITY:\r
ee4dc24f
RN
517 AsciiSPrint (\r
518 Buffer,\r
519 sizeof (Buffer),\r
520 "X2APIC Affinity Structure [%d]",\r
521 X2ApicAffinityIndex++\r
522 );\r
523 ParseAcpi (\r
524 TRUE,\r
525 2,\r
526 Buffer,\r
527 ResourcePtr,\r
528 *SratRALength,\r
529 PARSER_PARAMS (SratX2ApciAffinityParser)\r
530 );\r
531 break;\r
532\r
533 default:\r
534 IncrementErrorCount ();\r
535 Print (L"ERROR: Unknown SRAT Affinity type = 0x%x\n", *SratRAType);\r
536 break;\r
537 }\r
538\r
539 ResourcePtr += (*SratRALength);\r
540 Offset += (*SratRALength);\r
541 }\r
542}\r