REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the ShellPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
		
			
				
	
	
		
			674 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			674 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   PCCT table parser
 | |
| 
 | |
|   Copyright (c) 2021, Arm Limited.
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
|   @par Reference(s):
 | |
|     - ACPI 6.4 Specification - January 2021
 | |
| **/
 | |
| 
 | |
| #include <Library/BaseMemoryLib.h>
 | |
| #include <Library/PrintLib.h>
 | |
| #include <Library/UefiLib.h>
 | |
| #include "AcpiParser.h"
 | |
| #include "AcpiView.h"
 | |
| #include "AcpiViewConfig.h"
 | |
| #include "PcctParser.h"
 | |
| 
 | |
| // Local variables
 | |
| STATIC ACPI_DESCRIPTION_HEADER_INFO  AcpiHdrInfo;
 | |
| 
 | |
| STATIC UINT32  *PccGlobalFlags;
 | |
| STATIC UINT8   *PccSubspaceLength;
 | |
| STATIC UINT8   *PccSubspaceType;
 | |
| STATIC UINT8   *ExtendedPccSubspaceInterruptFlags;
 | |
| 
 | |
| /**
 | |
|   This function validates the length coded on 4 bytes of a shared memory range
 | |
| 
 | |
|   @param [in] Ptr     Pointer to the start of the field data.
 | |
|   @param [in] Context Pointer to context specific information e.g. this
 | |
|                       could be a pointer to the ACPI table header.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| EFIAPI
 | |
| ValidateRangeLength4 (
 | |
|   IN UINT8  *Ptr,
 | |
|   IN VOID   *Context
 | |
|   )
 | |
| {
 | |
|   if (*(UINT32 *)Ptr < MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN) {
 | |
|     IncrementErrorCount ();
 | |
|     Print (
 | |
|       L"\nError: Shared memory range length is too short.\n"
 | |
|       L"Length is %u when it should be greater than or equal to %u",
 | |
|       *(UINT32 *)Ptr,
 | |
|       MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN
 | |
|       );
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   This function validates the length coded on 8 bytes of a shared memory range
 | |
| 
 | |
|   @param [in] Ptr     Pointer to the start of the field data.
 | |
|   @param [in] Context Pointer to context specific information e.g. this
 | |
|                       could be a pointer to the ACPI table header.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| EFIAPI
 | |
| ValidateRangeLength8 (
 | |
|   IN UINT8  *Ptr,
 | |
|   IN VOID   *Context
 | |
|   )
 | |
| {
 | |
|   if (*(UINT64 *)Ptr <= MIN_MEMORY_RANGE_LENGTH) {
 | |
|     IncrementErrorCount ();
 | |
|     Print (
 | |
|       L"\nError: Shared memory range length is too short.\n"
 | |
|       L"Length is %u when it should be greater than %u",
 | |
|       *(UINT64 *)Ptr,
 | |
|       MIN_MEMORY_RANGE_LENGTH
 | |
|       );
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   This function validates address space for Memory/IO GAS.
 | |
| 
 | |
|   @param [in] Ptr     Pointer to the start of the field data.
 | |
|   @param [in] Context Pointer to context specific information e.g. this
 | |
|                       could be a pointer to the ACPI table header.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| EFIAPI
 | |
| ValidatePccMemoryIoGas (
 | |
|   IN UINT8  *Ptr,
 | |
|   IN VOID   *Context
 | |
|   )
 | |
| {
 | |
|   switch (*(UINT8 *)Ptr) {
 | |
|  #if !(defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
 | |
|     case EFI_ACPI_6_4_SYSTEM_IO:
 | |
|  #endif //if not (defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
 | |
|     case EFI_ACPI_6_4_SYSTEM_MEMORY:
 | |
|       return;
 | |
|     default:
 | |
|       IncrementErrorCount ();
 | |
|       Print (L"\nError: Invalid address space");
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   This function validates address space for structures of types other than 0.
 | |
| 
 | |
|   @param [in] Ptr     Pointer to the start of the field data.
 | |
|   @param [in] Context Pointer to context specific information e.g. this
 | |
|                       could be a pointer to the ACPI table header.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| EFIAPI
 | |
| ValidatePccGas (
 | |
|   IN UINT8  *Ptr,
 | |
|   IN VOID   *Context
 | |
|   )
 | |
| {
 | |
|   switch (*(UINT8 *)Ptr) {
 | |
|  #if !(defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
 | |
|     case EFI_ACPI_6_4_SYSTEM_IO:
 | |
|  #endif //if not (defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
 | |
|     case EFI_ACPI_6_4_FUNCTIONAL_FIXED_HARDWARE:
 | |
|     case EFI_ACPI_6_4_SYSTEM_MEMORY:
 | |
|       return;
 | |
|     default:
 | |
|       IncrementErrorCount ();
 | |
|       Print (L"\nError: Invalid address space");
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   This function validates doorbell address space for type 4 structure.
 | |
| 
 | |
|   @param [in] Ptr     Pointer to the start of the field data.
 | |
|   @param [in] Context Pointer to context specific information e.g. this
 | |
|                       could be a pointer to the ACPI table header.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| EFIAPI
 | |
| ValidatePccDoorbellGas (
 | |
|   IN UINT8  *Ptr,
 | |
|   IN VOID   *Context
 | |
|   )
 | |
| {
 | |
|   // For slave subspaces this field is optional, if not present the field
 | |
|   // should just contain zeros.
 | |
|   if (*PccSubspaceType == EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC) {
 | |
|     if (IsZeroBuffer (
 | |
|           Ptr,
 | |
|           sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE)
 | |
|           ))
 | |
|     {
 | |
|       return;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   ValidatePccGas (Ptr, Context);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   This function validates interrupt acknowledge address space for
 | |
|   type 4 structure.
 | |
| 
 | |
|   @param [in] Ptr     Pointer to the start of the field data.
 | |
|   @param [in] Context Pointer to context specific information e.g. this
 | |
|                       could be a pointer to the ACPI table header.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| EFIAPI
 | |
| ValidatePccIntAckGas (
 | |
|   IN UINT8  *Ptr,
 | |
|   IN VOID   *Context
 | |
|   )
 | |
| {
 | |
|   // If the subspace does not support interrupts or the interrupt is
 | |
|   // edge driven the register may be omitted. A value of 0x0 on all
 | |
|   // 12 bytes of the GAS structure indicates the register is not
 | |
|   // present.
 | |
|   if (((*PccGlobalFlags & EFI_ACPI_6_4_PCCT_FLAGS_PLATFORM_INTERRUPT) !=
 | |
|        EFI_ACPI_6_4_PCCT_FLAGS_PLATFORM_INTERRUPT) ||
 | |
|       ((*ExtendedPccSubspaceInterruptFlags &
 | |
|         EFI_ACPI_6_4_PCCT_SUBSPACE_PLATFORM_INTERRUPT_FLAGS_MODE) ==
 | |
|        EFI_ACPI_6_4_PCCT_SUBSPACE_PLATFORM_INTERRUPT_FLAGS_MODE))
 | |
|   {
 | |
|     if (IsZeroBuffer (
 | |
|           Ptr,
 | |
|           sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE)
 | |
|           ))
 | |
|     {
 | |
|       return;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   ValidatePccGas (Ptr, Context);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   This function validates error status address space for type 4 structure.
 | |
| 
 | |
|   @param [in] Ptr     Pointer to the start of the field data.
 | |
|   @param [in] Context Pointer to context specific information e.g. this
 | |
|                       could be a pointer to the ACPI table header.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| EFIAPI
 | |
| ValidatePccErrStatusGas (
 | |
|   IN UINT8  *Ptr,
 | |
|   IN VOID   *Context
 | |
|   )
 | |
| {
 | |
|   // This field is ignored by the OSPM on slave channels.
 | |
|   if (*PccSubspaceType == EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   ValidatePccGas (Ptr, Context);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   This function validates platform interrupt flags for type 4 structure.
 | |
| 
 | |
|   @param [in] Ptr     Pointer to the start of the field data.
 | |
|   @param [in] Context Pointer to context specific information e.g. this
 | |
|                       could be a pointer to the ACPI table header.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| EFIAPI
 | |
| ValidatePlatInterrupt (
 | |
|   IN UINT8  *Ptr,
 | |
|   IN VOID   *Context
 | |
|   )
 | |
| {
 | |
|   // If a slave subspace is present in the PCCT, then the global Platform
 | |
|   // Interrupt flag must be set to 1.
 | |
|   if ((*PccSubspaceType == EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC) &&
 | |
|       ((*PccGlobalFlags & EFI_ACPI_6_4_PCCT_FLAGS_PLATFORM_INTERRUPT) !=
 | |
|        EFI_ACPI_6_4_PCCT_FLAGS_PLATFORM_INTERRUPT))
 | |
|   {
 | |
|     IncrementErrorCount ();
 | |
|     Print (
 | |
|       L"\nError: Global Platform interrupt flag must be set to 1" \
 | |
|       L" if a PCC type 4 structure is present in PCCT."
 | |
|       );
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   An ACPI_PARSER array describing the ACPI PCCT Table.
 | |
| */
 | |
