From: Marc Zyngier <maz@kernel.org>
To: linux-arm-kernel@lists.infradead.org
Cc: Mark Rutland <mark.rutland@arm.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>, Mark Brown <broonie@kernel.org>
Subject: [PATCH] arm64: Add basic JSON register parser
Date: Wed, 25 Dec 2024 18:57:11 +0000 [thread overview]
Message-ID: <20241225185711.582648-1-maz@kernel.org> (raw)
We currently populate the sysreg file by hand from the ARM ARM,
resulting in a bunch of errors being introduced on a regular basis.
While there is an XML dump of the architecture produced on a quarterly
basis, the license that comes attached to it excludes any sort of
open-source usage.
However, ARM has recently made available a JSON dump[1] that contains
a reduced set of information under a BSD license. This has enough
data to extract what is relevant to the sysreg file.
This is achieved using a JQ script that I cobbled together over
the holiday, and while it has a number of limitations, it already
works well enough to extract useful data.
As an example, here's what the script returns for TCR_EL1:
$ jq -r --arg REG TCR_EL1 -f arch/arm64/tools/dumpreg.jq ~/Work/XML/2024-12/AARCHMRS_BSD_A_profile/Registers.json
TCR_EL1 [3,0,0,2,2] MRS
TCR_EL1 [3,0,0,2,2] MSRregister
TCR_EL12 [3,5,0,2,2] MRS
TCR_EL12 [3,5,0,2,2] MSRregister
TCRALIAS_EL1 [3,0,7,2,6] MRS
TCRALIAS_EL1 [3,0,7,2,6] MSRregister
true
true
Res0 63:62
Field 61 MTX1 (IsFeatureImplemented(FEAT_MTE_NO_ADDRESS_TAGS) || IsFeatureImplemented(FEAT_MTE_CANONICAL_TAGS))
Field 60 MTX0 (IsFeatureImplemented(FEAT_MTE_NO_ADDRESS_TAGS) || IsFeatureImplemented(FEAT_MTE_CANONICAL_TAGS))
Field 59 DS (IsFeatureImplemented(FEAT_LPA2) && (!IsFeatureImplemented(FEAT_D128) || (AArch64 TCR2_EL1.D128 == '0')))
Field 59 DS true
Field 58 TCMA1 IsFeatureImplemented(FEAT_MTE2)
Field 57 TCMA0 IsFeatureImplemented(FEAT_MTE2)
Field 56 E0PD1 IsFeatureImplemented(FEAT_E0PD)
Field 55 E0PD0 IsFeatureImplemented(FEAT_E0PD)
Field 54 NFD1 (IsFeatureImplemented(FEAT_SVE) || IsFeatureImplemented(FEAT_TME))
Field 53 NFD0 (IsFeatureImplemented(FEAT_SVE) || IsFeatureImplemented(FEAT_TME))
Field 52 TBID1 IsFeatureImplemented(FEAT_PAuth)
Field 51 TBID0 IsFeatureImplemented(FEAT_PAuth)
Field 50 HWU162 IsFeatureImplemented(FEAT_HPDS2)
Field 49 HWU161 IsFeatureImplemented(FEAT_HPDS2)
Field 48 HWU160 IsFeatureImplemented(FEAT_HPDS2)
Field 47 HWU159 IsFeatureImplemented(FEAT_HPDS2)
Field 46 HWU062 IsFeatureImplemented(FEAT_HPDS2)
Field 45 HWU061 IsFeatureImplemented(FEAT_HPDS2)
Field 44 HWU060 IsFeatureImplemented(FEAT_HPDS2)
Field 43 HWU059 IsFeatureImplemented(FEAT_HPDS2)
Field 42 HPD1 IsFeatureImplemented(FEAT_HPDS)
Field 41 HPD0 IsFeatureImplemented(FEAT_HPDS)
Field 40 HD IsFeatureImplemented(FEAT_HAFDBS)
Field 39 HA IsFeatureImplemented(FEAT_HAFDBS)
Field 38 TBI1
Field 37 TBI0
Field 36 AS
Res0 35
Field 34:32 IPS
Field 31:30 TG1
Field 29:28 SH1
Field 27:26 ORGN1
Field 25:24 IRGN1
Field 23 EPD1
Field 22 A1
Field 21:16 T1SZ
Field 15:14 TG0
Field 13:12 SH0
Field 11:10 ORGN0
Field 9:8 IRGN0
Field 7 EPD0
Res0 6
Field 5:0 T0SZ
I completely expect this to quickly rewritten by people who know
what they are doing (I don't) and improved as we understand more
of the data model.
[1] https://developer.arm.com/-/cdn-downloads/permalink/Exploration-Tools-OS-Machine-Readable-Data/AARCHMRS_BSD/AARCHMRS_BSD_A_profile-2024-12.tar.gz
Signed-off-by: Marc Zyngier <maz@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Mark Brown <broonie@kernel.org>
---
arch/arm64/tools/dumpreg.jq | 124 ++++++++++++++++++++++++++++++++++++
1 file changed, 124 insertions(+)
create mode 100644 arch/arm64/tools/dumpreg.jq
diff --git a/arch/arm64/tools/dumpreg.jq b/arch/arm64/tools/dumpreg.jq
new file mode 100644
index 000000000000..84527e8d52bf
--- /dev/null
+++ b/arch/arm64/tools/dumpreg.jq
@@ -0,0 +1,124 @@
+# SPDX-License-Identifier: GPL-2.0
+# dumpreg.jq: JSON arm64 system register data extrator
+#
+# Usage: jq -r --arg REG "XZY_ELx" -f ./dumpreg.jq Registers.json
+
+# Dump a set of semi-pertinent informations (encodings, fields,
+# conditions, field position and width) about register XZY_ELx as
+# contained in ARM's AARCHMRS_BSD_A_profile JSON tarball.
+
+# This can/should be used to populate the arch/arm64/tools/sysreg
+# file, instead of copying things by hand.
+
+# The tool currently has a bunch of limitations that users need to be
+# aware of, but that should have a major impact on the usability:
+
+# - All accessors are shown, irrespective of the conditions in which
+# the accessors are actually available
+
+# - All Fields.ConstantField are displayed as UnsignedEnum,
+# irrespective of the signess of the field (as the JSON doesn't
+# carry this information).
+
+# - Not all the field types are supported (Fields.Array being the most
+# obvious one).
+
+# - Value ranges are displayed using '[...]'.
+
+# - MSRimmediate accessors have a giberish encoding displayed.
+
+# - ... and probably more...
+
+def walknode:
+ if (._type == "AST.Identifier" or ._type == "AST.Integer") then
+ .value
+ elif (._type == "Types.Field") then
+ @text "\(.value.state) \(.value.name).\(.value.field)"
+ elif (._type == "AST.UnaryOp") then
+ @text "\(.op)\(.expr | walknode)"
+ elif (._type == "AST.Function") then
+ @text "\(.name)(\(.arguments[] | walknode))"
+ elif (._type == "AST.DotAtom") then
+ .values | map(walknode) | join(".")
+ elif (._type == "AST.BinaryOp") then
+ @text "(\(.left | walknode) \(.op) \(.right | walknode))"
+ elif (._type == "Values.Value" or ._type == "AST.Bool") then
+ @text "\(.value)"
+ else # debug catch-all
+ .
+ end;
+
+def range:
+ . as { _type: $type, start: $start, width: $width } |
+ if ($width == 1) then
+ @text "\($start)"
+ else
+ @text "\($start + $width - 1):\($start)"
+ end;
+
+def fld:
+ @text "\(.type)\t\(.range | range)\t\(.name)";
+
+def condition:
+ @text "\(.condition | walknode)";
+
+def unquote:
+ "'" as $q | (.value | ltrimstr($q) | rtrimstr($q));
+
+def binvalue:
+ unquote as $v | @text "\t0b\($v)\tVAL_\($v)";
+
+def dumpconstants:
+ if (._type == "Values.Value") then
+ binvalue
+ elif (._type == "Values.ValueRange") then
+ (.start | binvalue), @text "\t[...]", (.end | binvalue)
+ end;
+
+def walkfields:
+ if (._type == "Fields.Reserved" and .value == "RES0") then
+ { type: "Res0", name: "", range: .rangeset[] } | fld
+ elif (._type == "Fields.Reserved" and .value == "RES1") then
+ { type: "Res1", name: "", range: .rangeset[] } | fld
+ elif (._type == "Fields.ConditionalField") then
+ .fields[] as $f |
+ { type: "Field", name: $f.field.name, range: .rangeset[],
+ condition: $f.condition } |
+ @text "\(fld)\t\(condition)"
+
+ elif (._type == "Fields.Dynamic") then
+ .instances[] | @text "\(.values[] | walkfields)\t\(condition)"
+ elif (._type == "Fields.ConstantField") then
+ ({ type: "UnsignedEnum", name: .name, range: .rangeset[] } | fld),
+ (.value.constraints.values[]? | dumpconstants),
+ @text "EndEnum"
+ elif (._type == "Fields.Field") then
+ { type: "Field", name: .name, range: .rangeset[] } | fld
+ else # Debug catch all
+ .
+ end;
+
+def walkreg:
+ .fieldsets[] | condition,(.values[] | walkfields);
+
+# https://rosettacode.org/wiki/Non-decimal_radices/Convert#jq
+def bin_to_i:
+ explode | reverse| map(. - 48) |
+ reduce .[] as $c
+ # state: [power, ans]
+ ([1,0]; (.[0] * 2) as $b | [$b, .[1] + (.[0] * $c)]) | .[1];
+
+def encodings:
+ "'" as $q | .encodings |
+ @text "\(map(.value) | map(ltrimstr($q) | rtrimstr($q)) | map(bin_to_i) |
+ [ .[2], .[3], .[0], .[1], .[4]])";
+
+def encoding:
+ "A64." as $a64 |
+ @text "\(.encoding[].asmvalue)\t\(.encoding[] | encodings)\t\(.name | ltrimstr($a64))";
+
+def accessors:
+ .accessors[] | encoding;
+
+.[] | select (._type == "Register" and .name == $REG) |
+ accessors,condition,walkreg
--
2.43.0
next reply other threads:[~2024-12-25 18:58 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-25 18:57 Marc Zyngier [this message]
2024-12-27 17:47 ` [PATCH] arm64: Add basic JSON register parser Marc Zyngier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241225185711.582648-1-maz@kernel.org \
--to=maz@kernel.org \
--cc=broonie@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=mark.rutland@arm.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.