AARCHMRS Schema 2.7.4

Registers

The Register schema defines the layout of Arm Architecture registers. Below is a guide that represents the general concepts in a register.

A register defines a named layout of fields. For example:

{
    "_type": "Register",
    "state": "AArch64",
    "name": "REG0",
    "title": "Register 0",
    "purpose": "To describe a simple register in the user guide.",
    "fieldsets": [
        {
            "_type": "Fieldset",
            "width": 32,
            "values": [
                {
                    "_type": "Fields.Reserved",
                    "value": "RES0",
                    "rangeset": [
                        {
                            "_type": "Range",
                            "start": 1,
                            "width": 31
                        }
                    ]
                },
                {
                    "_type": "Fields.Field",
                    "name": "F0",
                    "rangeset": [
                        {
                            "_type": "Range",
                            "start": 0,
                            "width": 1
                        }
                    ],
                    "values": {
                        "_type": "Valuesets.Values",
                        "values": [
                            {
                                "_type": "Values.Value",
                                "meaning": "Value 0.",
                                "value": "'0'"
                            },
                            {
                                "_type": "Values.Value",
                                "meaning": "Value 1.",
                                "value": "'1'"
                            }
                        ]
                    }
                }
            ]
        }
    ]
}

This example shows a 32-bit register called REG0 in the AArch64 state, which has two fields:

Note

Field bit positions are always represented with the most significant bit first, followed by the least significant bit. For example: MSB:LSB, or 31:1.

Registers are uniquely qualified by the combination of the state and name, which is denoted by joining the two with -. For example: AArch64-REG0. Therefore, a register in the external state which shares the name REG0, ext-REG0, is distinct from AArch64-REG0 in MRS.

See the Register schema definition for a full list of properties and their usage.

Fieldsets

A fieldset in MRS describes an arrangement of bits in a register. Fieldsets are children of registers, and a register can contain many Fieldsets.

{
    "_type": "Register",
    "state": "AArch64",
    "name": "REG0",
    "purpose": "To describe a register containing fieldsets.",
    "fieldsets": [
        {
            "_type": "Fieldset",
            "width": 64,
            "condition": "IsFeatureImplemented(FEAT_A)",
            "values": [
                {
                    "_type": "Fields.Reserved",
                    "value": "RES0",
                    "rangeset": [
                        {
                            "_type": "Range",
                            "start": 4,
                            "width": 60
                        }
                    ]
                },
                {
                    "_type": "Fields.Field",
                    "description": {
                        "_type": "Description",
                        "after": null,
                        "before": "A description of the F1 field."
                    },
                    "name": "F1",
                    "rangeset": [
                        {
                            "_type": "Range",
                            "start": 0,
                            "width": 4
                        }
                    ],
                    "values": {
                        "_type": "Valuesets.Values",
                        "values": [
                            {
                                "_type": "Values.Value",
                                "meaning": "The first defined value.",
                                "value": "'0000'"
                            },
                            {
                                "_type": "Values.Value",
                                "meaning": "The second defined value.",
                                "value": "'0011'"
                            }
                        ]
                    }
                }
            ]
        },
        {
            "_type": "Fieldset",
            "condition": null,
            "values": [
                {
                    "_type": "Fields.Reserved",
                    "rangeset": [
                        {
                            "_type": "Range",
                            "start": 0,
                            "width": 64
                        }
                    ],
                    "value": "RES1"
                }
            ],
            "width": 64
        }
    ]
}

In this example, two fieldsets are contained within a fieldsets array, defining two distinct layouts of the same register. Where:

Note

Conditions can be defined for both Register and Fieldset models, in addition to other models in MRS. If the condition for a register is not met, and there is no null condition specified, the register is absent. However, if defining conditional fieldsets, you must also specify a null condition fieldset.

The sum of the widths of the fields in a fieldset must equal the width of the fieldset.

Fields

A named field

A field in MRS gives the meaning of a specified range of bits within a fieldset. Fields are children of the values property of fieldsets. The following example demonstrates a simple field:

{
    "_type": "Fields.Field",
    "description": {
        "_type": "Description",
        "after": null,
        "before": "A description of the F1 field."
    },
    "name": "F1",
    "rangeset": [
        {
            "_type": "Range",
            "start": 0,
            "width": 4
        }
    ],
    "values": {
        "_type": "Valuesets.Values",
        "values": [
            {
                "_type": "Values.Value",
                "meaning": "The first defined value.",
                "value": "'0000'"
            },
            {
                "_type": "Values.Value",
                "meaning": "The second defined value.",
                "value": "'0011'"
            },
            {
                "_type": "Values.Value",
                "meaning": "The third defined value.",
                "value": "'0100'"
            },
            {
                "_type": "Values.Value",
                "meaning": "The fourth defined value.",
                "value": "'1110'"
            }
        ]
    }
}

Where:

The above example should produce an output of the form:

F1, bits[3:0]

A description of the F1 field.

  • '0000': The first defined value.
  • '0011': The second defined value.
  • '0100': The third defined value.
  • '1110': The fourth defined value

While different Fields schemas have different required properties, all fields must have a specified rangeset. The rangeset encodes the size of the field in bits, and specifies the location of this field in the containing Fieldset.

See the Fields schema definition for a full list of properties and their usage, including optional properties and default implied values.

Values

An architecture defines bit-patterns which are expressed as values, and which can have an architectural meaning associated to them. Values defined in a field must fit the range of the field, for example the field F1 is 4-bits (3:0), therefore it can only contain values within this range.

Note

The above output shows the short form of values, The Fields.Field.values property is fully defined as a Valuesets.Values (a set of Values types), you can see the full canonical usage in the next example.

You can define conditional values using a Values.ConditionalValue model. In the example below, the conditional values only have meaning when FEAT_A is implemented. When FEAT_A is not implemented these values do not exist.

{
    "_type": "Fields.Field",
    "description": {
        "_type": "Description",
        "after": null,
        "before": "An example field with conditional fields."
    },
    "name": "FS",
    "rangeset": [
        {
            "_type": "Range",
            "start": 0,
            "width": 4
        }
    ],
    "values": {
        "_type": "Valuesets.Values",
        "values": [
            {
                "_type": "Values.Value",
                "meaning": "The first defined value.",
                "value": "'0001'"
            },
            {
                "_type": "Values.Value",
                "meaning": "The second defined value.",
                "value": "'0010'"
            },
            {
                "_type": "Values.ConditionalValue",
                "condition": "IsFeatureImplemented(FEAT_A)",
                "values": {
                    "_type": "Valuesets.Values",
                    "values": [
                        {
                            "_type": "Values.Value",
                            "meaning": "The third defined value, conditioned on FEAT_A.",
                            "value": "'1110'"
                        },
                        {
                            "_type": "Values.Value",
                            "meaning": "The third defined value, conditioned on FEAT_A.",
                            "value": "'1111'"
                        }
                    ]
                }
            }
        ]
    }
}

F1, bits[3:0]

An example field with conditional fields.

  • '0000': The first defined value.
  • '0011': The second defined value.
  • when FEAT_A is implemented, '0100': The third defined value, conditioned on FEAT_A.
  • when FEAT_A is implemented, '1110': The fourth defined value, conditioned on FEAT_A.

See the Values.ConditionalValue for more information

Resets

A field may have an architecturally defined reset value, to which it is set when the CPU is booted or reset. This is specified using the reset property in fields. For example:

{
    "_type": "Fields.Field",
    "description": {
        "_type": "Description",
        "after": null,
        "before": "An example field with conditional fields."
    },
    "name": "FS",
    "rangeset": [
        {
            "_type": "Range",
            "start": 0,
            "width": 4
        }
    ],
    "values": {
        "_type": "Valuesets.Values",
        "values": [
            {
                "_type": "Values.Value",
                "meaning": "The value that is set during reset.",
                "value": "'0000'"
            },
            {
                "_type": "Values.Value",
                "meaning": "Another value set during runtime.",
                "value": "'0011'"
            }
        ]
    },
    "resets": {
        "_type": "FieldResets",
        "domains": {
            "warm": {
                "_type": "Values.Value",
                "meaning": null,
                "value": "'0000'"
            }
        }
    }
}

Where:

The resets property of a field is used to contain a FieldResets model, which defines the reset value for the field. You must usually specify reset behavior for each field, even if the reset behavior of the field is the default.

As shown in the Fields.Field and Values.ConditionalValue examples above, the resets property of the field specifies which domain the reset is defined for (warm), and the value of the field following a reset of that specified domain (architecturally unknown).

A constant field

A Fields.ConstantField model in MRS defines a named read-only field which holds one constant value in an implementation. Here is an example:

{
    "_type": "Fields.ConstantField",
    "description": {
        "_type": "Description",
        "after": null,
        "before": "An 8-bit value set by an implementation, to define the version"
    },
    "name": "Version",
    "rangeset": [
        {
            "_type": "Range",
            "start": 0,
            "width": 8
        }
    ],
    "value": {
        "_type": "Values.ImplementationDefined"
    }
}

In the example above, Values.ImplementationDefined allows the implementation to specify any constant value.

In some cases, an architecture can create constraints, this is done using the constraint property on Values.ImplementationDefined:

{
    "_type": "Fields.ConstantField",
    "description": "An 8-bit value set by an implementation, defined by the architecture.",
    "name": "Version",
    "rangeset": [
        {
            "_type": "Range",
            "start": 0,
            "width": 8
        }
    ],
    "value": {
        "_type": "Values.ImplementationDefined",
        "constraints": {
            "_type": "Valuesets.Values",
            "values": [
                {
                    "_type": "Values.Value",
                    "meaning": "vMercury architecture.",
                    "value": "'00000000'"
                },
                {
                    "_type": "Values.Value",
                    "meaning": "vVenus architecture.",
                    "value": "'00000001'"
                },
                {
                    "_type": "Values.Value",
                    "meaning": "vEarth architecture.",
                    "value": "'00000010'"
                },
                {
                    "_type": "Values.Value",
                    "meaning": "vMars architecture.",
                    "value": "'00000011'"
                }
            ]
        }
    }
}

Alternatively, architecture may define a constant field with a known value:

{
    "_type": "Fields.ConstantField",
    "description": {
        "_type": "Description",
        "after": null,
        "before": "An 8-bit value set by the architecture."
    },
    "name": "Constant",
    "rangeset": [
        {
            "_type": "Range",
            "start": 0,
            "width": 8
        }
    ],
    "value": {
        "_type": "Values.Value",
        "meaning": "vEarth architecture.",
        "value": "'00000010'"
    }
}

A conditional field

A Fields.ConditionalField model allows you to define different layouts on a specific range of bits.

You can use Fields.ConditionalField, for example, in cases where a field is added by a feature and is reserved otherwise, or in cases where a field might be different depending on the properties of the implementation. For example:

{
    "_type": "Fields.ConditionalField",
    "fields": [
        {
            "condition": "IsFeatureImplemented(FEAT_A)",
            "field": {
                "_type": "Fields.Field",
                "name": "F1",
                "description": {
                    "_type": "Description",
                    "after": null,
                    "before": "F1 when FEAT_A is implemented"
                },
                "rangeset": [
                    {
                        "_type": "Range",
                        "start": 0,
                        "width": 4
                    }
                ],
                "values": {}
            }
        },
        {
            "condition": null,
            "field": {
                "_type": "Fields.Field",
                "name": "F2",
                "description": {
                    "_type": "Description",
                    "after": null,
                    "before": "F2 otherwise"
                },
                "rangeset": [
                    {
                        "_type": "Range",
                        "start": 0,
                        "width": 4
                    }
                ],
                "values": {}
            }
        }
    ],
    "rangeset": [
        {
            "_type": "Range",
            "start": 50,
            "width": 4
        }
    ],
    "reservedtype": "RES0"
}

Where:

A dynamic field

A Fields.Dynamic model allows you to define different layouts of multiple fields (unlike Fields.ConditionalField which allows you to specify one varying field). Similar to the fields array in Fields.ConditionalField, the fieldset that exists at any given instant is determined by a condition, and you can specify different properties for each fieldset and the fields it contains.

{
    "_type": "Register",
    "state": "AArch64",
    "name": "REG0",
    "purpose": "To describe a register containing a dynamic field.",
    "fieldsets": [
        {
            "_type": "Fieldset",
            "width": 32,
            "condition": null,
            "values": [
                {
                    "_type": "Fields.Dynamic",
                    "description": {
                        "_type": "Description",
                        "after": null,
                        "before": "A Dynamic field called F_DYNAMIC with layout D1 and D2"
                    },
                    "name": "F_DYNAMIC",
                    "rangeset": [
                        {
                            "_type": "Range",
                            "start": 1,
                            "width": 31
                        }
                    ],
                    "instances": [
                        {
                            "_type": "Fieldset",
                            "name": "D1",
                            "values": [
                                {
                                    "_type": "Fields.Reserved",
                                    "rangeset": [
                                        {
                                            "_type": "Range",
                                            "start": 2,
                                            "width": 29
                                        }
                                    ],
                                    "value": "RES0"
                                },
                                {
                                    "_type": "Fields.Field",
                                    "rangeset": [
                                        {
                                            "_type": "Range",
                                            "start": 0,
                                            "width": 2
                                        }
                                    ],
                                    "name": "F1",
                                    "values": {
                                        "_type": "Valuesets.Values",
                                        "values": [
                                            {
                                                "_type": "Values.Value",
                                                "meaning": "Value 0.",
                                                "value": "'00'"
                                            },
                                            {
                                                "_type": "Values.Value",
                                                "meaning": "Value 1.",
                                                "value": "'01'"
                                            }
                                        ]
                                    }
                                }
                            ],
                            "width": 31
                        },
                        {
                            "_type": "Fieldset",
                            "name": "D2",
                            "condition": "IsFeatureImplemented(FEAT_A)",
                            "values": [
                                {
                                    "_type": "Fields.Reserved",
                                    "rangeset": [
                                        {
                                            "_type": "Range",
                                            "start": 4,
                                            "width": 27
                                        }
                                    ],
                                    "value": "RES0"
                                },
                                {
                                    "_type": "Fields.Field",
                                    "rangeset": [
                                        {
                                            "_type": "Range",
                                            "start": 0,
                                            "width": 4
                                        }
                                    ],
                                    "name": "F5",
                                    "values": {
                                        "_type": "Valuesets.Values",
                                        "values": [
                                            {
                                                "_type": "Values.Value",
                                                "meaning": "Value 0.",
                                                "value": "'0000'"
                                            },
                                            {
                                                "_type": "Values.Value",
                                                "meaning": "Value 1.",
                                                "value": "'0001'"
                                            }
                                        ]
                                    }
                                }
                            ],
                            "width": 31
                        }
                    ]
                },
                {
                    "_type": "Fields.Reserved",
                    "rangeset": [
                        {
                            "_type": "Range",
                            "start": 0,
                            "width": 1
                        }
                    ],
                    "value": "RES0"
                }
            ]
        }
    ]
}

Here you see a dynamic field called F_DYNAMIC with two layouts D1 and D2. D2 only exists when FEAT_A is implemented and the fields D1.F1 and D2.F1 are completely different fields.

In some cases a layout may apply, given a value of another field. For example D1 may apply if a value of FOTHER == '00000'. To specify this behavior we use a Values.Link within the FOTHER field.

An implementation defined field

A Fields.ImplementationDefined model in MRS allocates space in a fieldset for implementation-specific fields. Use an implementation defined field to specify bits in a register that an implementation can use as required.

{
    "_type": "Fields.ImplementationDefined",
    "rangeset": [
        {
            "_type": "Range",
            "start": 8,
            "width": 4
        }
    ]
}

The allocated space for implementation defined fields can be divided into as many distinct fields as the implementation requires.

An array of fields

A Fields.Array model defines a fixed number of fields as an array. This is a shorthand method of creating multiple similar fields, which are generated from a single Fields.Array model.

{
    "_type": "Fields.Array",
    "description": {
        "_type": "Description",
        "after": null,
        "before": "Array of F<n> fields, where n = 0 to 15."
    },
    "index_variable": "n",
    "indexes": [
        {
            "_type": "Range",
            "start": 0,
            "width": 16
        }
    ],
    "name": "F<n>",
    "rangeset": [
        {
            "_type": "Range",
            "start": 0,
            "width": 32
        }
    ],
    "values": {
        "_type": "Valuesets.Values",
        "values": [
            {
                "_type": "Values.Value",
                "meaning": "Value 0.",
                "value": "'00'"
            },
            {
                "_type": "Values.Value",
                "meaning": "Value 1.",
                "value": "'01'"
            },
            {
                "_type": "Values.Value",
                "meaning": "Value 3.",
                "value": "'11'"
            }
        ]
    }
}

In the example above, the index_variable, indexes, name, and rangeset properties determine how the array of fields is generated. For each individual field within the array, the rangeset is expressed in terms of the index value. For example:

Note

In the example above, the Fields.Array model automatically generates 16 fields, named F(0-15). This means that no other fields within the same fieldset are permitted to share the name of a field that would be generated from the Fields.Array model.

A reserved field

A Fields.Reserved model specifies a range of bits that are reserved by Arm for future use.

{
    "_type": "Fields.Reserved",
    "value": "RES0",
    "rangeset": [
        {
            "_type": "Range",
            "start": 56,
            "width": 8
        }
    ]
}

The above example defines a RES0 field at bits 63:56.

Descriptions

A Description model in MRS allows you to add descriptive text within another model, such as a register, fieldset, or field, etc. A simple description, where text is only required before the content, can be implemented in a short-hand form as a property of a model:

{
    "_type": "Fields.Field",
    "description": {
        "_type": "Description",
        "after": null,
        "before": [
            "The first paragraph of the F1 field description.",
            "The second paragraph of the F1 field description.",
            [
                "The third paragraph.",
                "This line is also part of the third paragraph."
            ]
        ]
    },
    "name": "F1",
    "rangeset": [
        {
            "_type": "Range",
            "start": 0,
            "width": 4
        }
    ],
    "values": {}
}

