[edk2-devel] [PATCH] add ArmCpuInfo EFI application

Rebecca Cran rebecca at bsdio.com
Thu Apr 6 21:05:38 UTC 2023


Looks good - thanks.

There are a few style issues:


First, this patch came through as quoted-printable, with some lines 
wrapped. I'd be interested to learn how other people are dealing with 
this, since I've not seen complaints since Lazslo left the project.

Are people saving the _formatted_ output to apply with git? Or is there 
a script which can demangle the saved emails?


diff --git a/MdeModulePkg/Application/ArmCpuInfo/ArmCpuInfo.c b/MdeModulePk=
g/Application/ArmCpuInfo/ArmCpuInfo.c
new file mode 100644
index 0000000000..79a02ae430
--- /dev/null
+++ b/MdeModulePkg/Application/ArmCpuInfo/ArmCpuInfo.c
@@ -0,0 +1,2277 @@
+/** @file
+
+  Copyright (c) 2023 Marcin Juszkiewicz
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ **/
+
+#include <stdbool.h>
+#include <Library/UefiLib.h>
+#include "readargs.h"
+
+bool sve_present =3D false;
+bool sme_present =3D false;


There are also some style issues: the ones I've noticed are using tabs 
(edk2 uses spaces) and not having a space before the opening parenthesis 
in function calls - e.g.:


AsciiPrint("ID_AA64MMFR0_EL1 = 0x%016lx\n", aa64mmfr0_el1);


If you push your changes to a fork on GitHub you can submit a private PR 
and have CI run against it to tell you any further issues, or I can 
fixup the formatting and send you a copy if you'd like.


-- 

Rebecca Cran


On 3/31/23 12:02 PM, Marcin Juszkiewicz wrote:
> App goes through ID_AA64*_EL1 system registers and decode their values.
>
> First version which does not use much of current AArch64 support code
> present in EDK2. Written to check what data is there and what can be
> done with it.
> ---
>   .../Application/ArmCpuInfo/ArmCpuInfo.c       | 2277 +++++++++++++++++
>   .../Application/ArmCpuInfo/ArmCpuInfo.inf     |   38 +
>   .../Application/ArmCpuInfo/readargs.h         |   12 +
>   .../Application/ArmCpuInfo/readregs.s         |   49 +
>   MdeModulePkg/MdeModulePkg.dsc                 |    3 +-
>   5 files changed, 2378 insertions(+), 1 deletion(-)
>   create mode 100644 MdeModulePkg/Application/ArmCpuInfo/ArmCpuInfo.c
>   create mode 100644 MdeModulePkg/Application/ArmCpuInfo/ArmCpuInfo.inf
>   create mode 100644 MdeModulePkg/Application/ArmCpuInfo/readargs.h
>   create mode 100644 MdeModulePkg/Application/ArmCpuInfo/readregs.s
>
> diff --git a/MdeModulePkg/Application/ArmCpuInfo/ArmCpuInfo.c b/MdeModulePkg/Application/ArmCpuInfo/ArmCpuInfo.c
> new file mode 100644
> index 0000000000..79a02ae430
> --- /dev/null
> +++ b/MdeModulePkg/Application/ArmCpuInfo/ArmCpuInfo.c
> @@ -0,0 +1,2277 @@
> +/** @file
> +
> +  Copyright (c) 2023 Marcin Juszkiewicz
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> + **/
> +
> +#include <stdbool.h>
> +#include <Library/UefiLib.h>
> +#include "readargs.h"
> +
> +bool sve_present = false;
> +bool sme_present = false;
> +
> +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)
> +{
> +	char binaries[17][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], description);
> +}
> +
> +void print_spacer(void)
> +{
> +	AsciiPrint("------------------|-------|-------|----------------------------------------------\n");
> +}
> +
> +void handle_aa64mmfr0_el1(const UINT64 aa64mmfr0_el1)
> +{
> +	UINT64 value;
> +	char* 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;
> +	char* 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;
> +	char* 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;
> +	char* 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;
> +	char* 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;
> +	char* 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;
> +	char* 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;
> +	char* 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;
> +	char* 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/MdeModulePkg/Application/ArmCpuInfo/ArmCpuInfo.inf b/MdeModulePkg/Application/ArmCpuInfo/ArmCpuInfo.inf
> new file mode 100644
> index 0000000000..aa4a1ea148
> --- /dev/null
> +++ b/MdeModulePkg/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/MdeModulePkg/Application/ArmCpuInfo/readargs.h b/MdeModulePkg/Application/ArmCpuInfo/readargs.h
> new file mode 100644
> index 0000000000..eaa52cf161
> --- /dev/null
> +++ b/MdeModulePkg/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/MdeModulePkg/Application/ArmCpuInfo/readregs.s b/MdeModulePkg/Application/ArmCpuInfo/readregs.s
> new file mode 100644
> index 0000000000..19312f1e27
> --- /dev/null
> +++ b/MdeModulePkg/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;
> diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
> index 1014598f31..1ecfb34515 100644
> --- a/MdeModulePkg/MdeModulePkg.dsc
> +++ b/MdeModulePkg/MdeModulePkg.dsc
> @@ -216,6 +216,7 @@
>     gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryFileName|L"FVMAIN.FV"
>   
>   [Components]
> +  MdeModulePkg/Application/ArmCpuInfo/ArmCpuInfo.inf
>     MdeModulePkg/Application/HelloWorld/HelloWorld.inf
>     MdeModulePkg/Application/DumpDynPcd/DumpDynPcd.inf
>     MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.inf
> @@ -520,4 +521,4 @@
>     MdeModulePkg/Universal/CapsulePei/CapsuleX64.inf
>   
>   [BuildOptions]
> -
> +GCC:*_*_AARCH64_CC_FLAGS = -march=armv9-a


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#102629): https://edk2.groups.io/g/devel/message/102629
Mute This Topic: https://groups.io/mt/97979062/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-




More information about the edk2-devel-archive mailing list