| STATIC CONST ACPI_PARSER  PcctParser[] = {
 | |
|   PARSE_ACPI_HEADER (&AcpiHdrInfo),
 | |
|   { L"Flags",                      4,  36, NULL, NULL, (VOID **)&PccGlobalFlags, NULL, NULL },
 | |
|   { L"Reserved",                   8,  40, NULL, NULL, NULL,                     NULL, NULL }
 | |
| };
 | |
| 
 | |
| /**
 | |
|   An ACPI_PARSER array describing the platform communications channel subspace
 | |
|   structure header.
 | |
| */
 | |
| STATIC CONST ACPI_PARSER  PccSubspaceHeaderParser[] = {
 | |
|   PCC_SUBSPACE_HEADER ()
 | |
|   // ... Type Specific Fields ...
 | |
| };
 | |
| 
 | |
| /**
 | |
|   An ACPI_PARSER array describing the Generic Communications Subspace - Type 0
 | |
| */
 | |
| STATIC CONST ACPI_PARSER  PccSubspaceType0Parser[] = {
 | |
|   PCC_SUBSPACE_HEADER (),
 | |
|   { L"Reserved",         6,   2,  L"%x %x %x %x %x %x", Dump6Chars, NULL, NULL,                   NULL },
 | |
|   { L"Base Address",     8,   8,  L"0x%lx",             NULL,       NULL, NULL,                   NULL },
 | |
|   { L"Memory Range Length",8,   16, L"0x%lx",             NULL,       NULL, ValidateRangeLength8,
 | |
|     NULL },
 | |
|   { L"Doorbell Register",12,  24, NULL,                 DumpGas,    NULL, ValidatePccMemoryIoGas,
 | |
|     NULL },
 | |
|   { L"Doorbell Preserve",8,   36, L"0x%lx",             NULL,       NULL, NULL,                   NULL },
 | |
|   { L"Doorbell Write",   8,   44, L"0x%lx",             NULL,       NULL, NULL,                   NULL },
 | |
|   { L"Nominal Latency",  4,   52, L"%u",                NULL,       NULL, NULL,                   NULL },
 | |
|   { L"Maximum Periodic Access Rate",4,   56, L"%u",                NULL,       NULL, NULL,                   NULL },
 | |
|   { L"Minimum Request Turnaround Time",2,   60, L"%u",                NULL,       NULL, NULL,                   NULL }
 | |
| };
 | |