An array notation is used to provide multiline support in JSON, where:

Note

You could have used \n inside one long string explicitly and it will result in the same output

Before and After descriptions

In some cases you need to define some text that appears before values, and other text that appears after them. For example if you wanted to represent the following:

F1, bits[3:0]

My F1 fields with two values

  • '0000': The first defined value.
  • '0011': The second defined value.

My favourite value is '0000'

Here saying "My favourite value is '0000'" before the value is defined may lead to confusion. Because of this, a description object can be stored as a dictionary, with before and after keys.

{
    "_type": "Fields.Field",
    "description": {
        "_type": "Description",
        "before": "My F1 fields with two values",
        "after": "My favourite value is '0000'"
    },
    "name": "F1",
    "rangeset": [
        {
            "_type": "Range",
            "start": 0,
            "width": 4
        }
    ],
    "values": {
        "_type": "Valuesets.Values",
        "values": [
            {
                "_type": "Values.Value",
                "meaning": "The first defined value.",
                "value": "'0000'"
            },
            {
                "_type": "Values.Value",
                "meaning": "The second defined value.",
                "value": "'0011'"
            }
        ]
    }
}

Note

You can use the array notation for multiline support within before and after values

Mapset

A mapset array in MRS captures architectural mappings between registers or register blocks, as a property of a Register model. This information automatically generates text in the Configuration section of the System register page, that states which mappings a register has, if any.

Note

When specifying a bi-directional mapping between registers, you must specify the mapsets in both registers. The appropriate mapping information is then automatically rendered as text in the Configuration of both mapped registers. Specifying a mapset in only one register represents a uni-directional mapping.

A register can be mapped to multiple registers, such as equivalent AArch64, AArch32, and External registers which are all mapped to each other. However, as mappings can only be uni-directional or bi-directional, each pairwise mapping must be individually specified, if more than two registers are mapped to each other. For example, you must define mapsets in both AArch64-REG0 and ext-REG0 to capture an architectural mapping between them in MRS, even if both specify bi-directional mappings to a AArch32-REG0 register.

Below is an example of a mapset specified in AArch64-REG0:

{
    "_type": "Register",
    "state": "AArch64",
    "name": "REG0",
    "title": "Register 0",
    "purpose": "To describe a simple register in the user guide.",
    "fieldsets": [
        {
            "_type": "Fieldset",
            "width": 32,
            "values": [
                {
                    "_type": "Fields.Field",
                    "name": "F0",
                    "rangeset": [
                        {
                            "_type": "Range",
                            "start": 0,
                            "width": 32
                        }
                    ],
                    "values": {
                        "_type": "Valuesets.Values",
                        "values": [
                            {
                                "_type": "Values.Value",
                                "meaning": "The only known value.",
                                "value": "'00000000000000000000000000000000'"
                            }
                        ]
                    }
                }
            ]
        }
    ],
    "mapset": [
        {
            "_type": "Mapping.RegisterMapping",
            "condition": null,
            "instance": null,
            "mapping_type": "Architectural",
            "maps": [
                {
                    "_type": "AST.SquareOp",
                    "arguments": [
                        {
                            "_type": "AST.Slice",
                            "left": {
                                "_type": "AST.Integer",
                                "value": 31
                            },
                            "right": {
                                "_type": "AST.Integer",
                                "value": 0
                            }
                        }
                    ],
                    "var": {
                        "_type": "Types.RegisterType",
                        "value": {
                            "instance": null,
                            "name": "REG0",
                            "slices": null,
                            "state": "ext"
                        }
                    }
                }
            ],
            "slices": [
                {
                    "_type": "Range",
                    "start": 0,
                    "width": 32
                }
            ]
        }
    ]
}

Note

In ext-REG0 you would need a corresponding mapset mapping back to AArch64-REG0

You can define a Mapping.RegisterMapping or Mapping.RegisterBlockMapping model within a mapset array. See the Mapping.RegisterMapping and Mapping.RegisterBlockMapping schema definitions for a full list of properties and their usage.

Register Blocks

A RegisterBlock encapsulates an array of Register or RegisterBlock object that occupy a contiguous range of the address map, and share a common set of accessors. The accessors define the access behaviors for each of the Registers and RegisterBlocks present in the blocks property.

For examples of the RegisterBlock and a full list of properties and their usage, refer to the RegisterBlock schema definition.