* [PATCH v2 0/2] Add AEST parser support to Acpiview @ 2020-10-21 15:55 Sami Mujawar 2020-10-21 15:55 ` [PATCH v2 1/2] MdePkg/IndustryStandard: AEST Table definition Sami Mujawar 2020-10-21 15:55 ` [PATCH v2 2/2] ShellPkg/Acpiview: AEST Parser Sami Mujawar 0 siblings, 2 replies; 4+ messages in thread From: Sami Mujawar @ 2020-10-21 15:55 UTC (permalink / raw) To: devel Cc: Sami Mujawar, michael.d.kinney, gaoliming, zhiguang.liu, ray.ni, zhichao.gao, Matteo.Carlini, Ben.Adderson, nd Arm Error Source Table (AEST) enables kernel-first handling of errors in a system that supports the Armv8 RAS extensions. AEST is described in the ACPI for the Armv8 RAS Extensions 1.1, Platform Design Document, dated 28 September 2020. (https://developer.arm.com/documentation/den0085/0101/) This v2 patch series: - adds AEST parser support to Acpiview. - addresses the review feedback for v1 series. The changes can be seen at: https://github.com/samimujawar/edk2/tree/1429_aest_parser_v2 Marc Moisson-Franckhauser (2): MdePkg/IndustryStandard: AEST Table definition ShellPkg/Acpiview: AEST Parser MdePkg/Include/IndustryStandard/ArmErrorSourceTable.h | 357 +++++++++ ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h | 21 + ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h | 4 +- ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c | 755 ++++++++++++++++++++ ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c | 4 +- ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf | 3 +- ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni | 3 +- 7 files changed, 1142 insertions(+), 5 deletions(-) create mode 100644 MdePkg/Include/IndustryStandard/ArmErrorSourceTable.h create mode 100644 ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c -- 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)' ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 1/2] MdePkg/IndustryStandard: AEST Table definition 2020-10-21 15:55 [PATCH v2 0/2] Add AEST parser support to Acpiview Sami Mujawar @ 2020-10-21 15:55 ` Sami Mujawar 2020-10-22 1:26 ` 回复: " gaoliming 2020-10-21 15:55 ` [PATCH v2 2/2] ShellPkg/Acpiview: AEST Parser Sami Mujawar 1 sibling, 1 reply; 4+ messages in thread From: Sami Mujawar @ 2020-10-21 15:55 UTC (permalink / raw) To: devel Cc: Sami Mujawar, michael.d.kinney, gaoliming, zhiguang.liu, ray.ni, zhichao.gao, ard.biesheuvel, Matteo.Carlini, Ben.Adderson, nd From: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com> Add definition for the Arm Error Source Table (AEST) described in the ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document, dated 28 September 2020. (https://developer.arm.com/documentation/den0085/0101/) Signed-off-by: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com> --- Notes: v2: - AEST is not defined in ACPI 6.3 spec and should not be [Liming] added to Acpi63.h and for structure definition and its field, its comment starts with /// or //. - Moved AEST table signature to ArmErrorSourceTable.h and [SAMI] updated structure and field documenting style to match coding convention. Ref: https://edk2.groups.io/g/devel/message/66151 MdePkg/Include/IndustryStandard/ArmErrorSourceTable.h | 357 ++++++++++++++++++++ 1 file changed, 357 insertions(+) diff --git a/MdePkg/Include/IndustryStandard/ArmErrorSourceTable.h b/MdePkg/Include/IndustryStandard/ArmErrorSourceTable.h new file mode 100644 index 0000000000000000000000000000000000000000..369b03a50b65a7f6d0012eec9898a14dcd61976d --- /dev/null +++ b/MdePkg/Include/IndustryStandard/ArmErrorSourceTable.h @@ -0,0 +1,357 @@ +/** @file + Arm Error Source Table as described in the + 'ACPI for the Armv8 RAS Extensions 1.1' Specification. + + Copyright (c) 2020 Arm Limited. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document, + dated 28 September 2020. + (https://developer.arm.com/documentation/den0085/0101/) + + @par Glossary + - Ref : Reference + - Id : Identifier +**/ + +#ifndef ARM_ERROR_SOURCE_TABLE_H_ +#define ARM_ERROR_SOURCE_TABLE_H_ + +/// +/// "AEST" Arm Error Source Table +/// +#define EFI_ACPI_6_3_ARM_ERROR_SOURCE_TABLE_SIGNATURE SIGNATURE_32('A', 'E', 'S', 'T') + +#define EFI_ACPI_ARM_ERROR_SOURCE_TABLE_REVISION 1 + +#pragma pack(1) + +/// +/// Arm Error Source Table definition. +/// +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; +} EFI_ACPI_ARM_ERROR_SOURCE_TABLE; + +/// +/// AEST Node structure. +/// +typedef struct { + /// Node type: + /// 0x00 - Processor error node + /// 0x01 - Memory error node + /// 0x02 - SMMU error node + /// 0x03 - Vendor-defined error node + /// 0x04 - GIC error node + UINT8 Type; + + /// Length of structure in bytes. + UINT16 Length; + + /// Reserved - Must be zero. + UINT8 Reserved; + + /// Offset from the start of the node to node-specific data. + UINT32 DataOffset; + + /// Offset from the start of the node to the node interface structure. + UINT32 InterfaceOffset; + + /// Offset from the start of the node to node interrupt array. + UINT32 InterruptArrayOffset; + + /// Number of entries in the interrupt array. + UINT32 InterruptArrayCount; + + // Generic node data + + /// The timestamp frequency of the counter in Hz. + UINT64 TimestampRate; + + /// Reserved - Must be zero. + UINT64 Reserved1; + + /// The rate in Hz at which the Error Generation Counter decrements. + UINT64 ErrorInjectionCountdownRate; +} EFI_ACPI_AEST_NODE_STRUCT; + +// AEST Node type definitions +#define EFI_ACPI_AEST_NODE_TYPE_PROCESSOR 0x0 +#define EFI_ACPI_AEST_NODE_TYPE_MEMORY 0x1 +#define EFI_ACPI_AEST_NODE_TYPE_SMMU 0x2 +#define EFI_ACPI_AEST_NODE_TYPE_VENDOR_DEFINED 0x3 +#define EFI_ACPI_AEST_NODE_TYPE_GIC 0x4 + +/// +/// AEST Node Interface structure. +/// +typedef struct { + /// Interface type: + /// 0x0 - System register (SR) + /// 0x1 - Memory mapped (MMIO) + UINT8 Type; + + /// Reserved - Must be zero. + UINT8 Reserved[3]; + + /// AEST node interface flags. + UINT32 Flags; + + /// Base address of error group that contains the error node. + UINT64 BaseAddress; + + /// Zero-based index of the first standard error record that + /// belongs to this node. + UINT32 StartErrorRecordIndex; + + /// Number of error records in this node including both + /// implemented and unimplemented records. + UINT32 NumberErrorRecords; + + /// A bitmap indicating the error records within this + /// node that are implemented in the current system. + UINT64 ErrorRecordImplemented; + + /// A bitmap indicating the error records within this node that + /// support error status reporting through the ERRGSR register. + UINT64 ErrorRecordStatusReportingSupported; + + /// A bitmap indicating the addressing mode used by each error + /// record within this node to populate the ERR<n>_ADDR register. + UINT64 AddressingMode; +} EFI_ACPI_AEST_INTERFACE_STRUCT; + +// AEST Interface node type definitions. +#define EFI_ACPI_AEST_INTERFACE_TYPE_SR 0x0 +#define EFI_ACPI_AEST_INTERFACE_TYPE_MMIO 0x1 + +// AEST node interface flag definitions. +#define EFI_ACPI_AEST_INTERFACE_FLAG_PRIVATE 0 +#define EFI_ACPI_AEST_INTERFACE_FLAG_SHARED BIT0 +#define EFI_ACPI_AEST_INTERFACE_FLAG_CLEAR_MISCX BIT1 + +/// +/// AEST Node Interrupt structure. +/// +typedef struct { + /// Interrupt type: + /// 0x0 - Fault Handling Interrupt + /// 0x1 - Error Recovery Interrupt + UINT8 InterruptType; + + /// Reserved - Must be zero. + UINT8 Reserved[2]; + + /// Interrupt flags + /// Bits [31:1]: Must be zero. + /// Bit 0: + /// 0b - Interrupt is edge-triggered + /// 1b - Interrupt is level-triggered + UINT8 InterruptFlags; + + /// GSIV of interrupt, if interrupt is an SPI or a PPI. + UINT32 InterruptGsiv; + + /// If MSI is supported, then this field must be set to the + /// Identifier field of the IORT ITS Group node. + UINT8 ItsGroupRefId; + + /// Reserved - must be zero. + UINT8 Reserved1[3]; +} EFI_ACPI_AEST_INTERRUPT_STRUCT; + +// AEST Interrupt node - interrupt type defintions. +#define EFI_ACPI_AEST_INTERRUPT_TYPE_FAULT_HANDLING 0x0 +#define EFI_ACPI_AEST_INTERRUPT_TYPE_ERROR_RECOVERY 0x1 + +// AEST Interrupt node - interrupt flag defintions. +#define EFI_ACPI_AEST_INTERRUPT_FLAG_TRIGGER_TYPE_EDGE 0 +#define EFI_ACPI_AEST_INTERRUPT_FLAG_TRIGGER_TYPE_LEVEL BIT0 + +/// +/// Cache Processor Resource structure. +/// +typedef struct { + /// Reference to the cache structure in the PPTT table. + UINT32 CacheRefId; + + /// Reserved + UINT32 Reserved; +} EFI_ACPI_AEST_PROCESSOR_CACHE_RESOURCE_STRUCT; + +/// +/// TLB Processor Resource structure. +/// +typedef struct { + /// TLB level from perspective of current processor. + UINT32 TlbRefId; + + /// Reserved + UINT32 Reserved; +} EFI_ACPI_AEST_PROCESSOR_TLB_RESOURCE_STRUCT; + +/// +/// Processor Generic Resource structure. +/// +typedef struct { + /// Vendor-defined supplementary data. + UINT32 Data; +} EFI_ACPI_AEST_PROCESSOR_GENERIC_RESOURCE_STRUCT; + +/// +/// AEST Processor Resource union. +/// +typedef union { + /// Processor Cache resource. + EFI_ACPI_AEST_PROCESSOR_CACHE_RESOURCE_STRUCT Cache; + + /// Processor TLB resource. + EFI_ACPI_AEST_PROCESSOR_TLB_RESOURCE_STRUCT Tlb; + + /// Processor Generic resource. + EFI_ACPI_AEST_PROCESSOR_GENERIC_RESOURCE_STRUCT Generic; +} EFI_ACPI_AEST_PROCESSOR_RESOURCE; + +/// +/// AEST Processor structure. +/// +typedef struct { + /// AEST Node header + EFI_ACPI_AEST_NODE_STRUCT NodeHeader; + + /// Processor ID of node. + UINT32 AcpiProcessorId; + + /// Resource type of the processor node. + /// 0x0 - Cache + /// 0x1 - TLB + /// 0x2 - Generic + UINT8 ResourceType; + + /// Reserved - must be zero. + UINT8 Reserved; + + /// Processor structure flags. + UINT8 Flags; + + /// Processor structure revision. + UINT8 Revision; + + /// Processor affinity descriptor for the resource that this + /// error node pertains to. + UINT64 ProcessorAffinityLevelIndicator; + + /// Processor resource + EFI_ACPI_AEST_PROCESSOR_RESOURCE Resource; + + // Node Interface + // EFI_ACPI_AEST_INTERFACE_STRUCT NodeInterface; + + // Node Interrupt Array + // EFI_ACPI_AEST_INTERRUPT_STRUCT NodeInterruptArray[n]; +} EFI_ACPI_AEST_PROCESSOR_STRUCT; + +// AEST Processor resource type definitions. +#define EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_CACHE 0x0 +#define EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_TLB 0x1 +#define EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_GENERIC 0x2 + +// AEST Processor flag definitions. +#define EFI_ACPI_AEST_PROCESSOR_FLAG_GLOBAL BIT0 +#define EFI_ACPI_AEST_PROCESSOR_FLAG_SHARED BIT1 + +/// +/// Memory Controller structure. +/// +typedef struct { + /// AEST Node header + EFI_ACPI_AEST_NODE_STRUCT NodeHeader; + + /// SRAT proximity domain. + UINT32 ProximityDomain; + + // Node Interface + // EFI_ACPI_AEST_INTERFACE_STRUCT NodeInterface; + + // Node Interrupt Array + // EFI_ACPI_AEST_INTERRUPT_STRUCT NodeInterruptArray[n]; +} EFI_ACPI_AEST_MEMORY_CONTROLLER_STRUCT; + +/// +/// SMMU structure. +/// +typedef struct { + /// AEST Node header + EFI_ACPI_AEST_NODE_STRUCT NodeHeader; + + /// Reference to the IORT table node that describes this SMMU. + UINT32 SmmuRefId; + + /// Reference to the IORT table node that is associated with the + /// sub-component within this SMMU. + UINT32 SubComponentRefId; + + // Node Interface + // EFI_ACPI_AEST_INTERFACE_STRUCT NodeInterface; + + // Node Interrupt Array + // EFI_ACPI_AEST_INTERRUPT_STRUCT NodeInterruptArray[n]; +} EFI_ACPI_AEST_SMMU_STRUCT; + +/// +/// Vendor-Defined structure. +/// +typedef struct { + /// AEST Node header + EFI_ACPI_AEST_NODE_STRUCT NodeHeader; + + /// ACPI HID of the component. + UINT32 HardwareId; + + /// The ACPI Unique identifier of the component. + UINT32 UniqueId; + + /// Vendor-specific data, for example to identify this error source. + UINT8 VendorData[16]; + + // Node Interface + // EFI_ACPI_AEST_INTERFACE_STRUCT NodeInterface; + + // Node Interrupt Array + // EFI_ACPI_AEST_INTERRUPT_STRUCT NodeInterruptArray[n]; +} EFI_ACPI_AEST_VENDOR_DEFINED_STRUCT; + +/// +/// GIC structure. +/// +typedef struct { + /// AEST Node header + EFI_ACPI_AEST_NODE_STRUCT NodeHeader; + + /// Type of GIC interface that is associated with this error node. + /// 0x0 - GIC CPU (GICC) + /// 0x1 - GIC Distributor (GICD) + /// 0x2 - GIC Resistributor (GICR) + /// 0x3 - GIC ITS (GITS) + UINT32 InterfaceType; + + /// Identifier for the interface instance. + UINT32 GicInterfaceRefId; + + // Node Interface + // EFI_ACPI_AEST_INTERFACE_STRUCT NodeInterface; + + // Node Interrupt Array + // EFI_ACPI_AEST_INTERRUPT_STRUCT NodeInterruptArray[n]; +} EFI_ACPI_AEST_GIC_STRUCT; + +// AEST GIC interface type definitions. +#define EFI_ACPI_AEST_GIC_INTERFACE_TYPE_GICC 0x0 +#define EFI_ACPI_AEST_GIC_INTERFACE_TYPE_GICD 0x1 +#define EFI_ACPI_AEST_GIC_INTERFACE_TYPE_GICR 0x2 +#define EFI_ACPI_AEST_GIC_INTERFACE_TYPE_GITS 0x3 + +#pragma pack() + +#endif // ARM_ERROR_SOURCE_TABLE_H_ -- 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)' ^ permalink raw reply related [flat|nested] 4+ messages in thread
* 回复: [PATCH v2 1/2] MdePkg/IndustryStandard: AEST Table definition 2020-10-21 15:55 ` [PATCH v2 1/2] MdePkg/IndustryStandard: AEST Table definition Sami Mujawar @ 2020-10-22 1:26 ` gaoliming 0 siblings, 0 replies; 4+ messages in thread From: gaoliming @ 2020-10-22 1:26 UTC (permalink / raw) To: 'Sami Mujawar', devel Cc: michael.d.kinney, zhiguang.liu, ray.ni, zhichao.gao, ard.biesheuvel, Matteo.Carlini, Ben.Adderson, nd Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn> > -----邮件原件----- > 发件人: Sami Mujawar <sami.mujawar@arm.com> > 发送时间: 2020年10月21日 23:56 > 收件人: devel@edk2.groups.io > 抄送: Sami Mujawar <sami.mujawar@arm.com>; > michael.d.kinney@intel.com; gaoliming@byosoft.com.cn; > zhiguang.liu@intel.com; ray.ni@intel.com; zhichao.gao@intel.com; > ard.biesheuvel@arm.com; Matteo.Carlini@arm.com; > Ben.Adderson@arm.com; nd@arm.com > 主题: [PATCH v2 1/2] MdePkg/IndustryStandard: AEST Table definition > > From: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com> > > Add definition for the Arm Error Source Table (AEST) described in > the ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document, > dated 28 September 2020. > (https://developer.arm.com/documentation/den0085/0101/) > > Signed-off-by: Marc Moisson-Franckhauser > <marc.moisson-franckhauser@arm.com> > Signed-off-by: Sami Mujawar <sami.mujawar@arm.com> > --- > > Notes: > v2: > - AEST is not defined in ACPI 6.3 spec and should not be [Liming] > added to Acpi63.h and for structure definition and its > field, its comment starts with /// or //. > - Moved AEST table signature to ArmErrorSourceTable.h and > [SAMI] > updated structure and field documenting style to match > coding convention. > Ref: https://edk2.groups.io/g/devel/message/66151 > > MdePkg/Include/IndustryStandard/ArmErrorSourceTable.h | 357 > ++++++++++++++++++++ > 1 file changed, 357 insertions(+) > > diff --git a/MdePkg/Include/IndustryStandard/ArmErrorSourceTable.h > b/MdePkg/Include/IndustryStandard/ArmErrorSourceTable.h > new file mode 100644 > index > 0000000000000000000000000000000000000000..369b03a50b65a7f6d0012 > eec9898a14dcd61976d > --- /dev/null > +++ b/MdePkg/Include/IndustryStandard/ArmErrorSourceTable.h > @@ -0,0 +1,357 @@ > +/** @file > + Arm Error Source Table as described in the > + 'ACPI for the Armv8 RAS Extensions 1.1' Specification. > + > + Copyright (c) 2020 Arm Limited. > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > + @par Reference(s): > + - ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document, > + dated 28 September 2020. > + (https://developer.arm.com/documentation/den0085/0101/) > + > + @par Glossary > + - Ref : Reference > + - Id : Identifier > +**/ > + > +#ifndef ARM_ERROR_SOURCE_TABLE_H_ > +#define ARM_ERROR_SOURCE_TABLE_H_ > + > +/// > +/// "AEST" Arm Error Source Table > +/// > +#define EFI_ACPI_6_3_ARM_ERROR_SOURCE_TABLE_SIGNATURE > SIGNATURE_32('A', 'E', 'S', 'T') > + > +#define EFI_ACPI_ARM_ERROR_SOURCE_TABLE_REVISION 1 > + > +#pragma pack(1) > + > +/// > +/// Arm Error Source Table definition. > +/// > +typedef struct { > + EFI_ACPI_DESCRIPTION_HEADER Header; > +} EFI_ACPI_ARM_ERROR_SOURCE_TABLE; > + > +/// > +/// AEST Node structure. > +/// > +typedef struct { > + /// Node type: > + /// 0x00 - Processor error node > + /// 0x01 - Memory error node > + /// 0x02 - SMMU error node > + /// 0x03 - Vendor-defined error node > + /// 0x04 - GIC error node > + UINT8 Type; > + > + /// Length of structure in bytes. > + UINT16 Length; > + > + /// Reserved - Must be zero. > + UINT8 Reserved; > + > + /// Offset from the start of the node to node-specific data. > + UINT32 DataOffset; > + > + /// Offset from the start of the node to the node interface structure. > + UINT32 InterfaceOffset; > + > + /// Offset from the start of the node to node interrupt array. > + UINT32 InterruptArrayOffset; > + > + /// Number of entries in the interrupt array. > + UINT32 InterruptArrayCount; > + > + // Generic node data > + > + /// The timestamp frequency of the counter in Hz. > + UINT64 TimestampRate; > + > + /// Reserved - Must be zero. > + UINT64 Reserved1; > + > + /// The rate in Hz at which the Error Generation Counter decrements. > + UINT64 ErrorInjectionCountdownRate; > +} EFI_ACPI_AEST_NODE_STRUCT; > + > +// AEST Node type definitions > +#define EFI_ACPI_AEST_NODE_TYPE_PROCESSOR 0x0 > +#define EFI_ACPI_AEST_NODE_TYPE_MEMORY 0x1 > +#define EFI_ACPI_AEST_NODE_TYPE_SMMU 0x2 > +#define EFI_ACPI_AEST_NODE_TYPE_VENDOR_DEFINED 0x3 > +#define EFI_ACPI_AEST_NODE_TYPE_GIC 0x4 > + > +/// > +/// AEST Node Interface structure. > +/// > +typedef struct { > + /// Interface type: > + /// 0x0 - System register (SR) > + /// 0x1 - Memory mapped (MMIO) > + UINT8 Type; > + > + /// Reserved - Must be zero. > + UINT8 Reserved[3]; > + > + /// AEST node interface flags. > + UINT32 Flags; > + > + /// Base address of error group that contains the error node. > + UINT64 BaseAddress; > + > + /// Zero-based index of the first standard error record that > + /// belongs to this node. > + UINT32 StartErrorRecordIndex; > + > + /// Number of error records in this node including both > + /// implemented and unimplemented records. > + UINT32 NumberErrorRecords; > + > + /// A bitmap indicating the error records within this > + /// node that are implemented in the current system. > + UINT64 ErrorRecordImplemented; > + > + /// A bitmap indicating the error records within this node that > + /// support error status reporting through the ERRGSR register. > + UINT64 ErrorRecordStatusReportingSupported; > + > + /// A bitmap indicating the addressing mode used by each error > + /// record within this node to populate the ERR<n>_ADDR register. > + UINT64 AddressingMode; > +} EFI_ACPI_AEST_INTERFACE_STRUCT; > + > +// AEST Interface node type definitions. > +#define EFI_ACPI_AEST_INTERFACE_TYPE_SR 0x0 > +#define EFI_ACPI_AEST_INTERFACE_TYPE_MMIO 0x1 > + > +// AEST node interface flag definitions. > +#define EFI_ACPI_AEST_INTERFACE_FLAG_PRIVATE 0 > +#define EFI_ACPI_AEST_INTERFACE_FLAG_SHARED BIT0 > +#define EFI_ACPI_AEST_INTERFACE_FLAG_CLEAR_MISCX BIT1 > + > +/// > +/// AEST Node Interrupt structure. > +/// > +typedef struct { > + /// Interrupt type: > + /// 0x0 - Fault Handling Interrupt > + /// 0x1 - Error Recovery Interrupt > + UINT8 InterruptType; > + > + /// Reserved - Must be zero. > + UINT8 Reserved[2]; > + > + /// Interrupt flags > + /// Bits [31:1]: Must be zero. > + /// Bit 0: > + /// 0b - Interrupt is edge-triggered > + /// 1b - Interrupt is level-triggered > + UINT8 InterruptFlags; > + > + /// GSIV of interrupt, if interrupt is an SPI or a PPI. > + UINT32 InterruptGsiv; > + > + /// If MSI is supported, then this field must be set to the > + /// Identifier field of the IORT ITS Group node. > + UINT8 ItsGroupRefId; > + > + /// Reserved - must be zero. > + UINT8 Reserved1[3]; > +} EFI_ACPI_AEST_INTERRUPT_STRUCT; > + > +// AEST Interrupt node - interrupt type defintions. > +#define EFI_ACPI_AEST_INTERRUPT_TYPE_FAULT_HANDLING 0x0 > +#define EFI_ACPI_AEST_INTERRUPT_TYPE_ERROR_RECOVERY 0x1 > + > +// AEST Interrupt node - interrupt flag defintions. > +#define EFI_ACPI_AEST_INTERRUPT_FLAG_TRIGGER_TYPE_EDGE 0 > +#define EFI_ACPI_AEST_INTERRUPT_FLAG_TRIGGER_TYPE_LEVEL BIT0 > + > +/// > +/// Cache Processor Resource structure. > +/// > +typedef struct { > + /// Reference to the cache structure in the PPTT table. > + UINT32 CacheRefId; > + > + /// Reserved > + UINT32 Reserved; > +} EFI_ACPI_AEST_PROCESSOR_CACHE_RESOURCE_STRUCT; > + > +/// > +/// TLB Processor Resource structure. > +/// > +typedef struct { > + /// TLB level from perspective of current processor. > + UINT32 TlbRefId; > + > + /// Reserved > + UINT32 Reserved; > +} EFI_ACPI_AEST_PROCESSOR_TLB_RESOURCE_STRUCT; > + > +/// > +/// Processor Generic Resource structure. > +/// > +typedef struct { > + /// Vendor-defined supplementary data. > + UINT32 Data; > +} EFI_ACPI_AEST_PROCESSOR_GENERIC_RESOURCE_STRUCT; > + > +/// > +/// AEST Processor Resource union. > +/// > +typedef union { > + /// Processor Cache resource. > + EFI_ACPI_AEST_PROCESSOR_CACHE_RESOURCE_STRUCT Cache; > + > + /// Processor TLB resource. > + EFI_ACPI_AEST_PROCESSOR_TLB_RESOURCE_STRUCT Tlb; > + > + /// Processor Generic resource. > + EFI_ACPI_AEST_PROCESSOR_GENERIC_RESOURCE_STRUCT Generic; > +} EFI_ACPI_AEST_PROCESSOR_RESOURCE; > + > +/// > +/// AEST Processor structure. > +/// > +typedef struct { > + /// AEST Node header > + EFI_ACPI_AEST_NODE_STRUCT NodeHeader; > + > + /// Processor ID of node. > + UINT32 AcpiProcessorId; > + > + /// Resource type of the processor node. > + /// 0x0 - Cache > + /// 0x1 - TLB > + /// 0x2 - Generic > + UINT8 ResourceType; > + > + /// Reserved - must be zero. > + UINT8 Reserved; > + > + /// Processor structure flags. > + UINT8 Flags; > + > + /// Processor structure revision. > + UINT8 Revision; > + > + /// Processor affinity descriptor for the resource that this > + /// error node pertains to. > + UINT64 ProcessorAffinityLevelIndicator; > + > + /// Processor resource > + EFI_ACPI_AEST_PROCESSOR_RESOURCE Resource; > + > + // Node Interface > + // EFI_ACPI_AEST_INTERFACE_STRUCT NodeInterface; > + > + // Node Interrupt Array > + // EFI_ACPI_AEST_INTERRUPT_STRUCT NodeInterruptArray[n]; > +} EFI_ACPI_AEST_PROCESSOR_STRUCT; > + > +// AEST Processor resource type definitions. > +#define EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_CACHE 0x0 > +#define EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_TLB 0x1 > +#define EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_GENERIC 0x2 > + > +// AEST Processor flag definitions. > +#define EFI_ACPI_AEST_PROCESSOR_FLAG_GLOBAL BIT0 > +#define EFI_ACPI_AEST_PROCESSOR_FLAG_SHARED BIT1 > + > +/// > +/// Memory Controller structure. > +/// > +typedef struct { > + /// AEST Node header > + EFI_ACPI_AEST_NODE_STRUCT NodeHeader; > + > + /// SRAT proximity domain. > + UINT32 ProximityDomain; > + > + // Node Interface > + // EFI_ACPI_AEST_INTERFACE_STRUCT NodeInterface; > + > + // Node Interrupt Array > + // EFI_ACPI_AEST_INTERRUPT_STRUCT NodeInterruptArray[n]; > +} EFI_ACPI_AEST_MEMORY_CONTROLLER_STRUCT; > + > +/// > +/// SMMU structure. > +/// > +typedef struct { > + /// AEST Node header > + EFI_ACPI_AEST_NODE_STRUCT NodeHeader; > + > + /// Reference to the IORT table node that describes this SMMU. > + UINT32 SmmuRefId; > + > + /// Reference to the IORT table node that is associated with the > + /// sub-component within this SMMU. > + UINT32 SubComponentRefId; > + > + // Node Interface > + // EFI_ACPI_AEST_INTERFACE_STRUCT NodeInterface; > + > + // Node Interrupt Array > + // EFI_ACPI_AEST_INTERRUPT_STRUCT NodeInterruptArray[n]; > +} EFI_ACPI_AEST_SMMU_STRUCT; > + > +/// > +/// Vendor-Defined structure. > +/// > +typedef struct { > + /// AEST Node header > + EFI_ACPI_AEST_NODE_STRUCT NodeHeader; > + > + /// ACPI HID of the component. > + UINT32 HardwareId; > + > + /// The ACPI Unique identifier of the component. > + UINT32 UniqueId; > + > + /// Vendor-specific data, for example to identify this error source. > + UINT8 VendorData[16]; > + > + // Node Interface > + // EFI_ACPI_AEST_INTERFACE_STRUCT NodeInterface; > + > + // Node Interrupt Array > + // EFI_ACPI_AEST_INTERRUPT_STRUCT NodeInterruptArray[n]; > +} EFI_ACPI_AEST_VENDOR_DEFINED_STRUCT; > + > +/// > +/// GIC structure. > +/// > +typedef struct { > + /// AEST Node header > + EFI_ACPI_AEST_NODE_STRUCT NodeHeader; > + > + /// Type of GIC interface that is associated with this error node. > + /// 0x0 - GIC CPU (GICC) > + /// 0x1 - GIC Distributor (GICD) > + /// 0x2 - GIC Resistributor (GICR) > + /// 0x3 - GIC ITS (GITS) > + UINT32 InterfaceType; > + > + /// Identifier for the interface instance. > + UINT32 GicInterfaceRefId; > + > + // Node Interface > + // EFI_ACPI_AEST_INTERFACE_STRUCT NodeInterface; > + > + // Node Interrupt Array > + // EFI_ACPI_AEST_INTERRUPT_STRUCT NodeInterruptArray[n]; > +} EFI_ACPI_AEST_GIC_STRUCT; > + > +// AEST GIC interface type definitions. > +#define EFI_ACPI_AEST_GIC_INTERFACE_TYPE_GICC 0x0 > +#define EFI_ACPI_AEST_GIC_INTERFACE_TYPE_GICD 0x1 > +#define EFI_ACPI_AEST_GIC_INTERFACE_TYPE_GICR 0x2 > +#define EFI_ACPI_AEST_GIC_INTERFACE_TYPE_GITS 0x3 > + > +#pragma pack() > + > +#endif // ARM_ERROR_SOURCE_TABLE_H_ > -- > 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)' ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 2/2] ShellPkg/Acpiview: AEST Parser 2020-10-21 15:55 [PATCH v2 0/2] Add AEST parser support to Acpiview Sami Mujawar 2020-10-21 15:55 ` [PATCH v2 1/2] MdePkg/IndustryStandard: AEST Table definition Sami Mujawar @ 2020-10-21 15:55 ` Sami Mujawar 1 sibling, 0 replies; 4+ messages in thread From: Sami Mujawar @ 2020-10-21 15:55 UTC (permalink / raw) To: devel; +Cc: Sami Mujawar, ray.ni, zhichao.gao, Matteo.Carlini, Ben.Adderson, nd From: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com> Add a new parser for the Arm Error Source Table (AEST) described in the ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document, dated 28 September 2020. (https://developer.arm.com/documentation/den0085/0101/) AEST enables kernel-first handling of errors in a system that supports the Armv8 RAS extensions. It covers Armv8.2+ RAS extensions for PEs and the RAS system architecture for non-PE system components. Signed-off-by: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com> --- Notes: v2: - Minor update to include ArmErrorSourceTable.h to obtain [SAMI] the AEST signature macro definition. ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h | 21 + ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h | 4 +- ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c | 755 ++++++++++++++++++++ ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c | 4 +- ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf | 3 +- ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni | 3 +- 6 files changed, 785 insertions(+), 5 deletions(-) diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h index f81ccac7e118378aa185db4b625e5bcd75f78347..41acd77b1890b6f8efea823843d43220dea63f67 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h @@ -462,6 +462,27 @@ ParseAcpiHeader ( ); /** + This function parses the ACPI AEST table. + When trace is enabled this function parses the AEST 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 +ParseAcpiAest ( + IN BOOLEAN Trace, + IN UINT8* Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ); + +/** This function parses the ACPI BGRT table. When trace is enabled this function parses the BGRT table and traces the ACPI table fields. diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h index 4f92596b90a6ee422d8d0959881015ffd3de4da0..0ebf79fb653ae3a8190273aee452723c6213eb58 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h @@ -1,7 +1,7 @@ /** @file Header file for ACPI table parser - Copyright (c) 2016 - 2018, ARM Limited. All rights reserved. + Copyright (c) 2016 - 2020, Arm Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -11,7 +11,7 @@ /** The maximum number of ACPI table parsers. */ -#define MAX_ACPI_TABLE_PARSERS 16 +#define MAX_ACPI_TABLE_PARSERS 32 /** An invalid/NULL signature value. */ diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c new file mode 100644 index 0000000000000000000000000000000000000000..7aa8c8fd2167822f4f5e0f6e4067195aac510e5c --- /dev/null +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c @@ -0,0 +1,755 @@ +/** @file + AEST table parser + + Copyright (c) 2020, Arm Limited. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document, + dated 28 September 2020. + (https://developer.arm.com/documentation/den0085/0101/) +**/ + +#include <Library/PrintLib.h> +#include <Library/UefiLib.h> +#include <IndustryStandard/ArmErrorSourceTable.h> +#include "AcpiParser.h" +#include "AcpiView.h" +#include "AcpiViewConfig.h" + +// Local variables +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; +STATIC UINT8* AestNodeType; +STATIC UINT16* AestNodeLength; +STATIC UINT32* NodeDataOffset; +STATIC UINT32* NodeInterfaceOffset; +STATIC UINT32* NodeInterruptArrayOffset; +STATIC UINT32* NodeInterruptCount; +STATIC UINT32* ProcessorId; +STATIC UINT8* ProcessorFlags; +STATIC UINT8* ProcessorResourceType; + +/** + Validate Processor Flags. + + @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 +ValidateProcessorFlags ( + IN UINT8* Ptr, + IN VOID* Context + ) +{ + // If the global or shared node flag is set then the ACPI Processor ID + // field must be set to 0 and ignored. + if (((*Ptr & 0x3) != 0) && (*ProcessorId != 0)) { + IncrementErrorCount (); + Print (L"\nERROR: 'ACPI Processor ID' field must be set to 0 for global" + L" or shared nodes."); + } +} + +/** + Validate GIC Interface Type. + + @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 +ValidateGicInterfaceType ( + IN UINT8* Ptr, + IN VOID* Context + ) +{ + UINT32 GicInterfaceType; + + GicInterfaceType = *(UINT32*)Ptr; + if (GicInterfaceType > 3) { + IncrementErrorCount (); + Print (L"\nError: Invalid GIC Interface type %d", GicInterfaceType); + } +} + +/** + Validate Interface Type. + + @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 +ValidateInterfaceType ( + IN UINT8* Ptr, + IN VOID* Context + ) +{ + if (*Ptr > 1) { + IncrementErrorCount (); + Print (L"\nError: Interface type should be 0 or 1"); + } +} + +/** + Validate Interrupt Type. + + @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 +ValidateInterruptType ( + IN UINT8* Ptr, + IN VOID* Context + ) +{ + if (*Ptr > 1) { + IncrementErrorCount (); + Print (L"\nError: Interrupt type should be 0 or 1"); + } +} + +/** + Validate interrupt flags. + + @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 +ValidateInterruptFlags ( + IN UINT8* Ptr, + IN VOID* Context + ) +{ + if ((*Ptr & 0xfe) != 0) { + IncrementErrorCount (); + Print (L"\nError: Reserved Flag bits not set to 0"); + } +} + +/** + Dumps 16 bytes of data. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +VOID +EFIAPI +DumpVendorSpecificData ( + IN CONST CHAR16* Format OPTIONAL, + IN UINT8* Ptr + ) +{ + Print ( + L"%02X %02X %02X %02X %02X %02X %02X %02X\n", + Ptr[0], + Ptr[1], + Ptr[2], + Ptr[3], + Ptr[4], + Ptr[5], + Ptr[6], + Ptr[7] + ); + + Print ( + L"%*a %02X %02X %02X %02X %02X %02X %02X %02X", + OUTPUT_FIELD_COLUMN_WIDTH, + "", + Ptr[8], + Ptr[9], + Ptr[10], + Ptr[11], + Ptr[12], + Ptr[13], + Ptr[14], + Ptr[15] + ); +} + +/** + An ACPI_PARSER array describing the ACPI AEST Table. +**/ +STATIC CONST ACPI_PARSER AestParser[] = { + PARSE_ACPI_HEADER (&AcpiHdrInfo) +}; + +/** + An ACPI_PARSER array describing the AEST Node Header. +**/ +STATIC CONST ACPI_PARSER AestNodeHeaderParser[] = { + {L"Type", 1, 0, L"%d", NULL, (VOID**)&AestNodeType, NULL, NULL}, + {L"Length", 2, 1, L"%d", NULL, (VOID**)&AestNodeLength, NULL, NULL}, + {L"Reserved", 1, 3, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Node Data Offset", 4, 4, L"%d", NULL, (VOID**)&NodeDataOffset, NULL, NULL}, + {L"Node Interface Offset", 4, 8, L"%d", NULL, + (VOID**)&NodeInterfaceOffset, NULL, NULL}, + {L"Node Interrupt Array Offset", 4, 12, L"%d", NULL, + (VOID**)&NodeInterruptArrayOffset, NULL, NULL}, + {L"Node Interrupt Count", 4, 16, L"%d", NULL, + (VOID**)&NodeInterruptCount, NULL, NULL}, + {L"Timestamp Rate", 8, 20, L"%ld", NULL, NULL, NULL, NULL}, + {L"Reserved1", 8, 28, L"0x%lx", NULL, NULL, NULL, NULL}, + {L"Error Injection Countdown Rate", 8, 36, L"%ld", NULL, NULL, NULL, NULL} + // Node specific data... + // Node interface... + // Node interrupt array... +}; + +/** + An ACPI_PARSER array describing the Processor error node specific data. +**/ +STATIC CONST ACPI_PARSER AestProcessorStructure[] = { + {L"ACPI Processor ID", 4, 0, L"0x%x", NULL, (VOID**)&ProcessorId, NULL, NULL}, + {L"Resource Type", 1, 4, L"%d", NULL, (VOID**)&ProcessorResourceType, NULL, + NULL}, + {L"Reserved", 1, 5, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Flags", 1, 6, L"0x%x", NULL, (VOID**)&ProcessorFlags, + ValidateProcessorFlags, NULL}, + {L"Revision", 1, 7, L"%d", NULL, NULL, NULL, NULL}, + {L"Processor Affinity Level Indicator", 8, 8, L"0x%lx", NULL, NULL, NULL, + NULL}, + // Resource specific data... +}; + +/** + An ACPI_PARSER array describing the processor cache resource substructure. +**/ +STATIC CONST ACPI_PARSER AestProcessorCacheResourceSubstructure[] = { + {L"Cache reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Reserved", 4, 4, L"%d", NULL, NULL, NULL, NULL} +}; + +/** + An ACPI_PARSER array describing the processor TLB resource substructure. +**/ +STATIC CONST ACPI_PARSER AestProcessorTlbResourceSubstructure[] = { + {L"TLB reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Reserved", 4, 4, L"%d", NULL, NULL, NULL, NULL} +}; + +/** + An ACPI_PARSER array describing the processor generic resource substructure. +**/ +STATIC CONST ACPI_PARSER AestProcessorGenericResourceSubstructure[] = { + {L"Vendor-defined data", 4, 0, L"%x", NULL, NULL, NULL, NULL} +}; + +/** + An ACPI_PARSER array describing the memory controller structure. +**/ +STATIC CONST ACPI_PARSER AestMemoryControllerStructure[] = { + {L"Proximity Domain", 4, 0, L"0x%x", NULL, NULL, NULL, NULL} +}; + +/** + An ACPI_PARSER array describing the SMMU structure. +**/ +STATIC CONST ACPI_PARSER AestSmmuStructure[] = { + {L"IORT Node reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL}, + {L"SubComponent reference ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL} +}; + +/** + An ACPI_PARSER array describing the vendor-defined structure. +**/ +STATIC CONST ACPI_PARSER AestVendorDefinedStructure[] = { + {L"Hardware ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Unique ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Vendor-specific data", 16, 8, NULL, DumpVendorSpecificData, NULL, NULL} +}; + +/** + An ACPI_PARSER array describing the GIC structure. +**/ +STATIC CONST ACPI_PARSER AestGicStructure[] = { + {L"GIC Interface Type", 4, 0, L"0x%x", NULL, NULL, ValidateGicInterfaceType, + NULL}, + {L"GIC Interface reference ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL} +}; + +/** + An ACPI_PARSER array describing the node interface. +**/ +STATIC CONST ACPI_PARSER AestNodeInterface[] = { + {L"Interface Type", 1, 0, L"%d", NULL, NULL, ValidateInterfaceType, NULL}, + {L"Reserved", 3, 1, L"%x %x %x", Dump3Chars, NULL, NULL, NULL}, + {L"Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL}, + {L"Start Error Record Index", 4, 16, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Number of Error Records", 4, 20, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Error Records Implemented", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL}, + {L"Error Records Support", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL}, + {L"Addressing mode", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL} +}; + +/** + An ACPI_PARSER array describing the node interrupts. +**/ +STATIC CONST ACPI_PARSER AestNodeInterrupt[] = { + {L"Interrupt Type", 1, 0, L"%d", NULL, NULL, ValidateInterruptType, NULL}, + {L"Reserved", 2, 1, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Interrupt Flags", 1, 3, L"0x%x", NULL, NULL, ValidateInterruptFlags, NULL}, + {L"Interrupt GSIV", 4, 4, L"0x%x", NULL, NULL, NULL, NULL}, + {L"ID", 1, 8, L"0x%x", NULL, NULL, NULL, NULL}, + {L"Reserved1", 3, 9, L"%x %x %x", Dump3Chars, NULL, NULL, NULL} +}; + +/** + Parses the Processor Error Node structure along with its resource + specific data. + + @param [in] Ptr Pointer to the start of the Processor node. + @param [in] Length Maximum length of the Processor node. +**/ +STATIC +VOID +DumpProcessorNode ( + IN UINT8* Ptr, + IN UINT32 Length + ) +{ + UINT32 Offset; + + Offset = ParseAcpi ( + TRUE, + 2, + "Processor", + Ptr, + Length, + PARSER_PARAMS (AestProcessorStructure) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((ProcessorId == NULL) || + (ProcessorResourceType == NULL) || + (ProcessorFlags == NULL)) { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient Processor Error Node length. Length = %d.\n", + Length + ); + return; + } + + switch (*ProcessorResourceType) { + case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_CACHE: + ParseAcpi ( + TRUE, + 2, + "Cache Resource", + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (AestProcessorCacheResourceSubstructure) + ); + break; + case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_TLB: + ParseAcpi ( + TRUE, + 2, + "TLB Resource", + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (AestProcessorTlbResourceSubstructure) + ); + break; + case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_GENERIC: + ParseAcpi ( + TRUE, + 2, + "Generic Resource", + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (AestProcessorGenericResourceSubstructure) + ); + break; + default: + IncrementErrorCount (); + Print (L"ERROR: Invalid Processor Resource Type."); + return; + } // switch +} + +/** + Parses the Memory Controller node. + + @param [in] Ptr Pointer to the start of the Memory Controller node. + @param [in] Length Maximum length of the Memory Controller node. +**/ +STATIC +VOID +DumpMemoryControllerNode ( + IN UINT8* Ptr, + IN UINT32 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "Memory Controller", + Ptr, + Length, + PARSER_PARAMS (AestMemoryControllerStructure) + ); +} + +/** + Parses the SMMU node. + + @param [in] Ptr Pointer to the start of the SMMU node. + @param [in] Length Maximum length of the SMMU node. +**/ +STATIC +VOID +DumpSmmuNode ( + IN UINT8* Ptr, + IN UINT32 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "SMMU", + Ptr, + Length, + PARSER_PARAMS (AestSmmuStructure) + ); +} + +/** + Parses the Vendor-defined structure. + + @param [in] Ptr Pointer to the start of the Vendor-defined node. + @param [in] Length Maximum length of the Vendor-defined node. +**/ +STATIC +VOID +DumpVendorDefinedNode ( + IN UINT8* Ptr, + IN UINT32 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "Vendor-defined", + Ptr, + Length, + PARSER_PARAMS (AestVendorDefinedStructure) + ); +} + +/** + Parses the GIC node. + + @param [in] Ptr Pointer to the start of the GIC node. + @param [in] Length Maximum length of the GIC node. +**/ +STATIC +VOID +DumpGicNode ( + IN UINT8* Ptr, + IN UINT32 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "GIC", + Ptr, + Length, + PARSER_PARAMS (AestGicStructure) + ); +} + +/** + Parses the Node Interface structure. + + @param [in] Ptr Pointer to the start of the Node Interface Structure. + @param [in] Length Maximum length of the Node Interface Structure. +**/ +STATIC +VOID +DumpNodeInterface ( + IN UINT8* Ptr, + IN UINT32 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "Node Interface", + Ptr, + Length, + PARSER_PARAMS (AestNodeInterface) + ); +} + +/** + Parses the Node Interrupts Structure. + + @param [in] Ptr Pointer to the start of the Node Interrupt array. + @param [in] Length Maximum length of the Node Interrupt array. + @param [in] InterruptCount Number if interrupts in the Node Interrupts array. +**/ +STATIC +VOID +DumpNodeInterrupts ( + IN UINT8* Ptr, + IN UINT32 Length, + IN UINT32 InterruptCount + ) +{ + UINT32 Offset; + UINT32 Index; + CHAR8 Buffer[64]; + + if (Length < (InterruptCount * sizeof (EFI_ACPI_AEST_INTERRUPT_STRUCT))) { + IncrementErrorCount (); + Print ( + L"ERROR: Node not long enough for Interrupt Array.\n"\ + L" Length left = %d, Required = %d, Interrupt Count = %d\n", + Length, + (InterruptCount * sizeof (EFI_ACPI_AEST_INTERRUPT_STRUCT)), + InterruptCount + ); + return; + } + + Offset = 0; + for (Index = 0; Index < InterruptCount; Index++) { + AsciiSPrint ( + Buffer, + sizeof (Buffer), + "Node Interrupt [%d]", + Index + ); + + Offset += ParseAcpi ( + TRUE, + 4, + Buffer, + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (AestNodeInterrupt) + ); + } //for +} + +/** + Parses a single AEST Node Structure. + + @param [in] Ptr Pointer to the start of the Node. + @param [in] Length Maximum length of the Node. + @param [in] NodeType AEST node type. + @param [in] DataOffset Offset to the node data. + @param [in] InterfaceOffset Offset to the node interface data. + @param [in] InterruptArrayOffset Offset to the node interrupt array. + @param [in] InterruptCount Number of interrupts. +**/ +STATIC +VOID +DumpAestNodeStructure ( + IN UINT8* Ptr, + IN UINT32 Length, + IN UINT8 NodeType, + IN UINT32 DataOffset, + IN UINT32 InterfaceOffset, + IN UINT32 InterruptArrayOffset, + IN UINT32 InterruptCount + ) +{ + UINT32 Offset; + UINT32 RemainingLength; + UINT8* NodeDataPtr; + + Offset = ParseAcpi ( + TRUE, + 2, + "Node Structure", + Ptr, + Length, + PARSER_PARAMS (AestNodeHeaderParser) + ); + + if ((Offset > DataOffset) || (DataOffset > Length)) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Node Data Offset: %d.\n"\ + L" It should be between %d and %d.\n", + DataOffset, + Offset, + Length + ); + } + + if ((Offset > InterfaceOffset) || (InterfaceOffset > Length)) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Node Interface Offset: %d.\n"\ + L" It should be between %d and %d.\n", + InterfaceOffset, + Offset, + Length + ); + } + + if ((Offset > InterruptArrayOffset) || (InterruptArrayOffset > Length)) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Node Interrupt Array Offset: %d.\n"\ + L" It should be between %d and %d.\n", + InterruptArrayOffset, + Offset, + Length + ); + } + + // Parse Node Data Field. + NodeDataPtr = Ptr + DataOffset; + RemainingLength = Length - DataOffset; + switch (NodeType) { + case EFI_ACPI_AEST_NODE_TYPE_PROCESSOR: + DumpProcessorNode (NodeDataPtr, RemainingLength); + break; + case EFI_ACPI_AEST_NODE_TYPE_MEMORY: + DumpMemoryControllerNode (NodeDataPtr, RemainingLength); + break; + case EFI_ACPI_AEST_NODE_TYPE_SMMU: + DumpSmmuNode (NodeDataPtr, RemainingLength); + break; + case EFI_ACPI_AEST_NODE_TYPE_VENDOR_DEFINED: + DumpVendorDefinedNode (NodeDataPtr, RemainingLength); + break; + case EFI_ACPI_AEST_NODE_TYPE_GIC: + DumpGicNode (NodeDataPtr, RemainingLength); + break; + default: + IncrementErrorCount (); + Print (L"ERROR: Invalid Error Node Type.\n"); + return; + } // switch + + // Parse the Interface Field. + DumpNodeInterface ( + Ptr + InterfaceOffset, + Length - InterfaceOffset + ); + + // Parse the Node Interrupt Array. + DumpNodeInterrupts ( + Ptr + InterruptArrayOffset, + Length - InterruptArrayOffset, + InterruptCount + ); + + return; +} + +/** + This function parses the ACPI AEST table. + When trace is enabled this function parses the AEST 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 +ParseAcpiAest ( + IN BOOLEAN Trace, + IN UINT8* Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + UINT32 Offset; + UINT8* NodePtr; + + if (!Trace) { + return; + } + + Offset = ParseAcpi ( + TRUE, + 0, + "AEST", + Ptr, + AcpiTableLength, + PARSER_PARAMS (AestParser) + ); + + while (Offset < AcpiTableLength) { + NodePtr = Ptr + Offset; + + ParseAcpi ( + FALSE, + 0, + NULL, + NodePtr, + AcpiTableLength - Offset, + PARSER_PARAMS (AestNodeHeaderParser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((AestNodeType == NULL) || + (AestNodeLength == NULL) || + (NodeDataOffset == NULL) || + (NodeInterfaceOffset == NULL) || + (NodeInterruptArrayOffset == NULL) || + (NodeInterruptCount == NULL)) { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient length left for Node Structure.\n"\ + L" Length left = %d.\n", + AcpiTableLength - Offset + ); + return; + } + + // Validate AEST Node length + if ((*AestNodeLength == 0) || + ((Offset + (*AestNodeLength)) > AcpiTableLength)) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid AEST Node length. " \ + L"Length = %d. Offset = %d. AcpiTableLength = %d.\n", + *AestNodeLength, + Offset, + AcpiTableLength + ); + return; + } + + DumpAestNodeStructure ( + NodePtr, + *AestNodeLength, + *AestNodeType, + *NodeDataOffset, + *NodeInterfaceOffset, + *NodeInterruptArrayOffset, + *NodeInterruptCount + ); + + Offset += *AestNodeLength; + } // while +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c index d2f26ff89f12e596702281c38ab0de3729aa68e4..502bdcf30be50579bc5a4de30b71dc8a44fd55ae 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c @@ -1,12 +1,13 @@ /** @file Main file for 'acpiview' Shell command function. - Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.<BR> + Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include <Guid/ShellLibHiiGuid.h> #include <IndustryStandard/Acpi.h> +#include <IndustryStandard/ArmErrorSourceTable.h> #include <Library/BaseMemoryLib.h> #include <Library/HiiLib.h> @@ -46,6 +47,7 @@ STATIC CONST SHELL_PARAM_ITEM ParamList[] = { STATIC CONST ACPI_TABLE_PARSER ParserList[] = { + {EFI_ACPI_6_3_ARM_ERROR_SOURCE_TABLE_SIGNATURE, ParseAcpiAest}, {EFI_ACPI_6_2_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE, ParseAcpiBgrt}, {EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE, ParseAcpiDbg2}, {EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf index 91459f9ec632635ee453c5ef46f67445cd9eee0c..d89cfbba0da833d5c945ebeb0b462fa52504a865 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf @@ -1,7 +1,7 @@ ## @file # Provides Shell 'acpiview' command functions # -# Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.<BR> +# Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR> # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -27,6 +27,7 @@ [Sources.common] AcpiView.h AcpiViewConfig.c AcpiViewConfig.h + Parsers/Aest/AestParser.c Parsers/Bgrt/BgrtParser.c Parsers/Dbg2/Dbg2Parser.c Parsers/Dsdt/DsdtParser.c diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni index 7cd43d0518fd0a23dc547a5cab0d08b62602a113..9dbffcd7c534fa9039668cfbe79f75d3a94c9b28 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni @@ -1,6 +1,6 @@ // /** // -// Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.<BR> +// Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR> // SPDX-License-Identifier: BSD-2-Clause-Patent // // Module Name: @@ -78,6 +78,7 @@ " other than AcpiTable header. The actual header can refer to the ACPI spec\r\n" " 6.2\r\n" " Extra A. Particular types:\r\n" +" AEST - Arm Error Source Table\r\n" " APIC - Multiple APIC Description Table (MADT)\r\n" " BGRT - Boot Graphics Resource Table\r\n" " DBG2 - Debug Port Table 2\r\n" -- 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)' ^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2020-10-22 1:26 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2020-10-21 15:55 [PATCH v2 0/2] Add AEST parser support to Acpiview Sami Mujawar 2020-10-21 15:55 ` [PATCH v2 1/2] MdePkg/IndustryStandard: AEST Table definition Sami Mujawar 2020-10-22 1:26 ` 回复: " gaoliming 2020-10-21 15:55 ` [PATCH v2 2/2] ShellPkg/Acpiview: AEST Parser Sami Mujawar
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox