ArmPkg/ArmPkg.dsc | 1 + ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf | 38 + ArmPkg/Application/ArmCpuInfo/readargs.h | 12 + ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.c | 2317 ++++++++++++++++++++ ArmPkg/Application/ArmCpuInfo/readregs.s | 49 + 5 files changed, 2417 insertions(+)
App goes through ID_AA64*_EL1 system registers and decode their values.
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
---
ArmPkg/ArmPkg.dsc | 1 +
ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf | 38 +
ArmPkg/Application/ArmCpuInfo/readargs.h | 12 +
ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.c | 2317 ++++++++++++++++++++
ArmPkg/Application/ArmCpuInfo/readregs.s | 49 +
5 files changed, 2417 insertions(+)
diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc
index 3fb95d1951a9..6b938ce8b671 100644
--- a/ArmPkg/ArmPkg.dsc
+++ b/ArmPkg/ArmPkg.dsc
@@ -166,6 +166,7 @@ [Components.AARCH64]
ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.inf
ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
+ ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf
[Components.AARCH64, Components.ARM]
ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf
diff --git a/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf b/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf
new file mode 100644
index 000000000000..158f86a4740c
--- /dev/null
+++ b/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf
@@ -0,0 +1,38 @@
+## @file
+#
+# Attempt to have AArch64 cpu information.
+#
+# Based on HelloWorld:
+# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
+# Copyright (c) 2023 Marcin Juszkiewicz
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010019
+ BASE_NAME = ArmCpuInfo
+ FILE_GUID = b3134491-6502-4faf-a9da-007184e32163
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = UefiMain
+
+#
+# This flag specifies whether HII resource section is generated into PE image.
+#
+ UEFI_HII_RESOURCE_SECTION = TRUE
+
+[Sources]
+ ArmCpuInfo.c
+ readregs.s
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ UefiApplicationEntryPoint
+ UefiLib
diff --git a/ArmPkg/Application/ArmCpuInfo/readargs.h b/ArmPkg/Application/ArmCpuInfo/readargs.h
new file mode 100644
index 000000000000..eaa52cf16145
--- /dev/null
+++ b/ArmPkg/Application/ArmCpuInfo/readargs.h
@@ -0,0 +1,12 @@
+UINT64 read_aa64pfr0_el1(void);
+UINT64 read_aa64pfr1_el1(void);
+UINT64 read_aa64dfr0_el1(void);
+UINT64 read_aa64dfr1_el1(void);
+UINT64 read_aa64isar0_el1(void);
+UINT64 read_aa64isar1_el1(void);
+UINT64 read_aa64isar2_el1(void);
+UINT64 read_aa64mmfr0_el1(void);
+UINT64 read_aa64mmfr1_el1(void);
+UINT64 read_aa64mmfr2_el1(void);
+UINT64 read_aa64smfr0_el1(void);
+UINT64 read_aa64zfr0_el1(void);
diff --git a/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.c b/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.c
new file mode 100644
index 000000000000..6c31ad4dbcb9
--- /dev/null
+++ b/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.c
@@ -0,0 +1,2317 @@
+/** @file
+
+ Copyright (c) 2023 Marcin Juszkiewicz
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ **/
+
+#include <Library/UefiLib.h>
+#include "readargs.h"
+
+void
+print_text (
+ const char *field,
+ const char *bits,
+ const char *value,
+ const char *description
+ )
+{
+ AsciiPrint (" %-16a | %5a | %5a | %a\n", field, bits, value, description);
+}
+
+void
+print_values (
+ const char *field,
+ const char *bits,
+ const int value,
+ const char *description
+ )
+{
+ STATIC CONST CHAR8 binaries[][5] = {
+ "0000", "0001", "0010", "0011",
+ "0100", "0101", "0110", "0111","1000", "1001", "1010", "1011",
+ "1100", "1101", "1110", "1111"
+ };
+
+ AsciiPrint (" %-16a | %5a | %5a | %a\n", field, bits, binaries[value & 0xf], description);
+}
+
+void
+print_spacer (
+ void
+ )
+{
+ AsciiPrint ("------------------|-------|-------|----------------------------------------------\n");
+}
+
+void
+handle_aa64mmfr0_el1 (
+ const UINT64 aa64mmfr0_el1
+ )
+{
+ UINT64 value;
+ STATIC CONST CHAR8 RegName[] = "ID_AA64MMFR0_EL1";
+ char *description;
+ char *bits;
+
+ bits = "3:0 ";
+ value = aa64mmfr0_el1 & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "32 bits (4GB) of physical address range supported.";
+ break;
+ case 0b0001:
+ description = "36 bits (64GB) of physical address range supported.";
+ break;
+ case 0b0010:
+ description = "40 bits (1TB) of physical address range supported.";
+ break;
+ case 0b0011:
+ description = "42 bits (4TB) of physical address range supported.";
+ break;
+ case 0b0100:
+ description = "44 bits (16TB) of physical address range supported.";
+ break;
+ case 0b0101:
+ description = "48 bits (256TB) of physical address range supported.";
+ break;
+ case 0b0110:
+ description = "52 bits (4PB) of physical address range supported.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+ if (value == 0b0110) {
+ print_text ("", "", "", "FEAT_LPA implemented.");
+ }
+
+ bits = "7:4 ";
+ value = (aa64mmfr0_el1 >> 4) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "ASID: 8 bits";
+ break;
+ case 0b0010:
+ description = "ASID: 16 bits";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "11:8 ";
+ value = (aa64mmfr0_el1 >> 8) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "No mixed-endian support.";
+ break;
+ case 0b0001:
+ description = "Mixed-endian support.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ // only valid for BigEnd != 0b0000
+ if (((aa64mmfr0_el1 >> 8) & 0xf) != 0b0000 ) {
+ if (((aa64mmfr0_el1 >> 16) & 0xf) == 0b0000 ) {
+ print_values ("ID_AA64MMFR0_EL1", "19:16", 0b0000, "No mixed-endian support at EL0.");
+ }
+
+ if (((aa64mmfr0_el1 >> 16) & 0xf) == 0b0001 ) {
+ print_values ("ID_AA64MMFR0_EL1", "19:16", 0b0001, "Mixed-endian support at EL0.");
+ }
+ }
+
+ bits = "15:12";
+ value = (aa64mmfr0_el1 >> 12) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "No support for a distinction between Secure and Non-Secure Memory.";
+ break;
+ case 0b0001:
+ description = "Supports a distinction between Secure and Non-Secure Memory.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "31:28";
+ value = (aa64mmfr0_el1 >> 28) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = " 4KB granule supported.";
+ break;
+ case 0b1111:
+ description = " 4KB granule not supported.";
+ break;
+ case 0b0001: // add FEAT_LPA2 check
+ description = " 4KB granule supported for 52-bit address.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "43:40";
+ value = (aa64mmfr0_el1 >> 40) & 0xf;
+ switch (value) {
+ case 0b0001:
+ description = " 4KB granule not supported at stage 2.";
+ break;
+ case 0b0010:
+ description = " 4KB granule supported at stage 2.";
+ break;
+ case 0b0011:
+ description = " 4KB granule supported at stage 2 for 52-bit address.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "23:20";
+ value = (aa64mmfr0_el1 >> 20) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "16KB granule not supported.";
+ break;
+ case 0b0001:
+ description = "16KB granule supported.";
+ break;
+ case 0b0010: // add FEAT_LPA2 check
+ description = "16KB granule supported for 52-bit address.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "35:32";
+ value = (aa64mmfr0_el1 >> 32) & 0xf;
+ switch (value) {
+ case 0b0001:
+ description = "16KB granule not supported at stage 2.";
+ break;
+ case 0b0010:
+ description = "16KB granule supported at stage 2.";
+ break;
+ case 0b0011:
+ description = "16KB granule supported at stage 2 for 52-bit address.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "27:24";
+ value = (aa64mmfr0_el1 >> 24) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "64KB granule supported.";
+ break;
+ case 0b1111:
+ description = "64KB granule not supported.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "39:36";
+ value = (aa64mmfr0_el1 >> 36) & 0xf;
+ switch (value) {
+ case 0b0001:
+ description = "64KB granule not supported at stage 2.";
+ break;
+ case 0b0010:
+ description = "64KB granule supported at stage 2.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "47:44";
+ value = (aa64mmfr0_el1 >> 44) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_ExS not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_ExS implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ // 55:48 reserved
+
+ bits = "59:56";
+ value = (aa64mmfr0_el1 >> 56) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_FGT not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_FGT implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "63:60";
+ value = (aa64mmfr0_el1 >> 60) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_ECV not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_ECV implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_ECV implemented with extras.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+}
+
+void
+handle_aa64mmfr1_el1 (
+ const UINT64 aa64mmfr1_el1,
+ const UINT64 aa64pfr0_el1
+ )
+{
+ UINT64 value;
+ STATIC CONST CHAR8 RegName[] = "ID_AA64MMFR1_EL1";
+ char *description;
+ char *bits;
+
+ bits = "3:0 ";
+ value = aa64mmfr1_el1 & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_HAFDBS not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_HAFDBS implemented without dirty status support.";
+ break;
+ case 0b0010:
+ description = "FEAT_HAFDBS implemented with dirty status support.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "7:4 ";
+ value = (aa64mmfr1_el1 >> 4) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_VMID16 not implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_VMID16 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "11:8 ";
+ value = (aa64mmfr1_el1 >> 8) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_VHE not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_VHE implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "15:12";
+ value = (aa64mmfr1_el1 >> 12) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_HPDS not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_HPDS implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_HPDS2 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "19:16";
+ value = (aa64mmfr1_el1 >> 16) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_LOR not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_LOR implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "23:20";
+ value = (aa64mmfr1_el1 >> 20) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_PAN not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_PAN implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_PAN2 implemented.";
+ break;
+ case 0b0011:
+ description = "FEAT_PAN3 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ // when FEAT_RAS implemented
+ if ((((aa64pfr0_el1 >> 28) & 0xf) == 0b0001) ||
+ (((aa64pfr0_el1 >> 28) & 0xf) == 0b0010))
+ {
+ if (((aa64mmfr1_el1 >> 24) & 0xf) == 0b0000 ) {
+ print_values ("ID_AA64MMFR1_EL1", "27:24", 0b0000, "The PE never generates an SError interrupt due to");
+ print_text ("", "", "", "an External abort on a speculative read.");
+ }
+
+ if (((aa64mmfr1_el1 >> 24) & 0xf) == 0b0001 ) {
+ print_values ("ID_AA64MMFR1_EL1", "27:24", 0b0001, "The PE might generate an SError interrupt due to");
+ print_text ("", "", "", "an External abort on a speculative read.");
+ }
+ }
+
+ bits = "31:28";
+ value = (aa64mmfr1_el1 >> 28) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_XNX not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_XNX implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "35:32";
+ value = (aa64mmfr1_el1 >> 32) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_TWED not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_TWED implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "39:36";
+ value = (aa64mmfr1_el1 >> 36) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_ETS not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_ETS implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "43:40";
+ value = (aa64mmfr1_el1 >> 40) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_HCX not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_HCX implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "47:44";
+ value = (aa64mmfr1_el1 >> 44) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_AFP not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_AFP implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "51:48";
+ value = (aa64mmfr1_el1 >> 48) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_nTLBPA not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_nTLBPA implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "55:52";
+ value = (aa64mmfr1_el1 >> 52) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_TIDCP1 not implemented";
+ break;
+ case 0b0001:
+ description = "FEAT_TIDCP1 implemented";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "59:56";
+ value = (aa64mmfr1_el1 >> 56) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_CMOW not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_CMOW implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ // 63:60 reserved
+}
+
+void
+handle_aa64mmfr2_el1 (
+ const UINT64 aa64mmfr2_el1
+ )
+{
+ UINT64 value;
+ STATIC CONST CHAR8 RegName[] = "ID_AA64MMFR2_EL1";
+ char *description;
+ char *bits;
+
+ bits = "3:0 ";
+ value = (aa64mmfr2_el1) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_TTCNP not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_TTCNP implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "7:4 ";
+ value = (aa64mmfr2_el1 >> 4) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_UAO not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_UAO implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "11:8 ";
+ value = (aa64mmfr2_el1 >> 8) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_LSMAOC not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_LSMAOC implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "15:12";
+ value = (aa64mmfr2_el1 >> 12) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_IESB not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_IESB implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "19:16";
+ value = (aa64mmfr2_el1 >> 16) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_LVA not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_LVA implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "23:20";
+ value = (aa64mmfr2_el1 >> 20) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_CCIDX not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_CCIDX implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "27:24";
+ value = (aa64mmfr2_el1 >> 24) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_NV not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_NV implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_NV2 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "31:28";
+ value = (aa64mmfr2_el1 >> 28) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_TTST not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_TTST implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "35:32";
+ value = (aa64mmfr2_el1 >> 32) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_LSE2 not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_LSE2 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "39:36";
+ value = (aa64mmfr2_el1 >> 36) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_IDST not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_IDST implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "43:40";
+ value = (aa64mmfr2_el1 >> 40) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_S2FWB not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_S2FWB implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ // 47:44 reserved
+
+ bits = "51:48";
+ value = (aa64mmfr2_el1 >> 48) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_TTL not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_TTL implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "55:52";
+ value = (aa64mmfr2_el1 >> 52) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_BBM: Level 0 support for changing block size is supported.";
+ break;
+ case 0b0001:
+ description = "FEAT_BBM: Level 1 support for changing block size is supported.";
+ break;
+ case 0b0010:
+ description = "FEAT_BBM: Level 2 support for changing block size is supported.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "59:56";
+ value = (aa64mmfr2_el1 >> 56) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_EVT not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_EVT: HCR_EL2.{TOCU, TICAB, TID4} traps are supported.";
+ break;
+ case 0b0010:
+ description = "FEAT_EVT: HCR_EL2.{TTLBOS, TTLSBIS, TOCU, TICAB, TID4} traps are supported.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "63:60";
+ value = (aa64mmfr2_el1 >> 60) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_E0PD not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_E0PD implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+}
+
+void
+handle_aa64pfr0_el1 (
+ const UINT64 aa64pfr0_el1,
+ const UINT64 aa64pfr1_el1
+ )
+{
+ UINT64 value;
+ STATIC CONST CHAR8 RegName[] = "ID_AA64PFR0_EL1";
+ char *description;
+ char *bits;
+
+ bits = "3:0 ";
+ value = (aa64pfr0_el1) & 0xf;
+ switch (value) {
+ case 0b0001:
+ description = "EL0 in AArch64 only";
+ break;
+ case 0b0010:
+ description = "EL0 in AArch64 and AArch32";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "7:4 ";
+ value = (aa64pfr0_el1 >> 4) & 0xf;
+ switch (value) {
+ case 0b0001:
+ description = "EL1 in AArch64 only";
+ break;
+ case 0b0010:
+ description = "EL1 in AArch64 and AArch32";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "11:8 ";
+ value = (aa64pfr0_el1 >> 8) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "EL2 not implemented.";
+ break;
+ case 0b0001:
+ description = "EL2 in AArch64 only";
+ break;
+ case 0b0010:
+ description = "EL2 in AArch64 and AArch32";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "15:12";
+ value = (aa64pfr0_el1 >> 12) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "EL3 not implemented.";
+ break;
+ case 0b0001:
+ description = "EL3 in AArch64 only";
+ break;
+ case 0b0010:
+ description = "EL3 in AArch64 and AArch32";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "19:16";
+ value = (aa64pfr0_el1 >> 16) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "Floating-point implemented.";
+ break;
+ case 0b0001:
+ description = "Floating-point with half-precision support (FEAT_FP16).";
+ break;
+ case 0b1111:
+ description = "Floating-point not implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "23:20";
+ value = (aa64pfr0_el1 >> 20) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "Advanced SIMD implemented.";
+ break;
+ case 0b0001:
+ description = "Advanced SIMD with half precision support (FEAT_FP16).";
+ break;
+ case 0b1111:
+ description = "Advanced SIMD not implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "27:24";
+ value = (aa64pfr0_el1 >> 24) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "System registers of GIC CPU not implemented.";
+ break;
+ case 0b0001:
+ description = "System registers to versions 3.0/4.0 of GIC CPU implemented.";
+ break;
+ case 0b0011:
+ description = "System registers to versions 4.1 of GIC CPU implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "31:28";
+ value = (aa64pfr0_el1 >> 28) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_RAS not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_RAS implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_RASv1p1 implemented.";
+ // 0b0010 FEAT_RASv1p1 implemented and, if EL3 is implemented, FEAT_DoubleFault implemented.
+ if ((((aa64pfr0_el1 >> 12) & 0xf) == 0b0001) ||
+ (((aa64pfr0_el1 >> 12) & 0xf) == 0b0010))
+ {
+ description = "FEAT_RASv1p1 implemented. FEAT_DoubleFault implemented.";
+ }
+
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "35:32";
+ value = (aa64pfr0_el1 >> 32) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_SVE not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_SVE implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "39:36";
+ value = (aa64pfr0_el1 >> 36) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "Secure EL2 not implemented.";
+ break;
+ case 0b0001:
+ description = "Secure EL2 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "43:40";
+ value = (aa64pfr0_el1 >> 40) & 0xf;
+ switch (value) {
+ case 0b0000:
+ if (((aa64pfr1_el1 >> 16) & 0xf) == 0b0000 ) {
+ description = "FEAT_MPAM not implemented.";
+ }
+
+ if (((aa64pfr1_el1 >> 16) & 0xf) == 0b0001 ) {
+ description = "FEAT_MPAM v0.1 implemented.";
+ }
+
+ break;
+ case 0b0001:
+ if (((aa64pfr1_el1 >> 16) & 0xf) == 0b0000 ) {
+ description = "FEAT_MPAM v1.0 implemented.";
+ }
+
+ if (((aa64pfr1_el1 >> 16) & 0xf) == 0b0001 ) {
+ description = "FEAT_MPAM v1.1 implemented.";
+ }
+
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "47:44";
+ value = (aa64pfr0_el1 >> 44) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_AMU not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_AMUv1 implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_AMUv1p1 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "51:48";
+ value = (aa64pfr0_el1 >> 48) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_DIT not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_DIT implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "55:52";
+ value = (aa64pfr0_el1 >> 52) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_RME not implemented";
+ break;
+ case 0b0001:
+ description = "FEAT_RME implemented";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "59:56";
+ value = (aa64pfr0_el1 >> 56) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "no info is FEAT_CSV2 implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_CSV2 implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_CSV2_2 implemented.";
+ break;
+ case 0b0011:
+ description = "FEAT_CSV2_3 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+ if (value == 0b0001) {
+ if (((aa64pfr1_el1 >> 32) & 0xf) == 0b0001 ) {
+ print_values ("ID_AA64PRF1_EL1", "35:32", 0b0001, "FEAT_CSV2_1p1 implemented.");
+ }
+
+ if (((aa64pfr1_el1 >> 32) & 0xf) == 0b0010 ) {
+ print_values ("ID_AA64PRF1_EL1", "35:32", 0b0010, "FEAT_CSV2_1p2 implemented.");
+ }
+ }
+
+ bits = "63:60";
+ value = (aa64pfr0_el1 >> 60) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_CSV3 not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_CSV3 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+}
+
+void
+handle_aa64pfr1_el1 (
+ const UINT64 aa64pfr1_el1
+ )
+{
+ UINT64 value;
+ STATIC CONST CHAR8 RegName[] = "ID_AA64PFR1_EL1";
+ char *description;
+ char *bits;
+
+ bits = "3:0 ";
+ value = aa64pfr1_el1 & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_BTI not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_BTI implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "7:4 ";
+ value = (aa64pfr1_el1 >> 4) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_SSBS not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_SSBS implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_SSBS2 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "11:8 ";
+ value = (aa64pfr1_el1 >> 8) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_MTE not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_MTE implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_MTE2 implemented.";
+ break;
+ case 0b0011:
+ description = "FEAT_MTE3 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ // 15:12 is RAS_frac
+ // 19:16 is MPAM_frac
+ // 23:20 is reserved
+
+ bits = "27:24";
+ value = (aa64pfr1_el1 >> 24) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_SME not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_SME implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "31:28";
+ value = (aa64pfr1_el1 >> 28) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_RNG_TRAP not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_RNG_TRAP implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ // 35:32 is CSV2_frac
+
+ bits = "39:36";
+ value = (aa64pfr1_el1 >> 36) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_NMI not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_NMI implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ // 63:40 are reserved
+}
+
+void
+handle_aa64isar0_el1 (
+ const UINT64 aa64isar0_el1
+ )
+{
+ UINT64 value;
+ STATIC CONST CHAR8 RegName[] = "ID_AA64ISAR0_EL1";
+ char *description;
+ char *bits;
+
+ // 3:0 reserved
+
+ bits = "7:4 ";
+ value = (aa64isar0_el1 >> 4) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_AES, FEAT_PMULL not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_AES implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_AES and FEAT_PMULL implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "11:8 ";
+ value = (aa64isar0_el1 >> 8) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_SHA1 not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_SHA1 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "15:12";
+ value = (aa64isar0_el1 >> 12) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_SHA256, FEAT_SHA512 not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_SHA256 implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_SHA512 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "19:16";
+ value = (aa64isar0_el1 >> 16) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "CRC32 not implemented.";
+ break;
+ case 0b0001:
+ description = "CRC32 instructions implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "23:20";
+ value = (aa64isar0_el1 >> 20) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_LSE not implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_LSE implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "27:24";
+ value = (aa64isar0_el1 >> 24) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "TME instructions not implemented.";
+ break;
+ case 0b0001:
+ description = "TME instructions implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "31:28";
+ value = (aa64isar0_el1 >> 28) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_RDM not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_RDM implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "35:32";
+ value = (aa64isar0_el1 >> 32) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_SHA3 not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_SHA3 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "39:36";
+ value = (aa64isar0_el1 >> 36) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_SM3 not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_SM3 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "43:40";
+ value = (aa64isar0_el1 >> 40) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_SM4 not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_SM4 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "47:44";
+ value = (aa64isar0_el1 >> 44) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_DotProd not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_DotProd implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "51:48";
+ value = (aa64isar0_el1 >> 48) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_FHM not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_FHM implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "55:52";
+ value = (aa64isar0_el1 >> 52) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_FlagM/FEAT_FlagM2 not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_FlagM implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_FlagM2 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "59:56";
+ value = (aa64isar0_el1 >> 56) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_TLBIOS/FEAT_TLBIRANGE not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_TLBIOS implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_TLBIRANGE implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "63:60";
+ value = (aa64isar0_el1 >> 60) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_RNG not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_RNG implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+}
+
+void
+handle_aa64isar1_el1 (
+ const UINT64 aa64isar1_el1
+ )
+{
+ UINT64 value;
+ STATIC CONST CHAR8 RegName[] = "ID_AA64ISAR1_EL1";
+ char *description;
+ char *bits;
+
+ bits = "3:0 ";
+ value = (aa64isar1_el1 >> 4) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "DC CVAP not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_DPB implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_DPB2 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "7:4 ";
+ value = (aa64isar1_el1 >> 4) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "Address Authentication (APA) not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_PAuth implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_EPAC implemented.";
+ break;
+ case 0b0011:
+ description = "FEAT_PAuth2 implemented.";
+ break;
+ case 0b0100:
+ description = "FEAT_FPAC implemented.";
+ break;
+ case 0b0101:
+ description = "FEAT_FPACCOMBINE implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+ if (value > 0) {
+ print_text ("", "", "", "FEAT_PACQARMA5 implemented.");
+ }
+
+ bits = "11:8 ";
+ value = (aa64isar1_el1 >> 8) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "Address Authentication (API) not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_PAuth implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_EPAC implemented.";
+ break;
+ case 0b0011:
+ description = "FEAT_PAuth2 implemented.";
+ break;
+ case 0b0100:
+ description = "FEAT_FPAC implemented.";
+ break;
+ case 0b0101:
+ description = "FEAT_FPACCOMBINE implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+ if (value > 0) {
+ print_text ("", "", "", "FEAT_PACIMP implemented.");
+ }
+
+ bits = "15:12";
+ value = (aa64isar1_el1 >> 12) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_JSCVT not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_JSCVT implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "19:16";
+ value = (aa64isar1_el1 >> 16) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_FCMA not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_FCMA implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "23:20";
+ value = (aa64isar1_el1 >> 20) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_LRCPC (2) not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_LRCPC implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_LRCPC2 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "27:24";
+ value = (aa64isar1_el1 >> 24) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_PACQARMA5 not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_PACQARMA5 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "31:28";
+ value = (aa64isar1_el1 >> 28) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_PACIMP not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_PACIMP implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "35:32";
+ value = (aa64isar1_el1 >> 32) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_FRINTTS not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_FRINTTS implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "39:36";
+ value = (aa64isar1_el1 >> 36) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_SB not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_SB implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "43:40";
+ value = (aa64isar1_el1 >> 40) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_SPECRES not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_SPECRES implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "47:44";
+ value = (aa64isar1_el1 >> 44) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_BF16 not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_BF16 implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_EBF16 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "51:48";
+ value = (aa64isar1_el1 >> 48) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_DGH not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_DGH implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "55:52";
+ value = (aa64isar1_el1 >> 52) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_I8MM not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_I8MM implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "59:56";
+ value = (aa64isar1_el1 >> 56) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_XS not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_XS implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "63:60";
+ value = (aa64isar1_el1 >> 60) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_LS64 not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_LS64 implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_LS64_V implemented.";
+ break;
+ case 0b0011:
+ description = "FEAT_LS64_ACCDATA implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+}
+
+void
+handle_aa64isar2_el1 (
+ const UINT64 aa64isar2_el1
+ )
+{
+ UINT64 value;
+ STATIC CONST CHAR8 RegName[] = "ID_AA64ISAR2_EL1";
+ char *description;
+ char *bits;
+
+ bits = "3:0 ";
+ value = (aa64isar2_el1 >> 4) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_WFxT not implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_WFxT implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "7:4 ";
+ value = (aa64isar2_el1 >> 4) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_RPRES not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_RPRES implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "11:8 ";
+ value = (aa64isar2_el1 >> 8) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_PACQARMA3 not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_PACQARMA3 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "15:12";
+ value = (aa64isar2_el1 >> 12) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "Address Authentication (APA3) not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_PAuth implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_EPAC implemented.";
+ break;
+ case 0b0011:
+ description = "FEAT_PAuth2 implemented.";
+ break;
+ case 0b0100:
+ description = "FEAT_FPAC implemented.";
+ break;
+ case 0b0101:
+ description = "FEAT_FPACCOMBINE implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "19:16";
+ value = (aa64isar2_el1 >> 16) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_MOPS not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_MOPS implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "23:20";
+ value = (aa64isar2_el1 >> 20) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_HBC not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_HBC implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "27:24";
+ value = (aa64isar2_el1 >> 24) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_CONSTPACFIELD not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_CONSTPACFIELD implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ // 63:28 reserved
+}
+
+void
+handle_aa64dfr0_el1 (
+ const UINT64 aa64dfr0_el1
+ )
+{
+ UINT64 value;
+ STATIC CONST CHAR8 RegName[] = "ID_AA64DFR0_EL1";
+ char *description;
+ char *bits;
+
+ bits = "3:0 ";
+ value = (aa64dfr0_el1 >> 4) & 0xf;
+ switch (value) {
+ case 0b0110:
+ description = "Armv8 debug architecture";
+ break;
+ case 0b0111:
+ description = "Armv8 debug architecture with VHE";
+ break;
+ case 0b1000:
+ description = "FEAT_Debugv8p2 implemented.";
+ break;
+ case 0b1001:
+ description = "FEAT_Debugv8p4 implemented.";
+ break;
+ case 0b1010:
+ description = "FEAT_Debugv8p8 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "7:4 ";
+ value = (aa64dfr0_el1 >> 4) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "Trace unit System registers not implemented.";
+ break;
+ case 0b0001:
+ description = "Trace unit System registers implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "11:8 ";
+ value = (aa64dfr0_el1 >> 8) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "Performance Monitors Extension not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_PMUv3 implemented.";
+ break;
+ case 0b0100:
+ description = "FEAT_PMUv3p1 implemented.";
+ break;
+ case 0b0101:
+ description = "FEAT_PMUv3p4 implemented.";
+ break;
+ case 0b0110:
+ description = "FEAT_PMUv3p5 implemented.";
+ break;
+ case 0b0111:
+ description = "FEAT_PMUv3p7 implemented.";
+ break;
+ case 0b1000:
+ description = "FEAT_PMUv3p8 implemented.";
+ break;
+ case 0b1111:
+ description = "IMPLEMENTATION DEFINED form of performance monitors supported.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "15:12";
+ value = (aa64dfr0_el1 >> 12) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "reserved";
+ break;
+ default:
+ description = "Number of breakpoints, minus 1.";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ // 19:16 reserved
+
+ bits = "23:20";
+ value = (aa64dfr0_el1 >> 20) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "reserved";
+ break;
+ default:
+ description = "Number of watchpoints, minus 1.";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ // 27:24 reserved
+
+ bits = "31:28";
+ value = (aa64dfr0_el1 >> 28) & 0xf;
+ switch (value) {
+ default:
+ description = "Number of breakpoints that are context-aware, minus 1.";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "35:32";
+ value = (aa64dfr0_el1 >> 32) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_SPE not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_SPE implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_SPEv1p1 implemented.";
+ break;
+ case 0b0011:
+ description = "FEAT_SPEv1p2 implemented.";
+ break;
+ case 0b0100:
+ description = "FEAT_SPEv1p3 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "39:36";
+ value = (aa64dfr0_el1 >> 36) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_DoubleLock implemented.";
+ break;
+ case 0b1111:
+ description = "FEAT_DoubleLock not implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "43:40";
+ value = (aa64dfr0_el1 >> 40) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_TRF not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_TRF implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "47:44";
+ value = (aa64dfr0_el1 >> 44) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_TRBE not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_TRBE implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "51:48";
+ value = (aa64dfr0_el1 >> 48) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_MTPMU not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_MTPMU and FEAT_PMUv3 implemented.";
+ break;
+ case 0b1111:
+ description = "FEAT_MTPMU not implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ bits = "55:52";
+ value = (aa64dfr0_el1 >> 52) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "FEAT_BRBE not implemented.";
+ break;
+ case 0b0001:
+ description = "FEAT_BRBE implemented.";
+ break;
+ case 0b0010:
+ description = "FEAT_BRBEv1p1 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+
+ // 59:56 reserved
+
+ bits = "63:60";
+ value = (aa64dfr0_el1 >> 60) & 0xf;
+ switch (value) {
+ case 0b0000:
+ description = "Setting MDCR_EL2.HPMN to zero has CONSTRAINED UNPREDICTABLE behavior.";
+ break;
+ case 0b0001:
+ description = "FEAT_HPMN0 implemented.";
+ break;
+ default:
+ description = "unknown";
+ break;
+ }
+
+ print_values (RegName, bits, value, description);
+}
+
+EFI_STATUS
+EFIAPI
+UefiMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ UINT64 aa64dfr0_el1 = read_aa64dfr0_el1 ();
+ UINT64 aa64dfr1_el1 = read_aa64dfr1_el1 ();
+ UINT64 aa64isar0_el1 = read_aa64isar0_el1 ();
+ UINT64 aa64isar1_el1 = read_aa64isar1_el1 ();
+ UINT64 aa64isar2_el1 = read_aa64isar2_el1 ();
+ UINT64 aa64mmfr0_el1 = read_aa64mmfr0_el1 ();
+ UINT64 aa64mmfr1_el1 = read_aa64mmfr1_el1 ();
+ UINT64 aa64mmfr2_el1 = read_aa64mmfr2_el1 ();
+ UINT64 aa64pfr0_el1 = read_aa64pfr0_el1 ();
+ UINT64 aa64pfr1_el1 = read_aa64pfr1_el1 ();
+
+ /* UINT64 aa64smfr0_el1 = read_aa64smfr0_el1 ();*/
+ /* UINT64 aa64zfr0_el1 = read_aa64zfr0_el1 ();*/
+
+ AsciiPrint ("ID_AA64MMFR0_EL1 = 0x%016lx\n", aa64mmfr0_el1);
+ AsciiPrint ("ID_AA64MMFR1_EL1 = 0x%016lx\n", aa64mmfr1_el1);
+ AsciiPrint ("ID_AA64MMFR2_EL1 = 0x%016lx\n", aa64mmfr2_el1);
+ AsciiPrint ("ID_AA64PFR0_EL1 = 0x%016lx\n", aa64pfr0_el1);
+ AsciiPrint ("ID_AA64PFR1_EL1 = 0x%016lx\n", aa64pfr1_el1);
+ AsciiPrint ("ID_AA64ISAR0_EL1 = 0x%016lx\n", aa64isar0_el1);
+ AsciiPrint ("ID_AA64ISAR1_EL1 = 0x%016lx\n", aa64isar1_el1);
+ AsciiPrint ("ID_AA64ISAR2_EL1 = 0x%016lx\n", aa64isar2_el1);
+ AsciiPrint ("ID_AA64DFR0_EL1 = 0x%016lx\n", aa64dfr0_el1);
+ AsciiPrint ("ID_AA64DFR1_EL1 = 0x%016lx\n", aa64dfr1_el1); // ignore
+ /* AsciiPrint ("ID_AA64SMFR0_EL1 = 0x%016lx\n", aa64smfr0_el1);*/
+ /* AsciiPrint ("ID_AA64ZFR0_EL1 = 0x%016lx\n", aa64zfr0_el1);*/
+
+ AsciiPrint ("\n");
+ print_text ("Register", "Bits", "Value", "Feature");
+ print_spacer ();
+
+ handle_aa64mmfr0_el1 (aa64mmfr0_el1);
+ print_spacer ();
+ handle_aa64mmfr1_el1 (aa64mmfr1_el1, aa64pfr0_el1);
+ print_spacer ();
+ handle_aa64mmfr2_el1 (aa64mmfr2_el1);
+
+ print_spacer ();
+ handle_aa64pfr0_el1 (aa64pfr0_el1, aa64pfr1_el1);
+ print_spacer ();
+ handle_aa64pfr1_el1 (aa64pfr1_el1);
+
+ print_spacer ();
+ handle_aa64isar0_el1 (aa64isar0_el1);
+ print_spacer ();
+ handle_aa64isar1_el1 (aa64isar1_el1);
+ print_spacer ();
+ handle_aa64isar2_el1 (aa64isar2_el1);
+
+ print_spacer ();
+ handle_aa64dfr0_el1 (aa64dfr0_el1);
+
+ return EFI_SUCCESS;
+}
diff --git a/ArmPkg/Application/ArmCpuInfo/readregs.s b/ArmPkg/Application/ArmCpuInfo/readregs.s
new file mode 100644
index 000000000000..052834b3c3f2
--- /dev/null
+++ b/ArmPkg/Application/ArmCpuInfo/readregs.s
@@ -0,0 +1,49 @@
+#include <AsmMacroIoLibV8.h>
+
+ASM_FUNC(read_aa64pfr0_el1)
+ mrs x0, ID_AA64PFR0_EL1;
+ ret;
+
+ASM_FUNC(read_aa64pfr1_el1)
+ mrs x0, ID_AA64PFR1_EL1;
+ ret;
+
+ASM_FUNC(read_aa64dfr0_el1)
+ mrs x0, ID_AA64DFR0_EL1;
+ ret;
+
+ASM_FUNC(read_aa64dfr1_el1)
+ mrs x0, ID_AA64DFR1_EL1;
+ ret;
+
+ASM_FUNC(read_aa64isar0_el1)
+ mrs x0, ID_AA64ISAR0_EL1;
+ ret;
+
+ASM_FUNC(read_aa64isar1_el1)
+ mrs x0, ID_AA64ISAR1_EL1;
+ ret;
+
+ASM_FUNC(read_aa64isar2_el1)
+ mrs x0, ID_AA64ISAR2_EL1;
+ ret;
+
+ASM_FUNC(read_aa64mmfr0_el1)
+ mrs x0, ID_AA64MMFR0_EL1;
+ ret;
+
+ASM_FUNC(read_aa64mmfr1_el1)
+ mrs x0, ID_AA64MMFR1_EL1;
+ ret;
+
+ASM_FUNC(read_aa64mmfr2_el1)
+ mrs x0, ID_AA64MMFR2_EL1;
+ ret;
+
+# ASM_FUNC(read_aa64zfr0_el1)
+# mrs x0, ID_AA64ZFR0_EL1;
+# ret;
+
+# ASM_FUNC(read_aa64smfr0_el1)
+# mrs x0, ID_AA64SMFR0_EL1;
+# ret;
--
2.40.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#102694): https://edk2.groups.io/g/devel/message/102694
Mute This Topic: https://groups.io/mt/98123579/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
On Fri, Apr 7, 2023 at 1:47 PM Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org> wrote: > > App goes through ID_AA64*_EL1 system registers and decode their values. > > Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org> > --- > ArmPkg/ArmPkg.dsc | 1 + > ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf | 38 + > ArmPkg/Application/ArmCpuInfo/readargs.h | 12 + > ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.c | 2317 ++++++++++++++++++++ > ArmPkg/Application/ArmCpuInfo/readregs.s | 49 + > 5 files changed, 2417 insertions(+) > > diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc > index 3fb95d1951a9..6b938ce8b671 100644 > --- a/ArmPkg/ArmPkg.dsc > +++ b/ArmPkg/ArmPkg.dsc > @@ -166,6 +166,7 @@ [Components.AARCH64] > ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.inf > ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf > ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf > + ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf > > [Components.AARCH64, Components.ARM] > ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf > diff --git a/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf b/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf > new file mode 100644 > index 000000000000..158f86a4740c > --- /dev/null > +++ b/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf > @@ -0,0 +1,38 @@ > +## @file > +# > +# Attempt to have AArch64 cpu information. > +# > +# Based on HelloWorld: > +# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved. > +# Copyright (c) 2023 Marcin Juszkiewicz > +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +# > +## > + > +[Defines] > + INF_VERSION = 0x00010019 > + BASE_NAME = ArmCpuInfo > + FILE_GUID = b3134491-6502-4faf-a9da-007184e32163 > + MODULE_TYPE = UEFI_APPLICATION > + VERSION_STRING = 1.0 > + ENTRY_POINT = UefiMain > + > +# > +# This flag specifies whether HII resource section is generated into PE image. > +# > + UEFI_HII_RESOURCE_SECTION = TRUE > + > +[Sources] > + ArmCpuInfo.c > + readregs.s > + > +[Packages] > + ArmPkg/ArmPkg.dec > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + > +[LibraryClasses] > + UefiApplicationEntryPoint > + UefiLib > diff --git a/ArmPkg/Application/ArmCpuInfo/readargs.h b/ArmPkg/Application/ArmCpuInfo/readargs.h > new file mode 100644 > index 000000000000..eaa52cf16145 > --- /dev/null > +++ b/ArmPkg/Application/ArmCpuInfo/readargs.h > @@ -0,0 +1,12 @@ > +UINT64 read_aa64pfr0_el1(void); > +UINT64 read_aa64pfr1_el1(void); > +UINT64 read_aa64dfr0_el1(void); > +UINT64 read_aa64dfr1_el1(void); > +UINT64 read_aa64isar0_el1(void); > +UINT64 read_aa64isar1_el1(void); > +UINT64 read_aa64isar2_el1(void); > +UINT64 read_aa64mmfr0_el1(void); > +UINT64 read_aa64mmfr1_el1(void); > +UINT64 read_aa64mmfr2_el1(void); > +UINT64 read_aa64smfr0_el1(void); > +UINT64 read_aa64zfr0_el1(void); > diff --git a/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.c b/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.c > new file mode 100644 > index 000000000000..6c31ad4dbcb9 > --- /dev/null > +++ b/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.c > @@ -0,0 +1,2317 @@ > +/** @file > + > + Copyright (c) 2023 Marcin Juszkiewicz > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > + **/ > + > +#include <Library/UefiLib.h> > +#include "readargs.h" > + > +void > +print_text ( > + const char *field, > + const char *bits, > + const char *value, > + const char *description > + ) > +{ > + AsciiPrint (" %-16a | %5a | %5a | %a\n", field, bits, value, description); > +} > + > +void > +print_values ( > + const char *field, > + const char *bits, > + const int value, > + const char *description > + ) > +{ > + STATIC CONST CHAR8 binaries[][5] = { > + "0000", "0001", "0010", "0011", > + "0100", "0101", "0110", "0111","1000", "1001", "1010", "1011", > + "1100", "1101", "1110", "1111" > + }; > + > + AsciiPrint (" %-16a | %5a | %5a | %a\n", field, bits, binaries[value & 0xf], description); > +} > + > +void > +print_spacer ( > + void > + ) > +{ > + AsciiPrint ("------------------|-------|-------|----------------------------------------------\n"); > +} > + > +void > +handle_aa64mmfr0_el1 ( > + const UINT64 aa64mmfr0_el1 > + ) > +{ > + UINT64 value; > + STATIC CONST CHAR8 RegName[] = "ID_AA64MMFR0_EL1"; > + char *description; > + char *bits; > + > + bits = "3:0 "; > + value = aa64mmfr0_el1 & 0xf; > + switch (value) { > + case 0b0000: > + description = "32 bits (4GB) of physical address range supported."; > + break; > + case 0b0001: > + description = "36 bits (64GB) of physical address range supported."; > + break; > + case 0b0010: > + description = "40 bits (1TB) of physical address range supported."; > + break; > + case 0b0011: > + description = "42 bits (4TB) of physical address range supported."; > + break; > + case 0b0100: > + description = "44 bits (16TB) of physical address range supported."; > + break; > + case 0b0101: > + description = "48 bits (256TB) of physical address range supported."; > + break; > + case 0b0110: > + description = "52 bits (4PB) of physical address range supported."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + if (value == 0b0110) { > + print_text ("", "", "", "FEAT_LPA implemented."); > + } > + > + bits = "7:4 "; > + value = (aa64mmfr0_el1 >> 4) & 0xf; > + switch (value) { > + case 0b0000: > + description = "ASID: 8 bits"; > + break; > + case 0b0010: > + description = "ASID: 16 bits"; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "11:8 "; > + value = (aa64mmfr0_el1 >> 8) & 0xf; > + switch (value) { > + case 0b0000: > + description = "No mixed-endian support."; > + break; > + case 0b0001: > + description = "Mixed-endian support."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + // only valid for BigEnd != 0b0000 > + if (((aa64mmfr0_el1 >> 8) & 0xf) != 0b0000 ) { > + if (((aa64mmfr0_el1 >> 16) & 0xf) == 0b0000 ) { > + print_values ("ID_AA64MMFR0_EL1", "19:16", 0b0000, "No mixed-endian support at EL0."); > + } > + > + if (((aa64mmfr0_el1 >> 16) & 0xf) == 0b0001 ) { > + print_values ("ID_AA64MMFR0_EL1", "19:16", 0b0001, "Mixed-endian support at EL0."); > + } > + } > + > + bits = "15:12"; > + value = (aa64mmfr0_el1 >> 12) & 0xf; > + switch (value) { > + case 0b0000: > + description = "No support for a distinction between Secure and Non-Secure Memory."; > + break; > + case 0b0001: > + description = "Supports a distinction between Secure and Non-Secure Memory."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "31:28"; > + value = (aa64mmfr0_el1 >> 28) & 0xf; > + switch (value) { > + case 0b0000: > + description = " 4KB granule supported."; > + break; > + case 0b1111: > + description = " 4KB granule not supported."; > + break; > + case 0b0001: // add FEAT_LPA2 check > + description = " 4KB granule supported for 52-bit address."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "43:40"; > + value = (aa64mmfr0_el1 >> 40) & 0xf; > + switch (value) { > + case 0b0001: > + description = " 4KB granule not supported at stage 2."; > + break; > + case 0b0010: > + description = " 4KB granule supported at stage 2."; > + break; > + case 0b0011: > + description = " 4KB granule supported at stage 2 for 52-bit address."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "23:20"; > + value = (aa64mmfr0_el1 >> 20) & 0xf; > + switch (value) { > + case 0b0000: > + description = "16KB granule not supported."; > + break; > + case 0b0001: > + description = "16KB granule supported."; > + break; > + case 0b0010: // add FEAT_LPA2 check > + description = "16KB granule supported for 52-bit address."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "35:32"; > + value = (aa64mmfr0_el1 >> 32) & 0xf; > + switch (value) { > + case 0b0001: > + description = "16KB granule not supported at stage 2."; > + break; > + case 0b0010: > + description = "16KB granule supported at stage 2."; > + break; > + case 0b0011: > + description = "16KB granule supported at stage 2 for 52-bit address."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "27:24"; > + value = (aa64mmfr0_el1 >> 24) & 0xf; > + switch (value) { > + case 0b0000: > + description = "64KB granule supported."; > + break; > + case 0b1111: > + description = "64KB granule not supported."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "39:36"; > + value = (aa64mmfr0_el1 >> 36) & 0xf; > + switch (value) { > + case 0b0001: > + description = "64KB granule not supported at stage 2."; > + break; > + case 0b0010: > + description = "64KB granule supported at stage 2."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "47:44"; > + value = (aa64mmfr0_el1 >> 44) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_ExS not implemented."; > + break; > + case 0b0001: > + description = "FEAT_ExS implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + // 55:48 reserved > + > + bits = "59:56"; > + value = (aa64mmfr0_el1 >> 56) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_FGT not implemented."; > + break; > + case 0b0001: > + description = "FEAT_FGT implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "63:60"; > + value = (aa64mmfr0_el1 >> 60) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_ECV not implemented."; > + break; > + case 0b0001: > + description = "FEAT_ECV implemented."; > + break; > + case 0b0010: > + description = "FEAT_ECV implemented with extras."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > +} > + > +void > +handle_aa64mmfr1_el1 ( > + const UINT64 aa64mmfr1_el1, > + const UINT64 aa64pfr0_el1 > + ) > +{ > + UINT64 value; > + STATIC CONST CHAR8 RegName[] = "ID_AA64MMFR1_EL1"; > + char *description; > + char *bits; > + > + bits = "3:0 "; > + value = aa64mmfr1_el1 & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_HAFDBS not implemented."; > + break; > + case 0b0001: > + description = "FEAT_HAFDBS implemented without dirty status support."; > + break; > + case 0b0010: > + description = "FEAT_HAFDBS implemented with dirty status support."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "7:4 "; > + value = (aa64mmfr1_el1 >> 4) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_VMID16 not implemented."; > + break; > + case 0b0010: > + description = "FEAT_VMID16 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "11:8 "; > + value = (aa64mmfr1_el1 >> 8) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_VHE not implemented."; > + break; > + case 0b0001: > + description = "FEAT_VHE implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "15:12"; > + value = (aa64mmfr1_el1 >> 12) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_HPDS not implemented."; > + break; > + case 0b0001: > + description = "FEAT_HPDS implemented."; > + break; > + case 0b0010: > + description = "FEAT_HPDS2 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "19:16"; > + value = (aa64mmfr1_el1 >> 16) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_LOR not implemented."; > + break; > + case 0b0001: > + description = "FEAT_LOR implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "23:20"; > + value = (aa64mmfr1_el1 >> 20) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_PAN not implemented."; > + break; > + case 0b0001: > + description = "FEAT_PAN implemented."; > + break; > + case 0b0010: > + description = "FEAT_PAN2 implemented."; > + break; > + case 0b0011: > + description = "FEAT_PAN3 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + // when FEAT_RAS implemented > + if ((((aa64pfr0_el1 >> 28) & 0xf) == 0b0001) || > + (((aa64pfr0_el1 >> 28) & 0xf) == 0b0010)) > + { > + if (((aa64mmfr1_el1 >> 24) & 0xf) == 0b0000 ) { > + print_values ("ID_AA64MMFR1_EL1", "27:24", 0b0000, "The PE never generates an SError interrupt due to"); > + print_text ("", "", "", "an External abort on a speculative read."); > + } > + > + if (((aa64mmfr1_el1 >> 24) & 0xf) == 0b0001 ) { > + print_values ("ID_AA64MMFR1_EL1", "27:24", 0b0001, "The PE might generate an SError interrupt due to"); > + print_text ("", "", "", "an External abort on a speculative read."); > + } > + } > + > + bits = "31:28"; > + value = (aa64mmfr1_el1 >> 28) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_XNX not implemented."; > + break; > + case 0b0001: > + description = "FEAT_XNX implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "35:32"; > + value = (aa64mmfr1_el1 >> 32) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_TWED not implemented."; > + break; > + case 0b0001: > + description = "FEAT_TWED implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "39:36"; > + value = (aa64mmfr1_el1 >> 36) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_ETS not implemented."; > + break; > + case 0b0001: > + description = "FEAT_ETS implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "43:40"; > + value = (aa64mmfr1_el1 >> 40) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_HCX not implemented."; > + break; > + case 0b0001: > + description = "FEAT_HCX implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "47:44"; > + value = (aa64mmfr1_el1 >> 44) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_AFP not implemented."; > + break; > + case 0b0001: > + description = "FEAT_AFP implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "51:48"; > + value = (aa64mmfr1_el1 >> 48) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_nTLBPA not implemented."; > + break; > + case 0b0001: > + description = "FEAT_nTLBPA implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "55:52"; > + value = (aa64mmfr1_el1 >> 52) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_TIDCP1 not implemented"; > + break; > + case 0b0001: > + description = "FEAT_TIDCP1 implemented"; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "59:56"; > + value = (aa64mmfr1_el1 >> 56) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_CMOW not implemented."; > + break; > + case 0b0001: > + description = "FEAT_CMOW implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + // 63:60 reserved > +} > + > +void > +handle_aa64mmfr2_el1 ( > + const UINT64 aa64mmfr2_el1 > + ) > +{ > + UINT64 value; > + STATIC CONST CHAR8 RegName[] = "ID_AA64MMFR2_EL1"; > + char *description; > + char *bits; > + > + bits = "3:0 "; > + value = (aa64mmfr2_el1) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_TTCNP not implemented."; > + break; > + case 0b0001: > + description = "FEAT_TTCNP implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "7:4 "; > + value = (aa64mmfr2_el1 >> 4) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_UAO not implemented."; > + break; > + case 0b0001: > + description = "FEAT_UAO implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "11:8 "; > + value = (aa64mmfr2_el1 >> 8) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_LSMAOC not implemented."; > + break; > + case 0b0001: > + description = "FEAT_LSMAOC implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "15:12"; > + value = (aa64mmfr2_el1 >> 12) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_IESB not implemented."; > + break; > + case 0b0001: > + description = "FEAT_IESB implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "19:16"; > + value = (aa64mmfr2_el1 >> 16) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_LVA not implemented."; > + break; > + case 0b0001: > + description = "FEAT_LVA implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "23:20"; > + value = (aa64mmfr2_el1 >> 20) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_CCIDX not implemented."; > + break; > + case 0b0001: > + description = "FEAT_CCIDX implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "27:24"; > + value = (aa64mmfr2_el1 >> 24) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_NV not implemented."; > + break; > + case 0b0001: > + description = "FEAT_NV implemented."; > + break; > + case 0b0010: > + description = "FEAT_NV2 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "31:28"; > + value = (aa64mmfr2_el1 >> 28) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_TTST not implemented."; > + break; > + case 0b0001: > + description = "FEAT_TTST implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "35:32"; > + value = (aa64mmfr2_el1 >> 32) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_LSE2 not implemented."; > + break; > + case 0b0001: > + description = "FEAT_LSE2 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "39:36"; > + value = (aa64mmfr2_el1 >> 36) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_IDST not implemented."; > + break; > + case 0b0001: > + description = "FEAT_IDST implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "43:40"; > + value = (aa64mmfr2_el1 >> 40) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_S2FWB not implemented."; > + break; > + case 0b0001: > + description = "FEAT_S2FWB implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + // 47:44 reserved > + > + bits = "51:48"; > + value = (aa64mmfr2_el1 >> 48) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_TTL not implemented."; > + break; > + case 0b0001: > + description = "FEAT_TTL implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "55:52"; > + value = (aa64mmfr2_el1 >> 52) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_BBM: Level 0 support for changing block size is supported."; > + break; > + case 0b0001: > + description = "FEAT_BBM: Level 1 support for changing block size is supported."; > + break; > + case 0b0010: > + description = "FEAT_BBM: Level 2 support for changing block size is supported."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "59:56"; > + value = (aa64mmfr2_el1 >> 56) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_EVT not implemented."; > + break; > + case 0b0001: > + description = "FEAT_EVT: HCR_EL2.{TOCU, TICAB, TID4} traps are supported."; > + break; > + case 0b0010: > + description = "FEAT_EVT: HCR_EL2.{TTLBOS, TTLSBIS, TOCU, TICAB, TID4} traps are supported."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "63:60"; > + value = (aa64mmfr2_el1 >> 60) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_E0PD not implemented."; > + break; > + case 0b0001: > + description = "FEAT_E0PD implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > +} > + > +void > +handle_aa64pfr0_el1 ( > + const UINT64 aa64pfr0_el1, > + const UINT64 aa64pfr1_el1 > + ) > +{ > + UINT64 value; > + STATIC CONST CHAR8 RegName[] = "ID_AA64PFR0_EL1"; > + char *description; > + char *bits; > + > + bits = "3:0 "; > + value = (aa64pfr0_el1) & 0xf; > + switch (value) { > + case 0b0001: > + description = "EL0 in AArch64 only"; > + break; > + case 0b0010: > + description = "EL0 in AArch64 and AArch32"; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "7:4 "; > + value = (aa64pfr0_el1 >> 4) & 0xf; > + switch (value) { > + case 0b0001: > + description = "EL1 in AArch64 only"; > + break; > + case 0b0010: > + description = "EL1 in AArch64 and AArch32"; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "11:8 "; > + value = (aa64pfr0_el1 >> 8) & 0xf; > + switch (value) { > + case 0b0000: > + description = "EL2 not implemented."; > + break; > + case 0b0001: > + description = "EL2 in AArch64 only"; > + break; > + case 0b0010: > + description = "EL2 in AArch64 and AArch32"; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "15:12"; > + value = (aa64pfr0_el1 >> 12) & 0xf; > + switch (value) { > + case 0b0000: > + description = "EL3 not implemented."; > + break; > + case 0b0001: > + description = "EL3 in AArch64 only"; > + break; > + case 0b0010: > + description = "EL3 in AArch64 and AArch32"; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "19:16"; > + value = (aa64pfr0_el1 >> 16) & 0xf; > + switch (value) { > + case 0b0000: > + description = "Floating-point implemented."; > + break; > + case 0b0001: > + description = "Floating-point with half-precision support (FEAT_FP16)."; > + break; > + case 0b1111: > + description = "Floating-point not implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "23:20"; > + value = (aa64pfr0_el1 >> 20) & 0xf; > + switch (value) { > + case 0b0000: > + description = "Advanced SIMD implemented."; > + break; > + case 0b0001: > + description = "Advanced SIMD with half precision support (FEAT_FP16)."; > + break; > + case 0b1111: > + description = "Advanced SIMD not implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "27:24"; > + value = (aa64pfr0_el1 >> 24) & 0xf; > + switch (value) { > + case 0b0000: > + description = "System registers of GIC CPU not implemented."; > + break; > + case 0b0001: > + description = "System registers to versions 3.0/4.0 of GIC CPU implemented."; > + break; > + case 0b0011: > + description = "System registers to versions 4.1 of GIC CPU implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "31:28"; > + value = (aa64pfr0_el1 >> 28) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_RAS not implemented."; > + break; > + case 0b0001: > + description = "FEAT_RAS implemented."; > + break; > + case 0b0010: > + description = "FEAT_RASv1p1 implemented."; > + // 0b0010 FEAT_RASv1p1 implemented and, if EL3 is implemented, FEAT_DoubleFault implemented. > + if ((((aa64pfr0_el1 >> 12) & 0xf) == 0b0001) || > + (((aa64pfr0_el1 >> 12) & 0xf) == 0b0010)) > + { > + description = "FEAT_RASv1p1 implemented. FEAT_DoubleFault implemented."; > + } > + > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "35:32"; > + value = (aa64pfr0_el1 >> 32) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_SVE not implemented."; > + break; > + case 0b0001: > + description = "FEAT_SVE implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "39:36"; > + value = (aa64pfr0_el1 >> 36) & 0xf; > + switch (value) { > + case 0b0000: > + description = "Secure EL2 not implemented."; > + break; > + case 0b0001: > + description = "Secure EL2 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "43:40"; > + value = (aa64pfr0_el1 >> 40) & 0xf; > + switch (value) { > + case 0b0000: > + if (((aa64pfr1_el1 >> 16) & 0xf) == 0b0000 ) { > + description = "FEAT_MPAM not implemented."; > + } > + > + if (((aa64pfr1_el1 >> 16) & 0xf) == 0b0001 ) { > + description = "FEAT_MPAM v0.1 implemented."; > + } > + > + break; > + case 0b0001: > + if (((aa64pfr1_el1 >> 16) & 0xf) == 0b0000 ) { > + description = "FEAT_MPAM v1.0 implemented."; > + } > + > + if (((aa64pfr1_el1 >> 16) & 0xf) == 0b0001 ) { > + description = "FEAT_MPAM v1.1 implemented."; > + } > + > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "47:44"; > + value = (aa64pfr0_el1 >> 44) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_AMU not implemented."; > + break; > + case 0b0001: > + description = "FEAT_AMUv1 implemented."; > + break; > + case 0b0010: > + description = "FEAT_AMUv1p1 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "51:48"; > + value = (aa64pfr0_el1 >> 48) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_DIT not implemented."; > + break; > + case 0b0001: > + description = "FEAT_DIT implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "55:52"; > + value = (aa64pfr0_el1 >> 52) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_RME not implemented"; > + break; > + case 0b0001: > + description = "FEAT_RME implemented"; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "59:56"; > + value = (aa64pfr0_el1 >> 56) & 0xf; > + switch (value) { > + case 0b0000: > + description = "no info is FEAT_CSV2 implemented."; > + break; > + case 0b0001: > + description = "FEAT_CSV2 implemented."; > + break; > + case 0b0010: > + description = "FEAT_CSV2_2 implemented."; > + break; > + case 0b0011: > + description = "FEAT_CSV2_3 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + if (value == 0b0001) { > + if (((aa64pfr1_el1 >> 32) & 0xf) == 0b0001 ) { > + print_values ("ID_AA64PRF1_EL1", "35:32", 0b0001, "FEAT_CSV2_1p1 implemented."); > + } > + > + if (((aa64pfr1_el1 >> 32) & 0xf) == 0b0010 ) { > + print_values ("ID_AA64PRF1_EL1", "35:32", 0b0010, "FEAT_CSV2_1p2 implemented."); > + } > + } > + > + bits = "63:60"; > + value = (aa64pfr0_el1 >> 60) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_CSV3 not implemented."; > + break; > + case 0b0001: > + description = "FEAT_CSV3 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > +} > + > +void > +handle_aa64pfr1_el1 ( > + const UINT64 aa64pfr1_el1 > + ) > +{ > + UINT64 value; > + STATIC CONST CHAR8 RegName[] = "ID_AA64PFR1_EL1"; > + char *description; > + char *bits; > + > + bits = "3:0 "; > + value = aa64pfr1_el1 & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_BTI not implemented."; > + break; > + case 0b0001: > + description = "FEAT_BTI implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "7:4 "; > + value = (aa64pfr1_el1 >> 4) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_SSBS not implemented."; > + break; > + case 0b0001: > + description = "FEAT_SSBS implemented."; > + break; > + case 0b0010: > + description = "FEAT_SSBS2 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "11:8 "; > + value = (aa64pfr1_el1 >> 8) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_MTE not implemented."; > + break; > + case 0b0001: > + description = "FEAT_MTE implemented."; > + break; > + case 0b0010: > + description = "FEAT_MTE2 implemented."; > + break; > + case 0b0011: > + description = "FEAT_MTE3 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + // 15:12 is RAS_frac > + // 19:16 is MPAM_frac > + // 23:20 is reserved > + > + bits = "27:24"; > + value = (aa64pfr1_el1 >> 24) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_SME not implemented."; > + break; > + case 0b0001: > + description = "FEAT_SME implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "31:28"; > + value = (aa64pfr1_el1 >> 28) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_RNG_TRAP not implemented."; > + break; > + case 0b0001: > + description = "FEAT_RNG_TRAP implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + // 35:32 is CSV2_frac > + > + bits = "39:36"; > + value = (aa64pfr1_el1 >> 36) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_NMI not implemented."; > + break; > + case 0b0001: > + description = "FEAT_NMI implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + // 63:40 are reserved > +} > + > +void > +handle_aa64isar0_el1 ( > + const UINT64 aa64isar0_el1 > + ) > +{ > + UINT64 value; > + STATIC CONST CHAR8 RegName[] = "ID_AA64ISAR0_EL1"; > + char *description; > + char *bits; > + > + // 3:0 reserved > + > + bits = "7:4 "; > + value = (aa64isar0_el1 >> 4) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_AES, FEAT_PMULL not implemented."; > + break; > + case 0b0001: > + description = "FEAT_AES implemented."; > + break; > + case 0b0010: > + description = "FEAT_AES and FEAT_PMULL implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "11:8 "; > + value = (aa64isar0_el1 >> 8) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_SHA1 not implemented."; > + break; > + case 0b0001: > + description = "FEAT_SHA1 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "15:12"; > + value = (aa64isar0_el1 >> 12) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_SHA256, FEAT_SHA512 not implemented."; > + break; > + case 0b0001: > + description = "FEAT_SHA256 implemented."; > + break; > + case 0b0010: > + description = "FEAT_SHA512 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "19:16"; > + value = (aa64isar0_el1 >> 16) & 0xf; > + switch (value) { > + case 0b0000: > + description = "CRC32 not implemented."; > + break; > + case 0b0001: > + description = "CRC32 instructions implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "23:20"; > + value = (aa64isar0_el1 >> 20) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_LSE not implemented."; > + break; > + case 0b0010: > + description = "FEAT_LSE implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "27:24"; > + value = (aa64isar0_el1 >> 24) & 0xf; > + switch (value) { > + case 0b0000: > + description = "TME instructions not implemented."; > + break; > + case 0b0001: > + description = "TME instructions implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "31:28"; > + value = (aa64isar0_el1 >> 28) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_RDM not implemented."; > + break; > + case 0b0001: > + description = "FEAT_RDM implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "35:32"; > + value = (aa64isar0_el1 >> 32) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_SHA3 not implemented."; > + break; > + case 0b0001: > + description = "FEAT_SHA3 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "39:36"; > + value = (aa64isar0_el1 >> 36) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_SM3 not implemented."; > + break; > + case 0b0001: > + description = "FEAT_SM3 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "43:40"; > + value = (aa64isar0_el1 >> 40) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_SM4 not implemented."; > + break; > + case 0b0001: > + description = "FEAT_SM4 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "47:44"; > + value = (aa64isar0_el1 >> 44) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_DotProd not implemented."; > + break; > + case 0b0001: > + description = "FEAT_DotProd implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "51:48"; > + value = (aa64isar0_el1 >> 48) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_FHM not implemented."; > + break; > + case 0b0001: > + description = "FEAT_FHM implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "55:52"; > + value = (aa64isar0_el1 >> 52) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_FlagM/FEAT_FlagM2 not implemented."; > + break; > + case 0b0001: > + description = "FEAT_FlagM implemented."; > + break; > + case 0b0010: > + description = "FEAT_FlagM2 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "59:56"; > + value = (aa64isar0_el1 >> 56) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_TLBIOS/FEAT_TLBIRANGE not implemented."; > + break; > + case 0b0001: > + description = "FEAT_TLBIOS implemented."; > + break; > + case 0b0010: > + description = "FEAT_TLBIRANGE implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "63:60"; > + value = (aa64isar0_el1 >> 60) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_RNG not implemented."; > + break; > + case 0b0001: > + description = "FEAT_RNG implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > +} > + > +void > +handle_aa64isar1_el1 ( > + const UINT64 aa64isar1_el1 > + ) > +{ > + UINT64 value; > + STATIC CONST CHAR8 RegName[] = "ID_AA64ISAR1_EL1"; > + char *description; > + char *bits; > + > + bits = "3:0 "; > + value = (aa64isar1_el1 >> 4) & 0xf; > + switch (value) { > + case 0b0000: > + description = "DC CVAP not implemented."; > + break; > + case 0b0001: > + description = "FEAT_DPB implemented."; > + break; > + case 0b0010: > + description = "FEAT_DPB2 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "7:4 "; > + value = (aa64isar1_el1 >> 4) & 0xf; > + switch (value) { > + case 0b0000: > + description = "Address Authentication (APA) not implemented."; > + break; > + case 0b0001: > + description = "FEAT_PAuth implemented."; > + break; > + case 0b0010: > + description = "FEAT_EPAC implemented."; > + break; > + case 0b0011: > + description = "FEAT_PAuth2 implemented."; > + break; > + case 0b0100: > + description = "FEAT_FPAC implemented."; > + break; > + case 0b0101: > + description = "FEAT_FPACCOMBINE implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + if (value > 0) { > + print_text ("", "", "", "FEAT_PACQARMA5 implemented."); > + } > + > + bits = "11:8 "; > + value = (aa64isar1_el1 >> 8) & 0xf; > + switch (value) { > + case 0b0000: > + description = "Address Authentication (API) not implemented."; > + break; > + case 0b0001: > + description = "FEAT_PAuth implemented."; > + break; > + case 0b0010: > + description = "FEAT_EPAC implemented."; > + break; > + case 0b0011: > + description = "FEAT_PAuth2 implemented."; > + break; > + case 0b0100: > + description = "FEAT_FPAC implemented."; > + break; > + case 0b0101: > + description = "FEAT_FPACCOMBINE implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + if (value > 0) { > + print_text ("", "", "", "FEAT_PACIMP implemented."); > + } > + > + bits = "15:12"; > + value = (aa64isar1_el1 >> 12) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_JSCVT not implemented."; > + break; > + case 0b0001: > + description = "FEAT_JSCVT implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "19:16"; > + value = (aa64isar1_el1 >> 16) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_FCMA not implemented."; > + break; > + case 0b0001: > + description = "FEAT_FCMA implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "23:20"; > + value = (aa64isar1_el1 >> 20) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_LRCPC (2) not implemented."; > + break; > + case 0b0001: > + description = "FEAT_LRCPC implemented."; > + break; > + case 0b0010: > + description = "FEAT_LRCPC2 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "27:24"; > + value = (aa64isar1_el1 >> 24) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_PACQARMA5 not implemented."; > + break; > + case 0b0001: > + description = "FEAT_PACQARMA5 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "31:28"; > + value = (aa64isar1_el1 >> 28) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_PACIMP not implemented."; > + break; > + case 0b0001: > + description = "FEAT_PACIMP implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "35:32"; > + value = (aa64isar1_el1 >> 32) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_FRINTTS not implemented."; > + break; > + case 0b0001: > + description = "FEAT_FRINTTS implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "39:36"; > + value = (aa64isar1_el1 >> 36) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_SB not implemented."; > + break; > + case 0b0001: > + description = "FEAT_SB implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "43:40"; > + value = (aa64isar1_el1 >> 40) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_SPECRES not implemented."; > + break; > + case 0b0001: > + description = "FEAT_SPECRES implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "47:44"; > + value = (aa64isar1_el1 >> 44) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_BF16 not implemented."; > + break; > + case 0b0001: > + description = "FEAT_BF16 implemented."; > + break; > + case 0b0010: > + description = "FEAT_EBF16 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "51:48"; > + value = (aa64isar1_el1 >> 48) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_DGH not implemented."; > + break; > + case 0b0001: > + description = "FEAT_DGH implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "55:52"; > + value = (aa64isar1_el1 >> 52) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_I8MM not implemented."; > + break; > + case 0b0001: > + description = "FEAT_I8MM implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "59:56"; > + value = (aa64isar1_el1 >> 56) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_XS not implemented."; > + break; > + case 0b0001: > + description = "FEAT_XS implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "63:60"; > + value = (aa64isar1_el1 >> 60) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_LS64 not implemented."; > + break; > + case 0b0001: > + description = "FEAT_LS64 implemented."; > + break; > + case 0b0010: > + description = "FEAT_LS64_V implemented."; > + break; > + case 0b0011: > + description = "FEAT_LS64_ACCDATA implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > +} > + > +void > +handle_aa64isar2_el1 ( > + const UINT64 aa64isar2_el1 > + ) > +{ > + UINT64 value; > + STATIC CONST CHAR8 RegName[] = "ID_AA64ISAR2_EL1"; > + char *description; > + char *bits; > + > + bits = "3:0 "; > + value = (aa64isar2_el1 >> 4) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_WFxT not implemented."; > + break; > + case 0b0010: > + description = "FEAT_WFxT implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "7:4 "; > + value = (aa64isar2_el1 >> 4) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_RPRES not implemented."; > + break; > + case 0b0001: > + description = "FEAT_RPRES implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "11:8 "; > + value = (aa64isar2_el1 >> 8) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_PACQARMA3 not implemented."; > + break; > + case 0b0001: > + description = "FEAT_PACQARMA3 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "15:12"; > + value = (aa64isar2_el1 >> 12) & 0xf; > + switch (value) { > + case 0b0000: > + description = "Address Authentication (APA3) not implemented."; > + break; > + case 0b0001: > + description = "FEAT_PAuth implemented."; > + break; > + case 0b0010: > + description = "FEAT_EPAC implemented."; > + break; > + case 0b0011: > + description = "FEAT_PAuth2 implemented."; > + break; > + case 0b0100: > + description = "FEAT_FPAC implemented."; > + break; > + case 0b0101: > + description = "FEAT_FPACCOMBINE implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "19:16"; > + value = (aa64isar2_el1 >> 16) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_MOPS not implemented."; > + break; > + case 0b0001: > + description = "FEAT_MOPS implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "23:20"; > + value = (aa64isar2_el1 >> 20) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_HBC not implemented."; > + break; > + case 0b0001: > + description = "FEAT_HBC implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "27:24"; > + value = (aa64isar2_el1 >> 24) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_CONSTPACFIELD not implemented."; > + break; > + case 0b0001: > + description = "FEAT_CONSTPACFIELD implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + // 63:28 reserved > +} > + > +void > +handle_aa64dfr0_el1 ( > + const UINT64 aa64dfr0_el1 > + ) > +{ > + UINT64 value; > + STATIC CONST CHAR8 RegName[] = "ID_AA64DFR0_EL1"; > + char *description; > + char *bits; > + > + bits = "3:0 "; > + value = (aa64dfr0_el1 >> 4) & 0xf; > + switch (value) { > + case 0b0110: > + description = "Armv8 debug architecture"; > + break; > + case 0b0111: > + description = "Armv8 debug architecture with VHE"; > + break; > + case 0b1000: > + description = "FEAT_Debugv8p2 implemented."; > + break; > + case 0b1001: > + description = "FEAT_Debugv8p4 implemented."; > + break; > + case 0b1010: > + description = "FEAT_Debugv8p8 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "7:4 "; > + value = (aa64dfr0_el1 >> 4) & 0xf; > + switch (value) { > + case 0b0000: > + description = "Trace unit System registers not implemented."; > + break; > + case 0b0001: > + description = "Trace unit System registers implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "11:8 "; > + value = (aa64dfr0_el1 >> 8) & 0xf; > + switch (value) { > + case 0b0000: > + description = "Performance Monitors Extension not implemented."; > + break; > + case 0b0001: > + description = "FEAT_PMUv3 implemented."; > + break; > + case 0b0100: > + description = "FEAT_PMUv3p1 implemented."; > + break; > + case 0b0101: > + description = "FEAT_PMUv3p4 implemented."; > + break; > + case 0b0110: > + description = "FEAT_PMUv3p5 implemented."; > + break; > + case 0b0111: > + description = "FEAT_PMUv3p7 implemented."; > + break; > + case 0b1000: > + description = "FEAT_PMUv3p8 implemented."; > + break; > + case 0b1111: > + description = "IMPLEMENTATION DEFINED form of performance monitors supported."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "15:12"; > + value = (aa64dfr0_el1 >> 12) & 0xf; > + switch (value) { > + case 0b0000: > + description = "reserved"; > + break; > + default: > + description = "Number of breakpoints, minus 1."; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + // 19:16 reserved > + > + bits = "23:20"; > + value = (aa64dfr0_el1 >> 20) & 0xf; > + switch (value) { > + case 0b0000: > + description = "reserved"; > + break; > + default: > + description = "Number of watchpoints, minus 1."; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + // 27:24 reserved > + > + bits = "31:28"; > + value = (aa64dfr0_el1 >> 28) & 0xf; > + switch (value) { > + default: > + description = "Number of breakpoints that are context-aware, minus 1."; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "35:32"; > + value = (aa64dfr0_el1 >> 32) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_SPE not implemented."; > + break; > + case 0b0001: > + description = "FEAT_SPE implemented."; > + break; > + case 0b0010: > + description = "FEAT_SPEv1p1 implemented."; > + break; > + case 0b0011: > + description = "FEAT_SPEv1p2 implemented."; > + break; > + case 0b0100: > + description = "FEAT_SPEv1p3 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "39:36"; > + value = (aa64dfr0_el1 >> 36) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_DoubleLock implemented."; > + break; > + case 0b1111: > + description = "FEAT_DoubleLock not implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "43:40"; > + value = (aa64dfr0_el1 >> 40) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_TRF not implemented."; > + break; > + case 0b0001: > + description = "FEAT_TRF implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "47:44"; > + value = (aa64dfr0_el1 >> 44) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_TRBE not implemented."; > + break; > + case 0b0001: > + description = "FEAT_TRBE implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "51:48"; > + value = (aa64dfr0_el1 >> 48) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_MTPMU not implemented."; > + break; > + case 0b0001: > + description = "FEAT_MTPMU and FEAT_PMUv3 implemented."; > + break; > + case 0b1111: > + description = "FEAT_MTPMU not implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + bits = "55:52"; > + value = (aa64dfr0_el1 >> 52) & 0xf; > + switch (value) { > + case 0b0000: > + description = "FEAT_BRBE not implemented."; > + break; > + case 0b0001: > + description = "FEAT_BRBE implemented."; > + break; > + case 0b0010: > + description = "FEAT_BRBEv1p1 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > + > + // 59:56 reserved > + > + bits = "63:60"; > + value = (aa64dfr0_el1 >> 60) & 0xf; > + switch (value) { > + case 0b0000: > + description = "Setting MDCR_EL2.HPMN to zero has CONSTRAINED UNPREDICTABLE behavior."; > + break; > + case 0b0001: > + description = "FEAT_HPMN0 implemented."; > + break; > + default: > + description = "unknown"; > + break; > + } > + > + print_values (RegName, bits, value, description); > +} > + > +EFI_STATUS > +EFIAPI > +UefiMain ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + UINT64 aa64dfr0_el1 = read_aa64dfr0_el1 (); > + UINT64 aa64dfr1_el1 = read_aa64dfr1_el1 (); > + UINT64 aa64isar0_el1 = read_aa64isar0_el1 (); > + UINT64 aa64isar1_el1 = read_aa64isar1_el1 (); > + UINT64 aa64isar2_el1 = read_aa64isar2_el1 (); > + UINT64 aa64mmfr0_el1 = read_aa64mmfr0_el1 (); > + UINT64 aa64mmfr1_el1 = read_aa64mmfr1_el1 (); > + UINT64 aa64mmfr2_el1 = read_aa64mmfr2_el1 (); > + UINT64 aa64pfr0_el1 = read_aa64pfr0_el1 (); > + UINT64 aa64pfr1_el1 = read_aa64pfr1_el1 (); EDK2 requires separation between declarations and code (something alike old C89 semantics, but stricter). so: UINT64 aa64pfr1_el1; <...> aa64pfr1_el1 = read_aa64pfr1_el1 (); > + > + /* UINT64 aa64smfr0_el1 = read_aa64smfr0_el1 ();*/ > + /* UINT64 aa64zfr0_el1 = read_aa64zfr0_el1 ();*/ Dead Code? > + > + AsciiPrint ("ID_AA64MMFR0_EL1 = 0x%016lx\n", aa64mmfr0_el1); > + AsciiPrint ("ID_AA64MMFR1_EL1 = 0x%016lx\n", aa64mmfr1_el1); > + AsciiPrint ("ID_AA64MMFR2_EL1 = 0x%016lx\n", aa64mmfr2_el1); > + AsciiPrint ("ID_AA64PFR0_EL1 = 0x%016lx\n", aa64pfr0_el1); > + AsciiPrint ("ID_AA64PFR1_EL1 = 0x%016lx\n", aa64pfr1_el1); > + AsciiPrint ("ID_AA64ISAR0_EL1 = 0x%016lx\n", aa64isar0_el1); > + AsciiPrint ("ID_AA64ISAR1_EL1 = 0x%016lx\n", aa64isar1_el1); > + AsciiPrint ("ID_AA64ISAR2_EL1 = 0x%016lx\n", aa64isar2_el1); > + AsciiPrint ("ID_AA64DFR0_EL1 = 0x%016lx\n", aa64dfr0_el1); > + AsciiPrint ("ID_AA64DFR1_EL1 = 0x%016lx\n", aa64dfr1_el1); // ignore Why ignore? > + /* AsciiPrint ("ID_AA64SMFR0_EL1 = 0x%016lx\n", aa64smfr0_el1);*/ > + /* AsciiPrint ("ID_AA64ZFR0_EL1 = 0x%016lx\n", aa64zfr0_el1);*/ dead? > + > + AsciiPrint ("\n"); > + print_text ("Register", "Bits", "Value", "Feature"); > + print_spacer (); > + > + handle_aa64mmfr0_el1 (aa64mmfr0_el1); > + print_spacer (); > + handle_aa64mmfr1_el1 (aa64mmfr1_el1, aa64pfr0_el1); > + print_spacer (); > + handle_aa64mmfr2_el1 (aa64mmfr2_el1); > + > + print_spacer (); > + handle_aa64pfr0_el1 (aa64pfr0_el1, aa64pfr1_el1); > + print_spacer (); > + handle_aa64pfr1_el1 (aa64pfr1_el1); > + > + print_spacer (); > + handle_aa64isar0_el1 (aa64isar0_el1); > + print_spacer (); > + handle_aa64isar1_el1 (aa64isar1_el1); > + print_spacer (); > + handle_aa64isar2_el1 (aa64isar2_el1); > + > + print_spacer (); > + handle_aa64dfr0_el1 (aa64dfr0_el1); > + > + return EFI_SUCCESS; > +} > diff --git a/ArmPkg/Application/ArmCpuInfo/readregs.s b/ArmPkg/Application/ArmCpuInfo/readregs.s ASM files that require preprocessing should have a capital S here (.S vs .s) > new file mode 100644 > index 000000000000..052834b3c3f2 > --- /dev/null > +++ b/ArmPkg/Application/ArmCpuInfo/readregs.s > @@ -0,0 +1,49 @@ > +#include <AsmMacroIoLibV8.h> > + > +ASM_FUNC(read_aa64pfr0_el1) > + mrs x0, ID_AA64PFR0_EL1; > + ret; ASM lines (for GAS at least) don't usually end in semicolons. so +ASM_FUNC(read_aa64pfr0_el1) + mrs x0, ID_AA64PFR0_EL1 + ret You'd only need the semicolons if you had multiple instructions in one line (like mrs x0, ID_AA...; ret) > + > +ASM_FUNC(read_aa64pfr1_el1) > + mrs x0, ID_AA64PFR1_EL1; > + ret; > + > +ASM_FUNC(read_aa64dfr0_el1) > + mrs x0, ID_AA64DFR0_EL1; > + ret; > + > +ASM_FUNC(read_aa64dfr1_el1) > + mrs x0, ID_AA64DFR1_EL1; > + ret; > + > +ASM_FUNC(read_aa64isar0_el1) > + mrs x0, ID_AA64ISAR0_EL1; > + ret; > + > +ASM_FUNC(read_aa64isar1_el1) > + mrs x0, ID_AA64ISAR1_EL1; > + ret; > + > +ASM_FUNC(read_aa64isar2_el1) > + mrs x0, ID_AA64ISAR2_EL1; > + ret; > + > +ASM_FUNC(read_aa64mmfr0_el1) > + mrs x0, ID_AA64MMFR0_EL1; > + ret; > + > +ASM_FUNC(read_aa64mmfr1_el1) > + mrs x0, ID_AA64MMFR1_EL1; > + ret; > + > +ASM_FUNC(read_aa64mmfr2_el1) > + mrs x0, ID_AA64MMFR2_EL1; > + ret; > + > +# ASM_FUNC(read_aa64zfr0_el1) > +# mrs x0, ID_AA64ZFR0_EL1; > +# ret; > + > +# ASM_FUNC(read_aa64smfr0_el1) > +# mrs x0, ID_AA64SMFR0_EL1; > +# ret; Dead code? > -- > 2.40.0 Marcin, Brief comments in general: 1) You use binary literals extensively, which are not portable (GNU C extension, AFAIK not in MSVC) 2) Naming of identifiers (vars, functions, etc) needs to follow the EDK2 style. eg: description vs Description read_aa64mmfr1_el1 vs ReadAa64MmfrEl1 etc... -- Pedro -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#102695): https://edk2.groups.io/g/devel/message/102695 Mute This Topic: https://groups.io/mt/98123579/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=-=-=-=-=-=-=-=-=-=-=-
W dniu 7.04.2023 o 15:02, Pedro Falcato pisze: >> +EFI_STATUS >> +EFIAPI >> +UefiMain ( >> + IN EFI_HANDLE ImageHandle, >> + IN EFI_SYSTEM_TABLE *SystemTable >> + ) >> +{ >> + UINT64 aa64dfr0_el1 = read_aa64dfr0_el1 (); >> + UINT64 aa64dfr1_el1 = read_aa64dfr1_el1 (); >> + UINT64 aa64isar0_el1 = read_aa64isar0_el1 (); >> + UINT64 aa64isar1_el1 = read_aa64isar1_el1 (); >> + UINT64 aa64isar2_el1 = read_aa64isar2_el1 (); >> + UINT64 aa64mmfr0_el1 = read_aa64mmfr0_el1 (); >> + UINT64 aa64mmfr1_el1 = read_aa64mmfr1_el1 (); >> + UINT64 aa64mmfr2_el1 = read_aa64mmfr2_el1 (); >> + UINT64 aa64pfr0_el1 = read_aa64pfr0_el1 (); >> + UINT64 aa64pfr1_el1 = read_aa64pfr1_el1 (); > > EDK2 requires separation between declarations and code (something > alike old C89 semantics, but stricter). so: > UINT64 aa64pfr1_el1; > <...> > aa64pfr1_el1 = read_aa64pfr1_el1 (); done >> + >> + /* UINT64 aa64smfr0_el1 = read_aa64smfr0_el1 ();*/ >> + /* UINT64 aa64zfr0_el1 = read_aa64zfr0_el1 ();*/ > > Dead Code? I ignore SVE/SME registers for now. Dropped code. >> + >> + AsciiPrint ("ID_AA64MMFR0_EL1 = 0x%016lx\n", aa64mmfr0_el1); >> + AsciiPrint ("ID_AA64MMFR1_EL1 = 0x%016lx\n", aa64mmfr1_el1); >> + AsciiPrint ("ID_AA64MMFR2_EL1 = 0x%016lx\n", aa64mmfr2_el1); >> + AsciiPrint ("ID_AA64PFR0_EL1 = 0x%016lx\n", aa64pfr0_el1); >> + AsciiPrint ("ID_AA64PFR1_EL1 = 0x%016lx\n", aa64pfr1_el1); >> + AsciiPrint ("ID_AA64ISAR0_EL1 = 0x%016lx\n", aa64isar0_el1); >> + AsciiPrint ("ID_AA64ISAR1_EL1 = 0x%016lx\n", aa64isar1_el1); >> + AsciiPrint ("ID_AA64ISAR2_EL1 = 0x%016lx\n", aa64isar2_el1); >> + AsciiPrint ("ID_AA64DFR0_EL1 = 0x%016lx\n", aa64dfr0_el1); >> + AsciiPrint ("ID_AA64DFR1_EL1 = 0x%016lx\n", aa64dfr1_el1); // ignore > > Why ignore? Was 0 on systems I checked. Dropped. >> + /* AsciiPrint ("ID_AA64SMFR0_EL1 = 0x%016lx\n", aa64smfr0_el1);*/ >> + /* AsciiPrint ("ID_AA64ZFR0_EL1 = 0x%016lx\n", aa64zfr0_el1);*/ > > dead? Dropped. >> diff --git a/ArmPkg/Application/ArmCpuInfo/readregs.s b/ArmPkg/Application/ArmCpuInfo/readregs.s > > ASM files that require preprocessing should have a capital S here (.S vs .s) After renaming it to readregs.S (and changing in ArmCpuInfo.inf) I get: build.py... /home/marcin/devel/linaro/sbsa-qemu/code/edk2/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf(29): error 000E: File/directory not found in workspace readregs.S is not found in packages path: >> new file mode 100644 >> index 000000000000..052834b3c3f2 >> --- /dev/null >> +++ b/ArmPkg/Application/ArmCpuInfo/readregs.s >> @@ -0,0 +1,49 @@ >> +#include <AsmMacroIoLibV8.h> >> + >> +ASM_FUNC(read_aa64pfr0_el1) >> + mrs x0, ID_AA64PFR0_EL1; >> + ret; > > ASM lines (for GAS at least) don't usually end in semicolons. so > +ASM_FUNC(read_aa64pfr0_el1) > + mrs x0, ID_AA64PFR0_EL1 > + ret > > You'd only need the semicolons if you had multiple instructions in one > line (like mrs x0, ID_AA...; ret) thanks, dropped semicolons >> +# ASM_FUNC(read_aa64zfr0_el1) >> +# mrs x0, ID_AA64ZFR0_EL1; >> +# ret; >> + >> +# ASM_FUNC(read_aa64smfr0_el1) >> +# mrs x0, ID_AA64SMFR0_EL1; >> +# ret; > > Dead code? Those two registers names were missing so got disabled. Dropped. > Brief comments in general: > 1) You use binary literals extensively, which are not portable (GNU C > extension, AFAIK not in MSVC) My C skills are rusty and the last time I used compiler other than GCC was in Borland Turbo C 3 times. > 2) Naming of identifiers (vars, functions, etc) needs to follow the > EDK2 style. eg: > description vs Description > read_aa64mmfr1_el1 vs ReadAa64MmfrEl1 > etc... ok > Forgot mentioning: STATIC vs static, CONST vs const, > VOID vs void, CHAR8 vs char, etc. > All fun microsoftisms you need to use here. Will be fun. -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#102699): https://edk2.groups.io/g/devel/message/102699 Mute This Topic: https://groups.io/mt/98123579/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=-=-=-=-=-=-=-=-=-=-=-
(+cc old CCs) (Marcin, you're dropping CC's on your replies) On Fri, Apr 7, 2023 at 2:29 PM Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org> wrote: > > W dniu 7.04.2023 o 15:02, Pedro Falcato pisze: > > >> diff --git a/ArmPkg/Application/ArmCpuInfo/readregs.s b/ArmPkg/Application/ArmCpuInfo/readregs.s > > > > ASM files that require preprocessing should have a capital S here (.S vs .s) > > After renaming it to readregs.S (and changing in ArmCpuInfo.inf) I get: > > build.py... > /home/marcin/devel/linaro/sbsa-qemu/code/edk2/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf(29): > error 000E: File/directory not found in workspace > readregs.S is not found in packages path: > Odd. Other packages (e.g ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf) use .S just fine. Leif, Ard, any ideas? -- Pedro -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#102700): https://edk2.groups.io/g/devel/message/102700 Mute This Topic: https://groups.io/mt/98123579/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=-=-=-=-=-=-=-=-=-=-=-
Oops, now I screwed up the CC's, apologies. On Fri, Apr 7, 2023 at 2:40 PM Pedro Falcato <pedro.falcato@gmail.com> wrote: > > (+cc old CCs) > > (Marcin, you're dropping CC's on your replies) > > On Fri, Apr 7, 2023 at 2:29 PM Marcin Juszkiewicz > <marcin.juszkiewicz@linaro.org> wrote: > > > > W dniu 7.04.2023 o 15:02, Pedro Falcato pisze: > > > > >> diff --git a/ArmPkg/Application/ArmCpuInfo/readregs.s b/ArmPkg/Application/ArmCpuInfo/readregs.s > > > > > > ASM files that require preprocessing should have a capital S here (.S vs .s) > > > > After renaming it to readregs.S (and changing in ArmCpuInfo.inf) I get: > > > > build.py... > > /home/marcin/devel/linaro/sbsa-qemu/code/edk2/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf(29): > > error 000E: File/directory not found in workspace > > readregs.S is not found in packages path: > > > > Odd. Other packages (e.g ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf) > use .S just fine. > > Leif, Ard, any ideas? > > -- > Pedro -- Pedro -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#102701): https://edk2.groups.io/g/devel/message/102701 Mute This Topic: https://groups.io/mt/98123579/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=-=-=-=-=-=-=-=-=-=-=-
W dniu 7.04.2023 o 15:40, Pedro Falcato pisze: > (+cc old CCs) > > (Marcin, you're dropping CC's on your replies) Oops, sorry. >>> ASM files that require preprocessing should have a capital S here (.S vs .s) >> >> After renaming it to readregs.S (and changing in ArmCpuInfo.inf) I get: >> >> build.py... >> /home/marcin/devel/linaro/sbsa-qemu/code/edk2/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf(29): >> error 000E: File/directory not found in workspace >> readregs.S is not found in packages path: >> > > Odd. Other packages (e.g ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf) > use .S just fine. Sorted out. Will send v4 later. -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#102702): https://edk2.groups.io/g/devel/message/102702 Mute This Topic: https://groups.io/mt/98123579/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=-=-=-=-=-=-=-=-=-=-=-
Forgot mentioning: STATIC vs static, CONST vs const, VOID vs void, CHAR8 vs char, etc. All fun microsoftisms you need to use here. On Fri, Apr 7, 2023 at 2:02 PM Pedro Falcato <pedro.falcato@gmail.com> wrote: > > On Fri, Apr 7, 2023 at 1:47 PM Marcin Juszkiewicz > <marcin.juszkiewicz@linaro.org> wrote: > > > > App goes through ID_AA64*_EL1 system registers and decode their values. > > > > Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org> > > --- > > ArmPkg/ArmPkg.dsc | 1 + > > ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf | 38 + > > ArmPkg/Application/ArmCpuInfo/readargs.h | 12 + > > ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.c | 2317 ++++++++++++++++++++ > > ArmPkg/Application/ArmCpuInfo/readregs.s | 49 + > > 5 files changed, 2417 insertions(+) > > > > diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc > > index 3fb95d1951a9..6b938ce8b671 100644 > > --- a/ArmPkg/ArmPkg.dsc > > +++ b/ArmPkg/ArmPkg.dsc > > @@ -166,6 +166,7 @@ [Components.AARCH64] > > ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.inf > > ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf > > ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf > > + ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf > > > > [Components.AARCH64, Components.ARM] > > ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf > > diff --git a/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf b/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf > > new file mode 100644 > > index 000000000000..158f86a4740c > > --- /dev/null > > +++ b/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf > > @@ -0,0 +1,38 @@ > > +## @file > > +# > > +# Attempt to have AArch64 cpu information. > > +# > > +# Based on HelloWorld: > > +# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved. > > +# Copyright (c) 2023 Marcin Juszkiewicz > > +# > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +# > > +# > > +## > > + > > +[Defines] > > + INF_VERSION = 0x00010019 > > + BASE_NAME = ArmCpuInfo > > + FILE_GUID = b3134491-6502-4faf-a9da-007184e32163 > > + MODULE_TYPE = UEFI_APPLICATION > > + VERSION_STRING = 1.0 > > + ENTRY_POINT = UefiMain > > + > > +# > > +# This flag specifies whether HII resource section is generated into PE image. > > +# > > + UEFI_HII_RESOURCE_SECTION = TRUE > > + > > +[Sources] > > + ArmCpuInfo.c > > + readregs.s > > + > > +[Packages] > > + ArmPkg/ArmPkg.dec > > + MdePkg/MdePkg.dec > > + MdeModulePkg/MdeModulePkg.dec > > + > > +[LibraryClasses] > > + UefiApplicationEntryPoint > > + UefiLib > > diff --git a/ArmPkg/Application/ArmCpuInfo/readargs.h b/ArmPkg/Application/ArmCpuInfo/readargs.h > > new file mode 100644 > > index 000000000000..eaa52cf16145 > > --- /dev/null > > +++ b/ArmPkg/Application/ArmCpuInfo/readargs.h > > @@ -0,0 +1,12 @@ > > +UINT64 read_aa64pfr0_el1(void); > > +UINT64 read_aa64pfr1_el1(void); > > +UINT64 read_aa64dfr0_el1(void); > > +UINT64 read_aa64dfr1_el1(void); > > +UINT64 read_aa64isar0_el1(void); > > +UINT64 read_aa64isar1_el1(void); > > +UINT64 read_aa64isar2_el1(void); > > +UINT64 read_aa64mmfr0_el1(void); > > +UINT64 read_aa64mmfr1_el1(void); > > +UINT64 read_aa64mmfr2_el1(void); > > +UINT64 read_aa64smfr0_el1(void); > > +UINT64 read_aa64zfr0_el1(void); > > diff --git a/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.c b/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.c > > new file mode 100644 > > index 000000000000..6c31ad4dbcb9 > > --- /dev/null > > +++ b/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.c > > @@ -0,0 +1,2317 @@ > > +/** @file > > + > > + Copyright (c) 2023 Marcin Juszkiewicz > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > + > > + **/ > > + > > +#include <Library/UefiLib.h> > > +#include "readargs.h" > > + > > +void > > +print_text ( > > + const char *field, > > + const char *bits, > > + const char *value, > > + const char *description > > + ) > > +{ > > + AsciiPrint (" %-16a | %5a | %5a | %a\n", field, bits, value, description); > > +} > > + > > +void > > +print_values ( > > + const char *field, > > + const char *bits, > > + const int value, > > + const char *description > > + ) > > +{ > > + STATIC CONST CHAR8 binaries[][5] = { > > + "0000", "0001", "0010", "0011", > > + "0100", "0101", "0110", "0111","1000", "1001", "1010", "1011", > > + "1100", "1101", "1110", "1111" > > + }; > > + > > + AsciiPrint (" %-16a | %5a | %5a | %a\n", field, bits, binaries[value & 0xf], description); > > +} > > + > > +void > > +print_spacer ( > > + void > > + ) > > +{ > > + AsciiPrint ("------------------|-------|-------|----------------------------------------------\n"); > > +} > > + > > +void > > +handle_aa64mmfr0_el1 ( > > + const UINT64 aa64mmfr0_el1 > > + ) > > +{ > > + UINT64 value; > > + STATIC CONST CHAR8 RegName[] = "ID_AA64MMFR0_EL1"; > > + char *description; > > + char *bits; > > + > > + bits = "3:0 "; > > + value = aa64mmfr0_el1 & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "32 bits (4GB) of physical address range supported."; > > + break; > > + case 0b0001: > > + description = "36 bits (64GB) of physical address range supported."; > > + break; > > + case 0b0010: > > + description = "40 bits (1TB) of physical address range supported."; > > + break; > > + case 0b0011: > > + description = "42 bits (4TB) of physical address range supported."; > > + break; > > + case 0b0100: > > + description = "44 bits (16TB) of physical address range supported."; > > + break; > > + case 0b0101: > > + description = "48 bits (256TB) of physical address range supported."; > > + break; > > + case 0b0110: > > + description = "52 bits (4PB) of physical address range supported."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + if (value == 0b0110) { > > + print_text ("", "", "", "FEAT_LPA implemented."); > > + } > > + > > + bits = "7:4 "; > > + value = (aa64mmfr0_el1 >> 4) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "ASID: 8 bits"; > > + break; > > + case 0b0010: > > + description = "ASID: 16 bits"; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "11:8 "; > > + value = (aa64mmfr0_el1 >> 8) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "No mixed-endian support."; > > + break; > > + case 0b0001: > > + description = "Mixed-endian support."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + // only valid for BigEnd != 0b0000 > > + if (((aa64mmfr0_el1 >> 8) & 0xf) != 0b0000 ) { > > + if (((aa64mmfr0_el1 >> 16) & 0xf) == 0b0000 ) { > > + print_values ("ID_AA64MMFR0_EL1", "19:16", 0b0000, "No mixed-endian support at EL0."); > > + } > > + > > + if (((aa64mmfr0_el1 >> 16) & 0xf) == 0b0001 ) { > > + print_values ("ID_AA64MMFR0_EL1", "19:16", 0b0001, "Mixed-endian support at EL0."); > > + } > > + } > > + > > + bits = "15:12"; > > + value = (aa64mmfr0_el1 >> 12) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "No support for a distinction between Secure and Non-Secure Memory."; > > + break; > > + case 0b0001: > > + description = "Supports a distinction between Secure and Non-Secure Memory."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "31:28"; > > + value = (aa64mmfr0_el1 >> 28) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = " 4KB granule supported."; > > + break; > > + case 0b1111: > > + description = " 4KB granule not supported."; > > + break; > > + case 0b0001: // add FEAT_LPA2 check > > + description = " 4KB granule supported for 52-bit address."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "43:40"; > > + value = (aa64mmfr0_el1 >> 40) & 0xf; > > + switch (value) { > > + case 0b0001: > > + description = " 4KB granule not supported at stage 2."; > > + break; > > + case 0b0010: > > + description = " 4KB granule supported at stage 2."; > > + break; > > + case 0b0011: > > + description = " 4KB granule supported at stage 2 for 52-bit address."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "23:20"; > > + value = (aa64mmfr0_el1 >> 20) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "16KB granule not supported."; > > + break; > > + case 0b0001: > > + description = "16KB granule supported."; > > + break; > > + case 0b0010: // add FEAT_LPA2 check > > + description = "16KB granule supported for 52-bit address."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "35:32"; > > + value = (aa64mmfr0_el1 >> 32) & 0xf; > > + switch (value) { > > + case 0b0001: > > + description = "16KB granule not supported at stage 2."; > > + break; > > + case 0b0010: > > + description = "16KB granule supported at stage 2."; > > + break; > > + case 0b0011: > > + description = "16KB granule supported at stage 2 for 52-bit address."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "27:24"; > > + value = (aa64mmfr0_el1 >> 24) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "64KB granule supported."; > > + break; > > + case 0b1111: > > + description = "64KB granule not supported."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "39:36"; > > + value = (aa64mmfr0_el1 >> 36) & 0xf; > > + switch (value) { > > + case 0b0001: > > + description = "64KB granule not supported at stage 2."; > > + break; > > + case 0b0010: > > + description = "64KB granule supported at stage 2."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "47:44"; > > + value = (aa64mmfr0_el1 >> 44) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_ExS not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_ExS implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + // 55:48 reserved > > + > > + bits = "59:56"; > > + value = (aa64mmfr0_el1 >> 56) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_FGT not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_FGT implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "63:60"; > > + value = (aa64mmfr0_el1 >> 60) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_ECV not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_ECV implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_ECV implemented with extras."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > +} > > + > > +void > > +handle_aa64mmfr1_el1 ( > > + const UINT64 aa64mmfr1_el1, > > + const UINT64 aa64pfr0_el1 > > + ) > > +{ > > + UINT64 value; > > + STATIC CONST CHAR8 RegName[] = "ID_AA64MMFR1_EL1"; > > + char *description; > > + char *bits; > > + > > + bits = "3:0 "; > > + value = aa64mmfr1_el1 & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_HAFDBS not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_HAFDBS implemented without dirty status support."; > > + break; > > + case 0b0010: > > + description = "FEAT_HAFDBS implemented with dirty status support."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "7:4 "; > > + value = (aa64mmfr1_el1 >> 4) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_VMID16 not implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_VMID16 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "11:8 "; > > + value = (aa64mmfr1_el1 >> 8) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_VHE not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_VHE implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "15:12"; > > + value = (aa64mmfr1_el1 >> 12) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_HPDS not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_HPDS implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_HPDS2 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "19:16"; > > + value = (aa64mmfr1_el1 >> 16) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_LOR not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_LOR implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "23:20"; > > + value = (aa64mmfr1_el1 >> 20) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_PAN not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_PAN implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_PAN2 implemented."; > > + break; > > + case 0b0011: > > + description = "FEAT_PAN3 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + // when FEAT_RAS implemented > > + if ((((aa64pfr0_el1 >> 28) & 0xf) == 0b0001) || > > + (((aa64pfr0_el1 >> 28) & 0xf) == 0b0010)) > > + { > > + if (((aa64mmfr1_el1 >> 24) & 0xf) == 0b0000 ) { > > + print_values ("ID_AA64MMFR1_EL1", "27:24", 0b0000, "The PE never generates an SError interrupt due to"); > > + print_text ("", "", "", "an External abort on a speculative read."); > > + } > > + > > + if (((aa64mmfr1_el1 >> 24) & 0xf) == 0b0001 ) { > > + print_values ("ID_AA64MMFR1_EL1", "27:24", 0b0001, "The PE might generate an SError interrupt due to"); > > + print_text ("", "", "", "an External abort on a speculative read."); > > + } > > + } > > + > > + bits = "31:28"; > > + value = (aa64mmfr1_el1 >> 28) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_XNX not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_XNX implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "35:32"; > > + value = (aa64mmfr1_el1 >> 32) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_TWED not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_TWED implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "39:36"; > > + value = (aa64mmfr1_el1 >> 36) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_ETS not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_ETS implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "43:40"; > > + value = (aa64mmfr1_el1 >> 40) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_HCX not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_HCX implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "47:44"; > > + value = (aa64mmfr1_el1 >> 44) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_AFP not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_AFP implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "51:48"; > > + value = (aa64mmfr1_el1 >> 48) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_nTLBPA not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_nTLBPA implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "55:52"; > > + value = (aa64mmfr1_el1 >> 52) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_TIDCP1 not implemented"; > > + break; > > + case 0b0001: > > + description = "FEAT_TIDCP1 implemented"; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "59:56"; > > + value = (aa64mmfr1_el1 >> 56) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_CMOW not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_CMOW implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + // 63:60 reserved > > +} > > + > > +void > > +handle_aa64mmfr2_el1 ( > > + const UINT64 aa64mmfr2_el1 > > + ) > > +{ > > + UINT64 value; > > + STATIC CONST CHAR8 RegName[] = "ID_AA64MMFR2_EL1"; > > + char *description; > > + char *bits; > > + > > + bits = "3:0 "; > > + value = (aa64mmfr2_el1) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_TTCNP not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_TTCNP implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "7:4 "; > > + value = (aa64mmfr2_el1 >> 4) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_UAO not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_UAO implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "11:8 "; > > + value = (aa64mmfr2_el1 >> 8) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_LSMAOC not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_LSMAOC implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "15:12"; > > + value = (aa64mmfr2_el1 >> 12) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_IESB not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_IESB implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "19:16"; > > + value = (aa64mmfr2_el1 >> 16) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_LVA not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_LVA implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "23:20"; > > + value = (aa64mmfr2_el1 >> 20) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_CCIDX not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_CCIDX implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "27:24"; > > + value = (aa64mmfr2_el1 >> 24) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_NV not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_NV implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_NV2 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "31:28"; > > + value = (aa64mmfr2_el1 >> 28) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_TTST not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_TTST implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "35:32"; > > + value = (aa64mmfr2_el1 >> 32) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_LSE2 not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_LSE2 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "39:36"; > > + value = (aa64mmfr2_el1 >> 36) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_IDST not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_IDST implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "43:40"; > > + value = (aa64mmfr2_el1 >> 40) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_S2FWB not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_S2FWB implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + // 47:44 reserved > > + > > + bits = "51:48"; > > + value = (aa64mmfr2_el1 >> 48) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_TTL not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_TTL implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "55:52"; > > + value = (aa64mmfr2_el1 >> 52) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_BBM: Level 0 support for changing block size is supported."; > > + break; > > + case 0b0001: > > + description = "FEAT_BBM: Level 1 support for changing block size is supported."; > > + break; > > + case 0b0010: > > + description = "FEAT_BBM: Level 2 support for changing block size is supported."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "59:56"; > > + value = (aa64mmfr2_el1 >> 56) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_EVT not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_EVT: HCR_EL2.{TOCU, TICAB, TID4} traps are supported."; > > + break; > > + case 0b0010: > > + description = "FEAT_EVT: HCR_EL2.{TTLBOS, TTLSBIS, TOCU, TICAB, TID4} traps are supported."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "63:60"; > > + value = (aa64mmfr2_el1 >> 60) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_E0PD not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_E0PD implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > +} > > + > > +void > > +handle_aa64pfr0_el1 ( > > + const UINT64 aa64pfr0_el1, > > + const UINT64 aa64pfr1_el1 > > + ) > > +{ > > + UINT64 value; > > + STATIC CONST CHAR8 RegName[] = "ID_AA64PFR0_EL1"; > > + char *description; > > + char *bits; > > + > > + bits = "3:0 "; > > + value = (aa64pfr0_el1) & 0xf; > > + switch (value) { > > + case 0b0001: > > + description = "EL0 in AArch64 only"; > > + break; > > + case 0b0010: > > + description = "EL0 in AArch64 and AArch32"; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "7:4 "; > > + value = (aa64pfr0_el1 >> 4) & 0xf; > > + switch (value) { > > + case 0b0001: > > + description = "EL1 in AArch64 only"; > > + break; > > + case 0b0010: > > + description = "EL1 in AArch64 and AArch32"; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "11:8 "; > > + value = (aa64pfr0_el1 >> 8) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "EL2 not implemented."; > > + break; > > + case 0b0001: > > + description = "EL2 in AArch64 only"; > > + break; > > + case 0b0010: > > + description = "EL2 in AArch64 and AArch32"; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "15:12"; > > + value = (aa64pfr0_el1 >> 12) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "EL3 not implemented."; > > + break; > > + case 0b0001: > > + description = "EL3 in AArch64 only"; > > + break; > > + case 0b0010: > > + description = "EL3 in AArch64 and AArch32"; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "19:16"; > > + value = (aa64pfr0_el1 >> 16) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "Floating-point implemented."; > > + break; > > + case 0b0001: > > + description = "Floating-point with half-precision support (FEAT_FP16)."; > > + break; > > + case 0b1111: > > + description = "Floating-point not implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "23:20"; > > + value = (aa64pfr0_el1 >> 20) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "Advanced SIMD implemented."; > > + break; > > + case 0b0001: > > + description = "Advanced SIMD with half precision support (FEAT_FP16)."; > > + break; > > + case 0b1111: > > + description = "Advanced SIMD not implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "27:24"; > > + value = (aa64pfr0_el1 >> 24) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "System registers of GIC CPU not implemented."; > > + break; > > + case 0b0001: > > + description = "System registers to versions 3.0/4.0 of GIC CPU implemented."; > > + break; > > + case 0b0011: > > + description = "System registers to versions 4.1 of GIC CPU implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "31:28"; > > + value = (aa64pfr0_el1 >> 28) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_RAS not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_RAS implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_RASv1p1 implemented."; > > + // 0b0010 FEAT_RASv1p1 implemented and, if EL3 is implemented, FEAT_DoubleFault implemented. > > + if ((((aa64pfr0_el1 >> 12) & 0xf) == 0b0001) || > > + (((aa64pfr0_el1 >> 12) & 0xf) == 0b0010)) > > + { > > + description = "FEAT_RASv1p1 implemented. FEAT_DoubleFault implemented."; > > + } > > + > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "35:32"; > > + value = (aa64pfr0_el1 >> 32) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_SVE not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_SVE implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "39:36"; > > + value = (aa64pfr0_el1 >> 36) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "Secure EL2 not implemented."; > > + break; > > + case 0b0001: > > + description = "Secure EL2 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "43:40"; > > + value = (aa64pfr0_el1 >> 40) & 0xf; > > + switch (value) { > > + case 0b0000: > > + if (((aa64pfr1_el1 >> 16) & 0xf) == 0b0000 ) { > > + description = "FEAT_MPAM not implemented."; > > + } > > + > > + if (((aa64pfr1_el1 >> 16) & 0xf) == 0b0001 ) { > > + description = "FEAT_MPAM v0.1 implemented."; > > + } > > + > > + break; > > + case 0b0001: > > + if (((aa64pfr1_el1 >> 16) & 0xf) == 0b0000 ) { > > + description = "FEAT_MPAM v1.0 implemented."; > > + } > > + > > + if (((aa64pfr1_el1 >> 16) & 0xf) == 0b0001 ) { > > + description = "FEAT_MPAM v1.1 implemented."; > > + } > > + > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "47:44"; > > + value = (aa64pfr0_el1 >> 44) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_AMU not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_AMUv1 implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_AMUv1p1 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "51:48"; > > + value = (aa64pfr0_el1 >> 48) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_DIT not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_DIT implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "55:52"; > > + value = (aa64pfr0_el1 >> 52) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_RME not implemented"; > > + break; > > + case 0b0001: > > + description = "FEAT_RME implemented"; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "59:56"; > > + value = (aa64pfr0_el1 >> 56) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "no info is FEAT_CSV2 implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_CSV2 implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_CSV2_2 implemented."; > > + break; > > + case 0b0011: > > + description = "FEAT_CSV2_3 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + if (value == 0b0001) { > > + if (((aa64pfr1_el1 >> 32) & 0xf) == 0b0001 ) { > > + print_values ("ID_AA64PRF1_EL1", "35:32", 0b0001, "FEAT_CSV2_1p1 implemented."); > > + } > > + > > + if (((aa64pfr1_el1 >> 32) & 0xf) == 0b0010 ) { > > + print_values ("ID_AA64PRF1_EL1", "35:32", 0b0010, "FEAT_CSV2_1p2 implemented."); > > + } > > + } > > + > > + bits = "63:60"; > > + value = (aa64pfr0_el1 >> 60) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_CSV3 not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_CSV3 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > +} > > + > > +void > > +handle_aa64pfr1_el1 ( > > + const UINT64 aa64pfr1_el1 > > + ) > > +{ > > + UINT64 value; > > + STATIC CONST CHAR8 RegName[] = "ID_AA64PFR1_EL1"; > > + char *description; > > + char *bits; > > + > > + bits = "3:0 "; > > + value = aa64pfr1_el1 & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_BTI not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_BTI implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "7:4 "; > > + value = (aa64pfr1_el1 >> 4) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_SSBS not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_SSBS implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_SSBS2 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "11:8 "; > > + value = (aa64pfr1_el1 >> 8) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_MTE not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_MTE implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_MTE2 implemented."; > > + break; > > + case 0b0011: > > + description = "FEAT_MTE3 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + // 15:12 is RAS_frac > > + // 19:16 is MPAM_frac > > + // 23:20 is reserved > > + > > + bits = "27:24"; > > + value = (aa64pfr1_el1 >> 24) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_SME not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_SME implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "31:28"; > > + value = (aa64pfr1_el1 >> 28) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_RNG_TRAP not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_RNG_TRAP implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + // 35:32 is CSV2_frac > > + > > + bits = "39:36"; > > + value = (aa64pfr1_el1 >> 36) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_NMI not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_NMI implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + // 63:40 are reserved > > +} > > + > > +void > > +handle_aa64isar0_el1 ( > > + const UINT64 aa64isar0_el1 > > + ) > > +{ > > + UINT64 value; > > + STATIC CONST CHAR8 RegName[] = "ID_AA64ISAR0_EL1"; > > + char *description; > > + char *bits; > > + > > + // 3:0 reserved > > + > > + bits = "7:4 "; > > + value = (aa64isar0_el1 >> 4) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_AES, FEAT_PMULL not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_AES implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_AES and FEAT_PMULL implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "11:8 "; > > + value = (aa64isar0_el1 >> 8) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_SHA1 not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_SHA1 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "15:12"; > > + value = (aa64isar0_el1 >> 12) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_SHA256, FEAT_SHA512 not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_SHA256 implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_SHA512 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "19:16"; > > + value = (aa64isar0_el1 >> 16) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "CRC32 not implemented."; > > + break; > > + case 0b0001: > > + description = "CRC32 instructions implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "23:20"; > > + value = (aa64isar0_el1 >> 20) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_LSE not implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_LSE implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "27:24"; > > + value = (aa64isar0_el1 >> 24) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "TME instructions not implemented."; > > + break; > > + case 0b0001: > > + description = "TME instructions implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "31:28"; > > + value = (aa64isar0_el1 >> 28) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_RDM not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_RDM implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "35:32"; > > + value = (aa64isar0_el1 >> 32) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_SHA3 not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_SHA3 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "39:36"; > > + value = (aa64isar0_el1 >> 36) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_SM3 not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_SM3 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "43:40"; > > + value = (aa64isar0_el1 >> 40) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_SM4 not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_SM4 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "47:44"; > > + value = (aa64isar0_el1 >> 44) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_DotProd not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_DotProd implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "51:48"; > > + value = (aa64isar0_el1 >> 48) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_FHM not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_FHM implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "55:52"; > > + value = (aa64isar0_el1 >> 52) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_FlagM/FEAT_FlagM2 not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_FlagM implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_FlagM2 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "59:56"; > > + value = (aa64isar0_el1 >> 56) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_TLBIOS/FEAT_TLBIRANGE not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_TLBIOS implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_TLBIRANGE implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "63:60"; > > + value = (aa64isar0_el1 >> 60) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_RNG not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_RNG implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > +} > > + > > +void > > +handle_aa64isar1_el1 ( > > + const UINT64 aa64isar1_el1 > > + ) > > +{ > > + UINT64 value; > > + STATIC CONST CHAR8 RegName[] = "ID_AA64ISAR1_EL1"; > > + char *description; > > + char *bits; > > + > > + bits = "3:0 "; > > + value = (aa64isar1_el1 >> 4) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "DC CVAP not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_DPB implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_DPB2 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "7:4 "; > > + value = (aa64isar1_el1 >> 4) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "Address Authentication (APA) not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_PAuth implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_EPAC implemented."; > > + break; > > + case 0b0011: > > + description = "FEAT_PAuth2 implemented."; > > + break; > > + case 0b0100: > > + description = "FEAT_FPAC implemented."; > > + break; > > + case 0b0101: > > + description = "FEAT_FPACCOMBINE implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + if (value > 0) { > > + print_text ("", "", "", "FEAT_PACQARMA5 implemented."); > > + } > > + > > + bits = "11:8 "; > > + value = (aa64isar1_el1 >> 8) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "Address Authentication (API) not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_PAuth implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_EPAC implemented."; > > + break; > > + case 0b0011: > > + description = "FEAT_PAuth2 implemented."; > > + break; > > + case 0b0100: > > + description = "FEAT_FPAC implemented."; > > + break; > > + case 0b0101: > > + description = "FEAT_FPACCOMBINE implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + if (value > 0) { > > + print_text ("", "", "", "FEAT_PACIMP implemented."); > > + } > > + > > + bits = "15:12"; > > + value = (aa64isar1_el1 >> 12) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_JSCVT not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_JSCVT implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "19:16"; > > + value = (aa64isar1_el1 >> 16) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_FCMA not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_FCMA implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "23:20"; > > + value = (aa64isar1_el1 >> 20) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_LRCPC (2) not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_LRCPC implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_LRCPC2 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "27:24"; > > + value = (aa64isar1_el1 >> 24) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_PACQARMA5 not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_PACQARMA5 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "31:28"; > > + value = (aa64isar1_el1 >> 28) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_PACIMP not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_PACIMP implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "35:32"; > > + value = (aa64isar1_el1 >> 32) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_FRINTTS not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_FRINTTS implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "39:36"; > > + value = (aa64isar1_el1 >> 36) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_SB not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_SB implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "43:40"; > > + value = (aa64isar1_el1 >> 40) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_SPECRES not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_SPECRES implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "47:44"; > > + value = (aa64isar1_el1 >> 44) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_BF16 not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_BF16 implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_EBF16 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "51:48"; > > + value = (aa64isar1_el1 >> 48) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_DGH not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_DGH implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "55:52"; > > + value = (aa64isar1_el1 >> 52) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_I8MM not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_I8MM implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "59:56"; > > + value = (aa64isar1_el1 >> 56) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_XS not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_XS implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "63:60"; > > + value = (aa64isar1_el1 >> 60) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_LS64 not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_LS64 implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_LS64_V implemented."; > > + break; > > + case 0b0011: > > + description = "FEAT_LS64_ACCDATA implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > +} > > + > > +void > > +handle_aa64isar2_el1 ( > > + const UINT64 aa64isar2_el1 > > + ) > > +{ > > + UINT64 value; > > + STATIC CONST CHAR8 RegName[] = "ID_AA64ISAR2_EL1"; > > + char *description; > > + char *bits; > > + > > + bits = "3:0 "; > > + value = (aa64isar2_el1 >> 4) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_WFxT not implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_WFxT implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "7:4 "; > > + value = (aa64isar2_el1 >> 4) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_RPRES not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_RPRES implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "11:8 "; > > + value = (aa64isar2_el1 >> 8) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_PACQARMA3 not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_PACQARMA3 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "15:12"; > > + value = (aa64isar2_el1 >> 12) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "Address Authentication (APA3) not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_PAuth implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_EPAC implemented."; > > + break; > > + case 0b0011: > > + description = "FEAT_PAuth2 implemented."; > > + break; > > + case 0b0100: > > + description = "FEAT_FPAC implemented."; > > + break; > > + case 0b0101: > > + description = "FEAT_FPACCOMBINE implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "19:16"; > > + value = (aa64isar2_el1 >> 16) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_MOPS not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_MOPS implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "23:20"; > > + value = (aa64isar2_el1 >> 20) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_HBC not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_HBC implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "27:24"; > > + value = (aa64isar2_el1 >> 24) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_CONSTPACFIELD not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_CONSTPACFIELD implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + // 63:28 reserved > > +} > > + > > +void > > +handle_aa64dfr0_el1 ( > > + const UINT64 aa64dfr0_el1 > > + ) > > +{ > > + UINT64 value; > > + STATIC CONST CHAR8 RegName[] = "ID_AA64DFR0_EL1"; > > + char *description; > > + char *bits; > > + > > + bits = "3:0 "; > > + value = (aa64dfr0_el1 >> 4) & 0xf; > > + switch (value) { > > + case 0b0110: > > + description = "Armv8 debug architecture"; > > + break; > > + case 0b0111: > > + description = "Armv8 debug architecture with VHE"; > > + break; > > + case 0b1000: > > + description = "FEAT_Debugv8p2 implemented."; > > + break; > > + case 0b1001: > > + description = "FEAT_Debugv8p4 implemented."; > > + break; > > + case 0b1010: > > + description = "FEAT_Debugv8p8 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "7:4 "; > > + value = (aa64dfr0_el1 >> 4) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "Trace unit System registers not implemented."; > > + break; > > + case 0b0001: > > + description = "Trace unit System registers implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "11:8 "; > > + value = (aa64dfr0_el1 >> 8) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "Performance Monitors Extension not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_PMUv3 implemented."; > > + break; > > + case 0b0100: > > + description = "FEAT_PMUv3p1 implemented."; > > + break; > > + case 0b0101: > > + description = "FEAT_PMUv3p4 implemented."; > > + break; > > + case 0b0110: > > + description = "FEAT_PMUv3p5 implemented."; > > + break; > > + case 0b0111: > > + description = "FEAT_PMUv3p7 implemented."; > > + break; > > + case 0b1000: > > + description = "FEAT_PMUv3p8 implemented."; > > + break; > > + case 0b1111: > > + description = "IMPLEMENTATION DEFINED form of performance monitors supported."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "15:12"; > > + value = (aa64dfr0_el1 >> 12) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "reserved"; > > + break; > > + default: > > + description = "Number of breakpoints, minus 1."; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + // 19:16 reserved > > + > > + bits = "23:20"; > > + value = (aa64dfr0_el1 >> 20) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "reserved"; > > + break; > > + default: > > + description = "Number of watchpoints, minus 1."; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + // 27:24 reserved > > + > > + bits = "31:28"; > > + value = (aa64dfr0_el1 >> 28) & 0xf; > > + switch (value) { > > + default: > > + description = "Number of breakpoints that are context-aware, minus 1."; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "35:32"; > > + value = (aa64dfr0_el1 >> 32) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_SPE not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_SPE implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_SPEv1p1 implemented."; > > + break; > > + case 0b0011: > > + description = "FEAT_SPEv1p2 implemented."; > > + break; > > + case 0b0100: > > + description = "FEAT_SPEv1p3 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "39:36"; > > + value = (aa64dfr0_el1 >> 36) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_DoubleLock implemented."; > > + break; > > + case 0b1111: > > + description = "FEAT_DoubleLock not implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "43:40"; > > + value = (aa64dfr0_el1 >> 40) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_TRF not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_TRF implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "47:44"; > > + value = (aa64dfr0_el1 >> 44) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_TRBE not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_TRBE implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "51:48"; > > + value = (aa64dfr0_el1 >> 48) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_MTPMU not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_MTPMU and FEAT_PMUv3 implemented."; > > + break; > > + case 0b1111: > > + description = "FEAT_MTPMU not implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + bits = "55:52"; > > + value = (aa64dfr0_el1 >> 52) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "FEAT_BRBE not implemented."; > > + break; > > + case 0b0001: > > + description = "FEAT_BRBE implemented."; > > + break; > > + case 0b0010: > > + description = "FEAT_BRBEv1p1 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > + > > + // 59:56 reserved > > + > > + bits = "63:60"; > > + value = (aa64dfr0_el1 >> 60) & 0xf; > > + switch (value) { > > + case 0b0000: > > + description = "Setting MDCR_EL2.HPMN to zero has CONSTRAINED UNPREDICTABLE behavior."; > > + break; > > + case 0b0001: > > + description = "FEAT_HPMN0 implemented."; > > + break; > > + default: > > + description = "unknown"; > > + break; > > + } > > + > > + print_values (RegName, bits, value, description); > > +} > > + > > +EFI_STATUS > > +EFIAPI > > +UefiMain ( > > + IN EFI_HANDLE ImageHandle, > > + IN EFI_SYSTEM_TABLE *SystemTable > > + ) > > +{ > > + UINT64 aa64dfr0_el1 = read_aa64dfr0_el1 (); > > + UINT64 aa64dfr1_el1 = read_aa64dfr1_el1 (); > > + UINT64 aa64isar0_el1 = read_aa64isar0_el1 (); > > + UINT64 aa64isar1_el1 = read_aa64isar1_el1 (); > > + UINT64 aa64isar2_el1 = read_aa64isar2_el1 (); > > + UINT64 aa64mmfr0_el1 = read_aa64mmfr0_el1 (); > > + UINT64 aa64mmfr1_el1 = read_aa64mmfr1_el1 (); > > + UINT64 aa64mmfr2_el1 = read_aa64mmfr2_el1 (); > > + UINT64 aa64pfr0_el1 = read_aa64pfr0_el1 (); > > + UINT64 aa64pfr1_el1 = read_aa64pfr1_el1 (); > > EDK2 requires separation between declarations and code (something > alike old C89 semantics, but stricter). so: > UINT64 aa64pfr1_el1; > <...> > aa64pfr1_el1 = read_aa64pfr1_el1 (); > > > + > > + /* UINT64 aa64smfr0_el1 = read_aa64smfr0_el1 ();*/ > > + /* UINT64 aa64zfr0_el1 = read_aa64zfr0_el1 ();*/ > > Dead Code? > > + > > + AsciiPrint ("ID_AA64MMFR0_EL1 = 0x%016lx\n", aa64mmfr0_el1); > > + AsciiPrint ("ID_AA64MMFR1_EL1 = 0x%016lx\n", aa64mmfr1_el1); > > + AsciiPrint ("ID_AA64MMFR2_EL1 = 0x%016lx\n", aa64mmfr2_el1); > > + AsciiPrint ("ID_AA64PFR0_EL1 = 0x%016lx\n", aa64pfr0_el1); > > + AsciiPrint ("ID_AA64PFR1_EL1 = 0x%016lx\n", aa64pfr1_el1); > > + AsciiPrint ("ID_AA64ISAR0_EL1 = 0x%016lx\n", aa64isar0_el1); > > + AsciiPrint ("ID_AA64ISAR1_EL1 = 0x%016lx\n", aa64isar1_el1); > > + AsciiPrint ("ID_AA64ISAR2_EL1 = 0x%016lx\n", aa64isar2_el1); > > + AsciiPrint ("ID_AA64DFR0_EL1 = 0x%016lx\n", aa64dfr0_el1); > > + AsciiPrint ("ID_AA64DFR1_EL1 = 0x%016lx\n", aa64dfr1_el1); // ignore > > Why ignore? > > > + /* AsciiPrint ("ID_AA64SMFR0_EL1 = 0x%016lx\n", aa64smfr0_el1);*/ > > + /* AsciiPrint ("ID_AA64ZFR0_EL1 = 0x%016lx\n", aa64zfr0_el1);*/ > > dead? > > + > > + AsciiPrint ("\n"); > > + print_text ("Register", "Bits", "Value", "Feature"); > > + print_spacer (); > > + > > + handle_aa64mmfr0_el1 (aa64mmfr0_el1); > > + print_spacer (); > > + handle_aa64mmfr1_el1 (aa64mmfr1_el1, aa64pfr0_el1); > > + print_spacer (); > > + handle_aa64mmfr2_el1 (aa64mmfr2_el1); > > + > > + print_spacer (); > > + handle_aa64pfr0_el1 (aa64pfr0_el1, aa64pfr1_el1); > > + print_spacer (); > > + handle_aa64pfr1_el1 (aa64pfr1_el1); > > + > > + print_spacer (); > > + handle_aa64isar0_el1 (aa64isar0_el1); > > + print_spacer (); > > + handle_aa64isar1_el1 (aa64isar1_el1); > > + print_spacer (); > > + handle_aa64isar2_el1 (aa64isar2_el1); > > + > > + print_spacer (); > > + handle_aa64dfr0_el1 (aa64dfr0_el1); > > + > > + return EFI_SUCCESS; > > +} > > diff --git a/ArmPkg/Application/ArmCpuInfo/readregs.s b/ArmPkg/Application/ArmCpuInfo/readregs.s > > ASM files that require preprocessing should have a capital S here (.S vs .s) > > > new file mode 100644 > > index 000000000000..052834b3c3f2 > > --- /dev/null > > +++ b/ArmPkg/Application/ArmCpuInfo/readregs.s > > @@ -0,0 +1,49 @@ > > +#include <AsmMacroIoLibV8.h> > > + > > +ASM_FUNC(read_aa64pfr0_el1) > > + mrs x0, ID_AA64PFR0_EL1; > > + ret; > > ASM lines (for GAS at least) don't usually end in semicolons. so > +ASM_FUNC(read_aa64pfr0_el1) > + mrs x0, ID_AA64PFR0_EL1 > + ret > > You'd only need the semicolons if you had multiple instructions in one > line (like mrs x0, ID_AA...; ret) > > > + > > +ASM_FUNC(read_aa64pfr1_el1) > > + mrs x0, ID_AA64PFR1_EL1; > > + ret; > > + > > +ASM_FUNC(read_aa64dfr0_el1) > > + mrs x0, ID_AA64DFR0_EL1; > > + ret; > > + > > +ASM_FUNC(read_aa64dfr1_el1) > > + mrs x0, ID_AA64DFR1_EL1; > > + ret; > > + > > +ASM_FUNC(read_aa64isar0_el1) > > + mrs x0, ID_AA64ISAR0_EL1; > > + ret; > > + > > +ASM_FUNC(read_aa64isar1_el1) > > + mrs x0, ID_AA64ISAR1_EL1; > > + ret; > > + > > +ASM_FUNC(read_aa64isar2_el1) > > + mrs x0, ID_AA64ISAR2_EL1; > > + ret; > > + > > +ASM_FUNC(read_aa64mmfr0_el1) > > + mrs x0, ID_AA64MMFR0_EL1; > > + ret; > > + > > +ASM_FUNC(read_aa64mmfr1_el1) > > + mrs x0, ID_AA64MMFR1_EL1; > > + ret; > > + > > +ASM_FUNC(read_aa64mmfr2_el1) > > + mrs x0, ID_AA64MMFR2_EL1; > > + ret; > > + > > +# ASM_FUNC(read_aa64zfr0_el1) > > +# mrs x0, ID_AA64ZFR0_EL1; > > +# ret; > > + > > +# ASM_FUNC(read_aa64smfr0_el1) > > +# mrs x0, ID_AA64SMFR0_EL1; > > +# ret; > > Dead code? > > > -- > > 2.40.0 > > Marcin, > > Brief comments in general: > 1) You use binary literals extensively, which are not portable (GNU C > extension, AFAIK not in MSVC) > > 2) Naming of identifiers (vars, functions, etc) needs to follow the > EDK2 style. eg: > description vs Description > read_aa64mmfr1_el1 vs ReadAa64MmfrEl1 > etc... > > -- > Pedro -- Pedro -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#102696): https://edk2.groups.io/g/devel/message/102696 Mute This Topic: https://groups.io/mt/98123579/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=-=-=-=-=-=-=-=-=-=-=-
App goes through ID_AA64*_EL1 system registers and decode their values.
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
---
ArmPkg/ArmPkg.dsc | 1 +
ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf | 38 +
ArmPkg/Application/ArmCpuInfo/readargs.h | 10 +
ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.c | 2319 ++++++++++++++++++++
ArmPkg/Application/ArmCpuInfo/readregs.S | 41 +
5 files changed, 2409 insertions(+)
diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc
index 3fb95d1951a9..6b938ce8b671 100644
--- a/ArmPkg/ArmPkg.dsc
+++ b/ArmPkg/ArmPkg.dsc
@@ -166,6 +166,7 @@ [Components.AARCH64]
ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.inf
ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
+ ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf
[Components.AARCH64, Components.ARM]
ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf
diff --git a/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf b/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf
new file mode 100644
index 000000000000..d80a19660a55
--- /dev/null
+++ b/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.inf
@@ -0,0 +1,38 @@
+## @file
+#
+# Attempt to have AArch64 cpu information.
+#
+# Based on HelloWorld:
+# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
+# Copyright (c) 2023 Marcin Juszkiewicz
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010019
+ BASE_NAME = ArmCpuInfo
+ FILE_GUID = b3134491-6502-4faf-a9da-007184e32163
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = UefiMain
+
+#
+# This flag specifies whether HII resource section is generated into PE image.
+#
+ UEFI_HII_RESOURCE_SECTION = TRUE
+
+[Sources]
+ ArmCpuInfo.c
+ readregs.S
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ UefiApplicationEntryPoint
+ UefiLib
diff --git a/ArmPkg/Application/ArmCpuInfo/readargs.h b/ArmPkg/Application/ArmCpuInfo/readargs.h
new file mode 100644
index 000000000000..b154945c6562
--- /dev/null
+++ b/ArmPkg/Application/ArmCpuInfo/readargs.h
@@ -0,0 +1,10 @@
+UINT64 ReadAa64Pfr0El1(void);
+UINT64 ReadAa64Pfr1El1(void);
+UINT64 ReadAa64Dfr0El1(void);
+UINT64 ReadAa64Dfr1El1(void);
+UINT64 ReadAa64Isar0El1(void);
+UINT64 ReadAa64Isar1El1(void);
+UINT64 ReadAa64Isar2El1(void);
+UINT64 ReadAa64Mmfr0El1(void);
+UINT64 ReadAa64Mmfr1El1(void);
+UINT64 ReadAa64Mmfr2El1(void);
diff --git a/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.c b/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.c
new file mode 100644
index 000000000000..13f77717215d
--- /dev/null
+++ b/ArmPkg/Application/ArmCpuInfo/ArmCpuInfo.c
@@ -0,0 +1,2319 @@
+/** @file
+
+ Copyright (c) 2023 Marcin Juszkiewicz
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ **/
+
+#include <Library/UefiLib.h>
+#include "readargs.h"
+
+VOID
+PrintText (
+ CONST CHAR8 *field,
+ CONST CHAR8 *Bits,
+ CONST CHAR8 *Value,
+ CONST CHAR8 *Description
+ )
+{
+ AsciiPrint (" %-16a | %5a | %5a | %a\n", field, Bits, Value, Description);
+}
+
+VOID
+PrintValues (
+ CONST CHAR8 *field,
+ CONST CHAR8 *Bits,
+ CONST UINT8 Value,
+ CONST CHAR8 *Description
+ )
+{
+ STATIC CONST CHAR8 binaries[][5] = {
+ "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
+ "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
+ };
+
+ AsciiPrint (" %-16a | %5a | %5a | %a\n", field, Bits, binaries[Value & 0xf], Description);
+}
+
+VOID
+PrintSpacer (
+ VOID
+ )
+{
+ AsciiPrint ("------------------|-------|-------|----------------------------------------------\n");
+}
+
+VOID
+HandleAa64Mmfr0El1 (
+ CONST UINT64 Aa64Mmfr0El1
+ )
+{
+ UINT64 Value;
+ STATIC CONST CHAR8 RegName[] = "ID_AA64MMFR0El1";
+ CONST CHAR8 *Description;
+ CONST CHAR8 *Bits;
+
+ Bits = "3:0 ";
+ Value = Aa64Mmfr0El1 & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "32 Bits (4GB) of physical address range supported.";
+ break;
+ case 0b0001:
+ Description = "36 Bits (64GB) of physical address range supported.";
+ break;
+ case 0b0010:
+ Description = "40 Bits (1TB) of physical address range supported.";
+ break;
+ case 0b0011:
+ Description = "42 Bits (4TB) of physical address range supported.";
+ break;
+ case 0b0100:
+ Description = "44 Bits (16TB) of physical address range supported.";
+ break;
+ case 0b0101:
+ Description = "48 Bits (256TB) of physical address range supported.";
+ break;
+ case 0b0110:
+ Description = "52 Bits (4PB) of physical address range supported.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+ if (Value == 0b0110) {
+ PrintText ("", "", "", "FEAT_LPA implemented.");
+ }
+
+ Bits = "7:4 ";
+ Value = (Aa64Mmfr0El1 >> 4) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "ASID: 8 Bits";
+ break;
+ case 0b0010:
+ Description = "ASID: 16 Bits";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "11:8 ";
+ Value = (Aa64Mmfr0El1 >> 8) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "No mixed-endian support.";
+ break;
+ case 0b0001:
+ Description = "Mixed-endian support.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ // only valid for BigEnd != 0b0000
+ if (((Aa64Mmfr0El1 >> 8) & 0xf) != 0b0000 ) {
+ if (((Aa64Mmfr0El1 >> 16) & 0xf) == 0b0000 ) {
+ PrintValues ("ID_AA64MMFR0El1", "19:16", 0b0000, "No mixed-endian support at EL0.");
+ }
+
+ if (((Aa64Mmfr0El1 >> 16) & 0xf) == 0b0001 ) {
+ PrintValues ("ID_AA64MMFR0El1", "19:16", 0b0001, "Mixed-endian support at EL0.");
+ }
+ }
+
+ Bits = "15:12";
+ Value = (Aa64Mmfr0El1 >> 12) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "No support for a distinction between Secure and Non-Secure Memory.";
+ break;
+ case 0b0001:
+ Description = "Supports a distinction between Secure and Non-Secure Memory.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "31:28";
+ Value = (Aa64Mmfr0El1 >> 28) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = " 4KB granule supported.";
+ break;
+ case 0b1111:
+ Description = " 4KB granule not supported.";
+ break;
+ case 0b0001: // add FEAT_LPA2 check
+ Description = " 4KB granule supported for 52-bit address.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "43:40";
+ Value = (Aa64Mmfr0El1 >> 40) & 0xf;
+ switch (Value) {
+ case 0b0001:
+ Description = " 4KB granule not supported at stage 2.";
+ break;
+ case 0b0010:
+ Description = " 4KB granule supported at stage 2.";
+ break;
+ case 0b0011:
+ Description = " 4KB granule supported at stage 2 for 52-bit address.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "23:20";
+ Value = (Aa64Mmfr0El1 >> 20) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "16KB granule not supported.";
+ break;
+ case 0b0001:
+ Description = "16KB granule supported.";
+ break;
+ case 0b0010: // add FEAT_LPA2 check
+ Description = "16KB granule supported for 52-bit address.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "35:32";
+ Value = (Aa64Mmfr0El1 >> 32) & 0xf;
+ switch (Value) {
+ case 0b0001:
+ Description = "16KB granule not supported at stage 2.";
+ break;
+ case 0b0010:
+ Description = "16KB granule supported at stage 2.";
+ break;
+ case 0b0011:
+ Description = "16KB granule supported at stage 2 for 52-bit address.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "27:24";
+ Value = (Aa64Mmfr0El1 >> 24) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "64KB granule supported.";
+ break;
+ case 0b1111:
+ Description = "64KB granule not supported.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "39:36";
+ Value = (Aa64Mmfr0El1 >> 36) & 0xf;
+ switch (Value) {
+ case 0b0001:
+ Description = "64KB granule not supported at stage 2.";
+ break;
+ case 0b0010:
+ Description = "64KB granule supported at stage 2.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "47:44";
+ Value = (Aa64Mmfr0El1 >> 44) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_ExS not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_ExS implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ // 55:48 reserved
+
+ Bits = "59:56";
+ Value = (Aa64Mmfr0El1 >> 56) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_FGT not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_FGT implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "63:60";
+ Value = (Aa64Mmfr0El1 >> 60) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_ECV not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_ECV implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_ECV implemented with extras.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+}
+
+VOID
+HandleAa64Mmfr1El1 (
+ CONST UINT64 Aa64Mmfr1El1,
+ CONST UINT64 Aa64Pfr0El1
+ )
+{
+ UINT64 Value;
+ STATIC CONST CHAR8 RegName[] = "ID_AA64MMFR1El1";
+ CONST CHAR8 *Description;
+ CONST CHAR8 *Bits;
+
+ Bits = "3:0 ";
+ Value = Aa64Mmfr1El1 & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_HAFDBS not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_HAFDBS implemented without dirty status support.";
+ break;
+ case 0b0010:
+ Description = "FEAT_HAFDBS implemented with dirty status support.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "7:4 ";
+ Value = (Aa64Mmfr1El1 >> 4) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_VMID16 not implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_VMID16 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "11:8 ";
+ Value = (Aa64Mmfr1El1 >> 8) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_VHE not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_VHE implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "15:12";
+ Value = (Aa64Mmfr1El1 >> 12) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_HPDS not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_HPDS implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_HPDS2 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "19:16";
+ Value = (Aa64Mmfr1El1 >> 16) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_LOR not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_LOR implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "23:20";
+ Value = (Aa64Mmfr1El1 >> 20) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_PAN not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_PAN implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_PAN2 implemented.";
+ break;
+ case 0b0011:
+ Description = "FEAT_PAN3 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ // when FEAT_RAS implemented
+ if ((((Aa64Pfr0El1 >> 28) & 0xf) == 0b0001) ||
+ (((Aa64Pfr0El1 >> 28) & 0xf) == 0b0010))
+ {
+ if (((Aa64Mmfr1El1 >> 24) & 0xf) == 0b0000 ) {
+ PrintValues ("ID_AA64MMFR1El1", "27:24", 0b0000, "The PE never generates an SError interrupt due to");
+ PrintText ("", "", "", "an External abort on a speculative read.");
+ }
+
+ if (((Aa64Mmfr1El1 >> 24) & 0xf) == 0b0001 ) {
+ PrintValues ("ID_AA64MMFR1El1", "27:24", 0b0001, "The PE might generate an SError interrupt due to");
+ PrintText ("", "", "", "an External abort on a speculative read.");
+ }
+ }
+
+ Bits = "31:28";
+ Value = (Aa64Mmfr1El1 >> 28) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_XNX not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_XNX implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "35:32";
+ Value = (Aa64Mmfr1El1 >> 32) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_TWED not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_TWED implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "39:36";
+ Value = (Aa64Mmfr1El1 >> 36) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_ETS not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_ETS implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "43:40";
+ Value = (Aa64Mmfr1El1 >> 40) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_HCX not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_HCX implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "47:44";
+ Value = (Aa64Mmfr1El1 >> 44) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_AFP not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_AFP implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "51:48";
+ Value = (Aa64Mmfr1El1 >> 48) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_nTLBPA not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_nTLBPA implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "55:52";
+ Value = (Aa64Mmfr1El1 >> 52) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_TIDCP1 not implemented";
+ break;
+ case 0b0001:
+ Description = "FEAT_TIDCP1 implemented";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "59:56";
+ Value = (Aa64Mmfr1El1 >> 56) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_CMOW not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_CMOW implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ // 63:60 reserved
+}
+
+VOID
+HandleAa64Mmfr2El1 (
+ CONST UINT64 Aa64Mmfr2El1
+ )
+{
+ UINT64 Value;
+ STATIC CONST CHAR8 RegName[] = "ID_AA64MMFR2El1";
+ CONST CHAR8 *Description;
+ CONST CHAR8 *Bits;
+
+ Bits = "3:0 ";
+ Value = (Aa64Mmfr2El1) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_TTCNP not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_TTCNP implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "7:4 ";
+ Value = (Aa64Mmfr2El1 >> 4) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_UAO not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_UAO implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "11:8 ";
+ Value = (Aa64Mmfr2El1 >> 8) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_LSMAOC not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_LSMAOC implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "15:12";
+ Value = (Aa64Mmfr2El1 >> 12) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_IESB not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_IESB implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "19:16";
+ Value = (Aa64Mmfr2El1 >> 16) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_LVA not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_LVA implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "23:20";
+ Value = (Aa64Mmfr2El1 >> 20) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_CCIDX not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_CCIDX implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "27:24";
+ Value = (Aa64Mmfr2El1 >> 24) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_NV not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_NV implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_NV2 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "31:28";
+ Value = (Aa64Mmfr2El1 >> 28) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_TTST not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_TTST implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "35:32";
+ Value = (Aa64Mmfr2El1 >> 32) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_LSE2 not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_LSE2 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "39:36";
+ Value = (Aa64Mmfr2El1 >> 36) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_IDST not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_IDST implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "43:40";
+ Value = (Aa64Mmfr2El1 >> 40) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_S2FWB not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_S2FWB implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ // 47:44 reserved
+
+ Bits = "51:48";
+ Value = (Aa64Mmfr2El1 >> 48) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_TTL not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_TTL implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "55:52";
+ Value = (Aa64Mmfr2El1 >> 52) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_BBM: Level 0 support for changing block size is supported.";
+ break;
+ case 0b0001:
+ Description = "FEAT_BBM: Level 1 support for changing block size is supported.";
+ break;
+ case 0b0010:
+ Description = "FEAT_BBM: Level 2 support for changing block size is supported.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "59:56";
+ Value = (Aa64Mmfr2El1 >> 56) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_EVT not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_EVT: HCR_EL2.{TOCU, TICAB, TID4} traps are supported.";
+ break;
+ case 0b0010:
+ Description = "FEAT_EVT: HCR_EL2.{TTLBOS, TTLSBIS, TOCU, TICAB, TID4} traps are supported.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "63:60";
+ Value = (Aa64Mmfr2El1 >> 60) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_E0PD not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_E0PD implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+}
+
+VOID
+HandleAa64Pfr0El1 (
+ CONST UINT64 Aa64Pfr0El1,
+ CONST UINT64 Aa64Pfr1El1
+ )
+{
+ UINT64 Value;
+ STATIC CONST CHAR8 RegName[] = "ID_AA64PFR0El1";
+ CONST CHAR8 *Description;
+ CONST CHAR8 *Bits;
+
+ Bits = "3:0 ";
+ Value = (Aa64Pfr0El1) & 0xf;
+ switch (Value) {
+ case 0b0001:
+ Description = "EL0 in AArch64 only";
+ break;
+ case 0b0010:
+ Description = "EL0 in AArch64 and AArch32";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "7:4 ";
+ Value = (Aa64Pfr0El1 >> 4) & 0xf;
+ switch (Value) {
+ case 0b0001:
+ Description = "EL1 in AArch64 only";
+ break;
+ case 0b0010:
+ Description = "EL1 in AArch64 and AArch32";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "11:8 ";
+ Value = (Aa64Pfr0El1 >> 8) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "EL2 not implemented.";
+ break;
+ case 0b0001:
+ Description = "EL2 in AArch64 only";
+ break;
+ case 0b0010:
+ Description = "EL2 in AArch64 and AArch32";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "15:12";
+ Value = (Aa64Pfr0El1 >> 12) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "EL3 not implemented.";
+ break;
+ case 0b0001:
+ Description = "EL3 in AArch64 only";
+ break;
+ case 0b0010:
+ Description = "EL3 in AArch64 and AArch32";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "19:16";
+ Value = (Aa64Pfr0El1 >> 16) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "Floating-point implemented.";
+ break;
+ case 0b0001:
+ Description = "Floating-point with half-precision support (FEAT_FP16).";
+ break;
+ case 0b1111:
+ Description = "Floating-point not implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "23:20";
+ Value = (Aa64Pfr0El1 >> 20) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "Advanced SIMD implemented.";
+ break;
+ case 0b0001:
+ Description = "Advanced SIMD with half precision support (FEAT_FP16).";
+ break;
+ case 0b1111:
+ Description = "Advanced SIMD not implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "27:24";
+ Value = (Aa64Pfr0El1 >> 24) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "System registers of GIC CPU not implemented.";
+ break;
+ case 0b0001:
+ Description = "System registers to versions 3.0/4.0 of GIC CPU implemented.";
+ break;
+ case 0b0011:
+ Description = "System registers to versions 4.1 of GIC CPU implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "31:28";
+ Value = (Aa64Pfr0El1 >> 28) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_RAS not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_RAS implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_RASv1p1 implemented.";
+ // 0b0010 FEAT_RASv1p1 implemented and, if EL3 is implemented, FEAT_DoubleFault implemented.
+ if ((((Aa64Pfr0El1 >> 12) & 0xf) == 0b0001) ||
+ (((Aa64Pfr0El1 >> 12) & 0xf) == 0b0010))
+ {
+ Description = "FEAT_RASv1p1 implemented. FEAT_DoubleFault implemented.";
+ }
+
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "35:32";
+ Value = (Aa64Pfr0El1 >> 32) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_SVE not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_SVE implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "39:36";
+ Value = (Aa64Pfr0El1 >> 36) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "Secure EL2 not implemented.";
+ break;
+ case 0b0001:
+ Description = "Secure EL2 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "43:40";
+ Value = (Aa64Pfr0El1 >> 40) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ if (((Aa64Pfr1El1 >> 16) & 0xf) == 0b0000 ) {
+ Description = "FEAT_MPAM not implemented.";
+ }
+
+ if (((Aa64Pfr1El1 >> 16) & 0xf) == 0b0001 ) {
+ Description = "FEAT_MPAM v0.1 implemented.";
+ }
+
+ break;
+ case 0b0001:
+ if (((Aa64Pfr1El1 >> 16) & 0xf) == 0b0000 ) {
+ Description = "FEAT_MPAM v1.0 implemented.";
+ }
+
+ if (((Aa64Pfr1El1 >> 16) & 0xf) == 0b0001 ) {
+ Description = "FEAT_MPAM v1.1 implemented.";
+ }
+
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "47:44";
+ Value = (Aa64Pfr0El1 >> 44) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_AMU not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_AMUv1 implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_AMUv1p1 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "51:48";
+ Value = (Aa64Pfr0El1 >> 48) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_DIT not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_DIT implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "55:52";
+ Value = (Aa64Pfr0El1 >> 52) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_RME not implemented";
+ break;
+ case 0b0001:
+ Description = "FEAT_RME implemented";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "59:56";
+ Value = (Aa64Pfr0El1 >> 56) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "no info is FEAT_CSV2 implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_CSV2 implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_CSV2_2 implemented.";
+ break;
+ case 0b0011:
+ Description = "FEAT_CSV2_3 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+ if (Value == 0b0001) {
+ if (((Aa64Pfr1El1 >> 32) & 0xf) == 0b0001 ) {
+ PrintValues ("ID_AA64PRF1El1", "35:32", 0b0001, "FEAT_CSV2_1p1 implemented.");
+ }
+
+ if (((Aa64Pfr1El1 >> 32) & 0xf) == 0b0010 ) {
+ PrintValues ("ID_AA64PRF1El1", "35:32", 0b0010, "FEAT_CSV2_1p2 implemented.");
+ }
+ }
+
+ Bits = "63:60";
+ Value = (Aa64Pfr0El1 >> 60) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_CSV3 not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_CSV3 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+}
+
+VOID
+HandleAa64Pfr1El1 (
+ CONST UINT64 Aa64Pfr1El1
+ )
+{
+ UINT64 Value;
+ STATIC CONST CHAR8 RegName[] = "ID_AA64PFR1El1";
+ CONST CHAR8 *Description;
+ CONST CHAR8 *Bits;
+
+ Bits = "3:0 ";
+ Value = Aa64Pfr1El1 & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_BTI not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_BTI implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "7:4 ";
+ Value = (Aa64Pfr1El1 >> 4) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_SSBS not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_SSBS implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_SSBS2 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "11:8 ";
+ Value = (Aa64Pfr1El1 >> 8) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_MTE not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_MTE implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_MTE2 implemented.";
+ break;
+ case 0b0011:
+ Description = "FEAT_MTE3 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ // 15:12 is RAS_frac
+ // 19:16 is MPAM_frac
+ // 23:20 is reserved
+
+ Bits = "27:24";
+ Value = (Aa64Pfr1El1 >> 24) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_SME not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_SME implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "31:28";
+ Value = (Aa64Pfr1El1 >> 28) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_RNG_TRAP not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_RNG_TRAP implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ // 35:32 is CSV2_frac
+
+ Bits = "39:36";
+ Value = (Aa64Pfr1El1 >> 36) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_NMI not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_NMI implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ // 63:40 are reserved
+}
+
+VOID
+HandleAa64Isar0El1 (
+ CONST UINT64 Aa64Isar0El1
+ )
+{
+ UINT64 Value;
+ STATIC CONST CHAR8 RegName[] = "ID_AA64ISAR0El1";
+ CONST CHAR8 *Description;
+ CONST CHAR8 *Bits;
+
+ // 3:0 reserved
+
+ Bits = "7:4 ";
+ Value = (Aa64Isar0El1 >> 4) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_AES, FEAT_PMULL not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_AES implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_AES and FEAT_PMULL implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "11:8 ";
+ Value = (Aa64Isar0El1 >> 8) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_SHA1 not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_SHA1 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "15:12";
+ Value = (Aa64Isar0El1 >> 12) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_SHA256, FEAT_SHA512 not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_SHA256 implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_SHA512 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "19:16";
+ Value = (Aa64Isar0El1 >> 16) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "CRC32 not implemented.";
+ break;
+ case 0b0001:
+ Description = "CRC32 instructions implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "23:20";
+ Value = (Aa64Isar0El1 >> 20) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_LSE not implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_LSE implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "27:24";
+ Value = (Aa64Isar0El1 >> 24) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "TME instructions not implemented.";
+ break;
+ case 0b0001:
+ Description = "TME instructions implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "31:28";
+ Value = (Aa64Isar0El1 >> 28) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_RDM not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_RDM implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "35:32";
+ Value = (Aa64Isar0El1 >> 32) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_SHA3 not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_SHA3 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "39:36";
+ Value = (Aa64Isar0El1 >> 36) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_SM3 not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_SM3 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "43:40";
+ Value = (Aa64Isar0El1 >> 40) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_SM4 not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_SM4 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "47:44";
+ Value = (Aa64Isar0El1 >> 44) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_DotProd not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_DotProd implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "51:48";
+ Value = (Aa64Isar0El1 >> 48) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_FHM not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_FHM implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "55:52";
+ Value = (Aa64Isar0El1 >> 52) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_FlagM/FEAT_FlagM2 not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_FlagM implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_FlagM2 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "59:56";
+ Value = (Aa64Isar0El1 >> 56) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_TLBIOS/FEAT_TLBIRANGE not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_TLBIOS implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_TLBIRANGE implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "63:60";
+ Value = (Aa64Isar0El1 >> 60) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_RNG not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_RNG implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+}
+
+VOID
+HandleAa64Isar1El1 (
+ CONST UINT64 Aa64Isar1El1
+ )
+{
+ UINT64 Value;
+ STATIC CONST CHAR8 RegName[] = "ID_AA64ISAR1El1";
+ CONST CHAR8 *Description;
+ CONST CHAR8 *Bits;
+
+ Bits = "3:0 ";
+ Value = (Aa64Isar1El1 >> 4) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "DC CVAP not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_DPB implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_DPB2 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "7:4 ";
+ Value = (Aa64Isar1El1 >> 4) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "Address Authentication (APA) not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_PAuth implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_EPAC implemented.";
+ break;
+ case 0b0011:
+ Description = "FEAT_PAuth2 implemented.";
+ break;
+ case 0b0100:
+ Description = "FEAT_FPAC implemented.";
+ break;
+ case 0b0101:
+ Description = "FEAT_FPACCOMBINE implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+ if (Value > 0) {
+ PrintText ("", "", "", "FEAT_PACQARMA5 implemented.");
+ }
+
+ Bits = "11:8 ";
+ Value = (Aa64Isar1El1 >> 8) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "Address Authentication (API) not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_PAuth implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_EPAC implemented.";
+ break;
+ case 0b0011:
+ Description = "FEAT_PAuth2 implemented.";
+ break;
+ case 0b0100:
+ Description = "FEAT_FPAC implemented.";
+ break;
+ case 0b0101:
+ Description = "FEAT_FPACCOMBINE implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+ if (Value > 0) {
+ PrintText ("", "", "", "FEAT_PACIMP implemented.");
+ }
+
+ Bits = "15:12";
+ Value = (Aa64Isar1El1 >> 12) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_JSCVT not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_JSCVT implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "19:16";
+ Value = (Aa64Isar1El1 >> 16) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_FCMA not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_FCMA implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "23:20";
+ Value = (Aa64Isar1El1 >> 20) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_LRCPC (2) not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_LRCPC implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_LRCPC2 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "27:24";
+ Value = (Aa64Isar1El1 >> 24) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_PACQARMA5 not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_PACQARMA5 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "31:28";
+ Value = (Aa64Isar1El1 >> 28) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_PACIMP not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_PACIMP implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "35:32";
+ Value = (Aa64Isar1El1 >> 32) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_FRINTTS not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_FRINTTS implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "39:36";
+ Value = (Aa64Isar1El1 >> 36) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_SB not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_SB implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "43:40";
+ Value = (Aa64Isar1El1 >> 40) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_SPECRES not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_SPECRES implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "47:44";
+ Value = (Aa64Isar1El1 >> 44) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_BF16 not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_BF16 implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_EBF16 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "51:48";
+ Value = (Aa64Isar1El1 >> 48) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_DGH not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_DGH implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "55:52";
+ Value = (Aa64Isar1El1 >> 52) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_I8MM not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_I8MM implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "59:56";
+ Value = (Aa64Isar1El1 >> 56) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_XS not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_XS implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "63:60";
+ Value = (Aa64Isar1El1 >> 60) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_LS64 not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_LS64 implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_LS64_V implemented.";
+ break;
+ case 0b0011:
+ Description = "FEAT_LS64_ACCDATA implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+}
+
+VOID
+HandleAa64Isar2El1 (
+ CONST UINT64 Aa64Isar2El1
+ )
+{
+ UINT64 Value;
+ STATIC CONST CHAR8 RegName[] = "ID_AA64ISAR2El1";
+ CONST CHAR8 *Description;
+ CONST CHAR8 *Bits;
+
+ Bits = "3:0 ";
+ Value = (Aa64Isar2El1 >> 4) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_WFxT not implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_WFxT implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "7:4 ";
+ Value = (Aa64Isar2El1 >> 4) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_RPRES not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_RPRES implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "11:8 ";
+ Value = (Aa64Isar2El1 >> 8) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_PACQARMA3 not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_PACQARMA3 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "15:12";
+ Value = (Aa64Isar2El1 >> 12) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "Address Authentication (APA3) not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_PAuth implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_EPAC implemented.";
+ break;
+ case 0b0011:
+ Description = "FEAT_PAuth2 implemented.";
+ break;
+ case 0b0100:
+ Description = "FEAT_FPAC implemented.";
+ break;
+ case 0b0101:
+ Description = "FEAT_FPACCOMBINE implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "19:16";
+ Value = (Aa64Isar2El1 >> 16) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_MOPS not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_MOPS implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "23:20";
+ Value = (Aa64Isar2El1 >> 20) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_HBC not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_HBC implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "27:24";
+ Value = (Aa64Isar2El1 >> 24) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_CONSTPACFIELD not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_CONSTPACFIELD implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ // 63:28 reserved
+}
+
+VOID
+HandleAa64Dfr0El1 (
+ CONST UINT64 Aa64Dfr0El1
+ )
+{
+ UINT64 Value;
+ STATIC CONST CHAR8 RegName[] = "ID_AA64DFR0El1";
+ CONST CHAR8 *Description;
+ CONST CHAR8 *Bits;
+
+ Bits = "3:0 ";
+ Value = (Aa64Dfr0El1 >> 4) & 0xf;
+ switch (Value) {
+ case 0b0110:
+ Description = "Armv8 debug architecture";
+ break;
+ case 0b0111:
+ Description = "Armv8 debug architecture with VHE";
+ break;
+ case 0b1000:
+ Description = "FEAT_Debugv8p2 implemented.";
+ break;
+ case 0b1001:
+ Description = "FEAT_Debugv8p4 implemented.";
+ break;
+ case 0b1010:
+ Description = "FEAT_Debugv8p8 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "7:4 ";
+ Value = (Aa64Dfr0El1 >> 4) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "Trace unit System registers not implemented.";
+ break;
+ case 0b0001:
+ Description = "Trace unit System registers implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "11:8 ";
+ Value = (Aa64Dfr0El1 >> 8) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "Performance Monitors Extension not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_PMUv3 implemented.";
+ break;
+ case 0b0100:
+ Description = "FEAT_PMUv3p1 implemented.";
+ break;
+ case 0b0101:
+ Description = "FEAT_PMUv3p4 implemented.";
+ break;
+ case 0b0110:
+ Description = "FEAT_PMUv3p5 implemented.";
+ break;
+ case 0b0111:
+ Description = "FEAT_PMUv3p7 implemented.";
+ break;
+ case 0b1000:
+ Description = "FEAT_PMUv3p8 implemented.";
+ break;
+ case 0b1111:
+ Description = "IMPLEMENTATION DEFINED form of performance monitors supported.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "15:12";
+ Value = (Aa64Dfr0El1 >> 12) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "reserved";
+ break;
+ default:
+ Description = "Number of breakpoints, minus 1.";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ // 19:16 reserved
+
+ Bits = "23:20";
+ Value = (Aa64Dfr0El1 >> 20) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "reserved";
+ break;
+ default:
+ Description = "Number of watchpoints, minus 1.";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ // 27:24 reserved
+
+ Bits = "31:28";
+ Value = (Aa64Dfr0El1 >> 28) & 0xf;
+ switch (Value) {
+ default:
+ Description = "Number of breakpoints that are context-aware, minus 1.";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "35:32";
+ Value = (Aa64Dfr0El1 >> 32) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_SPE not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_SPE implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_SPEv1p1 implemented.";
+ break;
+ case 0b0011:
+ Description = "FEAT_SPEv1p2 implemented.";
+ break;
+ case 0b0100:
+ Description = "FEAT_SPEv1p3 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "39:36";
+ Value = (Aa64Dfr0El1 >> 36) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_DoubleLock implemented.";
+ break;
+ case 0b1111:
+ Description = "FEAT_DoubleLock not implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "43:40";
+ Value = (Aa64Dfr0El1 >> 40) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_TRF not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_TRF implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "47:44";
+ Value = (Aa64Dfr0El1 >> 44) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_TRBE not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_TRBE implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "51:48";
+ Value = (Aa64Dfr0El1 >> 48) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_MTPMU not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_MTPMU and FEAT_PMUv3 implemented.";
+ break;
+ case 0b1111:
+ Description = "FEAT_MTPMU not implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ Bits = "55:52";
+ Value = (Aa64Dfr0El1 >> 52) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "FEAT_BRBE not implemented.";
+ break;
+ case 0b0001:
+ Description = "FEAT_BRBE implemented.";
+ break;
+ case 0b0010:
+ Description = "FEAT_BRBEv1p1 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+
+ // 59:56 reserved
+
+ Bits = "63:60";
+ Value = (Aa64Dfr0El1 >> 60) & 0xf;
+ switch (Value) {
+ case 0b0000:
+ Description = "Setting MDCR_EL2.HPMN to zero has CONSTRAINED UNPREDICTABLE behavior.";
+ break;
+ case 0b0001:
+ Description = "FEAT_HPMN0 implemented.";
+ break;
+ default:
+ Description = "unknown";
+ break;
+ }
+
+ PrintValues (RegName, Bits, Value, Description);
+}
+
+EFI_STATUS
+EFIAPI
+UefiMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ UINT64 Aa64Dfr0El1;
+ UINT64 Aa64Isar0El1;
+ UINT64 Aa64Isar1El1;
+ UINT64 Aa64Isar2El1;
+ UINT64 Aa64Mmfr0El1;
+ UINT64 Aa64Mmfr1El1;
+ UINT64 Aa64Mmfr2El1;
+ UINT64 Aa64Pfr0El1;
+ UINT64 Aa64Pfr1El1;
+
+ Aa64Dfr0El1 = ReadAa64Dfr0El1 ();
+ Aa64Isar0El1 = ReadAa64Isar0El1 ();
+ Aa64Isar1El1 = ReadAa64Isar1El1 ();
+ Aa64Isar2El1 = ReadAa64Isar2El1 ();
+ Aa64Mmfr0El1 = ReadAa64Mmfr0El1 ();
+ Aa64Mmfr1El1 = ReadAa64Mmfr1El1 ();
+ Aa64Mmfr2El1 = ReadAa64Mmfr2El1 ();
+ Aa64Pfr0El1 = ReadAa64Pfr0El1 ();
+ Aa64Pfr1El1 = ReadAa64Pfr1El1 ();
+
+ AsciiPrint ("ID_AA64MMFR0El1 = 0x%016lx\n", Aa64Mmfr0El1);
+ AsciiPrint ("ID_AA64MMFR1El1 = 0x%016lx\n", Aa64Mmfr1El1);
+ AsciiPrint ("ID_AA64MMFR2El1 = 0x%016lx\n", Aa64Mmfr2El1);
+ AsciiPrint ("ID_AA64PFR0El1 = 0x%016lx\n", Aa64Pfr0El1);
+ AsciiPrint ("ID_AA64PFR1El1 = 0x%016lx\n", Aa64Pfr1El1);
+ AsciiPrint ("ID_AA64ISAR0El1 = 0x%016lx\n", Aa64Isar0El1);
+ AsciiPrint ("ID_AA64ISAR1El1 = 0x%016lx\n", Aa64Isar1El1);
+ AsciiPrint ("ID_AA64ISAR2El1 = 0x%016lx\n", Aa64Isar2El1);
+ AsciiPrint ("ID_AA64DFR0El1 = 0x%016lx\n", Aa64Dfr0El1);
+
+ AsciiPrint ("\n");
+ PrintText ("Register", "Bits", "Value", "Feature");
+ PrintSpacer ();
+
+ HandleAa64Mmfr0El1 (Aa64Mmfr0El1);
+ PrintSpacer ();
+ HandleAa64Mmfr1El1 (Aa64Mmfr1El1, Aa64Pfr0El1);
+ PrintSpacer ();
+ HandleAa64Mmfr2El1 (Aa64Mmfr2El1);
+
+ PrintSpacer ();
+ HandleAa64Pfr0El1 (Aa64Pfr0El1, Aa64Pfr1El1);
+ PrintSpacer ();
+ HandleAa64Pfr1El1 (Aa64Pfr1El1);
+
+ PrintSpacer ();
+ HandleAa64Isar0El1 (Aa64Isar0El1);
+ PrintSpacer ();
+ HandleAa64Isar1El1 (Aa64Isar1El1);
+ PrintSpacer ();
+ HandleAa64Isar2El1 (Aa64Isar2El1);
+
+ PrintSpacer ();
+ HandleAa64Dfr0El1 (Aa64Dfr0El1);
+
+ return EFI_SUCCESS;
+}
diff --git a/ArmPkg/Application/ArmCpuInfo/readregs.S b/ArmPkg/Application/ArmCpuInfo/readregs.S
new file mode 100644
index 000000000000..21ba0a912823
--- /dev/null
+++ b/ArmPkg/Application/ArmCpuInfo/readregs.S
@@ -0,0 +1,41 @@
+#include <AsmMacroIoLibV8.h>
+
+ASM_FUNC(ReadAa64Pfr0El1)
+ mrs x0, ID_AA64PFR0_EL1
+ ret
+
+ASM_FUNC(ReadAa64Pfr1El1)
+ mrs x0, ID_AA64PFR1_EL1
+ ret
+
+ASM_FUNC(ReadAa64Dfr0El1)
+ mrs x0, ID_AA64DFR0_EL1
+ ret
+
+ASM_FUNC(ReadAa64Dfr1El1)
+ mrs x0, ID_AA64DFR1_EL1
+ ret
+
+ASM_FUNC(ReadAa64Isar0El1)
+ mrs x0, ID_AA64ISAR0_EL1
+ ret
+
+ASM_FUNC(ReadAa64Isar1El1)
+ mrs x0, ID_AA64ISAR1_EL1
+ ret
+
+ASM_FUNC(ReadAa64Isar2El1)
+ mrs x0, ID_AA64ISAR2_EL1
+ ret
+
+ASM_FUNC(ReadAa64Mmfr0El1)
+ mrs x0, ID_AA64MMFR0_EL1
+ ret
+
+ASM_FUNC(ReadAa64Mmfr1El1)
+ mrs x0, ID_AA64MMFR1_EL1
+ ret
+
+ASM_FUNC(ReadAa64Mmfr2El1)
+ mrs x0, ID_AA64MMFR2_EL1
+ ret
--
2.40.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#102703): https://edk2.groups.io/g/devel/message/102703
Mute This Topic: https://groups.io/mt/98124918/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
© 2016 - 2024 Red Hat, Inc.