| 
 | |
| /**
 | |
|   An ACPI_PARSER array describing the HW-Reduced Communications Subspace
 | |
|   - Type 1
 | |
| */
 | |
| STATIC CONST ACPI_PARSER  PccSubspaceType1Parser[] = {
 | |
|   PCC_SUBSPACE_HEADER (),
 | |
|   { L"Platform Interrupt",4,   2,  L"0x%x",  NULL,    NULL, NULL,                 NULL },
 | |
|   { L"Platform Interrupt Flags",1,   6,  L"0x%x",  NULL,    NULL, NULL,                 NULL },
 | |
|   { L"Reserved",         1,   7,  L"0x%x",  NULL,    NULL, NULL,                 NULL },
 | |
|   { L"Base Address",     8,   8,  L"0x%lx", NULL,    NULL, NULL,                 NULL },
 | |
|   { L"Memory Range Length",8,   16, L"0x%lx", NULL,    NULL, ValidateRangeLength8,
 | |
|     NULL },
 | |
|   { L"Doorbell Register",12,  24, NULL,     DumpGas, NULL,
 | |
|     ValidatePccGas,      NULL },
 | |
|   { L"Doorbell Preserve",8,   36, L"0x%lx", NULL,    NULL, NULL,                 NULL },
 | |
|   { L"Doorbell Write",   8,   44, L"0x%lx", NULL,    NULL, NULL,                 NULL },
 | |
|   { L"Nominal Latency",  4,   52, L"%u",    NULL,    NULL, NULL,                 NULL },
 | |
|   { L"Maximum Periodic Access Rate",4,   56, L"%u",    NULL,    NULL, NULL,                 NULL },
 | |
|   { L"Minimum Request Turnaround Time",2,   60, L"%u",    NULL,    NULL, NULL,                 NULL }
 | |
| };
 | |
| 
 | |
| /**
 | |
|   An ACPI_PARSER array describing the HW-Reduced Communications Subspace
 | |
|   - Type 2
 | |
| */
 | |
| STATIC CONST ACPI_PARSER  PccSubspaceType2Parser[] = {
 | |
|   PCC_SUBSPACE_HEADER (),
 | |
|   { L"Platform Interrupt",4,   2,  L"0x%x",  NULL,    NULL, NULL,                 NULL },
 | |
|   { L"Platform Interrupt Flags",1,   6,  L"0x%x",  NULL,    NULL, NULL,                 NULL },
 | |
|   { L"Reserved",         1,   7,  L"0x%x",  NULL,    NULL, NULL,                 NULL },
 | |
|   { L"Base Address",     8,   8,  L"0x%lx", NULL,    NULL, NULL,                 NULL },
 | |
|   { L"Memory Range Length",8,   16, L"0x%lx", NULL,    NULL, ValidateRangeLength8,
 | |
|     NULL },
 | |
|   { L"Doorbell Register",12,  24, NULL,     DumpGas, NULL,
 | |
|     ValidatePccGas,      NULL },
 | |
|   { L"Doorbell Preserve",8,   36, L"0x%lx", NULL,    NULL, NULL,                 NULL },
 | |
|   { L"Doorbell Write",   8,   44, L"0x%lx", NULL,    NULL, NULL,                 NULL },
 | |
|   { L"Nominal Latency",  4,   52, L"%u",    NULL,    NULL, NULL,                 NULL },
 | |
|   { L"Maximum Periodic Access Rate",4,   56, L"%u",    NULL,    NULL, NULL,                 NULL },
 | |
|   { L"Minimum Request Turnaround Time",2,   60, L"%u",    NULL,    NULL, NULL,                 NULL },
 | |
|   { L"Platform Interrupt Ack Register",12,  62, NULL,     DumpGas, NULL,
 | |
|     ValidatePccGas,      NULL },
 | |
|   { L"Platform Interrupt Ack Preserve",8,   74, L"0x%lx", NULL,    NULL, NULL,                 NULL },
 | |
|   { L"Platform Interrupt Ack Write",8,   82, L"0x%lx", NULL,    NULL,
 | |
|     NULL,                NULL },
 | |
| };
 | |
| 
 | |
| /**
 | |
|   An ACPI_PARSER array describing the Extended PCC Subspaces - Type 3/4
 | |
| */
 | |
| STATIC CONST ACPI_PARSER  PccSubspaceType3Parser[] = {
 | |
|   PCC_SUBSPACE_HEADER (),
 | |
|   { L"Platform Interrupt",                      4,     2,   L"0x%x",  NULL,    NULL,
 | |
|     ValidatePlatInterrupt,                      NULL },
 | |
|   { L"Platform Interrupt Flags",                1,     6,   L"0x%x",  NULL,
 | |
|     (VOID **)&ExtendedPccSubspaceInterruptFlags,NULL,  NULL },
 | |
|   { L"Reserved",                                1,     7,   L"0x%x",  NULL,    NULL,NULL,                  NULL },
 | |
|   { L"Base Address",                            8,     8,   L"0x%lx", NULL,    NULL,NULL,                  NULL },
 | |
|   { L"Memory Range Length",                     4,     16,  L"0x%x",  NULL,    NULL,ValidateRangeLength4,
 | |
|     NULL },
 | |
|   { L"Doorbell Register",                       12,    20,  NULL,     DumpGas, NULL,
 | |
|     ValidatePccDoorbellGas,                     NULL },
 | |
|   { L"Doorbell Preserve",                       8,     32,  L"0x%lx", NULL,    NULL,NULL,                  NULL },
 | |
|   { L"Doorbell Write",                          8,     40,  L"0x%lx", NULL,    NULL,NULL,                  NULL },
 | |
|   { L"Nominal Latency",                         4,     48,  L"%u",    NULL,    NULL,NULL,                  NULL },
 | |
|   { L"Maximum Periodic Access Rate",            4,     52,  L"%u",    NULL,    NULL,NULL,                  NULL },
 | |
|   { L"Minimum Request Turnaround Time",         4,     56,  L"%u",    NULL,    NULL,NULL,                  NULL },
 | |
|   { L"Platform Interrupt Ack Register",         12,    60,  NULL,     DumpGas, NULL,
 | |
|     ValidatePccIntAckGas,                       NULL },
 | |
|   { L"Platform Interrupt Ack Preserve",         8,     72,  L"0x%lx", NULL,    NULL,NULL,                  NULL },
 | |
|   { L"Platform Interrupt Ack Set",              8,     80,  L"0x%lx", NULL,    NULL,NULL,                  NULL },
 | |
|   { L"Reserved",                                8,     88,  L"0x%lx", NULL,    NULL,NULL,                  NULL },
 | |
|   { L"Cmd Complete Check Reg Addr",             12,    96,  NULL,     DumpGas, NULL,
 | |
|     ValidatePccGas,                             NULL },
 | |
|   { L"Cmd Complete Check Mask",                 8,     108, L"0x%lx", NULL,    NULL,NULL,                  NULL },
 | |
|   { L"Cmd Update Reg Addr",                     12,    116, NULL,     DumpGas, NULL,
 | |
|     ValidatePccGas,                             NULL },
 | |
|   { L"Cmd Update Preserve mask",                8,     128, L"0x%lx", NULL,    NULL,NULL,                  NULL },
 | |
|   { L"Cmd Update Set mask",                     8,     136, L"0x%lx", NULL,    NULL,NULL,                  NULL },
 | |
|   { L"Error Status Register",                   12,    144, NULL,     DumpGas, NULL,
 | |
|     ValidatePccErrStatusGas,                    NULL },
 | |
|   { L"Error Status Mask",                       8,     156, L"0x%lx", NULL,    NULL,NULL,                  NULL },
 | |
| };
 | |
| 
 | |
| /**
 | |
|   An ACPI_PARSER array describing the HW Registers based Communications
 | |
|   Subspace Structure - Type 5
 | |
| */
 | |
| STATIC CONST ACPI_PARSER  PccSubspaceType5Parser[] = {
 | |
|   PCC_SUBSPACE_HEADER (),
 | |
|   { L"Version",            2,   2,  L"0x%x",  NULL,    NULL, NULL, NULL },
 | |
|   { L"Base Address",       8,   4,  L"0x%lx", NULL,    NULL, NULL, NULL },
 | |
|   { L"Shared Memory Range Length",8,   12, L"0x%lx", NULL,    NULL, NULL, NULL },
 | |
|   { L"Doorbell Register",  12,  20, NULL,     DumpGas, NULL,
 | |
|     ValidatePccMemoryIoGas,NULL },
 | |
|   { L"Doorbell Preserve",  8,   32, L"0x%lx", NULL,    NULL, NULL, NULL },
 | |
|   { L"Doorbell Write",     8,   40, L"0x%lx", NULL,    NULL, NULL, NULL },
 | |
|   { L"Command Complete Check Register",12,  48, NULL,     DumpGas, NULL,
 | |
|     ValidatePccMemoryIoGas,NULL },
 | |
|   { L"Command Complete Check Mask",8,   60, L"0x%lx", NULL,    NULL, NULL, NULL },
 | |
|   { L"Error Status Register",12,  68, NULL,     DumpGas, NULL,
 | |
|     ValidatePccMemoryIoGas,NULL },
 | |
|   { L"Error Status Mask",  8,   80, L"0x%lx", NULL,    NULL, NULL, NULL },
 | |
|   { L"Nominal Latency",    4,   88, L"0x%x",  NULL,    NULL, NULL, NULL },
 | |
|   { L"Minimum Request Turnaround Time",4,   92, L"0x%x",  NULL,    NULL, NULL, NULL }
 | |
| };
 | |
| 
 | |
