From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from out2-smtp.messagingengine.com (out2-smtp.messagingengine.com [66.111.4.26]) by mx.groups.io with SMTP id smtpd.web11.170244.1680815141417497090 for ; Thu, 06 Apr 2023 14:05:41 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="signature has expired" header.i=@bsdio.com header.s=fm3 header.b=MMZETOwJ; spf=pass (domain: bsdio.com, ip: 66.111.4.26, mailfrom: rebecca@bsdio.com) Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailout.nyi.internal (Postfix) with ESMTP id C44595C0043; Thu, 6 Apr 2023 17:05:40 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Thu, 06 Apr 2023 17:05:40 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bsdio.com; h=cc :cc:content-transfer-encoding:content-type:content-type:date :date:from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:sender:subject:subject:to:to; s=fm3; t= 1680815140; x=1680901540; bh=Hj/JymY4a4728KHy4WIn6N7UXACqGrBgvTR pkvujqQ0=; b=MMZETOwJugGYdVDcCuNJBxlCHn+9xXuHgDnbw4t6kGVk/KSR00F gwlo9oaLVGrfLoTg5RFTjJGbt9skwyEmeVTF2VA/dOo32q9xfNB3r/eRBfBhk6VT GhqKNCuAUEha2SnUzeKOpmftBkZPGMxsv+Yzdr3o6RCElAOt1N180WqO2DkvafWw ZCZ1vp/ovjouVu9q57HeyhkZh1TMbEb7upYn+jDlQWVYop6ISIGde4ghWQXgGIOC m5mSV67IhqYOaiHdpjHR0uU78KIZUIR4aQP2+JWst2hkS6aIEDGoU+ObVdq8CGQX PvrfgeKC0GUM2PMtHXFtsd2cFmZi1l9XLtg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:sender:subject:subject:to:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t= 1680815140; x=1680901540; bh=Hj/JymY4a4728KHy4WIn6N7UXACqGrBgvTR pkvujqQ0=; b=XZB6j5H4PQBQulxrmkimLIBzPEfaSa3ckDRM6JWvhNxmfRDFI+x e61YIh8R8U1ctFkvQDbFbGN5kP0eInBeqkF3QPrbCX/EYfRAwP1osmX9e9kejRv0 KiIC5co5LWW77ssWKlxWgJFBUSHQZoks+wbYNFdmkw5torMhpVczLtv/NzNlLlh4 1JJ6um+0ZObyLnKyDtBYYf8m+MaRTS+VMEaJHDCUAJeLEKaH1luoxwWw0UJwgavb cgpFOaiMh6R0MQLootfV13YbHt2V471i3SIXky5fL2GJXpDXg3UlqJX9gRKGUffp 2oZ72KkF387dz0UprckPgyY7tHFtLd3wfaA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvhedrvdejfedgudehhecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecunecujfgurhepkfffgggfuffvfhevhfgjtgfgse htkeertddtfeejnecuhfhrohhmpeftvggsvggttggrucevrhgrnhcuoehrvggsvggttggr segsshguihhordgtohhmqeenucggtffrrghtthgvrhhnpeekkeffhfeutddtteeigfeftd eklefhheduveeukeeiudduvddvkeetvdekgeekieenucffohhmrghinheprhgvrggurhgv ghhsrdhssgenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhroh hmpehrvggsvggttggrsegsshguihhordgtohhm X-ME-Proxy: Feedback-ID: i5b994698:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 6 Apr 2023 17:05:39 -0400 (EDT) Message-ID: <77a6f44f-cd1f-71a7-0964-c8bc9fc103d5@bsdio.com> Date: Thu, 6 Apr 2023 15:05:38 -0600 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Thunderbird/102.9.1 Subject: Re: [edk2-devel] [PATCH] add ArmCpuInfo EFI application To: devel@edk2.groups.io, marcin.juszkiewicz@linaro.org References: <20230331180242.3593-1-marcin.juszkiewicz@linaro.org> Cc: Ard Biesheuvel , Leif Lindholm From: "Rebecca Cran" In-Reply-To: <20230331180242.3593-1-marcin.juszkiewicz@linaro.org> Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit 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 +#include +#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 > +#include > +#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 > + > +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