This blog post provides a high-level introduction to the Arm Architecture Machine Readable Specification (AARCHMRS) Features.json. It provides some initial examples to interpret and start to work with the available data using Python.
The Armv8-A architecture introduced mandatory and optional architectural features. Some features must be implemented together to be compliant to the expectations of the architecture.
For example, an implementation is compliant to the original Armv8-A architecture if it includes all Armv8.0 mandatory architectural features. The implementation may include optional Armv8.0 architectural features and some architectural features of Armv8.1, if constraints are met.
The Arm Architecture Machine Readable Specification (AARCHMRS) provides structured data and representations of the Arm Architecture. As a part of AARCHMRS, Arm has made an accessible package providing a JSON model of the arm Architectural Features for Armv8-A and Armv9-A. Future releases may include more types of architectural data.
The Arm Architecture Features Model (AARCHMRS Features.json) package can be downloaded from the Arm Developer A-Profile Architecture Exploration Tools page.
The package contains the Features.json as well as additional schema and guidance documentation. It provides:
All detail in this blog post is in reference to the data and structure from AARCHMRS_A_profile-2024-12.tar.gz. Refer to the readme file for your download and for the package contents as well as terms and conditions of use.
The AARCHMRS Features Model provides structured information about the architectural configuration of individual features within the architecture, including constraints. Constraints are relationships between architectural features (FEAT_XXX), architectural versions (v8Ap1) and register ID fields, where a condition must be satisfied to apply an action. The relationships, or constraints, are provided within the JSON data as textual descriptions and as Parameters connected by Boolean logic.
A parameter will have a name and may have additional values and constraints associated with it. In the data, each parameter will contain:
Parameters might be architecture extensions like v8Ap1 and v8Ap2 or features like FEAT_A or FEAT_B.
For example, support for AArch64 at EL2 is optionally available in the architecture from Armv8.0.
This feature is represented as a parameter with a name, title and values:
The description for this parameter includes the string: “FEAT_AA64EL2 is OPTIONAL from Armv8.0.”
The fact it is available from Armv8.0 can also be logically represented as follows:
FEAT_AA64EL2 --> v8Ap0
where the existence of FEAT_AA64EL2 means that the architectural revision will be from v8Ap0 onwards.
These logical operation relationships are represented in the data according to an Abstract Syntax Tree BinaryOp model (AST.BinaryOp). The AST.BinaryOp covers all binary operation relationships, such as A == B, A --> B, and so on. AST stands for Abstract Syntax Tree. This model covers everything from simple binary logical conditions to more complex expressions to be satisfied. More guidance on the logical meaning is provided in the package.
In the documentation these might be summarized as strings, such as A --> B, however in the data these will be stored as AST.BinaryOp structured data.
The constraint FEAT_AA64EL2 --> v8Ap0 for example, is shown in the following data:
"constraints": [ { "_type": "AST.BinaryOp", "left": { "_type": "AST.Identifier", "value": "FEAT_AA64EL2" }, "op": "-->", "right": { "_type": "AST.Identifier", "value": "v8Ap0" } }, ]
In this first blog post we start to investigate ways to work with this data. Later, posts will provide more in-depth suggestions for parsing and working with the AST.BinaryOp structure.
What follows is a simplistic example of how you can use python to read in the Features.json file and start to interrogate fields.
The following code block reads in the Features.json file and uses the json.loads() method to then parse the contents into a Python Dictionary.
import json if __name__ == '__main__': # Set file path to load JSON from file_path = "C:\\Users\\johhun02\\OneDrive - Arm\\Desktop\\FEAT\\Features.json" #file_path = "<your-file-path>Features.json" # Open file and read contents with open(file_path, 'r') as file: file_contents = file.read() # Load JSON data data = json.loads(file_contents) # Get parameters from JSON data parameters = data["parameters"]
The following is an example of simple code that could be added to allow you to search for a named feature (FEAT_XXX). It consumes the parameters data and provides back a summary of the requested feature including text description and textual summary of constraints.
# Get feature to search for print("Enter FEAT to search for or press Enter to list all: ") requested_feat = input() if len(requested_feat) > 0: parameters = [parameter for parameter in parameters if parameter["name"] == requested_feat] # Loop through parameters and print them for parameter in parameters: if parameter["title"] is not None: # Get description description = parameter["description"] # Print parameter title print('Title:', parameter["title"]) # Print dashes to underline title print("-" * len(parameter["title"])) # Print parameter name print('Name:', parameter["name"])
When run, the prompt asks for a FEAT to search for. We us the example of FEAT_AA64EL2, which provides back the following:
The full Features.json file that appears in the AARCHMRS_A_profile download contains a “description” type. This is split into a Description.before property and a Description.after property. This enables placement of content before and after the constraints. Note that in the open source AARCHMRS_BSD download, all descriptions have been redacted. See later in this post for more information about the Open Source Machine Readable Data package.
We can add the ability to list out constraints as part of this loop using the Description contents.
# Print description if description is not None: if description["before"] is not None: print('Description:', description["before"]) if description["after"] is not None: print('Description:') # Loop through after descriptions and print them for after in description["after"]: print(after) print(" ")
It is important to note, as shown in the previous example, that descriptions may also include Arm Markdown Language (AML). More guidance on AML is provided in the package.
The Features model does not distinguish between architectural versions and features, these are represented as Parameters connected by Boolean logic.
At present as all architectural versions are represented in a consistent format, it is possible to additionally extrapolate the base version that a feature was available from, however this approach cannot be relied on:
# Print architectural version for constraint in parameter["constraints"]: if "value" in constraint["left"] and "value" in constraint["right"]: if constraint["left"]["value"] == parameter["name"] and constraint["op"].startswith("-->"): if constraint["right"]["value"].startswith("v"): print("Architectural Revision: " + constraint["right"]["value"])
We are working on making the AARCHMRS available as well as increasing guidance and examples in this space.
For example, also on the same A Profile Architecture Downloads page is a similar package released under a BSD License. The Open Source Machine Readable Data package contains a subset of the architecture feature constraints Features.json discussed in this blog post. While this package has reduced coverage of the architecture and omits content that is not currently in a machine-readable format and descriptive content, it provides additional json files:
There is a lot we would want to do with this data, and would really like to hear your thoughts on this:
If your answer is yes to any of these, please do leave a comment and let us know.