| /**
 | |
|   This function parses the PCC Subspace type 0.
 | |
| 
 | |
|   @param [in] Ptr     Pointer to the start of Subspace Structure.
 | |
|   @param [in] Length  Length of the Subspace Structure.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| DumpPccSubspaceType0 (
 | |
|   IN UINT8  *Ptr,
 | |
|   IN UINT8  Length
 | |
|   )
 | |
| {
 | |
|   ParseAcpi (
 | |
|     TRUE,
 | |
|     2,
 | |
|     "Subspace Type 0",
 | |
|     Ptr,
 | |
|     Length,
 | |
|     PARSER_PARAMS (PccSubspaceType0Parser)
 | |
|     );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   This function parses the PCC Subspace type 1.
 | |
| 
 | |
|   @param [in] Ptr     Pointer to the start of the Subspace Structure.
 | |
|   @param [in] Length  Length of the Subspace Structure.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| DumpPccSubspaceType1 (
 | |
|   IN UINT8  *Ptr,
 | |
|   IN UINT8  Length
 | |
|   )
 | |
| {
 | |
|   ParseAcpi (
 | |
|     TRUE,
 | |
|     2,
 | |
|     "Subspace Type 1",
 | |
|     Ptr,
 | |
|     Length,
 | |
|     PARSER_PARAMS (PccSubspaceType1Parser)
 | |
|     );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   This function parses the PCC Subspace type 2.
 | |
| 
 | |
|   @param [in] Ptr     Pointer to the start of the Subspace Structure.
 | |
|   @param [in] Length  Length of the Subspace Structure.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| DumpPccSubspaceType2 (
 | |
|   IN UINT8  *Ptr,
 | |
|   IN UINT8  Length
 | |
|   )
 | |
| {
 | |
|   ParseAcpi (
 | |
|     TRUE,
 | |
|     2,
 | |
|     "Subspace Type 2",
 | |
|     Ptr,
 | |
|     Length,
 | |
|     PARSER_PARAMS (PccSubspaceType2Parser)
 | |
|     );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   This function parses the PCC Subspace type 3.
 | |
| 
 | |
|   @param [in] Ptr     Pointer to the start of the Subspace Structure.
 | |
|   @param [in] Length  Length of the Subspace Structure.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| DumpPccSubspaceType3 (
 | |
|   IN UINT8  *Ptr,
 | |
|   IN UINT8  Length
 | |
|   )
 | |
| {
 | |
|   ParseAcpi (
 | |
|     TRUE,
 | |
|     2,
 | |
|     "Subspace Type 3",
 | |
|     Ptr,
 | |
|     Length,
 | |
|     PARSER_PARAMS (PccSubspaceType3Parser)
 | |
|     );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   This function parses the PCC Subspace type 4.
 | |
| 
 | |
|   @param [in] Ptr     Pointer to the start of the Subspace Structure.
 | |
|   @param [in] Length  Length of the Subspace Structure.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| DumpPccSubspaceType4 (
 | |
|   IN UINT8  *Ptr,
 | |
|   IN UINT8  Length
 | |
|   )
 | |
| {
 | |
|   ParseAcpi (
 | |
|     TRUE,
 | |
|     2,
 | |
|     "Subspace Type 4",
 | |
|     Ptr,
 | |
|     Length,
 | |
|     PARSER_PARAMS (PccSubspaceType3Parser)
 | |
|     );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   This function parses the PCC Subspace type 5.
 | |
| 
 | |
|   @param [in] Ptr     Pointer to the start of the Subspace Structure.
 | |
|   @param [in] Length  Length of the Subspace Structure.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| DumpPccSubspaceType5 (
 | |
|   IN UINT8  *Ptr,
 | |
|   IN UINT8  Length
 | |
|   )
 | |
| {
 | |
|   ParseAcpi (
 | |
|     TRUE,
 | |
|     2,
 | |
|     "Subspace Type 5",
 | |
|     Ptr,
 | |
|     Length,
 | |
|     PARSER_PARAMS (PccSubspaceType5Parser)
 | |
|     );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   This function parses the ACPI PCCT table including its sub-structures
 | |
|   of type 0 through 4.
 | |
|   When trace is enabled this function parses the PCCT table and
 | |
|   traces the ACPI table fields.
 | |
| 
 | |
|   This function also performs validation of the ACPI table fields.
 | |
| 
 | |
|   @param [in] Trace              If TRUE, trace the ACPI fields.
 | |
|   @param [in] Ptr                Pointer to the start of the buffer.
 | |
|   @param [in] AcpiTableLength    Length of the ACPI table.
 | |
|   @param [in] AcpiTableRevision  Revision of the ACPI table.
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| ParseAcpiPcct (
 | |
|   IN BOOLEAN  Trace,
 | |
|   IN UINT8    *Ptr,
 | |
|   IN UINT32   AcpiTableLength,
 | |
|   IN UINT8    AcpiTableRevision
 | |
|   )
 | |
| {
 | |
|   UINT32  Offset;
 | |
|   UINT8   *PccSubspacePtr;
 | |
|   UINTN   SubspaceCount;
 | |
| 
 | |
|   if (!Trace) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   Offset = ParseAcpi (
 | |
|              TRUE,
 | |
|              0,
 | |
|              "PCCT",
 | |
|              Ptr,
 | |
|              AcpiTableLength,
 | |
|              PARSER_PARAMS (PcctParser)
 | |
|              );
 | |
| 
 | |
|   PccSubspacePtr = Ptr + Offset;
 | |
| 
 | |
|   SubspaceCount = 0;
 | |
|   while (Offset < AcpiTableLength) {
 | |
|     // Parse common structure header to obtain Type and Length.
 | |
|     ParseAcpi (
 | |
|       FALSE,
 | |
|       0,
 | |
|       NULL,
 | |
|       PccSubspacePtr,
 | |
|       AcpiTableLength - Offset,
 | |
|       PARSER_PARAMS (PccSubspaceHeaderParser)
 | |
|       );
 | |
| 
 | |
|     // Check if the values used to control the parsing logic have been
 | |
|     // successfully read.
 | |
|     if ((PccSubspaceType == NULL) ||
 | |
|         (PccSubspaceLength == NULL))
 | |
|     {
 | |
|       IncrementErrorCount ();
 | |
|       Print (
 | |
|         L"ERROR: Insufficient remaining table buffer length to read the " \
 | |
|         L"structure header. Length = %u.\n",
 | |
|         AcpiTableLength - Offset
 | |
|         );
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     // Validate Structure length
 | |
|     if ((*PccSubspaceLength == 0) ||
 | |
|         ((Offset + (*PccSubspaceLength)) > AcpiTableLength))
 | |
|     {
 | |
|       IncrementErrorCount ();
 | |
|       Print (
 | |
|         L"ERROR: Invalid Structure length. " \
 | |
|         L"Length = %u. Offset = %u. AcpiTableLength = %u.\n",
 | |
|         *PccSubspaceLength,
 | |
|         Offset,
 | |
|         AcpiTableLength
 | |
|         );
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     switch (*PccSubspaceType) {
 | |
|       case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC:
 | |
|         DumpPccSubspaceType0 (
 | |
|           PccSubspacePtr,
 | |
|           *PccSubspaceLength
 | |
|           );
 | |
|         break;
 | |
|       case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS:
 | |
|         DumpPccSubspaceType1 (
 | |
|           PccSubspacePtr,
 | |
|           *PccSubspaceLength
 | |
|           );
 | |
|         break;
 | |
|       case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS:
 | |
|         DumpPccSubspaceType2 (
 | |
|           PccSubspacePtr,
 | |
|           *PccSubspaceLength
 | |
|           );
 | |
|         break;
 | |
|       case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC:
 | |
|         DumpPccSubspaceType3 (
 | |
|           PccSubspacePtr,
 | |
|           *PccSubspaceLength
 | |
|           );
 | |
|         break;
 | |
|       case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC:
 | |
|         DumpPccSubspaceType4 (
 | |
|           PccSubspacePtr,
 | |
|           *PccSubspaceLength
 | |
|           );
 | |
|         break;
 | |
|       case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS:
 | |
|         DumpPccSubspaceType5 (
 | |
|           PccSubspacePtr,
 | |
|           *PccSubspaceLength
 | |
|           );
 | |
|         break;
 | |
|       default:
 | |
|         IncrementErrorCount ();
 | |
|         Print (
 | |
|           L"ERROR: Unknown PCC subspace structure:"
 | |
|           L" Type = %u, Length = %u\n",
 | |
|           PccSubspaceType,
 | |
|           *PccSubspaceLength
 | |
|           );
 | |
|     }
 | |
| 
 | |
|     PccSubspacePtr += *PccSubspaceLength;
 | |
|     Offset         += *PccSubspaceLength;
 | |
|     SubspaceCount++;
 | |
|   } // while
 | |
| 
 | |
|   if (SubspaceCount > MAX_PCC_SUBSPACES) {
 | |
|     IncrementErrorCount ();
 | |
|     Print (L"ERROR: Too many PCC subspaces.");
 | |
|   }
 | |
| }
 |