]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c
ShellPkg: Apply uncrustify changes
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / Parsers / Pcct / PcctParser.c
1 /** @file
2 PCCT table parser
3
4 Copyright (c) 2021, Arm Limited.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 @par Reference(s):
8 - ACPI 6.4 Specification - January 2021
9 **/
10
11 #include <Library/BaseMemoryLib.h>
12 #include <Library/PrintLib.h>
13 #include <Library/UefiLib.h>
14 #include "AcpiParser.h"
15 #include "AcpiView.h"
16 #include "AcpiViewConfig.h"
17 #include "PcctParser.h"
18
19 // Local variables
20 STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
21
22 STATIC UINT32 *PccGlobalFlags;
23 STATIC UINT8 *PccSubspaceLength;
24 STATIC UINT8 *PccSubspaceType;
25 STATIC UINT8 *ExtendedPccSubspaceInterruptFlags;
26
27 /**
28 This function validates the length coded on 4 bytes of a shared memory range
29
30 @param [in] Ptr Pointer to the start of the field data.
31 @param [in] Context Pointer to context specific information e.g. this
32 could be a pointer to the ACPI table header.
33 **/
34 STATIC
35 VOID
36 EFIAPI
37 ValidateRangeLength4 (
38 IN UINT8 *Ptr,
39 IN VOID *Context
40 )
41 {
42 if (*(UINT32 *)Ptr < MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN) {
43 IncrementErrorCount ();
44 Print (
45 L"\nError: Shared memory range length is too short.\n"
46 L"Length is %u when it should be greater than or equal to %u",
47 *(UINT32 *)Ptr,
48 MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN
49 );
50 }
51 }
52
53 /**
54 This function validates the length coded on 8 bytes of a shared memory range
55
56 @param [in] Ptr Pointer to the start of the field data.
57 @param [in] Context Pointer to context specific information e.g. this
58 could be a pointer to the ACPI table header.
59 **/
60 STATIC
61 VOID
62 EFIAPI
63 ValidateRangeLength8 (
64 IN UINT8 *Ptr,
65 IN VOID *Context
66 )
67 {
68 if (*(UINT64 *)Ptr <= MIN_MEMORY_RANGE_LENGTH) {
69 IncrementErrorCount ();
70 Print (
71 L"\nError: Shared memory range length is too short.\n"
72 L"Length is %u when it should be greater than %u",
73 *(UINT64 *)Ptr,
74 MIN_MEMORY_RANGE_LENGTH
75 );
76 }
77 }
78
79 /**
80 This function validates address space for Memory/IO GAS.
81
82 @param [in] Ptr Pointer to the start of the field data.
83 @param [in] Context Pointer to context specific information e.g. this
84 could be a pointer to the ACPI table header.
85 **/
86 STATIC
87 VOID
88 EFIAPI
89 ValidatePccMemoryIoGas (
90 IN UINT8 *Ptr,
91 IN VOID *Context
92 )
93 {
94 switch (*(UINT8 *)Ptr) {
95 #if !(defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
96 case EFI_ACPI_6_4_SYSTEM_IO:
97 #endif //if not (defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
98 case EFI_ACPI_6_4_SYSTEM_MEMORY:
99 return;
100 default:
101 IncrementErrorCount ();
102 Print (L"\nError: Invalid address space");
103 }
104 }
105
106 /**
107 This function validates address space for structures of types other than 0.
108
109 @param [in] Ptr Pointer to the start of the field data.
110 @param [in] Context Pointer to context specific information e.g. this
111 could be a pointer to the ACPI table header.
112 **/
113 STATIC
114 VOID
115 EFIAPI
116 ValidatePccGas (
117 IN UINT8 *Ptr,
118 IN VOID *Context
119 )
120 {
121 switch (*(UINT8 *)Ptr) {
122 #if !(defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
123 case EFI_ACPI_6_4_SYSTEM_IO:
124 #endif //if not (defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
125 case EFI_ACPI_6_4_FUNCTIONAL_FIXED_HARDWARE:
126 case EFI_ACPI_6_4_SYSTEM_MEMORY:
127 return;
128 default:
129 IncrementErrorCount ();
130 Print (L"\nError: Invalid address space");
131 }
132 }
133
134 /**
135 This function validates doorbell address space for type 4 structure.
136
137 @param [in] Ptr Pointer to the start of the field data.
138 @param [in] Context Pointer to context specific information e.g. this
139 could be a pointer to the ACPI table header.
140 **/
141 STATIC
142 VOID
143 EFIAPI
144 ValidatePccDoorbellGas (
145 IN UINT8 *Ptr,
146 IN VOID *Context
147 )
148 {
149 // For slave subspaces this field is optional, if not present the field
150 // should just contain zeros.
151 if (*PccSubspaceType == EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC) {
152 if (IsZeroBuffer (
153 Ptr,
154 sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE)
155 ))
156 {
157 return;
158 }
159 }
160
161 ValidatePccGas (Ptr, Context);
162 }
163
164 /**
165 This function validates interrupt acknowledge address space for
166 type 4 structure.
167
168 @param [in] Ptr Pointer to the start of the field data.
169 @param [in] Context Pointer to context specific information e.g. this
170 could be a pointer to the ACPI table header.
171 **/
172 STATIC
173 VOID
174 EFIAPI
175 ValidatePccIntAckGas (
176 IN UINT8 *Ptr,
177 IN VOID *Context
178 )
179 {
180 // If the subspace does not support interrupts or the interrupt is
181 // edge driven the register may be omitted. A value of 0x0 on all
182 // 12 bytes of the GAS structure indicates the register is not
183 // present.
184 if (((*PccGlobalFlags & EFI_ACPI_6_4_PCCT_FLAGS_PLATFORM_INTERRUPT) !=
185 EFI_ACPI_6_4_PCCT_FLAGS_PLATFORM_INTERRUPT) ||
186 ((*ExtendedPccSubspaceInterruptFlags &
187 EFI_ACPI_6_4_PCCT_SUBSPACE_PLATFORM_INTERRUPT_FLAGS_MODE) ==
188 EFI_ACPI_6_4_PCCT_SUBSPACE_PLATFORM_INTERRUPT_FLAGS_MODE))
189 {
190 if (IsZeroBuffer (
191 Ptr,
192 sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE)
193 ))
194 {
195 return;
196 }
197 }
198
199 ValidatePccGas (Ptr, Context);
200 }
201
202 /**
203 This function validates error status address space for type 4 structure.
204
205 @param [in] Ptr Pointer to the start of the field data.
206 @param [in] Context Pointer to context specific information e.g. this
207 could be a pointer to the ACPI table header.
208 **/
209 STATIC
210 VOID
211 EFIAPI
212 ValidatePccErrStatusGas (
213 IN UINT8 *Ptr,
214 IN VOID *Context
215 )
216 {
217 // This field is ignored by the OSPM on slave channels.
218 if (*PccSubspaceType == EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC) {
219 return;
220 }
221
222 ValidatePccGas (Ptr, Context);
223 }
224
225 /**
226 This function validates platform interrupt flags for type 4 structure.
227
228 @param [in] Ptr Pointer to the start of the field data.
229 @param [in] Context Pointer to context specific information e.g. this
230 could be a pointer to the ACPI table header.
231 **/
232 STATIC
233 VOID
234 EFIAPI
235 ValidatePlatInterrupt (
236 IN UINT8 *Ptr,
237 IN VOID *Context
238 )
239 {
240 // If a slave subspace is present in the PCCT, then the global Platform
241 // Interrupt flag must be set to 1.
242 if ((*PccSubspaceType == EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC) &&
243 ((*PccGlobalFlags & EFI_ACPI_6_4_PCCT_FLAGS_PLATFORM_INTERRUPT) !=
244 EFI_ACPI_6_4_PCCT_FLAGS_PLATFORM_INTERRUPT))
245 {
246 IncrementErrorCount ();
247 Print (
248 L"\nError: Global Platform interrupt flag must be set to 1" \
249 L" if a PCC type 4 structure is present in PCCT."
250 );
251 }
252 }
253
254 /**
255 An ACPI_PARSER array describing the ACPI PCCT Table.
256 */
257 STATIC CONST ACPI_PARSER PcctParser[] = {
258 PARSE_ACPI_HEADER (&AcpiHdrInfo),
259 { L"Flags", 4, 36, NULL, NULL, (VOID **)&PccGlobalFlags, NULL, NULL },
260 { L"Reserved", 8, 40, NULL, NULL, NULL, NULL, NULL }
261 };
262
263 /**
264 An ACPI_PARSER array describing the platform communications channel subspace
265 structure header.
266 */
267 STATIC CONST ACPI_PARSER PccSubspaceHeaderParser[] = {
268 PCC_SUBSPACE_HEADER ()
269 // ... Type Specific Fields ...
270 };
271
272 /**
273 An ACPI_PARSER array describing the Generic Communications Subspace - Type 0
274 */
275 STATIC CONST ACPI_PARSER PccSubspaceType0Parser[] = {
276 PCC_SUBSPACE_HEADER (),
277 { L"Reserved", 6, 2, L"%x %x %x %x %x %x", Dump6Chars, NULL, NULL, NULL },
278 { L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL },
279 { L"Memory Range Length",8, 16, L"0x%lx", NULL, NULL, ValidateRangeLength8,
280 NULL },
281 { L"Doorbell Register",12, 24, NULL, DumpGas, NULL, ValidatePccMemoryIoGas,
282 NULL },
283 { L"Doorbell Preserve",8, 36, L"0x%lx", NULL, NULL, NULL, NULL },
284 { L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL },
285 { L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL },
286 { L"Maximum Periodic Access Rate",4, 56, L"%u", NULL, NULL, NULL, NULL },
287 { L"Minimum Request Turnaround Time",2, 60, L"%u", NULL, NULL, NULL, NULL }
288 };
289
290 /**
291 An ACPI_PARSER array describing the HW-Reduced Communications Subspace
292 - Type 1
293 */
294 STATIC CONST ACPI_PARSER PccSubspaceType1Parser[] = {
295 PCC_SUBSPACE_HEADER (),
296 { L"Platform Interrupt",4, 2, L"0x%x", NULL, NULL, NULL, NULL },
297 { L"Platform Interrupt Flags",1, 6, L"0x%x", NULL, NULL, NULL, NULL },
298 { L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL },
299 { L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL },
300 { L"Memory Range Length",8, 16, L"0x%lx", NULL, NULL, ValidateRangeLength8,
301 NULL },
302 { L"Doorbell Register",12, 24, NULL, DumpGas, NULL,
303 ValidatePccGas, NULL },
304 { L"Doorbell Preserve",8, 36, L"0x%lx", NULL, NULL, NULL, NULL },
305 { L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL },
306 { L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL },
307 { L"Maximum Periodic Access Rate",4, 56, L"%u", NULL, NULL, NULL, NULL },
308 { L"Minimum Request Turnaround Time",2, 60, L"%u", NULL, NULL, NULL, NULL }
309 };
310
311 /**
312 An ACPI_PARSER array describing the HW-Reduced Communications Subspace
313 - Type 2
314 */
315 STATIC CONST ACPI_PARSER PccSubspaceType2Parser[] = {
316 PCC_SUBSPACE_HEADER (),
317 { L"Platform Interrupt",4, 2, L"0x%x", NULL, NULL, NULL, NULL },
318 { L"Platform Interrupt Flags",1, 6, L"0x%x", NULL, NULL, NULL, NULL },
319 { L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL },
320 { L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL },
321 { L"Memory Range Length",8, 16, L"0x%lx", NULL, NULL, ValidateRangeLength8,
322 NULL },
323 { L"Doorbell Register",12, 24, NULL, DumpGas, NULL,
324 ValidatePccGas, NULL },
325 { L"Doorbell Preserve",8, 36, L"0x%lx", NULL, NULL, NULL, NULL },
326 { L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL },
327 { L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL },
328 { L"Maximum Periodic Access Rate",4, 56, L"%u", NULL, NULL, NULL, NULL },
329 { L"Minimum Request Turnaround Time",2, 60, L"%u", NULL, NULL, NULL, NULL },
330 { L"Platform Interrupt Ack Register",12, 62, NULL, DumpGas, NULL,
331 ValidatePccGas, NULL },
332 { L"Platform Interrupt Ack Preserve",8, 74, L"0x%lx", NULL, NULL, NULL, NULL },
333 { L"Platform Interrupt Ack Write",8, 82, L"0x%lx", NULL, NULL,
334 NULL, NULL },
335 };
336
337 /**
338 An ACPI_PARSER array describing the Extended PCC Subspaces - Type 3/4
339 */
340 STATIC CONST ACPI_PARSER PccSubspaceType3Parser[] = {
341 PCC_SUBSPACE_HEADER (),
342 { L"Platform Interrupt", 4, 2, L"0x%x", NULL, NULL,
343 ValidatePlatInterrupt, NULL },
344 { L"Platform Interrupt Flags", 1, 6, L"0x%x", NULL,
345 (VOID **)&ExtendedPccSubspaceInterruptFlags,NULL, NULL },
346 { L"Reserved", 1, 7, L"0x%x", NULL, NULL,NULL, NULL },
347 { L"Base Address", 8, 8, L"0x%lx", NULL, NULL,NULL, NULL },
348 { L"Memory Range Length", 4, 16, L"0x%x", NULL, NULL,ValidateRangeLength4,
349 NULL },
350 { L"Doorbell Register", 12, 20, NULL, DumpGas, NULL,
351 ValidatePccDoorbellGas, NULL },
352 { L"Doorbell Preserve", 8, 32, L"0x%lx", NULL, NULL,NULL, NULL },
353 { L"Doorbell Write", 8, 40, L"0x%lx", NULL, NULL,NULL, NULL },
354 { L"Nominal Latency", 4, 48, L"%u", NULL, NULL,NULL, NULL },
355 { L"Maximum Periodic Access Rate", 4, 52, L"%u", NULL, NULL,NULL, NULL },
356 { L"Minimum Request Turnaround Time", 4, 56, L"%u", NULL, NULL,NULL, NULL },
357 { L"Platform Interrupt Ack Register", 12, 60, NULL, DumpGas, NULL,
358 ValidatePccIntAckGas, NULL },
359 { L"Platform Interrupt Ack Preserve", 8, 72, L"0x%lx", NULL, NULL,NULL, NULL },
360 { L"Platform Interrupt Ack Set", 8, 80, L"0x%lx", NULL, NULL,NULL, NULL },
361 { L"Reserved", 8, 88, L"0x%lx", NULL, NULL,NULL, NULL },
362 { L"Cmd Complete Check Reg Addr", 12, 96, NULL, DumpGas, NULL,
363 ValidatePccGas, NULL },
364 { L"Cmd Complete Check Mask", 8, 108, L"0x%lx", NULL, NULL,NULL, NULL },
365 { L"Cmd Update Reg Addr", 12, 116, NULL, DumpGas, NULL,
366 ValidatePccGas, NULL },
367 { L"Cmd Update Preserve mask", 8, 128, L"0x%lx", NULL, NULL,NULL, NULL },
368 { L"Cmd Update Set mask", 8, 136, L"0x%lx", NULL, NULL,NULL, NULL },
369 { L"Error Status Register", 12, 144, NULL, DumpGas, NULL,
370 ValidatePccErrStatusGas, NULL },
371 { L"Error Status Mask", 8, 156, L"0x%lx", NULL, NULL,NULL, NULL },
372 };
373
374 /**
375 An ACPI_PARSER array describing the HW Registers based Communications
376 Subspace Structure - Type 5
377 */
378 STATIC CONST ACPI_PARSER PccSubspaceType5Parser[] = {
379 PCC_SUBSPACE_HEADER (),
380 { L"Version", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },
381 { L"Base Address", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL },
382 { L"Shared Memory Range Length",8, 12, L"0x%lx", NULL, NULL, NULL, NULL },
383 { L"Doorbell Register", 12, 20, NULL, DumpGas, NULL,
384 ValidatePccMemoryIoGas,NULL },
385 { L"Doorbell Preserve", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL },
386 { L"Doorbell Write", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL },
387 { L"Command Complete Check Register",12, 48, NULL, DumpGas, NULL,
388 ValidatePccMemoryIoGas,NULL },
389 { L"Command Complete Check Mask",8, 60, L"0x%lx", NULL, NULL, NULL, NULL },
390 { L"Error Status Register",12, 68, NULL, DumpGas, NULL,
391 ValidatePccMemoryIoGas,NULL },
392 { L"Error Status Mask", 8, 80, L"0x%lx", NULL, NULL, NULL, NULL },
393 { L"Nominal Latency", 4, 88, L"0x%x", NULL, NULL, NULL, NULL },
394 { L"Minimum Request Turnaround Time",4, 92, L"0x%x", NULL, NULL, NULL, NULL }
395 };
396
397 /**
398 This function parses the PCC Subspace type 0.
399
400 @param [in] Ptr Pointer to the start of Subspace Structure.
401 @param [in] Length Length of the Subspace Structure.
402 **/
403 STATIC
404 VOID
405 DumpPccSubspaceType0 (
406 IN UINT8 *Ptr,
407 IN UINT8 Length
408 )
409 {
410 ParseAcpi (
411 TRUE,
412 2,
413 "Subspace Type 0",
414 Ptr,
415 Length,
416 PARSER_PARAMS (PccSubspaceType0Parser)
417 );
418 }
419
420 /**
421 This function parses the PCC Subspace type 1.
422
423 @param [in] Ptr Pointer to the start of the Subspace Structure.
424 @param [in] Length Length of the Subspace Structure.
425 **/
426 STATIC
427 VOID
428 DumpPccSubspaceType1 (
429 IN UINT8 *Ptr,
430 IN UINT8 Length
431 )
432 {
433 ParseAcpi (
434 TRUE,
435 2,
436 "Subspace Type 1",
437 Ptr,
438 Length,
439 PARSER_PARAMS (PccSubspaceType1Parser)
440 );
441 }
442
443 /**
444 This function parses the PCC Subspace type 2.
445
446 @param [in] Ptr Pointer to the start of the Subspace Structure.
447 @param [in] Length Length of the Subspace Structure.
448 **/
449 STATIC
450 VOID
451 DumpPccSubspaceType2 (
452 IN UINT8 *Ptr,
453 IN UINT8 Length
454 )
455 {
456 ParseAcpi (
457 TRUE,
458 2,
459 "Subspace Type 2",
460 Ptr,
461 Length,
462 PARSER_PARAMS (PccSubspaceType2Parser)
463 );
464 }
465
466 /**
467 This function parses the PCC Subspace type 3.
468
469 @param [in] Ptr Pointer to the start of the Subspace Structure.
470 @param [in] Length Length of the Subspace Structure.
471 **/
472 STATIC
473 VOID
474 DumpPccSubspaceType3 (
475 IN UINT8 *Ptr,
476 IN UINT8 Length
477 )
478 {
479 ParseAcpi (
480 TRUE,
481 2,
482 "Subspace Type 3",
483 Ptr,
484 Length,
485 PARSER_PARAMS (PccSubspaceType3Parser)
486 );
487 }
488
489 /**
490 This function parses the PCC Subspace type 4.
491
492 @param [in] Ptr Pointer to the start of the Subspace Structure.
493 @param [in] Length Length of the Subspace Structure.
494 **/
495 STATIC
496 VOID
497 DumpPccSubspaceType4 (
498 IN UINT8 *Ptr,
499 IN UINT8 Length
500 )
501 {
502 ParseAcpi (
503 TRUE,
504 2,
505 "Subspace Type 4",
506 Ptr,
507 Length,
508 PARSER_PARAMS (PccSubspaceType3Parser)
509 );
510 }
511
512 /**
513 This function parses the PCC Subspace type 5.
514
515 @param [in] Ptr Pointer to the start of the Subspace Structure.
516 @param [in] Length Length of the Subspace Structure.
517 **/
518 STATIC
519 VOID
520 DumpPccSubspaceType5 (
521 IN UINT8 *Ptr,
522 IN UINT8 Length
523 )
524 {
525 ParseAcpi (
526 TRUE,
527 2,
528 "Subspace Type 5",
529 Ptr,
530 Length,
531 PARSER_PARAMS (PccSubspaceType5Parser)
532 );
533 }
534
535 /**
536 This function parses the ACPI PCCT table including its sub-structures
537 of type 0 through 4.
538 When trace is enabled this function parses the PCCT table and
539 traces the ACPI table fields.
540
541 This function also performs validation of the ACPI table fields.
542
543 @param [in] Trace If TRUE, trace the ACPI fields.
544 @param [in] Ptr Pointer to the start of the buffer.
545 @param [in] AcpiTableLength Length of the ACPI table.
546 @param [in] AcpiTableRevision Revision of the ACPI table.
547 **/
548 VOID
549 EFIAPI
550 ParseAcpiPcct (
551 IN BOOLEAN Trace,
552 IN UINT8 *Ptr,
553 IN UINT32 AcpiTableLength,
554 IN UINT8 AcpiTableRevision
555 )
556 {
557 UINT32 Offset;
558 UINT8 *PccSubspacePtr;
559 UINTN SubspaceCount;
560
561 if (!Trace) {
562 return;
563 }
564
565 Offset = ParseAcpi (
566 TRUE,
567 0,
568 "PCCT",
569 Ptr,
570 AcpiTableLength,
571 PARSER_PARAMS (PcctParser)
572 );
573
574 PccSubspacePtr = Ptr + Offset;
575
576 SubspaceCount = 0;
577 while (Offset < AcpiTableLength) {
578 // Parse common structure header to obtain Type and Length.
579 ParseAcpi (
580 FALSE,
581 0,
582 NULL,
583 PccSubspacePtr,
584 AcpiTableLength - Offset,
585 PARSER_PARAMS (PccSubspaceHeaderParser)
586 );
587
588 // Check if the values used to control the parsing logic have been
589 // successfully read.
590 if ((PccSubspaceType == NULL) ||
591 (PccSubspaceLength == NULL))
592 {
593 IncrementErrorCount ();
594 Print (
595 L"ERROR: Insufficient remaining table buffer length to read the " \
596 L"structure header. Length = %u.\n",
597 AcpiTableLength - Offset
598 );
599 return;
600 }
601
602 // Validate Structure length
603 if ((*PccSubspaceLength == 0) ||
604 ((Offset + (*PccSubspaceLength)) > AcpiTableLength))
605 {
606 IncrementErrorCount ();
607 Print (
608 L"ERROR: Invalid Structure length. " \
609 L"Length = %u. Offset = %u. AcpiTableLength = %u.\n",
610 *PccSubspaceLength,
611 Offset,
612 AcpiTableLength
613 );
614 return;
615 }
616
617 switch (*PccSubspaceType) {
618 case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC:
619 DumpPccSubspaceType0 (
620 PccSubspacePtr,
621 *PccSubspaceLength
622 );
623 break;
624 case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS:
625 DumpPccSubspaceType1 (
626 PccSubspacePtr,
627 *PccSubspaceLength
628 );
629 break;
630 case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS:
631 DumpPccSubspaceType2 (
632 PccSubspacePtr,
633 *PccSubspaceLength
634 );
635 break;
636 case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC:
637 DumpPccSubspaceType3 (
638 PccSubspacePtr,
639 *PccSubspaceLength
640 );
641 break;
642 case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC:
643 DumpPccSubspaceType4 (
644 PccSubspacePtr,
645 *PccSubspaceLength
646 );
647 break;
648 case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS:
649 DumpPccSubspaceType5 (
650 PccSubspacePtr,
651 *PccSubspaceLength
652 );
653 break;
654 default:
655 IncrementErrorCount ();
656 Print (
657 L"ERROR: Unknown PCC subspace structure:"
658 L" Type = %u, Length = %u\n",
659 PccSubspaceType,
660 *PccSubspaceLength
661 );
662 }
663
664 PccSubspacePtr += *PccSubspaceLength;
665 Offset += *PccSubspaceLength;
666 SubspaceCount++;
667 } // while
668
669 if (SubspaceCount > MAX_PCC_SUBSPACES) {
670 IncrementErrorCount ();
671 Print (L"ERROR: Too many PCC subspaces.");
672 }
673 }