| Document number: | DEN0137 |
| Document quality: | ALP |
| Document version: | 1.1-alp10alp11 |
| Document confidentiality: | Non-confidential |
| Document Build Information: |
Contents
Preface
Quality level
This table below summarises the quality level of the features which have been added in version 1.1 of this specification.
| Feature | Quality level |
|---|---|
| Realm device assignment (foundation) | BETA |
| Realm device assignment (stage 1 SMMU) | ALPHA |
| Planes | BETA |
| Realm memory encryption | BETA |
| Live firmware activation | ALPHA |
| Platform software component countersigners | BETA |
Due to the fact that some features are at ALPHA, the overall quality level of this version of the specification is ALPHA.
Conventions
Typographical conventions
The typographical conventions are:
italic
Introduces special terminology, and denotes citations.
monospace
Used for pseudocode and source code examples.
Also used in the main text for instruction mnemonics and for references to other items appearing in pseudocode and source code examples.
small capitals
Used for some common terms such as implementation defined.
Used for a few terms that have specific technical meanings, and are included in the Glossary.
Red text
Indicates an open issue.
Blue text
Indicates a link. This can be
- A cross-reference to another location within the document
- A URL, for example http://developer.arm.com
Numbers
Numbers are normally written in decimal. Binary numbers are preceded
by 0b, and hexadecimal numbers by 0x. In both
cases, the prefix and the associated value are written in a monospace
font, for example 0xFFFF0000. To improve readability, long
numbers can be written with an underscore separator between every four
characters, for example 0xFFFF_0000_0000_0000. Ignore any
underscores when interpreting the value of a number.
Pseudocode descriptions
This book uses a form of pseudocode to provide precise descriptions of the specified functionality. This pseudocode is written in a monospace font. The pseudocode language is described in the Arm Architecture Reference Manual.
Addresses
Unless otherwise stated, the term address in this specification refers to a physical address.
Rules-based writing
This specification consists of a set of individual content items. A content item is classified as one of the following:
- Declaration
- Rule
- Goal
- Information
- Rationale
- Implementation note
- Software usage
Declarations and Rules are normative statements. An implementation that is compliant with this specification must conform to all Declarations and Rules in this specification that apply to that implementation.
Declarations and Rules must not be read in isolation. Where a particular feature is specified by multiple Declarations and Rules, these are generally grouped into sections and subsections that provide context. Where appropriate, these sections begin with a short introduction.
Arm strongly recommends that implementers read all chapters and sections of this document to ensure that an implementation is compliant.
Content items other than Declarations and Rules are informative statements. These are provided as an aid to understanding this specification.
Content item identifiers
A content item may have an associated identifier which is unique among content items in this specification.
After this specification reaches beta status, a given content item has the same identifier across subsequent versions of the specification.
Content item rendering
In this document, a content item is rendered with a token of the following format in the left margin: Liiiii
- L is a label that indicates the content class of the content item.
- iiiii is the identifier of the content item.
Content item classes
Declaration
A Declaration is a statement that does one or more of the following:
- Introduces a concept
- Introduces a term
- Describes the structure of data
- Describes the encoding of data
A Declaration does not describe behaviour.
A Declaration is rendered with the label D.
Rule
A Rule is a statement that describes the behaviour of a compliant implementation.
A Rule explains what happens in a particular situation.
A Rule does not define concepts or terminology.
A Rule is rendered with the label R.
Goal
A Goal is a statement about the purpose of a set of rules.
A Goal explains why a particular feature has been included in the specification.
A Goal is comparable to a “business requirement” or an “emergent property.”
A Goal is intended to be upheld by the logical conjunction of a set of rules.
A Goal is rendered with the label G.
Information
An Information statement provides information and guidance as an aid to understanding the specification.
An Information statement is rendered with the label I.
Rationale
A Rationale statement explains why the specification was specified in the way it was.
A Rationale statement is rendered with the label X.
Implementation note
An Implementation note provides guidance on implementation of the specification.
An Implementation note is rendered with the label U.
Software usage
A Software usage statement provides guidance on how software can make use of the features defined by the specification.
A Software usage statement is rendered with the label S.
Additional reading
This section lists publications by Arm and by third parties.
See Arm Developer (http://developer.arm.com) for access to Arm documentation.
Feedback
Arm welcomes feedback on its documentation.
Feedback on this book
If you have any comments or suggestions for additions and improvements, create a ticket at https://support.developer.arm.com/. As part of the ticket, include:
- The title (Realm Management Monitor specification).
- The number (DEN0137 1.1-alp10alp11).
- The section name(s) to which your comments refer.
- The page number(s) to which your comments apply.
- The rule identifier(s) to which your comments apply, if applicable.
- A concise explanation of your comments.
Arm also welcomes general suggestions for additions and improvements.
Arm tests PDFs only in Adobe Acrobat and Acrobat Reader, and cannot guarantee the appearance or behavior of any document when viewed with any other PDF reader.
Open issues
The following table lists known open issues in this version of the document.
| Key | Description |
|---|---|
| - | Consider how teardown of DRAM mappings (via RMI_DATA_DESTROY) composes with teardown of device memory mappings (via RMI_DEV_MEM_UNMAP). In each case, the command returns the IPA of the next live entry - but it doesn’t tell the caller whether this is DRAM or IO. How then can the caller know which of the two commands to call next, while still avoiding a (race-prone) call to RMI_RTT_READ_ENTRY? |
| - | In RMI_RTT_SET_RIPASRMI_RTT_DEV_MEM_VALIDATE, consider how to combine:
|
1 Overview
The RMM is a software component which forms part of a system which implements the Arm Confidential Compute Architecture (Arm CCA). Arm CCA is an architecture which provides protected execution environments called Realms.
The threat model which Arm CCA is designed to address is described in Introducing Arm CCA [1].
The hardware architecture of Arm CCA is called the Realm Management Extension (RME), and is described in Arm Architecture Reference Manual Supplement, The Realm Management Extension (RME), for Armv9-A [2].
1.1 Confidential computing
The Armv8-A architecture (Arm Architecture Reference Manual for A-Profile architecture [3]) includes mechanisms that establish a privilege hierarchy. Software operating at higher privilege levels is responsible for managing the resources (principally memory and processor cycles) that are used by entities at lower privilege levels.
Prior to Arm CCA, resource management was coupled with a right of access. That is, a resource that is managed by a higher-privileged entity is also accessible by it. A Realm is a protected execution environment for which this coupling is broken, so that the right to manage resources is separated from the right to access those resources.
The purpose of a Realm is to provide to the Realm owner an environment for confidential computing, without requiring the Realm owner to trust the software components that manage the resources used by the Realm.
Construction of a Realm, and allocation of resources to a Realm at runtime, are the responsibility of the Virtual Machine Monitor (VMM). In this specification, the term Host is used to refer to the VMM.
See also:
- Section 2.1
1.2 System software components
The system software architecture of Arm CCA is summarised in the following figure.
The components shown in the diagram are listed below.
| Component | Description |
|---|---|
| Monitor | The most privileged software component, which is responsible for switching between the Security states used at EL2, EL1 and EL0. |
| Realm | A protected execution environment. |
| Realm Management Monitor (RMM) | The software component which is responsible for the management of Realms. |
| Virtual Machine (VM) | An execution environment within which an operating system can run. Note that a Realm is a VM which executes in the Realm security state. |
| Hypervisor | The software component which is responsible for the management of VMs. |
| Secure Partition Manager (SPM) | The software component which is responsible for the management of Secure Partitions. |
| Trusted OS (TOS) | An operating system which runs in a Secure Partition. |
| Trusted Application (TA) | An application hosted by a TOS. |
1.3 Realm Management Monitor
The Realm Management Monitor (RMM) is the system component that is responsible for the management of Realms.
The responsibilities of the RMM are to:
Provide services that allow the Host to create, populate, execute and destroy Realms.
Provide services that allow the initial configuration and contents of a Realm to be attested.
Protect the confidentiality and integrity of Realm state during the lifetime of the Realm.
Protect the confidentiality of Realm state during and following destruction of the Realm.
Act as the Trusted Security Manager (TSM) in Realm device assignment.
The RMM exposes the following interfaces, which are accessed via SMC instructions, to the Host:
- The Realm Management Interface (RMI), which provides services for the creation, population, execution and destruction of Realms.
The RMM exposes the following interfaces, which are accessed via SMC instructions, to Realms:
The Realm Services Interface (RSI), which provides services used to manage resources allocated to the Realm, and to request an attestation report.
The Power State Coordination Interface (PSCI), which provides services used to control power states of VPEs within a Realm. Note that the HVC conduit for PSCI is not supported for Realms.
The RMM operates by manipulating data structures which are stored in memory accessible only to the RMM.
2 Concepts
This chapter introduces the following concepts which are central to the RMM architecture:
2.1 Realm
This section describes the concept of a Realm.
2.1.1 Overview
A Realm is an execution environment which is protected from agents in the Non-secure and Secure Security states, and from other Realms.
2.1.2 Realm execution environment
The execution environment of a Realm is an EL0 + EL1 environment, as described in Arm Architecture Reference Manual for A-Profile architecture [3].
2.1.2.1 Realm registers
On first entry to a Realm VPE, PE state is initialized according to “PE state on reset to AArch64 state” in Arm Architecture Reference Manual for A-Profile architecture [3], except for GPR and PC values which are specified by the Host during Realm creation.
Confidentiality is guaranteed for a Realm VPE’s general purpose and SIMD / floating point registers.
Confidentiality is guaranteed for other Realm VPE register state (including stack pointer, program counter and EL0 / EL1 system registers).
Integrity is guaranteed for a Realm VPE’s general purpose and SIMD / floating point registers.
Integrity is guaranteed for other Realm VPE register state (including stack pointer, program counter and EL0 / EL1 system registers).
A Realm can use a Host call to pass arguments to the Host and receive results from the Host.
2.1.2.2 Realm memory
A Realm is able to determine whether a given IPA is protected or unprotected.
Confidentiality is guaranteed for memory contents accessed via a protected address. Informally, this means that a change to the contents of such a memory location is not observable by any agent outside the CCA platform.
Integrity is guaranteed for memory contents accessed via a protected address. Informally, this means that the Realm does not observe the contents of the location to change unless the Realm itself has either written a different value to the location, or provided consent to the RMM for integrity of the location to be violated.
See also:
- Section 5.2.1
2.1.2.3 Realm processor features
The value returned to a Realm from reading a feature register is architecturally valid and describes the set of features which are present in the Realm’s execution environment.
The RMM may suppress a feature which is supported by the underlying hardware platform, if exposing that feature to a Realm could lead to a security vulnerability.
See also:
- Section 3
2.1.2.4 IMPDEF system registers
A Realm read from or write to an implementation defined system register causes an Unknown exception taken to the Realm.
2.1.3 Realm attributes
This section describes the attributes of a Realm.
A Realm attribute is a property of a Realm whose value can be observed or modified either by the Host or by the Realm.
An example of a way in which a Realm attribute may be observable is the outcome of an RMM command.
The attributes of a Realm are summarized in the following table.
| Name | Type | Description |
|---|---|---|
| feat_lpa2 | RmmFeature | Whether LPA2 is enabled for this Realm |
| ipa_width | UInt8 | IPA width in bits |
| measurements | RmmRealmMeasurement[5] | Realm measurements |
| hash_algo | RmmHashAlgorithm | Algorithm used to compute Realm measurements |
| rec_index | UInt64 | Index of next REC to be created |
| rtt_base | Address[4] | Realm Translation Table base addresses If rtt_tree_per_plane is FEATURE_FALSE then only the first entry is valid. If rtt_tree_per_plane is FEATURE_TRUE then only the first (num_aux_planes + 1) entries are valid. |
| rtt_level_start | Int64 | RTT starting level |
| rtt_num_start | UInt64 | Number of physically contiguous starting level RTTs |
| state | RmmRealmState | Lifecycle state |
| vmid | Bits16[4] | Virtual Machine Identifiers If rtt_tree_per_plane is FEATURE_FALSE then only the first entry is valid. If rtt_tree_per_plane is FEATURE_TRUE then only the first (num_aux_planes + 1) entries are valid. |
| rpv | Bits512 | Realm Personalization Value |
| feat_da | RmmFeature | Whether Realm device assignment is enabled for this Realm |
| rtt_tree_per_plane | RmmFeature | Whether this Realm has an RTT tree per Plane |
| num_aux_planes | UInt64 | Number of auxiliary Planes |
| rtt_s2ap_indirectrtt_s2ap_encoding | RmmFeatureRmmRttS2APEncoding | Whether the Realm uses S2AP indirect encoding |
| overlay_perms | RmmMemPerms[4] | Memory overlay permissions |
| overlay_locked | RmmMemPermLocked[16] | Whether memory overlay value is locked |
| lfa_policy | RmmLfaPolicy | Live Firmware Activation policy for components within the Realm’s TCB |
| mecid | Bits64 | Memory Encryption Context Identifier |
| mec_policy | RmmMecPolicy | MEC policy |
| num_recs | UInt64 | Number of RECs owned by this Realm |
| num_vdevs | UInt64 | Number of VDEVs owned by this Realm |
| vdev_count | UInt64 | Number of VDEVs which have been assigned to this Realm |
A Realm Initial Measurement (RIM) is a measurement of the configuration and contents of a Realm at the time of activation.
A Realm Extensible Measurement (REM) is a measurement value which can be extended during the lifetime of a Realm.
Attributes of a Realm include an array of measurement values. The first entry in this array is a RIM. The remaining entries in this array are REMs.
During Realm creation, the Host provides ipa_width, rtt_level_start and rtt_num_start values as Realm parameters. According to the VMSA, the rtt_num_start value is architecturally defined as a function of the ipa_width and rtt_level_start values. It would therefore have been possible to design the Realm creation interface such that the Host provided only the ipa_width and rtt_level_start values. However, this would potentially allow a Realm to be successfully created, but with a configuration which did not match the Host’s intent. For this reason, it was decided that the Host should specify all three values explicitly, and that Realm creation should fail if the values are not consistent. See Arm Architecture Reference Manual for A-Profile architecture [3] for further details.
The VMID of a Realm is chosen by the Host. The VMID must be within the range supported by the hardware platform. The RMM ensures that every Realm on the system has a unique VMID.
A Realm Personalization Value (RPV) is a provided by the Host, to distinguish between Realms which have the same Realm Initial Measurement, but different behavior.
Possible uses of the RPV include:
- A GUID
- Hash of Realm Owner public key
- Hash of a “personalisation document” which is provided to the Realm via a side-band (for example, via NS memory) and contains configuration information used by Realm software.
The RMM treats the RPV as an opaque value.
The RPV is included in the Realm attestation report as a separate claim.
The RPV is included in the output of the RSI_REALM_CONFIG command.
If Realm device assignment is not enabled for a Realm then all of the following are true:
- Assignment of a virtual device to the Realm by execution of RMI_VDEV_CREATE fails.
- The device assignment feature is reported to the Realm by RSI_FEATURES as not enabled. Consequently, execution of any RSI_RDEV command fails.
See also:
2.1.4 Realm liveness
Realm liveness is a property which means that there exists one or more Granules, other than the RD and the starting level RTTs, which are owned by the Realm.
If a Realm is live, it cannot be destroyed.
A Realm is live if any of the following is true:
- The number of RECs owned by the Realm is not zero
- A starting level RTT of the Realm is live
- The number of VDEVs owned by the Realm is not zero
- The number of VSMMUs owned by the Realm is not zero
If a Realm owns a non-zero number of Data Granules, this implies that it has a starting level RTT which is live, and therefore that the Realm itself is live.
See also:
2.1.5 Realm lifecycle
2.1.5.1 States
The states of a Realm are listed below.
| State | Description |
|---|---|
| REALM_NEW | Under construction. Not eligible for execution. |
| REALM_ACTIVE | Eligible for execution. |
| REALM_SYSTEM_OFF | System has been turned off. Not eligible for execution. |
2.1.5.2 State transitions
Permitted Realm state transitions are shown in the following table. The rightmost column lists the events which can cause the corresponding state transition.
A transition from the pseudo-state NULL represents creation of a Realm object. A transition to the pseudo-state NULL represents destruction of a Realm object.
| From state | To state | Events |
|---|---|---|
| NULL | REALM_NEW | RMI_REALM_CREATE |
| REALM_NEW | NULL | RMI_REALM_DESTROY |
| REALM_ACTIVE | NULL | RMI_REALM_DESTROY |
| REALM_SYSTEM_OFF | NULL | RMI_REALM_DESTROY |
| REALM_NEW | REALM_ACTIVE | RMI_REALM_ACTIVATE |
| REALM_ACTIVE | REALM_SYSTEM_OFF |
Permitted Realm state transitions are shown in the following figure. Each arc is labeled with the events which can cause the corresponding state transition.
A transition from the pseudo-state NULL represents creation of an RD. A transition to the pseudo-state NULL represents destruction of an RD.
2.1.6 Realm parameters
A Realm parameter is a value which is provided by the Host during Realm creation.
2.1.7 Realm Descriptor
A Realm Descriptor (RD) is an RMM data structure which stores attributes of a Realm.
The size of an RD is one Granule.
2.2 Granule
This section describes the concept of a Granule.
A Granule is a unit of physical memory whose size is 4KB.
A Granule may be used for one of the following purposes:
- To store code or data used by the Host
- To store code or data used by software in the Secure Security state
- To store code or data used by a Realm
- To access device memory, such as a memory-mapped register interface
- To store data used by the RMM to manage a Realm
The use of a Granule is reflected in its lifecycle state.
2.2.1 Granule category
A Granule is delegable if it can be delegated by the Host for use by the RMM or by a Realm.
Granule category is a static property of each physical location in a system.
The category of a Granule determines:
- Whether the Granule can be used to store RMM data
- Whether the Granule can be allocated to a Realm, and if so what constraints are imposed on the attributes of mappings to the Granule.
The set of Granule categories are listed in the following table.
| Granule category | Description |
|---|---|
| Delegable DRAM | DRAM which can be used to store RMM data, or allocated to a Realm |
| Delegable non-coherent device memory | Non-coherent device memory which can be allocated to a Realm |
| Delegable coherent device memory | Coherent device memory which can be allocated to a Realm |
| Non-delegable memory | Memory which cannot be used to store RMM data, or allocated to a Realm |
Delegable device memory is the union of Delegable non-coherent device memory and Delegable coherent device memory.
Delegable memory is the union of Delegable DRAM and Delegable device memory.
In a typical implementation, all memory which is presented to the Host as RAM is Delegable DRAM.
Examples of Non-delegable memory may include memory which is carved out for use by the Root world, the RMM or the Secure world.
The following diagram summarizes the relationship between Granule categories.
See also:
- Section 9
2.2.2 Granule attributes
This section describes the attributes of a Granule.
A Granule attribute is a property of a Granule whose value can be observed or modified either by the Host or by a Realm.
Examples of ways in which a Granule attribute may be observable include the outcome of an RMM command, and whether a memory access generates a fault.
The attributes of a Granule are summarized in the following table.
| Name | Type | Description |
|---|---|---|
| gpt | RmmGptEntry | GPT entry |
| state | RmmGranuleState | Lifecycle state |
2.2.23 Granule lifecycle
2.2.23.1 States
The states of a Granule are listed below.
For each state, the corresponding GPT entry value is shown.
| Granule state | Description | GPT entry |
|---|---|---|
| UNDELEGATED | Not delegated for use by the RMM. | Not GPT_REALM |
| DELEGATED | Delegated for use by the RMM. | GPT_REALM |
| RD | Realm Descriptor. | GPT_REALM |
| REC | Realm Execution Context. | GPT_REALM |
| REC_AUX | Realm Execution Context auxiliary Granule. | GPT_REALM |
| DATA | Realm code or data. | GPT_REALM |
| RTT | Realm Translation Table. | GPT_REALM |
| PDEV | Physical device. | GPT_REALM |
| PDEV_AUX | Physical device auxiliary Granule. | GPT_REALM |
| VDEV | Virtual device. | GPT_REALM |
| DEV_MAPPED | Device memory, mapped into a Realm. | GPT_REALM |
| VSMMU | Virtual SMMU. | GPT_REALM |
If the state of a Granule is UNDELEGATED or DEV_UNDELEGATED then the RMM does not prevent the GPT entry of the Granule from being changed by another agent to any value except GPT_REALM.
An NS Granule is a Granule whose GPT entry is GPT_NS.
2.2.23.2 State transitions
The initial state of all Granules of Delegable memory is UNDELEGATED.
The set of reachable states depends on the Granule category.
Permitted Granule state transitions are shown in the following table. The rightmost column lists the events which can cause the corresponding state transition.
| From state | To state | Events |
|---|---|---|
| UNDELEGATED | DELEGATED | RMI_GRANULE_DELEGATE |
| DELEGATED | UNDELEGATED | RMI_GRANULE_UNDELEGATE |
| DELEGATED | RD | RMI_REALM_CREATE |
| RD | DELEGATED | RMI_REALM_DESTROY |
| DELEGATED | DATA | |
| DATA | DELEGATED | RMI_DATA_DESTROY |
| DELEGATED | REC | RMI_REC_CREATE |
| REC | DELEGATED | RMI_REC_DESTROY |
| DELEGATED | REC_AUX | RMI_REC_CREATE |
| REC_AUX | DELEGATED | RMI_REC_DESTROY |
| DELEGATED | RTT | |
| RTT | DELEGATED | |
| DELEGATED | PDEV | RMI_PDEV_CREATE |
| PDEV | DELEGATED | RMI_PDEV_DESTROY |
| DELEGATED | PDEV_AUX | RMI_PDEV_CREATE |
| PDEV_AUX | DELEGATED | RMI_PDEV_DESTROY |
| DELEGATED | VDEV | RMI_VDEV_CREATE |
| VDEV | DELEGATED | RMI_VDEV_DESTROY |
| DEV_UNDELEGATEDDELEGATED | DEV_DELEGATED RMI_GRANULE_DEV_DELEGATE DEV_DELEGATED DEV_UNDELEGATED RMI_GRANULE_DEV_UNDELEGATE DEV_DELEGATEDDEV_MAPPED | RMI_DEV_MEM_MAP |
| DEV_MAPPED | DEV_DELEGATEDDELEGATED | RMI_DEV_MEM_UNMAP |
| DELEGATED | VSMMU | RMI_VSMMU_CREATE |
| VSMMU | DELEGATED | RMI_VSMMU_DESTROY |
Permitted Granule state transitions are shown in the following figures. Each arc is labeled with the events which can cause the corresponding state transition.
See also:
- Section 15.3.1
- Section 15.3.2
- Section 15.3.3
- Section 15.3.4
- Section 15.3.5
- Section 15.3.7
- Section 15.3.8 Section 15.3.9 Section 15.3.10
- Section 15.3.1614
- Section 15.3.1715
- Section 15.3.2725
- Section 15.3.2826
- Section 15.3.3028
- Section 15.3.3129
- Section 15.3.4038
- Section 15.3.4139
- Section 15.3.5352
- Section 15.3.5453
- Section 15.3.5857
- Section 15.3.5958
2.2.34 Granule ownership
A Granule whose state is none of the following is owned by a Realm:
- UNDELEGATED
- DELEGATED
- PDEV DEV_UNDELEGATED DEV_DELEGATED
- DEV_MAPPED
The owner of a Granule is identified by the address of a Realm Descriptor (RD).
For a Granule whose state is RD, the ownership relation is recursive: the owning Realm is identified by the address of the RD itself.
A Granule whose state is RTT is one of the following:
A starting level RTT. The address of this RTT is stored in the RD of the owning Realm.
A non-starting level RTT. The address of this RTT is stored in its parent RTT, in an RTT entry whose state is TABLE. Recursively following the parent relationship leads to the RD of the owning Realm.
A Granule whose state is DATA is mapped at a Protected IPA, in an RTT entry whose state is ASSIGNED. The Realm which owns the RTT is the owner of the DATA Granule.
A REC has an “owner” attribute which points to the RD of the owning Realm.
A REC is not mapped at a Protected IPA. Its ownership therefore needs to be recorded explicitly.
A VDEV has an “owner” attribute which points to the RD of the owning Realm.
A VDEV is not mapped at a Protected IPA. Its ownership therefore needs to be recorded explicitly.
See also:
2.2.45 Granule wiping
When the state of a Granule has transitioned from P to DELEGATED and then to any other state, any content associated with P has been wiped.
Any sequence of Granule state transitions which passes through the DELEGATED state causes the Granule contents to be wiped. This is necessary to ensure that information does not leak from one Realm to another, or from a Realm to the Host. Note that no agent can observe the contents of a Granule while its state is DELEGATED.
Wiping is an operation which changes the observable value of a memory location from X to Y, such that the value X cannot be determined from the value Y.
Wiping of a memory location does not reveal, directly or indirectly, any confidential Realm data.
Wiping is not guaranteed to be implemented as zero filling.
Realm software should not assume that the initial contents of uninitialized memory (that is, Realm IPA space which is backed by DATA Granules created using RMI_DATA_CREATE_UNKNOWN) are zero.
See also:
- Arm CCA Security model [4]
- Section 15.3.2
2.3 Realm Execution Context
This section describes the concept of a Realm Execution Context (REC).
2.3.1 Overview
A Realm Execution Context (REC) is an R-EL0&1 execution context which is associated with a Realm VPE.
A REC object is an RMM data structure which is used to store the register state of a REC.
2.3.2 REC attributes
This section describes the attributes of a REC.
A REC attribute is a property of a REC whose value can be observed or modified either by the Host or by the Realm which owns the REC.
Examples of ways in which a REC attribute may be observable include the outcome of an RMM command, and the PE state following Realm entry.
The attributes of a REC are summarized in the following table.
| Name | Type | Description |
|---|---|---|
| attest_stateowner | RmmRecAttestStateAddress | Attestation token generation statePA of RD of Realm which owns this REC |
| aux | Address[16] | AddressesPAs of auxiliary Granules |
| flags | RmmRecFlags | Flags which control REC behavior |
| mpidr | Bits64 | MPIDR value |
| gic_owner | UInt64 | Index of Plane which is the GIC owner |
| state | RmmRecState | Lifecycle state |
| pending | RmmRecPending | Whether a REC operation is pending |
| emulatable_abort | RmmRecEmulatableAbort | Whether the most recent exit from this REC was due to an Emulatable Data Abort |
| gprs | Bits64[32] | General-purpose register values |
| mpidrpc | Bits64 | MPIDRProgram counter value |
| sysregs | RmmSystemRegisters | EL1 and EL0 system register values |
| ownerattest_state | RmmRecAttestState | Attestation token generation state |
| attest_challenge | Bits512 | Challenge for under-construction attestation token |
| ripas_addr | Address | Next IPA to be processed in RIPAS change |
| ripas_top | Address | Top IPA of pending RIPAS change |
| ripas_value | RmmRipas | RIPAS value of pending RIPAS change |
| ripas_destroyed | RmmRipasChangeDestroyed | Whether a RIPAS change from DESTROYED should be permitted |
| ripas_response | RmmRecResponse | Host response to RIPAS change request |
| dev_mem_addr | Address | Next IPA to be processed in device memory mapping validation |
| dev_mem_top | Address | Top IPA of pending device memory mapping validation |
| dev_mem_pa | Address | PA of RD of Realm which owns this RECdevice memory |
| dev_mem_flags | RmmDevMemFlags | Device memory mapping validation flags |
| pcdev_mem_response | RmmRecResponse | Host response to device memory mapping validation request |
| s2ap_addr | Address | Next IPA to be processed in S2AP change |
| s2ap_top | Address | Top IPA of pending S2AP change |
| s2ap_overlay_index | UInt4 | Overlay index of pending S2AP change |
| s2ap_response | RmmRecResponse | Host response to S2AP change request |
| vdev_id | Bits64 | Program counter value pending RmmRecPending Whether a REC operation is pending vdev_id Bits64Virtual device ID |
| inst_id | UInt64 | Device instance ID |
| inst_id_valid | RmmBoolean | Whether device instance ID is valid |
The aux attribute of a REC is a list of auxiliary Granules.
The number of auxiliary Granules required for a REC is returned by the RMI_REC_AUX_COUNT command.
Depending on the configuration of the CCA platform and of the Realm, the amount of storage space required for a REC may exceed a single Granule.
The number of auxiliary Granules required for a REC can vary between Realms on a CCA platform.
The number of auxiliary Granules required for a REC is a constant for the lifetime of a given Realm.
The gprs attribute of a REC is the set of general-purpose register values which are saved by the RMM on exit from the REC and restored by the RMM on entry to the REC.
The mpidr attribute of a REC is a value which can be used to identify the VPE associated with the REC.
The pc attribute of a REC is the program counter which is saved by the RMM on exit from the REC and restored by the RMM on entry to the REC.
The runnable flag of a REC determines whether the REC is eligible for execution. The RMI_REC_ENTER command results in a REC entry only if the value of the flag is RUNNABLE.
The runnable flag of a REC is controlled by the Realm. Its initial value is reflected in the Realm Initial Measurement, and during Realm execution its value can be changed by execution of the PSCI_CPU_ON and PSCI_CPU_OFF commands.
The state attribute of a REC is controlled by the Host, by execution of the RMI_REC_ENTER command.
The sysregs attribute of a REC is the set of system register values which are saved by the RMM on exit from the REC and restored by the RMM on entry to the REC.
The gic_owner attribute of a REC is the index of the Plane which is the GIC owner for the REC.
See also:
2.3.3 REC index and MPIDR value
The REC index is the unsigned integer value generated by concatenation of MPIDR fields:
index = Aff3:Aff2:Aff1:Aff0[3:0]
This is illustrated by the following table.
| REC index | Aff3 | Aff2 | Aff1 | Aff0[3:0] |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 1 | 0 | 0 | 0 | 1 |
| … | … | … | … | … |
| 16 | 0 | 0 | 1 | 0 |
| … | … | … | … | … |
| 4096 | 0 | 1 | 0 | 0 |
| … | … | … | … | … |
| 1048576 | 1 | 0 | 0 | 0 |
| … | … | … | … | … |
The Aff0[7:4] field of a REC MPIDR value is res0 for compatibility with GICv3.
When creating the nth REC in a Realm, the Host is required to use the MPIDR corresponding to REC index n.
2.3.4 REC lifecycle
2.3.4.1 States
The states of a REC are listed below.
| State | Description |
|---|---|
| REC_READY | REC is not currently running. |
| REC_RUNNING | REC is currently running. |
2.3.4.2 State transitions
Permitted REC state transitions are shown in the following table. The rightmost column lists the events which can cause the corresponding state transition.
A transition from the pseudo-state NULL represents creation of a REC object. A transition to the pseudo-state NULL represents destruction of a REC object.
| From state | To state | Events |
|---|---|---|
| NULL | REC_READY | RMI_REC_CREATE |
| REC_READY | NULL | RMI_REC_DESTROY |
| REC_READY | REC_RUNNING | RMI_REC_ENTER |
| REC_RUNNING | REC_READY | Return from RMI_REC_ENTER |
Permitted REC state transitions are shown in the following figure. Each arc is labeled with the events which can cause the corresponding state transition.
A transition from the pseudo-state NULL represents creation of a REC. A transition to the pseudo-state NULL represents destruction of a REC.
The maximum number of RECs per Realm is an implementation defined value which is discoverable via RMI_FEATURES.
See also:
- Section 15.3.6
3 Feature discovery and configuration
This section describes how the Host discovers features which are supported by the RMM implementation, and how the Host configures the features which are used by or available to a Realm.
3.1 Feature discovery and configuration overview
RMM implementations across different CCA platforms may support disparate features and may offer disparate configuration options for Realms.
The features supported by an RMI implementation are discovered by reading feature pseudo-register values using the RMI_FEATURES command.
The term pseudo-register is used because, although these values are stored in memory, their usage model is similar to feature registers specified in the Arm A-profile architecture.
On Realm creation, the Host provides a desired configuration in a Realm parameters structure to the RMI_REALM_CREATE command. The RMM checks that the configuration provided by the Host is supported by the implementation.
Aspects of the Realm configuration which affect the security posture of the Realm are included in the Realm Initial Measurement.
The features supported by an RSI implementation are discovered by reading feature pseudo-register values using the RSI_FEATURES command.
See also:
3.2 Realm hash algorithm
The set of hash algorithms supported by the implementation is reported by the RMI_FEATURES command in RmiFeatureRegister0.
The hash algorithm used by a Realm is provided by the Host when calling RMI_REALM_CREATE.
Providing an unsupported hash algorithm causes execution of RMI_REALM_CREATE to fail.
3.3 Realm LPA2 and IPA width
Support by the implementation for LPA2 is reported by the RMI_FEATURES command in RmiFeatureRegister0.
Usage of LPA2 for Realm Translation Tables is configured by the Host when calling RMI_REALM_CREATE.
Realm IPA width is provided by the Host when calling RMI_REALM_CREATE.
Providing an unsupported IPA width (for example, smaller than the minimum supported, or larger than the maximum supported) causes execution of RMI_REALM_CREATE to fail.
The Host can choose a smaller IPA width than the maximum supported IPA width reported by RMI_FEATURES. This is true regardless of whether LPA2 is enabled for the Realm.
The Host may want to enable LPA2 for a Realm due to either or both of the following reasons:
- to allow the Realm to be configured with a larger IPA width
- to allow access from mappings in the Realm’s stage 2 translation to a larger PA space
A Realm can query its IPA width using the RSI_REALM_CONFIG command.
If LPA2 is not enabled for a Realm then passing a PA greater than or
equal to 2^48 to any of the following commands causes an
error to be returned:
- RMI_DATA_CREATE
- RMI_DATA_CREATE_UNKNOWN
- RMI_RTT_CREATE
- RMI_RTT_AUX_CREATE
- RMI_RTT_MAP_UNPROTECTED
3.4 Realm support for Scalable Vector Extension
Support by the implementation for the Scalable Vector Extension (FEAT_SVE) is reported by the RMI_FEATURES command in RmiFeatureRegister0.
Availability of SVE to a Realm is configured by the Host when calling RMI_REALM_CREATE.
SVE vector length for a Realm is provided by the Host when calling RMI_REALM_CREATE.
Providing a larger-than-supported SVE vector length causes execution of RMI_REALM_CREATE to fail. This is different from the behaviour of the hardware architecture, in which a larger-than-supported SVE vector length value is silently truncated.
The RMI ABI provides a natural mechanism to signal an invalid feature selection, via the return code of RMI_REALM_CREATE. The analog in the hardware architecture would be to generate an illegal exception return, which would cause undesirable coupling between two disparate parts of the architecture, namely the exception model and the SVE feature.
Providing a larger-than-supported SVE vector length causes execution of RMI_REALM_CREATE to fail prepares the architecture for addition of Realm live migration support in future. Assuming that the live migration flow starts with creation of an empty destination Realm, configured identically to the source Realm, this provides a point where the necessary feature support can be checked on the destination platform.
If SVE is supported by the platform but is disabled for the Realm via
the RMI_REALM_CREATE command then a read of
ID_AA64PFR0_EL1.SVE indicates that SVE is not
supported.
The RMM should trap and emulate reads of
ID_AA64PFR0_EL1.SVE.
A Realm should discover SVE support by reading
ID_AA64PFR0_EL1.SVE rather than based on the platform
identity read from MIDR_EL1.
3.5 Realm support for self-hosted debug
Self-hosted debug is always available in Armv8-A.
The number of breakpoints and watchpoints are provided by the Host when calling RMI_REALM_CREATE.
Providing a number of breakpoints which is larger than the number of breakpoints available causes execution of RMI_REALM_CREATE to fail.
Providing a number of watchpoints which is larger than the number of watchpoints available causes execution of RMI_REALM_CREATE to fail.
Specifying that a larger-than-supported number of breakpoints or watchpoints causes execution of RMI_REALM_CREATE to fail prepares the architecture for addition of Realm live migration support in future. Assuming that the live migration flow starts with creation of an empty destination Realm, configured identically to the source Realm, this provides a point where the necessary feature support can be checked on the destination platform.
3.6 Realm support for Performance Monitors Extension
Support by the implementation for the Performance Monitors Extension (FEAT_PMU) is reported by the RMI_FEATURES command in RmiFeatureRegister0.
Availability of PMU to a Realm is configured by the Host when calling RMI_REALM_CREATE.
The number of PMU counters available to a Realm is provided by the Host when calling RMI_REALM_CREATE.
Providing a number of PMU counters which is larger than the number of PMU counters available causes RMI_REALM_CREATE to fail.
Specifying that a larger-than-supported number of PMU counters causes RMI_REALM_CREATE to fail prepares the architecture for addition of Realm live migration support in future. Assuming that the live migration flow starts with creation of an empty destination Realm, configured identically to the source Realm, this provides a point where the necessary feature support can be checked on the destination platform.
3.7 Realm support for Activity Monitors Extension
The Activity Monitors Extension (FEAT_AMUv1) is not available to a Realm.
3.8 Realm support for Statistical Profiling Extension
The Statistical Profiling Extension (FEAT_SPE) is not available to a Realm.
3.9 Realm support for Trace Buffer Extension
The Trace Buffer Extension (FEAT_TRBE) is not available to a Realm.
3.10 Support for Realm device assignment
Support by the implementation for Realm device assignment is reported by the RMI_FEATURES command in RmiFeatureRegister0.
Availability of Realm device assignment for a Realm is configured by the Host when calling RMI_REALM_CREATE.
3.11 Support for auxiliary Planes
The maximum number of auxiliary Planes supported by the implementation is reported by the RMI_FEATURES command in the NUM_AUX_PLANES field of RmiFeatureRegister0.
The maximum number of auxiliary Planes supported by the implementation is either 0 or 3.
The number of auxiliary Planes for a Realm is provided by the Host when calling RMI_REALM_CREATE.
Providing a number of auxiliary Planes which is larger than the maximum number of auxiliary Planes causes RMI_REALM_CREATE to fail.
For a Realm with a non-zero number of auxiliary Planes, the RTT_PLANE field of RmiFeatureRegister0 indicates which one of the following configurations is supported by the implementation:
- The Realm has an RTT tree per Plane
- The Realm has a single RTT tree
- The Realm can be configured to either have an RTT tree per Plane, or a single RTT tree.
Whether a Realm has an RTT tree per Plane is configured by the Host when calling RMI_REALM_CREATE.
3.12 Support for Stage 2 Access Permissions indirect encoding
The RTT_S2AP_INDIRECT field of RmiFeatureRegister0 indicates whether the Stage 2 Access Permissions (S2AP) value for a Realm IPA is:
- Encoded directly in the RTT entry, or
- Encoded indirectly, as described in “Stage 2 Indirect permissions” in Arm Architecture Reference Manual for A-Profile architecture [3].
Whether a Realm uses S2AP indirect encoding is configured by the Host when calling RMI_REALM_CREATE.
See also:
3.13 Live Firmware Activation
Live Firmware Activation (LFA) allows an update to a platform firmware component to be activated without rebooting the system. This potentially includes components which are within the TCB of a Realm.
A Realm has an LFA policy which is provided by the Host when calling RMI_REALM_CREATE.
If the LFA policy of a Realm is LFA_DISALLOW then all firmware components within the Realm’s TCB are guaranteed not to be live activated during the lifetime of the Realm.
In order to apply LFA to any firmware component (including the RMM) which is within the TCB of a Realm whose LFA policy is LFA_DISALLOW, the Host must first destroy the Realm.
The mechanism via which the LFA implementation determines whether any Realm with an LFA policy of LFA_DISALLOW currently exists on the system is implementation defined.
If the LFA policy of a Realm is LFA_DISALLOW then the contents of the CCA platform software components claim reflect the state of all firmware components within the Realm’s TCB, throughout the lifetime of the Realm.
The LFA policy of a Realm is reflected in the Realm attestation token.
See also:
- Live Firmware Activation SMC Interface [5]
- Section 7.2.3.2.7
- Section 15.3.2725
- Section 15.4.19
3.14 GICv3 virtualization
The number of GICv3 List Registers which can be provided by the Host via the RMI_REC_ENTER command is reported by the RMI_FEATURES command in RmiFeatureRegister0.
Making the number of GICv3 List Registers discoverable via RMI allows the RMM to reserve List Registers for its own usage.
3.15 Support for Realm memory encryption
A Realm is configured on creation with a MEC policy.
A MEC policy describes whether the Realm’s memory encryption context is:
- Shared with other Realms
- Private to the Realm
4 Realm exception model
This section describes how Realms are executed, and how exceptions which cause exit from a Realm are handled.
See also:
- Section 2.1.2
4.1 Realm exception model overview
A Realm entry is a transfer of control to a Realm.
A Realm exit is a transition of control from a Realm.
When executing in a Realm, an exception taken to R-EL2 or EL3 results in a Realm exit.
A REC entry is a Realm entry due to execution of RMI_REC_ENTER.
The Host provides the address of a REC as an input to the RMI_REC_ENTER command.
In this chapter, both rec and “the target REC” refer to
the REC object which is provided to the RMI_REC_ENTER command.
A RecRun object is a data structure used to pass values between the RMM and the Host on REC entry and on REC exit.
A RecRun object is stored in Non-secure memory.
The Host provides the address of a RecRun object as an input to the RMI_REC_ENTER command.
An implementation is permitted to return RMI_SUCCESS from RMI_REC_ENTER without performing a REC entry. For example, on observing a pending interrupt, the implementation can generate a REC exit due to IRQ without entering the target REC.
A REC exit is return from an execution of RMI_REC_ENTER which caused a REC entry.
The following diagram summarises the possible control flows that result from a Realm exit.
The exception is taken to EL3. The Monitor handles the exception and returns control to the Realm.
The exception is taken to EL3. The Monitor pre-empts Realm Security state and passes control to the Secure Security state. This may be for example due to an FIQ.
The exception is taken to EL2. The RMM decides to perform a REC exit. The RMM executes an SMC instruction, requesting the Monitor to pass control to the Non-secure Security state.
The exception is taken to EL2. The RMM executes an SMC instruction, requesting the Monitor to perform an operation, then returns control to the Realm.
The exception is taken to EL2. The RMM handles the exception and returns control to the Realm.
4.2 REC entry
This section describes REC entry.
4.2.1 RmiRecEnter object
An RmiRecEnter object is a data structure used to pass values from the Host to the RMM on REC entry.
An RmiRecEnter object is stored in the RecRun object which is passed by the Host as an input to the RMI_REC_ENTER command.
On REC entry, execution state is restored from the REC object and from the RmiRecEnter object to the PE.
An RmiRecEnter object contains attributes which are used to manage Realm virtual interrupts.
The attributes of an RmiRecEnter object are summarized in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| flags | 0x0 |
RmiRecEnterFlags | Flags |
| gprs[31] | 0x200 |
Bits64 | Registers |
| gicv3_hcr | 0x300 |
Bits64 | GICv3 Hypervisor Control Register value |
| gicv3_lrs[16] | 0x308 |
Bits64 | GICv3 List Register values |
In this chapter, both rec_enter and “the RmiRecEnter
object” refer to the RmiRecEnter object which is provided to the
RMI_REC_ENTER command.
On REC entry, all rec_enter fields are ignored unless
specified otherwise.
4.2.2 General purpose registers restored on REC entry
On REC entry, if the most recent exit from the target REC was a REC exit due to PSCI, then all of the following occur:
- X0 to X6 contain the PSCI return code and PSCI output values.
- GPR values X7 to X30 are restored from the REC object to the PE.
On REC entry, if either this is the first entry to this REC, or the most recent exit from the target REC was not a REC exit due to PSCI, then GPR values X0 to X30 are restored from the REC object to the PE.
On REC entry, if rec.pending is REC_PENDING_HOST_CALL,
then GPR values X0 to X30 are copied from
rec_enter.gprs[0..30] to the RsiHostCall data
structure.
On REC entry, if writing to the RsiHostCall data structure fails due to the target IPA not being mapped then a REC exit to Data Abort results.
On REC entry, if writing to the RsiHostCall data structure succeeds
then rec.pending is REC_PENDING_NONE.
On REC entry, if RMM access to rec_enter causes a GPF
then the RMI_REC_ENTER command fails with RMI_ERROR_INPUT.
4.2.3 REC entry following REC exit due to Data Abort
On REC entry, if
rec_enter.flags.inject_sea == RMI_INJECT_SEA then the value
of
rec_enter.flags.emul_mmio is ignored.
On REC entry, if the most recent exit from the target REC was a REC
exit due to Emulatable Data Abort and
rec_enter.flags.emul_mmio == RMI_EMULATED_MMIO, then the
return address is the next instruction following the faulting
instruction.
On REC entry, if the most recent exit from the target REC was a REC
exit due to Emulatable Data Abort and the Realm memory access was a read
and rec_enter.flags.emul_mmio == RMI_EMULATED_MMIO, then
the register indicated by ESR_EL2.ISS.SRT is set to
rec_enter.gprs[0].
On execution of RMI_REC_ENTER, if the most recent exit from the
target REC was not a REC exit due to Emulatable Data Abort and
rec_enter.flags.emul_mmio == RMI_EMULATED_MMIO, then the
RMI_REC_ENTER command fails.
On REC entry, if the most recent exit from the target REC was a REC
exit due to Data Abort at an Unprotected IPA and
rec_enter.flags.inject_sea == RMI_INJECT_SEA, then a
Synchronous External Abort is taken to the Realm.
4.3 REC exit
This section describes REC exit.
4.3.1 RmiRecExit object
An RmiRecExit object is a data structure used to pass values from the RMM to the Host on REC exit.
An RmiRecExit object is stored in the RecRun object which is passed by the Host as an input to the RMI_REC_ENTER command.
On REC exit, execution state is saved from the PE to the REC object and to the RmiRecExit object.
An RmiRecExit object contains attributes which are used to manage Realm virtual interrupts and Realm timers.
The attributes of an RmiRecExit object are summarized in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| exit_reason | 0x0 |
RmiRecExitReason | Exit reason |
| esr | 0x100 |
Bits64 | Exception Syndrome Register |
| far | 0x108 |
Bits64 | Fault Address Register |
| hpfar | 0x110 |
Bits64 | Hypervisor IPA Fault Address register |
| rtt_tree | 0x118 |
UInt64 | Index of RTT tree active at time of the exit |
| rtt_level | 0x120 |
Int64 | Level of requested RTT |
| gprs[31] | 0x200 |
Bits64 | Registers |
| gicv3_hcr | 0x300 |
Bits64 | GICv3 Hypervisor Control Register value |
| gicv3_lrs[16] | 0x308 |
Bits64 | GICv3 List Register values |
| gicv3_misr | 0x388 |
Bits64 | GICv3 Maintenance Interrupt State Register value |
| gicv3_vmcr | 0x390 |
Bits64 | GICv3 Virtual Machine Control Register value |
| cntp_ctl | 0x400 |
Bits64 | Counter-timer Physical Timer Control Register value |
| cntp_cval | 0x408 |
Bits64 | Counter-timer Physical Timer CompareValue Register value |
| cntv_ctl | 0x410 |
Bits64 | Counter-timer Virtual Timer Control Register value |
| cntv_cval | 0x418 |
Bits64 | Counter-timer Virtual Timer CompareValue Register value |
| ripas_base | 0x500 |
Bits64 | Base addressIPA of target region for pending RIPAS change |
| ripas_top | 0x508 |
Bits64 | Top addressIPA of target region for pending RIPAS change |
| ripas_value | 0x510 |
RmiRipas | RIPAS value of pending RIPAS change |
| ripas_dev_pas2ap_base | 0x5180x520 |
Bits64 | Base IPA of target region for pending S2AP change |
| s2ap_top | 0x528 |
Bits64 | Top IPA of target region for pending S2AP change |
| vdev_id | 0x530 |
Bits64 | Virtual device ID |
| imm | 0x600 |
Bits16 | Host call immediate value |
| plane | 0x608 |
UInt64 | Plane index |
| vdev | 0x610 |
Address | Base PA of device memory region, if RIPAS change is pendingVDEV which triggered REC exit due to exection of RSI_RDEV_VALIDATE_MAPPING VDEV communication |
| s2ap_basevdev_action | 0x5200x618 |
RmiVdevAction | Action which triggered REC exit due to VDEV communication |
| dev_mem_base | 0x620 |
Bits64 | Base addressIPA of target region for pending S2AP changedevice memory mapping validation |
| s2ap_topdev_mem_top | 0x5280x628 |
Bits64 | Top addressIPA of target region for pending S2AP changedevice memory mapping validation |
| vdev_iddev_mem_pa | 0x5300x630 |
Bits64
Virtual device ID
imm
0x600
Bits16
Host call immediate value
plane
0x608
UInt64
Plane index
vdev
0x610
Address | VDEV which triggered REC exit due toBase PA of device communicationmemory region |
| pmu_ovf_status | 0x700 |
RmiPmuOverflowStatus | PMU overflow status |
In this chapter, both rec_exit and “the RmiRecExit
object” refer to the RmiRecExit object which is provided to the
RMI_REC_ENTER command.
On REC exit, all rec_exit fields are zero unless
specified otherwise.
4.3.2 Realm exit reason
On return from the RMI_REC_ENTER command, the reason for the REC exit
is indicated by
rec_exit.exit_reason and rec_exit.esr.
See also:
- Section 15.4.34
4.3.3 General purpose registers saved on REC exit
On REC exit due to PSCI, all of the following are true:
rec_exit.gprs[0]contains the PSCI FID.rec_exit.gprs[1..3]contain the corresponding PSCI arguments. If the PSCI command has fewer than 3 arguments, the remaining values contain zero.- GPR values X7 to X30 are saved from the PE to the REC object.
On REC exit for any reason which is not REC exit due to PSCI, GPR values X0 to X30 are saved from the PE to the REC.
On REC exit for any reason which is neither REC exit due to Host call
nor REC exit due to PSCI, rec_exit.gprs is zero.
On REC exit, if RMM access to rec_exit causes a GPF then
the RMI_REC_ENTER command fails with RMI_ERROR_INPUT.
4.3.4 REC exit due to synchronous exception
A synchronous exception taken to R-EL2 can cause a REC exit.
The following table summarises the behavior of synchronous exceptions taken to R-EL2.
| Exception class | Behavior |
|---|---|
| Trapped WFI or WFE instruction execution | REC exit due to WFI or WFE |
| HVC instruction execution in AArch64 state | Unknown exception taken to Realm |
| SMC instruction execution in AArch64 state | One of:
|
| Trapped MSR, MRS or System instruction execution in AArch64 state | Emulated by RMM, followed by return to Realm |
| Instruction Abort from a lower Exception level | REC exit due to Instruction Abort |
| Data Abort from a lower Exception level | REC exit due to Data Abort |
Realm execution of an SMC which is not part of one of the following ABIs results in a return value of SMCCC_NOT_SUPPORTED:
- PSCI
- RSI
4.3.4.1 REC exit due to WFI or WFE
A REC exit due to WFI or WFE is a REC exit due to WFI, WFIT, WFE or WFET instruction execution in a Realm.
On WFI or WFIT instruction execution in a Realm, a REC exit due to
WFI or WFE is caused if
rec_enter.trap_wfi is RMI_TRAP.
On WFE or WFET instruction execution in a Realm, a REC exit due to
WFI or WFE is caused if
rec_enter.trap_wfe is RMI_TRAP.
On REC exit due to WFI or WFE, all of the following are true:
rec_exit.exit_reasonis RMI_EXIT_SYNC.rec_exit.esr.ECcontains the value ofESR_EL2.ECat the time of the Realm exit.rec_exit.esr.ISS.TIcontains the value ofESR_EL2.ISS.TIat the time of the Realm exit.- All other
rec_exitfields except forrec_exit.givc3_*,rec_exit_cnt*and
rec_exit.pmu_ovf_statusare zero.
On REC exit due to WFI or WFE, if the exit was caused by WFET or WFIT
instruction execution then
rec_exit.gprs[0] contains the timeout value.
4.3.4.2 REC exit due to Instruction Abort
A REC exit due to Instruction Abort is a REC exit due to a Realm instruction fetch from a Protected IPA for which either of the following is true:
- HIPAS is UNASSIGNED and RIPAS is RAM
- RIPAS is DESTROYED
On REC exit due to Instruction Abort, all of the following are true:
rec_exit.exit_reasonis RMI_EXIT_SYNC.rec_exit.esr.ECcontains the value ofESR_EL2.ECat the time of the Realm exit.rec_exit.esr.ISS.SETcontains the value ofESR_EL2.ISS.SETat the time of the Realm exit.rec_exit.esr.ISS.EAcontains the value ofESR_EL2.ISS.EAat the time of the Realm exit.rec_exit.esr.ISS.IFSCcontains the value ofESR_EL2.ISS.IFSCat the time of the Realm exit.rec_exit.hpfarcontains the value ofHPFAR_EL2at the time of the Realm exit.rec_exit.rtt_treecontains the index of the RTT tree within which the contents of an RTTE cause the Realm to exit.- All other
rec_exitfields except forrec_exit.givc3_*,rec_exit_cnt*and
rec_exit.pmu_ovf_statusare zero.
HPFAR_EL2.FIPA does not include the lowest 12 bits of
the faulting IPA. rec_exit.hpfar therefore only reveals the
Realm’s access patterns at a granularity of 4KB. If support was added to
this specification for Granule sizes larger than 4KB,
rec_exit.hpfar would need to be masked accordingly.
4.3.4.3 REC exit due to Data Abort
A REC exit due to Emulatable Data Abort is a REC exit due to a Realm data access to one of the following:
- an Unprotected IPA whose HIPAS is UNASSIGNED_NS, where the access
caused
ESR_EL2.ISS.ISVto be set to'1' - an Unprotected IPA whose HIPAS is ASSIGNED_NS, where the access
caused a stage 2 permission fault and caused
ESR_EL2.ISS.ISVto be set to'1'
A REC exit due to Non-emulatable Data Abort is a REC exit due to a Realm data access to one of the following:
- an Unprotected IPA whose HIPAS is UNASSIGNED_NS, where the access
caused
ESR_EL2.ISS.ISVto be set to'0' - an Unprotected IPA whose HIPAS is ASSIGNED_NS, where the access
caused a stage 2 permission fault and caused
ESR_EL2.ISS.ISVto be set to'0' - a Protected IPA whose HIPAS is UNASSIGNED and whose RIPAS is RAM
- a Protected IPA whose RIPAS is DESTROYED.
On REC exit due to Data Abort, all of the following are true:
rec_exit.exit_reasonis RMI_EXIT_SYNC.rec_exit.esr.ECcontains the value ofESR_EL2.ECat the time of the Realm exit.rec_exit.esr.ISS.SETcontains the value ofESR_EL2.ISS.SETat the time of the Realm exit.rec_exit.esr.ISS.FnVcontains the value ofESR_EL2.ISS.FnVat the time of the Realm exit.rec_exit.esr.ISS.EAcontains the value ofESR_EL2.ISS.EAat the time of the Realm exit.rec_exit.esr.ISS.DFSCcontains the value ofESR_EL2.ISS.DFSCat the time of the Realm exit.rec_exit.hpfarcontains the value ofHPFAR_EL2at the time of the Realm exit.rec_exit.rtt_treecontains the index of the RTT tree within which the contents of an RTTE cause the Realm to exit.
On REC exit due to Emulatable Data Abort, all of the following are true:
rec.emulatable_abortis EMULATABLE_ABORT.rec_exit.esr.ISS.ISVcontains the value ofESR_EL2.ISS.ISVat the time of the Realm exit.rec_exit.esr.ISS.SAScontains the value ofESR_EL2.ISS.SASat the time of the Realm exit.rec_exit.esr.ISS.SFcontains the value ofESR_EL2.ISS.SFat the time of the Realm exit.rec_exit.esr.ISS.WnRcontains the value ofESR_EL2.ISS.WnRat the time of the Realm exit.rec_exit.farcontains the value ofFAR_EL2at the time of the Realm exit, with bits more significant than the size of a Granule masked to zero.
On REC exit due to Non-emulatable Data Abort at an Unprotected IPA, all of the following are true:
rec_exit.esr.ILcontains the value ofESR_EL2.ILat the time of the Realm exit.
On REC exit due to Data Abort, all other rec_exit fields
except for rec_exit.givc3_*, rec_exit_cnt*
and
rec_exit.pmu_ovf_status are zero.
On REC exit due to Emulatable Data Abort,
ESR_EL2.ISS.SSE is not propagated to the Host. This is
because this field is used to emulate sign extension on loads, which
must be performed by the RMM so that the Realm can rely on
architecturally correct behavior of the virtual execution
environment.
On REC exit due to Emulatable Data Abort, the Host can calculate the
faulting IPA from the rec_exit.hpfar and
rec_exit.far values.
HPFAR_EL2.FIPA does not include the lowest 12 bits of
the faulting IPA. rec_exit.hpfar therefore only reveals the
Realm’s access patterns at a granularity of 4KB. If support was added to
this specification for Granule sizes larger than 4KB,
rec_exit.hpfar would need to be masked accordingly.
On REC exit due to Emulatable Data Abort, if the Realm memory access
was a write,
rec_exit.gprs[0] contains the value of the register
indicated by ESR_EL2.ISS.SRT at the time of the Realm
exit.
On REC exit not due to Emulatable Data Abort,
rec.emulatable_abort is NOT_EMULATABLE_ABORT.
See also:
4.3.5 REC exit due to IRQ
A REC exit due to IRQ is a REC exit due to an IRQ exception which should be handled by the Host.
On REC exit due to IRQ, rec_exit.exit_reason is
RMI_EXIT_IRQ.
On REC exit due to IRQ, rec_exit.esr is zero.
See also:
- Section 6
4.3.6 REC exit due to FIQ
A REC exit due to FIQ is a REC exit due to an FIQ exception which should be handled by the Host.
On REC exit due to FIQ, rec_exit.exit_reason is
RMI_EXIT_FIQ.
On REC exit due to FIQ, rec_exit.esr is zero.
See also:
- Section 6
4.3.7 REC exit due to PSCI
A PSCI function executed by a Realm is either:
- handled by the RMM, returning to the Realm, or
- forwarded by the RMM to the Host via a REC exit due to PSCI.
A REC exit due to PSCI is a REC exit due to Realm PSCI function execution by SMC instruction which was forwarded by the RMM to the Host.
The following table summarises the behavior of PSCI function execution by a Realm.
PSCI functions not listed in this table are not supported. Calling a non-supported PSCI function results in a return value of PSCI_NOT_SUPPORTED.
| PSCI function | Can result in REC exit due to PSCI | Requires Host to call RMI_PSCI_COMPLETE |
|---|---|---|
| PSCI_VERSION | No | - |
| PSCI_FEATURES | No | - |
| PSCI_CPU_SUSPEND | Yes | No |
| PSCI_CPU_OFF | Yes | No |
| PSCI_CPU_ON | Yes | Yes |
| PSCI_AFFINITY_INFO | Yes | Yes |
| PSCI_SYSTEM_OFF | Yes | No |
| PSCI_SYSTEM_RESET | Yes | No |
On REC exit due to PSCI, rec_exit.exit_reason is
RMI_EXIT_PSCI.
On REC exit due to PSCI, rec_exit.gprs contains
sanitised parameters from the PSCI call.
On REC exit due to PSCI, if the command arguments include an MPIDR
value, rec.pending is set to REC_PENDING_PSCI. Otherwise,
rec.pending is set to REC_PENDING_NONE.
Following REC exit due to PSCI, if rec.pending is
REC_PENDING_PSCI, the Host must complete the request by calling the
RMI_PSCI_COMPLETE command, prior to re-entering the REC.
In the call to RMI_PSCI_COMPLETE, the Host provides the target REC, which corresponds to the MPIDR value provided by the Realm. This is necessary because the RMM does not maintain a mapping from MPIDR values to REC addresses. The RMM validates that the REC provided by the Host matches the MPIDR value.
In the call to RMI_PSCI_COMPLETE, the Host provides a PSCI status value, which the RMM handles as follows:
If the Host provides PSCI_SUCCESS, the RMM performs the PSCI operation requested by the Realm. The result of the PSCI operation is recorded in the REC and returned to the Realm on the next entry to the calling REC.
If the Host provides a status value other than PSCI_SUCCESS, the RMM validates that the status code is permitted for the PSCI operation requested by the Realm. If the status code is permitted, it is recorded in the REC and returned to the Realm on the next entry to the calling REC.
4.3.8 REC exit due to RIPAS change pending
A REC exit due to RIPAS change pending is a REC exit due to the Realm issuing a RIPAS change request.
On REC exit due to RIPAS change pending, all of the following are true:
rec_exit.exit_reasonis RMI_EXIT_RIPAS_CHANGE.rec_exit.ripas_baseis the base addressIPA of the region on which a RIPAS change is pending.rec_exit.ripas_topis the top addressIPA of the region on which a RIPAS change is pending.rec_exit.ripas_valueis the requested RIPAS value.rec.ripas_addris the base addressIPA of the region on which a RIPAS change is pending.rec.ripas_topis the top addressIPA of the region on which a RIPAS change is pending.rec.ripas_valueis the requested RIPAS value.
On REC exit due to RIPAS change pending:
rec_exitholds the base addressIPA and the size of the region on which a RIPAS change is pending. These values inform the Host of the bounds of the RIPAS change request.recholds the next addressIPA to be processed in a RIPAS change, and the top of the requested RIPAS change region. These values are used by the RMM to enforce that the RMI_RTT_SET_RIPAS command can only apply RIPAS change within the bounds of the RIPAS change request, and to report the progress of the RIPAS change to the Realm on the next REC entry.
4.3.9 REC exit due to Host call
A REC exit due to Host call is a REC exit due to RSI_HOST_CALL execution in a Realm.
On REC exit due to Host call, all of the following are true:
rec.pendingis REC_PENDING_HOST_CALL.rec_exit.exit_reasonis RMI_EXIT_HOST_CALL.rec_exit.immcontains the immediate value passed to the RSI_HOST_CALL command.rec_exit.planecontains the index of the Plane which executed the RSI_HOST_CALL command.rec_exit.gprs[0..30]contain the register values passed to the RSI_HOST_CALL command.- All other
rec_exitfields except forrec_exit.givc3_*,rec_exit_cnt*and
rec_exit.pmu_ovf_statusare zero.
4.3.10 REC exit due to SError
A REC exit due to SError is a REC exit due to an SError interrupt during Realm execution.
On REC exit due to SError, all of the following occur:
rec_exit.exit_reasonis RMI_EXIT_SERROR.rec_exit.esr.ECcontains the value ofESR_EL2.ECat the time of the Realm exit.rec_exit.esr.ISS.IDScontains the value ofESR_EL2.ISS.IDSat the time of the Realm exit.rec_exit.esr.ISS.AETcontains the value ofESR_EL2.ISS.AETat the time of the Realm exit.rec_exit.esr.ISS.EAcontains the value ofESR_EL2.ISS.EAat the time of the Realm exit.rec_exit.esr.ISS.DFSCcontains the value ofESR_EL2.ISS.DFSCat the time of the Realm exit.- All other
rec_exitfields except forrec_exit.givc3_*,rec_exit_cnt*and
rec_exit.pmu_ovf_statusare zero.
4.3.11 REC exit due to device communicationS2AP change pending
A REC exit due to device communicationS2AP change pending is a REC exit due to RSI_RDEV_CONTINUE execution in athe Realm issuing an S2AP change request.
On REC exit due to device communicationS2AP change pending, all of the following are true:
rec_exit.vdevexit_reasonidentifies the VDEV is RMI_EXIT_S2AP_CHANGE.rec_exit.s2ap_baseis the base IPA of the region on which triggered thean S2AP change is pending.rec_exit.s2ap_topis the top IPA of the region on which an S2AP change is pending.rec.s2ap_addris the base IPA of the region on which an S2AP change is pending.rec.s2ap_topis the top IPA of the region on which an S2AP change is pending.rec.s2ap_valueis the requested S2AP value.
On REC exit due to RIPAS change pending:
rec_exitholds the base IPA and the size of the region on which an S2AP change is pending. These values inform the Host of the bounds of the RIPAS change request.recholds the next IPA to be processed in an S2AP change, and the top of the requested S2AP change region. These values are used by the RMM to enforce that the RMI_RTT_SET_S2AP command can only apply S2AP change within the bounds of the S2AP change request, and to report the progress of the S2AP change to the Realm on the next REC entry.
On REC exit not due to device communicationS2AP change pending, the state of the VDEV which triggered the REC exit becomes VDEV_COMMUNICATINGall of the following are true:
rec.s2ap_addris 0rec.s2ap_topis 0
See also:
- Section 92.3.2 Section 9.5 Section 16.3.15 4.3.12 REC exit due to RTT request D A REC exit due to RTT request is a REC exit due to the RMM requiring an RTT to be created in order to proceed with an operation. R On REC exit due to RTT request, rec_exit.rtt_tree contains the index of the RTT tree within which the contents of an RTTE cause the Realm to exit. R On REC exit due to RTT request, rec_exit.rtt_level identifies the level of the requested RTT. See also:
- Section 10.3.3.2
4.3.12 REC exit due to VDEV request
A REC exit due to VDEV request is a REC exit due to the RMM requiring the Host to provide the VDEV object which matches a specified virtual device ID.
On REC exit due to VDEV request, rec_exit.exit_reason is
RMI_EXIT_VDEV_REQUEST.
On REC exit due to VDEV request, rec_exit.vdev_id
contains the requested virtual device ID.
On REC exit due to VDEV request, rec.vdev_pending is set
to REC_PENDING_VDEV_REQUEST.
Following REC exit due to VDEV request, the Host must complete the request by calling the RMI_VDEV_COMPLETE command, prior to re-entering the REC.
In the call to RMI_VDEV_COMPLETE, the Host provides the target VDEV, which corresponds to the virtual device ID value provided by the Realm. This is necessary because the RMM does not maintain a mapping from virtual device IDs to VDEV objects. The RMM validates that the VDEV provided by the Host matches the virtual device ID value.
4.3.13 REC exit due to S2AP change pendingVDEV communication
A REC exit due to S2AP change pendingVDEV communication is a REC exit due to theRSI_RDEV_CONTINUE execution in a Realm.
On REC exit due to VDEV communication,
rec_exit.exit_reason is RMI_EXIT_VDEV_COMM.
On REC exit due to VDEV communication, rec_exit.vdev
identifies the VDEV which triggered the REC exit.
On REC exit due to VDEV communication, the state of the VDEV which triggered the REC exit becomes VDEV_COMMUNICATING.
On REC exit due to VDEV communication, the communication status of the VDEV which triggered the REC exit becomes DEV_COMM_PENDING.
4.3.14 REC exit due to device memory mapping validation
A REC exit due to device memory mapping validation is a REC exit due to the Realm issuing ana S2AP change device memory mapping validation request.
On REC exit due to S2AP change pendingdevice memory mapping validation, all of the following are true:
rec_exit.exit_reasonis RMI_EXIT_S2AP_CHANGERMI_EXIT_DEV_MEM_MAP.rec_exit.s2ap_basedev_mem_baseis the base addressIPA of the region on which an S2AP changedevice memory mapping validation is pending.rec_exit.s2ap_topdev_mem_topis the top addressIPA of the region on which an S2AP changedevice memory mapping validation is pending.rec.s2ap_addrdev_mem_addris the base addressIPA of the region on which an S2AP change device memory mapping validation is pending.rec.s2ap_topdev_mem_topis the top addressIPA of the region on which an S2AP changedevice memory mapping validation is pending.rec_exit.dev_mem_pais the base PA of the device memory region.rec.s2ap_valuedev_mem_pais the requested S2AP valuebase PA of the device memory region.
On REC exit due to RIPAS change pending:device memory mapping validation:
rec_exitholds the base addressIPA and the size of the region on which an S2AP changedevice memory mapping validation is pending. These values inform the Host of the bounds of the RIPAS changedevice memory mapping validation request.rec_exitholds the base PA of the device memory region. This value enables the Host to create device memory mappings (by calling RMI_DEV_MEM_MAP) on demand.recholds the next addressIPA to be processed in an S2AP changea device memory mapping validation, and the top of the requested S2AP changeIPA region. These values are used by the RMM to enforce that the RMI_RTT_SET_S2AP RMI_RTT_DEV_MEM_VALIDATE command can only apply S2AP changedevice memory mapping validation within the bounds of the S2AP change device memory mapping validation request, and to report the progress of the S2AP changedevice memory mapping validation to the Realm on the next REC entry.
4.4 Emulated Data Aborts
On REC exit due to Emulatable Data Abort, sufficient information is provided to the Host to enable it to emulate the access, for example to emulate a virtual peripheral.
On taking the REC exit, the Host can either
Establish a mapping in the RTT, in which case it would want the Realm to re-attempt the access. In this case, on the next REC entry the Host sets
enter.flags.emul_mmio = RMI_NOT_EMULATED_MMIO, which indicates that instruction emulation was not performed. This causes the return address to be the faulting instruction.Emulate the access. For an emulated write, the data is provided in
exit.gprs[0]. For an emulated read, the data is provided inenter.gprs[0]. In this case, on the next REC entry the Host sets
enter.flags.emul_mmio = RMI_EMULATED_MMIO, which indicates that the instruction was emulated. This causes the return address to be the address of the instruction which generated the Data Abort plus 4 bytes.
4.5 Host call
This section describes the programming model for Realm communication with the Host.
A Host call is a call made by the Realm to the Host, by execution of the RSI_HOST_CALL command.
A Host call can be used by a Realm to make a hypercall.
On Realm execution of HVC, an Unknown exception is taken to the Realm.
5 Realm memory management
This section describes how Realm memory is managed. This includes:
- How the translation tables which describe the Realm’s address space are managed by the Host.
- Properties of the Realm’s address space, and of the memory which can be mapped into it.
- How faults caused by Realm memory accesses are handled.
5.1 Realm memory management overview
Realm memory management can be viewed from one of two standpoints: the Realm and the Host.
From the Realm’s point of view, the RMM provides security guarantees regarding the IPA space of the Realm and the memory which is mapped into it. These security guarantees are upheld via RSI commands which the Realm can execute in order to query the initial configuration and contents of its address space, and to modify properties of the address space at runtime.
From the Host’s point of view, Realm memory management involves manipulating the stage 2 translation tables which describe the Realm’s address space, and handling faults which are caused by Realm memory accesses. These operations are similar to those involved in managing the memory of a normal VM, but in the case of a Realm they are performed via execution of RMI commands.
5.2 Realm view of memory management
This section describes memory management from the Realm’s point of view.
5.2.1 Realm IPA space
The IPA space of a Realm is divided into two halves: Protected IPA space and Unprotected IPA space.
Software in a Realm should treat the most significant bit of an IPA as a protection attribute.
A Protected IPA is an address in the lower half of a Realm’s
IPA space. The most significant bit of a Protected IPA is
0.
An Unprotected IPA is an address in the upper half of a
Realm’s IPA space. The most significant bit of an Unprotected IPA is
1.
5.2.2 Realm IPA state
A Protected IPA has an associated Realm IPA state (RIPAS).
The RIPAS values are shown in the following table.
| Name | Description |
|---|---|
| DESTROYED | Address which is inaccessible to the Realm due to an action taken by the Host. |
| DEV | Address where memory of an assigned Realm device is mapped. |
| EMPTY | Address where no Realm resources are mapped. |
| RAM | Address where private code or data owned by the Realm is mapped. |
RIPAS values are stored in an RTT.
The Realm can query the RIPAS of an IPA range by executing RSI_IPA_STATE_GET.
5.2.3 Realm access to a Protected IPA
Realm data access to a Protected IPA whose RIPAS is EMPTY causes a Synchronous External Abort taken to the Realm.
Realm instruction fetch from a Protected IPA whose RIPAS is EMPTY causes a Synchronous External Abort taken to the Realm.
Realm data access to a Protected IPA whose RIPAS is RAM does not cause a Synchronous External Abort taken to the Realm.
Realm data access to a Protected IPA whose RIPAS is RAM can cause an REC exit due to Data Abort.
Realm instruction fetch from a Protected IPA whose RIPAS is RAM does not cause a Synchronous External Abort taken to the Realm.
Realm instruction fetch from a Protected IPA whose RIPAS is RAM can cause a REC exit due to Instruction Abort.
Realm data access to a Protected IPA whose RIPAS is DESTROYED causes a REC exit due to Data Abort.
Realm instruction fetch from a Protected IPA whose RIPAS is DESTROYED causes a REC exit due to Instruction Abort.
Realm data access to a Protected IPA whose RIPAS is DEV does not cause a Synchronous External Abort taken to the Realm.
Realm data access to a Protected IPA whose RIPAS is DEV can cause an REC exit due to Data Abort.
Realm instruction fetch from a Protected IPA whose RIPAS is DEV causes a Synchronous External Abort taken to the Realm.
5.2.4 RSI command access to a Protected IPA
Access by an RSI command to a Protected IPA whose RIPAS is EMPTY causes the command to fail and return an error to the Realm.
Access by an RSI command to a Protected IPA whose RIPAS is not EMPTY is treated as a Realm data access to the same address, for the purposes of deciding whether the access causes a REC exit due to Data Abort.
See also:
- Section 5.2.3
5.2.5 Changes to RIPAS while Realm state is REALM_NEW
This section describes how the RIPAS of a Protected IPA can change while the Realm state is REALM_NEW.
For a Realm in the REALM_NEW state, the RIPAS of a Protected IPA can change to RAM due to Host execution of RMI_DATA_CREATE or RMI_RTT_INIT_RIPAS.
For a Realm in the REALM_NEW state, changing the RIPAS of a Protected IPA to RAM causes the RIM to be updated.
For a Realm in the REALM_NEW state, the RIPAS of a Protected IPA can change to DESTROYED due to Host execution of RMI_DATA_DESTROY or RMI_RTT_DESTROY.
For a Realm in the REALM_NEW state, changing the RIPAS of a Protected IPA to DESTROYED does not cause the RIM to be updated.
5.2.6 Changes to RIPAS while Realm state is REALM_ACTIVE
This section describes how the RIPAS of a Protected IPA can change while the Realm state is REALM_ACTIVE.
A Realm in the REALM_ACTIVE state can request the RIPAS of a region of Protected IPA space to be changed to EMPTY, RAM or DEV.
A Realm in the REALM_ACTIVE state cannot request the RIPAS of a region of Protected IPA space to be changed to DESTROYED.
For a Realm in the REALM_ACTIVE state, the RIPAS of a Protected IPA can change to EMPTY only in response to Realm execution of RSI_IPA_STATE_SET.
The fact that the Host cannot change the RIPAS of a Protected IPA to EMPTY without the Realm having consented to this change prevents the Host from injecting an SEA at a Protected IPA which has been configured to have a RIPAS of RAM, which could potentially trigger unexpected behavior in the Realm.
For a Realm in the REALM_ACTIVE state, the RIPAS of a Protected IPA can change to RAM only in response to Realm execution of RSI_IPA_STATE_SET.
On execution of RSI_IPA_STATE_SET, a Realm can optionally specify that the RIPAS change should only succeed if the current RIPAS is not DESTROYED.
An expected pattern for Realm creation is as follows:
Host populates an “initial image” range of Realm IPA space with measured content:
Host executes RMI_DATA_CREATE, establishing a mapping to physical memory, changing RIPAS to RAM and updating the RIM.
Host informs the Realm of the range of IPA space which should be considered by the Realm as DRAM. This is a superset of the IPA range populated in step 1. For unpopulated parts of this IPA range, the RIPAS is EMPTY.
Realm executes RSI_IPA_STATE_SET(ripas=RAM) for the DRAM IPA range described to it in step 2. Following this command, the desired state is:
For the initial image IPA range, the contents match those described by the RIM.
For the entire DRAM IPA range, RIPAS is RAM.
If at step 2, the Host were to execute RMI_DATA_DESTROY on a page within the initial image IPA range, its RIPAS would change to DESTROYED. The Host could then execute RMI_DATA_CREATE_UNKNOWN, with the result that contents of the initial image IPA range no longer match those described by the RIM.
By specifying at step 3 that the RIPAS change should only succeed if the current RIPAS is not DESTROYED, the Realm is able to prevent loss of integrity within the initial image IPA range.
For a Realm in the REALM_ACTIVE state, the RIPAS of a Protected IPA can change to DEV only in response to Realm execution of RSI_RDEV_VALIDATE_MAPPING.
For a Realm in the REALM_ACTIVE state, the RIPAS of a Protected IPA can change to DESTROYED due to Host execution of RMI_DATA_DESTROY or RMI_RTT_DESTROY.
The result of changing the RIPAS of a Protected IPA to DESTROYED is that subsequent Realm accesses to that address do not make forward progress. This is consistent with the principle that the RMM does not provide an availability guarantee to a Realm.
The following diagram summarizes RIPAS changes which can occur when the Realm state is REALM_ACTIVE.
See also:
5.2.7 Realm access to an Unprotected IPA
An access by a Realm to an Unprotected IPA can result in a Granule Protection Fault (GPF).
The RMM does not ensure that the GPT entry of a Granule mapped at an Unprotected IPA permits access via Non-secure PAS.
Realm software must be able to handle taking a GPF during access to an Unprotected IPA.
Realm data access to an Unprotected IPA can cause a REC exit due to Data Abort.
On taking a REC exit due to Data Abort at an Unprotected IPA, the Host can inject a Synchronous External Abort to the Realm.
The Host can inject an SEA in response to an unexpected Realm data access to an Unprotected IPA.
Realm data access to an Unprotected IPA which caused
ESR_EL2.ISS.ISV to be set to '1' can be
emulated by the Host.
Realm instruction fetch from an Unprotected IPA causes a Synchronous External Abort taken to the Realm.
5.2.8 Synchronous External Aborts
When a Synchronous External Abort is taken to a Realm,
ESR_EL1.EA == '1'.
5.2.9 Realm access outside IPA space
If stage 1 translation is enabled, Realm access to an IPA which is greater than the IPA space of the Realm causes a stage 1 Address Size Fault taken to the Realm, with the fault status code indicating the level at which the fault occurred.
If stage 1 translation is disabled, Realm access to an IPA which is greater than the IPA space of the Realm causes a stage 1 level 0 Address Size Fault taken to the Realm.
5.2.10 Summary of Realm IPA space properties
The following table summarizes the properties of Realm IPA space.
| Realm IPA | Data access causes abort to Realm? | Data access causes REC exit due to Data Abort? | Instruction fetch causes abort to Realm? | Instruction fetch causes REC exit due to Instruction Abort? |
|---|---|---|---|---|
| Protected, RIPAS=EMPTY | Always (SEA) | Never | Always (SEA) | Never |
| Protected, RIPAS=RAM | Never | When HIPAS=UNASSIGNED | Never | When HIPAS=UNASSIGNED |
| Protected, RIPAS=DEV | Never | When HIPAS=UNASSIGNED | Always (SEA) | Never |
| Protected, RIPAS=DESTROYED | Never | Always | Never | Always |
| Unprotected | Host can inject SEA following REC exit due to Data Abort | When HIPAS=UNASSIGNED_NS or HIPAS=ASSIGNED_NS and access caused a stage 2 permission fault | Always (SEA) | Never |
| Outside Realm IPA space | Always (Address Size Fault) | Never | Always (Address Size Fault) | Never |
See also:
- Section 4.2.3
5.2.11 Cache maintenance operations
A data cache invalidate by set / way instruction executed by a Realm either has no effect, or performs a data cache clean and invalidate.
This is to ensure that a Realm cannot invalidate a cache line owned by another Realm.
Arm expects that the RMM will set HCR_EL2.VM == '1',
which causes a data cache invalidate instruction executed at EL1 to
perform a data cache clean and invalidate.
5.3 Host view of memory management
This section describes memory management from the Host’s point of view.
5.3.1 Host IPA state
A Realm IPA has an associated Host IPA state (HIPAS).
The HIPAS values are shown in the following table.
| Name | Description |
|---|---|
| HIPAS_ASSIGNED | Protected IPA which is associated with a DATA Granule. |
| HIPAS_ASSIGNED_DEV | Protected IPA which is associated with a DEV_MAPPED Granule. |
| HIPAS_ASSIGNED_NS | Unprotected IPA which is associated with a physical Granule. |
| HIPAS_ASSIGNED_VSMMU | Protected IPA which is associated with a VSMMU Granule. |
| HIPAS_UNASSIGNED | Protected IPA which is not associated with any Granule. |
| HIPAS_UNASSIGNED_NS | Unprotected IPA which is not associated with any Granule. |
HIPAS values are stored in a Realm Translation Table (RTT).
HIPAS transitions are caused by execution of RMI commands.
A mapping at a Protected IPA is valid if the HIPAS is ASSIGNED and the RIPAS is RAM.
A mapping at a Protected IPA is valid if the HIPAS is ASSIGNED_DEV and the RIPAS is DEV.
The RMM emulates access to a Protected IPA if the HIPAS is ASSIGNED_SMMU and the RIPAS is DEV.
The following table summarizes, for each combination of RIPAS and HIPAS for a Protected IPA:
- the translation table entry attributes, and
- the behavior which results from Realm access to that IPA.
Each TTD.X column refers to the value of the corresponding “X” field in the architecturally-defined Stage 2 translation table descriptor which is written by the RMM.
| RIPAS | HIPAS | TTD.ADDR | TTD.NS | TTD.VALID | Data access | Instruction fetch |
|---|---|---|---|---|---|---|
| EMPTY | UNASSIGNED | 0 | SEA to Realm | SEA to Realm | ||
| EMPTY | ASSIGNED | DATA | 0 | SEA to Realm | SEA to Realm | |
| EMPTY | ASSIGNED_DEV | DEV | 0 | SEA to Realm | SEA to Realm | |
| EMPTY | ASSIGNED_VSMMU | DEV | 0 | SEA to Realm | SEA to Realm | |
| RAM | UNASSIGNED | 0 | REC exit due to Data Abort | REC exit due to Instruction Abort | ||
| RAM | ASSIGNED | DATA | 0 | 1 | Data access | Instruction fetch |
| RAM | ASSIGNED_DEV | DEV | 0 | REC exit due to Data Abort | REC exit due to Instruction Abort | |
| RAM | ASSIGNED_VSMMU | DEV | 0 | REC exit due to Data Abort | REC exit due to Instruction Abort | |
| DESTROYED | UNASSIGNED | 0 | REC exit due to Data Abort | REC exit due to Instruction Abort | ||
| DESTROYED | ASSIGNED | DATA | 0 | REC exit due to Data Abort | REC exit due to Instruction Abort | |
| DESTROYED | ASSIGNED_DEV | DEV | 0 | REC exit due to Data Abort | REC exit due to Instruction Abort | |
| DESTROYED | ASSIGNED_VSMMU | DEV | 0 | REC exit due to Data Abort | REC exit due to Instruction Abort | |
| DEV | UNASSIGNED | 0 | REC exit due to Data Abort | SEA to Realm | ||
| DEV | ASSIGNED | DATA | 0 | REC exit due to Data Abort | SEA to Realm | |
| DEV | ASSIGNED_DEV | DEV | 1 | Device access | SEA to Realm | |
| DEV | ASSIGNED_VSMMU | DEV | 0 | Emulated by RMM | SEA to Realm |
5.3.2 Changes to HIPAS while Realm state is REALM_NEW
This section describes how the HIPAS of a Protected IPA can change while the Realm state is REALM_NEW.
The following diagram summarizes HIPAS changes at a Protected IPA which can occur when the Realm state is REALM_NEW.
See also:
5.3.3 Changes to HIPAS while Realm state is REALM_ACTIVE
This section describes how the HIPAS of a Protected IPA can change while the Realm state is REALM_ACTIVE.
The following diagram summarizes HIPAS changes at a Protected IPA which can occur when the Realm state is REALM_ACTIVE.
5.3.4 Summary of changes to HIPAS and RIPAS of a Protected IPA
The following diagram summarizes HIPAS and RIPAS changes at a Protected IPA which can occur when the Realm state is NEW.
Transitions due to execution of RMI_RTT_DESTROY are omitted from the diagram. Execution of this command results in a transition to HIPAS=UNASSIGNED, RIPAS=DESTROYED.
The following diagram summarizes HIPAS and RIPAS changes at a Protected IPA which can occur when the Realm state is REALM_ACTIVE.
Transitions due to execution of RMI_RTT_DESTROY are omitted from the diagram. Execution of this command results in a transition to HIPAS=UNASSIGNED, RIPAS=DESTROYED.
See also:
5.3.5 Dependency of RMI command execution on RIPAS and HIPAS values
The following table summarizes dependencies on RMI command execution on the current Protected IPA.
| Command | Dependency on RIPAS | Dependency on HIPAS | New RIPAS | New HIPAS |
|---|---|---|---|---|
| RMI_DATA_CREATE | None | HIPAS is UNASSIGNED | RAM | ASSIGNED |
| RMI_DATA_CREATE_UNKNOWN | None | HIPAS is UNASSIGNED | Unchanged | ASSIGNED |
| RMI_DATA_DESTROY | If RIPAS is not RAM | HIPAS is ASSIGNED | Unchanged | UNASSIGNED |
| RMI_DATA_DESTROY | If RIPAS is RAM | HIPAS is ASSIGNED | DESTROYED | UNASSIGNED |
| RMI_RTT_CREATE | None | None | Unchanged | Unchanged |
| RMI_RTT_DESTROY | None | HIPAS of all entries is UNASSIGNED | DESTROYED | UNASSIGNED |
| RMI_RTT_DEV_MEM_VALIDATE | None | HIPAS of all entries is ASSIGNED_DEV | DEV | Unchanged |
| RMI_RTT_FOLD | RIPAS of all entries is identical | HIPAS of all entries is identical | Unchanged | Unchanged |
| RMI_RTT_INIT_RIPAS | None | HIPAS is UNASSIGNED | RAM | Unchanged |
| RMI_RTT_SET_RIPAS | Optionally, Realm may specify that RIPAS is not DESTROYED | None | As specified by Realm | Unchanged |
| RMI_DEV_MEM_MAP | None | HIPAS is UNASSIGNED | Unchanged | ASSIGNED_DEV |
| RMI_DEV_MEM_UNMAP | If RIPAS is not DEV | HIPAS is ASSIGNED_DEV | Unchanged | UNASSIGNED |
| RMI_DEV_MEM_UNMAP | If RIPAS is DEV | HIPAS is ASSIGNED_DEV | DESTROYED | UNASSIGNED |
| RMI_VSMMU_MAP | RIPAS is EMPTY | HIPAS is UNASSIGNED | Unchanged | ASSIGNED_VSMMU |
| RMI_VSMMU_UNMAP | If RIPAS is not DEV | HIPAS is ASSIGNED_VSMMU | Unchanged | UNASSIGNED |
| RMI_VSMMU_UNMAP | If RIPAS is DEV | HIPAS is ASSIGNED_VSMMU | DESTROYED | UNASSIGNED |
Successful execution of RMI_DATA_CREATE_UNKNOWN does not depend on the RIPAS value of the target IPA.
Successful execution of RMI_DATA_DESTROY does not depend on the RIPAS value of the target IPA.
Successful execution of RMI_RTT_DESTROY does not depend on the RIPAS values of entries in the target RTT.
Successful execution of RMI_RTT_FOLD does depend on the RIPAS values of entries in the target RTT.
Successful execution of RMI_DEV_MEM_UNMAP does not depend on the RIPAS value of the target IPA.
See also:
5.3.6 Changes to HIPAS of an Unprotected IPA
The following diagram summarises HIPAS transitions for an Unprotected IPA.
See also:
5.4 RIPAS change
A RIPAS change is a process via which the RIPAS of a region of Protected IPA space is changed, for a Realm whose state is REALM_ACTIVE.
A RIPAS change consists of actions taken first by the Realm, and then by the Host:
- The Realm issues a RIPAS change request by executing
RSI_IPA_STATE_SET or RSI_RDEV_VALIDATE_MAPPING.
- The input values to RSI_IPA_STATE_SET include:
- The requested IPA range:
[base, top) - The requested RIPAS value (either EMPTY or RAM)
- A flag which indicates whether a change from DESTROYED should be permitted
- The requested IPA range:
- For RSI_RDEV_VALIDATE_MAPPING: The inputThe RMM records these values include the requested IPA range: [base, top) The requested RIPAS value is implicitly DEV A change from DESTROYED is implicitly not permitted The RMM records these values in the REC, and then performs a REC exit due to RIPAS change pending.
- The input values to RSI_IPA_STATE_SET include:
- In response, the Host executes zero or more RMI_RTT_SET_RIPAS commands.
- If the requested RIPAS value was not EMPTY then at the next RMI_REC_ENTER the Host can optionally indicate that it rejects the RIPAS change request.
Output values from RSI_IPA_STATE_SET or RSI_RDEV_VALIDATE_MAPPING indicate:
- The top of the IPA range which has been modified by the command
(
new_base). - If the requested RIPAS value was not EMPTY, whether the Host rejected the Realm request.
Output values from RSI_IPA_STATE_SET or RSI_RDEV_VALIDATE_MAPPING are are expected to be handled by the Realm as follows:
new_base |
response |
Meaning | Expected Realm action |
|---|---|---|---|
new_base == base |
RSI_ACCEPT | RIPAS change incomplete. | Call the command again, with base = new_base. |
base < new_base < top |
RSI_ACCEPT | RIPAS change incomplete. | Call the command again, with base = new_base. |
new_base == top |
RSI_ACCEPT | RIPAS change complete. | No further Realm action required. |
new_base == base |
RSI_REJECT | RIPAS change request rejected. | Depends on protocol agreed between Realm and Host, out of scope of this specification. |
base < new_base < top |
RSI_REJECT | RIPAS change to partial region Host rejected request to change RIPAS for region
|
Depends on protocol agreed between Realm and Host, out of scope of this specification. |
The RIPAS change process, together with the Realm Initial Measurement ensures that a Realm can always reliably determine the RIPAS of any Protected IPA.
A RIPAS change is applied by one or more calls to the RMI_RTT_SET_RIPAS command.
Successful execution of RMI_RTT_SET_RIPAS targets an RTTE at address
rec.ripas_addr.
On successful execution of RMI_RTT_SET_RIPAS, both of the following are set to the address of the next page whose RIPAS is to be modified:
rec.ripas_addr- The command output value
If both of the following are true on successful execution of RMI_RTT_SET_RIPAS
- The RIPAS change request indicated that a change from DESTROYED should not be permitted
- A page P within the target IPA range has RIPAS value DESTROYED
then rec.ripas_addr and the command output value are
both set to P.
On REC entry following a REC exit due to RIPAS change, GPR values are updated to indicate for how much of the target IPA range the RIPAS change has been applied.
To complete a RIPAS change for a given target IPA range, a Realm should execute RSI_IPA_STATE_SET or RSI_RDEV_VALIDATE_MAPPING in a loop, until the value of X1 reaches the top of the target IPA range.
On REC entry following a REC exit due to RIPAS change,
rec.ripas_response is set to the value of
enter.flags.ripas_response.
If all of the following are true then the output value of RSI_IPA_STATE_SET or RSI_RDEV_VALIDATE_MAPPING indicates “Host rejected the request”:
rec.ripas_valueis RAM.rec.ripas_addris not equal torec.ripas_top.rec.ripas_responseis REJECT.
Otherwise, the output value of RSI_IPA_STATE_SET or RSI_RDEV_VALIDATE_MAPPING indicates “Host accepted the request”.
Receipt of a rejection for a RIPAS change request whose parameters were valid is expected to be fatal for the Realm.
See also:
5.5 Device memory mapping validation
A Device memory mapping validation is a process via which the addresses and attributes of mappings to device memory are checked for consistency with values expected by the Realm.
The outcome of a successful Device memory mapping validation is a change of RIPAS to DEV.
A Device memory mapping validation consists of actions taken first by the Realm, and then by the Host:
- The Realm issues a Device memory mapping validation request
by executing RSI_RDEV_VALIDATE_MAPPING.
- The input values to RSI_RDEV_VALIDATE_MAPPING include:
- The requested IPA range:
[base, top) - The base of the expected PA range
- Flags which indicate the expected memory attributes
- The requested IPA range:
- The RMM records these values in the REC, and then performs a REC exit due to device memory mapping validation.
- The input values to RSI_RDEV_VALIDATE_MAPPING include:
- In response, the Host executes zero or more RMI_RTT_DEV_MEM_VALIDATE commands.
Output values from RSI_RDEV_VALIDATE_MAPPING indicate:
- The top of the IPA range which has been modified by the command
(
new_base). - Whether the Host rejected the Realm request.
Output values from RSI_RDEV_VALIDATE_MAPPING are expected to be handled by the Realm as follows:
new_base |
response |
Meaning | Expected Realm action |
|---|---|---|---|
new_base == base |
RSI_ACCEPT | Device memory mapping validation incomplete. | Call the command again, with base = new_base. |
base < new_base < top |
RSI_ACCEPT | Device memory mapping validation incomplete. | Call the command again, with base = new_base. |
new_base == top |
RSI_ACCEPT | Device memory mapping validation complete. | No further Realm action required. |
new_base == base |
RSI_REJECT | Device memory mapping validation request rejected. | Depends on protocol agreed between Realm and Host, out of scope of this specification. |
base < new_base < top |
RSI_REJECT | Device memory mapping validation to partial region
Host rejected request to validate evice memory mapping for region
|
Depends on protocol agreed between Realm and Host, out of scope of this specification. |
The Device memory mapping validation process, together with the Realm Initial Measurement ensures that a Realm can always reliably determine the RIPAS of any Protected IPA.
A Device memory mapping validation is applied by one or more calls to the RMI_RTT_DEV_MEM_VALIDATE command.
Successful execution of RMI_RTT_DEV_MEM_VALIDATE targets an RTTE at
address rec.dev_mem_addr.
On successful execution of RMI_RTT_DEV_MEM_VALIDATE, all of the following are set to the address of the next page whose device memory mapping is to be validated:
rec.dev_mem_addrrec.dev_mem_pa- The command output value
On REC entry following a REC exit due to device memory mapping validation, GPR values are updated to indicate for how much of the target IPA range the device memory mapping validation request has been applied.
To complete a Device memory mapping validation for a given target IPA range, a Realm should execute RSI_RDEV_VALIDATE_MAPPING in a loop, until the value of X1 reaches the top of the target IPA range.
On REC entry following a REC exit due to device memory mapping
validation, rec.dev_mem_response is set to the value
of
enter.flags.dev_mem_response.
If all of the following are true then the output value of RSI_RDEV_VALIDATE_MAPPING indicates “Host rejected the request”:
rec.dev_mem_addris not equal torec.dev_mem_top.rec.dev_mem_responseis REJECT.
Otherwise, the output value of RSI_RDEV_VALIDATE_MAPPING indicates “Host accepted the request”.
See also:
5.56 Realm Translation Table
This section introduces the stage 2 translation table used by a Realm.
5.56.1 RTT overview
A Realm Translation Table (RTT) is an abstraction over an Armv8-A stage 2 translation table used by a Realm.
The attributes and format of an Armv8-A stage 2 translation table are defined by the Armv8-A Virtual Memory System Architecture (VMSA) Arm Architecture Reference Manual for A-Profile architecture [3].
The translation granule size of an RTT is 4KB.
The RMM architecture can only be deployed on a hardware platform which implements a translation granule size of 4KB.
The contents of an RTT are not directly accessible to the Host.
The contents of an RTT are manipulated using RMM commands. These commands allow the Host to manipulate the contents of the RTT used by a Realm, subject to constraints imposed by the RMM.
An RTT entry (RTTE) is an abstraction over an Armv8-A stage 2 translation table descriptor.
An RTTE contains an output address which can point to one of the following:
- Another RTT
- A DATA Granule which is owned by the Realm
- Non-secure memory which is accessible to both the Realm and the Host
5.56.2 RTT structure and configuration
An RTT tree is a hierarchical data structure composed of RTTs, connected via Table Descriptors.
An RTT contains an array of RTTEs.
An RTT level is the depth of an RTT within an RTT tree.
An RTT does not have an intrinsic “level” attribute. The level of an RTT is determined by its position within an RTT tree.
The RTT level of the root of an RTT tree is called the starting level.
The maximum depth of an RTT tree depends on all of the following:
- whether LPA2 is selected when the Realm is created
- the rtt_level_start attribute of the Realm
- the ipa_width attribute of the Realm.
5.56.3 RTT starting level
The RTT starting level is set when a Realm is created.
The number of starting level RTTs is architecturally defined as a function of the Realm IPA width and the RTT starting level. See Arm Architecture Reference Manual for A-Profile architecture [3] for further details.
The address of the first starting level RTT is stored in the RTT base attribute of the owning Realm.
The RTT base attribute is set when a Realm is created.
See also:
- Section 2.1.3
5.56.4 RTT entry
An RTT entry (RTTE) is an abstraction over an Armv8-A stage 2 translation table descriptor. The attributes and format of an Armv8-A stage 2 translation table descriptor are defined by the Armv8-A Virtual Memory System Architecture (VMSA) Arm Architecture Reference Manual for A-Profile architecture [3].
An RTTE has a state.
The RTTE state values are shown in the following table.
| Name | Description |
|---|---|
| ASSIGNED | This RTTE is identified by a Protected IPA. The output address of this RTTE points to a DATA Granule. |
| ASSIGNED_DEV | This RTTE is identified by a Protected IPA. The output address of this RTTE points to a DEV_MAPPED Granule. |
| ASSIGNED_NS | This RTTE is identified by an Unprotected IPA. The output address of this RTTE points to a Granule-aligned address within NS PAS. |
| ASSIGNED_VSMMU | This RTTE is identified by a Protected IPA. The output address of this RTTE points to a VSMMU Granule. |
| AUX_DESTROYED | An auxiliary RTT was destroyed while a corresponding primary RTT entry was live. |
| TABLE | The output address of this RTTE points to the next-level RTT. |
| UNASSIGNED | This RTTE is identified by a Protected IPA. This RTTE is not associated with any Granule. |
| UNASSIGNED_NS | This RTTE is identified by an Unprotected IPA. This RTTE is not associated with any Granule. |
The state of an RTTE in a RTT which is not level 1 or level 2 or level 3 is UNASSIGNED, UNASSIGNED_NS or TABLE.
The output address of an RTTE whose state is TABLE and which is in a level n RTT is the physical address of a level n+1 RTT.
An RTT whose level n is not the starting RTT level is pointed-to by exactly one TABLE RTTE in a level n-1 RTT.
The following diagram shows an example RTT tree, annotated with RTTE states.
The function AddrIsRttLevelAligned() is used to evaluate
whether an address is aligned to the address range described by an RTTE
at a specified RTT level.
5.56.5 RTT reading
Attributes of an RTTE, including the RTTE state, can be read by calling the RMI_RTT_READ_ENTRY command. The set of RTTE attributes which are returned depends on the state of the RTTE.
See also:
- Section 15.3.4544
5.56.6 RTT folding
An RTT is homogeneous if all of the following are true:
- State of all entries is the same.
- RIPAS of all entries is the same, or the RTT describes Unprotected IPA space.
- Memory attributesS2AP fields of all entries are the same.
- S2AP fields ofEither the state is UNASSIGNED or UNASSIGNED_NS, or all of the
following are true:
- Level is 2 or 3.
- Output address of first entry is aligned to size of the address range described by an entry in the parent RTT.
- Output addresses of all entries are contiguous.
- Memory attributes of all entries are the same. Either the state is UNASSIGNED or UNASSIGNED_NS, or all of the following are true: Level is 2 or 3. Output address of first entry is aligned to size of the address range described by an entry in the parent RTT. Output addresses of all entries are contiguous.
The function RttIsHomogeneous() is used to evaluate
whether an RTT is homogeneous.
RTT folding is the operation of destroying a homogeneous child RTT, and moving information which was stored in the child RTT into the parent RTTE.
On RTT folding, the state of the parent RTTE is determined from the contents of the child RTTEs.
The function RttFold() is used to evaluate the parent
RTTE state which results from an RTT folding operation.
On RTT folding, if the state of the parent RTTE is any of the following then the attributes of the parent RTTE are copied from the child RTTEs:
- ASSIGNED
- ASSIGNED_NS
- ASSIGNED_DEV
5.56.7 RTT unfolding
RTT unfolding is the operation of creating a child RTT, and populating it based on the contents of the parent RTTE.
On RTT unfolding, the state of all RTTEs in the child RTT are set to the state of the parent RTTE.
On RTT unfolding, if the state of the parent RTTE is any of the following then the output addresses of RTTEs in the child RTT are set to a contiguous range which starts from the address of the parent RTTE:
- ASSIGNED
- ASSIGNED_NS
- ASSIGNED_DEV
See also:
- Section 15.3.4038
5.56.8 RTTE liveness and RTT liveness
RTTE liveness is a property which means that a physical address is stored in the RTTE.
An RTTE is live if the RTTE state is any of the following:
- ASSIGNED
- ASSIGNED_NS
- ASSIGNED_DEV
- TABLE
- VSMMU
The function RttSkipNonLiveEntries() is used to scan an
RTT to find the next live RTTE. The resulting IPA is returned to the
Host from commands whose successful execution causes a live RTTE to
become non-live.
Identifying the next live RTTE allows the Host to avoid calls to RMI_RTT_READ_ENTRY when unmapping ranges of a Realm’s IPA space, for example during Realm destruction.
RTT liveness is a property which means that there exists another RMM data structure which is referenced by the RTT.
An RTT is live if, for any of its entries, the RTTE state is any of the following:
- ASSIGNED
- ASSIGNED_DEV
- TABLE
- VSMMU
Note that an RTT can be non-live, even if one of its entries is live. This would be the case for example if the RTT corresponds to an Unprotected IPA range and the state of one of its entries is ASSIGNED_NS.
The function RttIsLive() is used to evaluate whether an
RTT is live.
See also:
5.56.9 RTT destruction
RTT destruction is the operation of destroying a child RTT, and discarding information which was stored in the child RTT.
An RTT cannot be destroyed if it is live.
An RTT can be destroyed regardless of whether it is homogeneous.
Following RTT destruction, all of the following are true for the parent RTTE:
- RIPAS is DESTROYED
- RTTE state is UNASSIGNED
5.56.10 RTT walk
An IPA is translated to a PA by walking an RTT tree, starting at the RTT base.
The behaviour of an RTT walk is defined by the Armv8-A Virtual Memory System Architecture (VMSA) Arm Architecture Reference Manual for A-Profile architecture [3].
The inputs to an RTT walk are:
- a Realm Descriptor, which contains the address of the initial RTT
- an RTT tree index
- a target IPA
- a target RTT level.
The RTT walk terminates when either:
- it reaches the target RTT level, or
- it reaches an RTTE whose state is not TABLE.
The result of an RTT walk performed by the RMM is a data structure of type RmmRttWalkResult.
The attributes of an RmmRttWalkResult are summarized in
the following table.
| Name | Type | Description |
|---|---|---|
| level | Int8 | RTT level reached by the walk |
| rtt_addr | Address | Address of RTT reached by the walk |
| rtte | RmmRttEntry | RTTE reached by the walk |
The function RmmRttWalkResult RttWalk(rd, addr, level)
is used to represent an RTT walk.
The input address to an RTT walk is always less than
2^w, where w is the IPA width of the target
Realm.
See also:
5.56.11 Stage 2 Access Permissions
This section describes how Stage 2 Access Permissions (S2AP) is managed for Realm IPA space, from the following perspectives:
- How S2AP is encoded in RTT descriptors.
- The programming model for control by the Realm of S2AP for Protected IPA space.
- The programming model for control by the Host of S2AP for Unprotected IPA space.
5.56.11.1 Encoding of Stage 2 Access Permissions in RTT descriptors
If the Realm uses S2AP direct encoding then S2AP values are encoded directly in RTT entries.
If the Realm uses S2AP indirect encoding then S2AP is encoded indirectly in RTT entries, as described in “Stage 2 Indirect permissions” in the Arm Architecture Reference Manual for A-Profile architecture [3].
See also:
5.56.11.2 Stage 2 Access Permissions for a Protected IPA
The programming model for control of S2AP for Protected IPA space is based on indirection, as follows:
The S2AP base value of a Protected IPA is determined by its HIPAS.
Each Protected IPA has an S2AP overlay index which is controlled by P0, via RSI commands.
Each { Plane, S2AP overlay index } tuple maps to an S2AP overlay value.
- For Pn, this mapping is controlled by P0 via RSI commands, subject to constraints imposed by the RMM.
- For P0, this mapping is architecturally fixed.
The S2AP which applies to an access from a given Plane to a given IPA are defined by the combination of the S2AP base value and the S2AP overlay value, following the rules for “Stage 2 Indirect permissions” in the Arm Architecture Reference Manual for A-Profile architecture [3].
The programming model for control of S2AP for Protected IPA space does not depend on whether the Realm uses S2AP indirect encoding.
If the Realm uses S2AP direct encoding, the RMM maps from the indirect programming model onto S2AP values which are directly stored in RTT entries.
For a Protected IPA whose HIPAS is ASSIGNED, the S2AP base value is RW+puX.
For a Protected IPA whose HIPAS is ASSIGNED_DEV, the S2AP base value is RW.
For a Protected IPA, all S2AP overlay indices map to RW+puX. R For a Protected IPA, all S2AP overlay indices map to RW+puX for P0.
See also:
5.56.11.3 Stage 2 Access Permissions for an Unprotected IPA
The S2AP which applies to a Realm access to an Unprotected IPA is controlled by the Host.
The programming model for control by the Host of S2AP for Unprotected IPA space depends on whether the Realm uses S2AP indirect encoding.
If the Realm uses S2AP direct encoding then S2AP is controlled as follows:
The Host provides read and write permissions via the
APfield in the descriptor passed to
RMI_RTT_MAP_UNPROTECTED to create the mapping in the primary RTT tree.The RMM sets
XN = '1'in the primary RTT tree.Execution of RMI_RTT_AUX_MAP_UNPROTECTED causes the RW and XN fields to be copied from the primary RTT tree into an auxiliary RTT tree.
If the Realm uses S2AP indirect encoding then S2AP is controlled as follows:
The Host provides an S2AP base index in the descriptor passed to RMI_RTT_MAP_UNPROTECTED.
The RMM configures the S2AP overlay index to provide a S2AP overlay value of RW.
The observed S2AP is defined by the combination of the S2AP base value and the S2AP overlay value, following the rules for “Stage 2 Indirect permissions” in the Arm Architecture Reference Manual for A-Profile architecture [3].
In this way, the RMM ensures that neither unprivileged execute permission (uX) nor privileged execute permission (pX) is observed on Realm access to an Unprotected IPA.
5.56.11.4 Stage 2 base permission values
The mapping from S2AP base index to S2AP base value is as follows:
| S2AP base index | S2AP base value |
|---|---|
| 0 | NoAccess |
| 1 | RO |
| 2 | WO |
| 3 | RW |
| 4 | RW+puX |
| 5 to 15 | Reserved |
5.56.12 RTT entryMemory attributes
5.56.12.1 RTT entryMemory attributes for ASSIGNED mappings
The memory type and cacheability attributes which result from Realm access to an IPA whose HIPAS is ASSIGNED are Normal Write-Back.
The shareability attributes which result from Realm access to an IPA whose HIPAS is ASSIGNED are Inner Shareable.
The cacheabilitymemory attributes of an RTT entrywhich result from Realm access to an IPA whose HIPAS is ASSIGNED are independent of any stage 1 descriptors and of the state is ASSIGNED are independent of anyof the stage 1 descriptors and of the state of the stage 1 MMU.
The RMM uses FEAT_S2FWB to ensure that the cacheabilitymemory attributes of an RTT entrywhich result from Realm access to an IPA whose stateHIPAS is ASSIGNED are independent of stage 1 translation.
See also:
5.56.12.2 RTT entryMemory attributes for ASSIGNED_DEV mappings
In an RTT entryThe memory type and cacheability attributes which result from Realm access to an IPA whose stateHIPAS is ASSIGNED_DEV and whose output address identifies an MMIOwhich maps to a Device non-coherent memory location are controlled by stage 1 translation and constrained to be one of the following:
- Device
, MemAttr is set to 0b101. Combined with FEAT_S2FWB, this allows the Realmwith device attributes specified via stage 1 to specify memory type to be either Device (with device attributes also specified via stage 1) or translation - Normal Non-Cacheable
The RMM uses FEAT_S2FWB to constrain the memory type and cacheability attributes which result from Realm access to an IPA whose HIPAS is ASSIGNED_DEV and which is mapped to a Device non-coherent memory physical location.
In an RTT entryThe memory type and cacheability attributes which result from Realm access to an IPA whose stateHIPAS is ASSIGNED_DEV and whose output address does not identify an MMIOwhich maps to a Device coherent memory physical location, MemAttr is set to 0b111. Combined with FEAT_S2FWB, this allows the Realm via are passed through from stage 1 to specify memory type to have any value translation.
The RMM uses FEAT_S2FWB to pass through from stage 1 translation the memory type and cacheability attributes which result from Realm access to an IPA whose HIPAS is ASSIGNED_DEV and which is mapped to a Device coherent memory physical location.
In an RTT entry The shareability attributes which result from Realm access to an IPA whose stateHIPAS is ASSIGNED_DEV and whose output address identifies an MMIOwhich maps to a Device non-coherent memory physical location, SH is set to are Outer Shareable.
In an RTT entry The shareability attributes which result from Realm access to an IPA whose stateHIPAS is ASSIGNED_DEV and whose output address does not identify an MMIOwhich maps to a Device coherent memory physical location, SH is set to are Inner Shareable.
See also:
- Arm Architecture Reference Manual for A-Profile architecture [3]
- Section 2.2.1
- Section 9.5.3
- Section 15.3.4
5.56.12.3 RTT entryMemory attributes for ASSIGNED_NS mappings
The following attributes of an RTT entry whose state is ASSIGNED_NS are Host-controlled Unprotected RTT attributes:
ADDRMemAttr[2:0]AP(if the Realm uses S2AP direct encoding) orPIIndex(if the Realm uses S2AP indirect encoding)
In an RTT entry whose state is ASSIGNED_NS, MemAttr[3]
is res0 because the RMM uses
FEAT_S2FWB.
In an RTT entry The shareability attributes which result from Realm access to an IPA whose stateHIPAS is ASSIGNED_NS, the shareability attributes are as follows:
- Inner Shareable if the mapping is cacheable.
- Outer Shareable if the mapping is non-cacheable.
The shareability attributes of an RTT entry which corresponds to an Unprotected IPA are expected to be controlled by the RMM as follows:
- If LPA2 is enabled at stage 2 then the RMM is expected to set
VTCR_EL2.DS == '1'. - If LPA2 is not enabled at stage 2 then the RMM is expected to set
the value of the
SHfield in the translation table descriptor based on the value of theMemAttrfield.
See also:
- Arm Architecture Reference Manual for A-Profile architecture [3]
- Section 3.12
- Section 14.116121
- Section 15.3.4443
5.56.12.4 Summary of memory attributes
The following table summarizes the resultant memory attributes for each permitted combination of HIPAS and Granule category.
| HIPAS | Granule category | Resultant memory type and cacheability attributes | Resultant shareability attributes |
|---|---|---|---|
| ASSIGNED | Delegable DRAM | Normal Write-Back | Inner Shareable |
| ASSIGNED_DEV | Delegable non-coherent device memory | One of the following:
(Specified by stage 1 translation) |
Outer Shareable |
| ASSIGNED_DEV | Delegable coherent device memory | Specified by stage 1 translation | Inner Shareable |
| ASSIGNED_NS | Delegable DRAM | Specified by combination of Host-controlled RTT attributes and stage 1 translation |
|
See also:
- Section 2.2.1
5.6.12.5 Hardware access flag and dirty bit management
Hardware access flag and dirty bit management is disabled for the stage 2 translation used by a Realm.
Hardware access flag and dirty bit management may be enabled by software executing within the Realm, for its own stage 1 translation.
6 Realm interrupts and timers
This specification requires that a virtual Generic Interrupt Controller (vGIC) is presented to a Realm. This vGIC should be architecturally compliant with respect to GICv3 with no legacy operation.
The Host is able to inject virtual interrupts using the GIC virtual CPU interface.
The vGIC presented to a Realm is expected to be implemented via a combination of Host emulation and RMM mediation, as follows:
Management of Non-secure physical interrupts is performed by the Host, via the GIC Interrupt Routing Infrastructure (IRI).
The Host is responsible for emulating a GICv3 distributor MMIO interface.
The Host is responsible for emulating a GICv3 redistributor MMIO interface for each REC.
The GIC MMIO interfaces emulated by the Host must be presented to the Realm via its Unprotected IPA space.
The Host may optionally provide a virtual Interrupt Translation Service (ITS). The Realm must allocate ITS tables within its Unprotected IPA space.
The RMM allows the Host to control some of the GIC virtual CPU interface state which is observed by the Realm. This state is designed to be the minimum required to allow the Host to correctly manage interrupts for the Realm, with integrity guaranteed by the RMM for the remainder of the GIC CPU interface state.
On REC exit, the RMM exposes some of the GIC virtual CPU interface state to the Host. This state is designed to be the minimum required to allow the Host to correctly manage interrupts for the Realm, with confidentiality guaranteed by the RMM for the remainder of the GIC virtual CPU interface state.
On every REC exit, the EL1 timer state is exposed to the Host. The RMM guarantees that a REC exit occurs whenever a Realm EL1 timer asserts or de-asserts its output.
See also:
6.1 Realm interrupts
This section describes the programming model for a REC’s GIC CPU interface.
The number of GICv3 List Registers which are available is discoverable via the RMI_FEATURES command.
Providing an ABI for discovery of the number of GICv3 List Registers which are available allows the RMM to reserve physical GICv3 List Registers for its own usage.
The value of enter.gicv3_lrs[n] is valid if all of the
following are true:
- The value is an architecturally valid encoding of
ICH_LR<n>_EL2according to Arm Generic Interrupt Controller (GIC) Architecture Specification version 3 and version 4 [6]. HW == '0'.
The GICv3 architecture states that, if HW == '1' then
the virtual interrupt must be linked to a physical interrupt whose state
is Active, otherwise behavior is undefined. The RMM is unable to
validate that invariant, so it imposes the constraint that
HW == '0'.
The value of enter.gicv3_hcr is valid if the value is an
architecturally valid encoding of ICH_HCR_EL2 according to
Arm Generic Interrupt Controller (GIC)
Architecture Specification version 3 and version 4
[6].
REC entry fails if the value of any enter.gicv3_*
attribute is invalid.
On REC entry, ICH_LR<n>_EL2 is set to
enter.gicv3_lrs[n], for all values of n
supported by the PE in the
set of GICv3 List Registers which are available.
On REC entry, the following fields in ICH_HCR_EL2 are
set to the corresponding values in enter.gicv3_hcr:
UIELRENPIENPIEVGrp0EIEVGrp0DIEVGrp1EIEVGrp1DIETDIR
On REC entry, fields in enter.gicv3_hcr must be set to
‘0’ except for the following:
UIELRENPIENPIEVGrp0EIEVGrp0DIEVGrp1EIEVGrp1DIETDIR
If any other field in enter.gicv3_hcr is set to ‘1’,
then RMI_REC_ENTER fails.
The RMM provides access to the GIC virtual CPU interface to the Realm
and therefore controls the enable bit and most trap bits in
ICH_HCR_EL2. The maintenance interrupt control bits are
controlled by the Host, because the maintenance interrupts are provided
as hints to the hypervisor to allocate List Registers optimally and to
correctly emulate GICv3 behavior. The TDIR bit is also
controlled by the Host because it is used when supporting
EOImode == '1' in the Realm. This mode is used to allow
deactivation of virtual interrupts across RECs. This deactivation must
be handled by the Host because the RMM can only operate on a single REC
during execution of RMI_REC_ENTER.
A REC exit due to IRQ is not generated for an interrupt which is
masked by the value of ICC_PMR_EL1 at the time of REC
entry.
The RMM should preserve the value of ICC_PMR_EL1 during
REC entry.
On REC exit, exit.gicv3_vmcr contains the value of
ICH_VMCR_EL2 at the time of the Realm exit.
On REC exit, exit.gicv3_misr contains the value of
ICH_MISR_EL2 at the time of the Realm exit.
The Host could in principle infer the value of
ICH_MISR_EL2 at the time of the Realm exit from the
combination of exit.gicv3_lrs[n] and
exit.gicv3_hcr. However, this would be cumbersome,
error-prone, and diverge from the design of existing hypervisor
software.
On REC exit, exit.gicv3_lrs[n] contains the value of
ICH_LR<n>_EL2 at the time of the Realm exit, for all
values of n supported by the PEin the set of GICv3 List Registers which are
available.
On REC exit, the following fields in exit.gicv3_hcr
contains the value of the corresponding field in
ICH_HCR_EL2 at the time of the Realm exit:
EOIcountUIELRENPIENPIEVGrp0EIEVGrp0DIEVGrp1EIEVGrp1DIETDIR
All other fields contain zero.
On REC exit, the values of the following registers may have changed:
ICH_AP0R<n>_EL2ICH_AP1R<n>_EL2ICH_LR<n>_EL2ICH_VMCR_EL2ICH_HCR_EL2
It is the responsibility of the caller to save and restore GIC virtualization system control registers if their value needs to be preserved following execution of RMI_REC_ENTER.
On REC entry, the values of the GIC virtualization control system registers are overwritten. The Non-secure hypervisor runs at EL2 and therefore does not make direct use of the virtual GIC CPU interface for its own execution. This means that saving / restoring the caller’s GIC virtualization control system registers would typically not be required and would add additional runtime overhead for each execution of RMI_REC_ENTER.
On REC exit, ICH_HCR_EL2.En == '0'.
Disabling the virtual GIC CPU interface ensures that the caller does not receive unexpected GIC maintenance interrupts. A stronger constraint, for example stating that all GIC virtualization control system registers are zero on REC exit, was considered. However, this was rejected on the basis that it may preclude future optimisations, such as returning early from execution of RMI_REC_ENTER, without needing to first write zero to all GIC virtualization control system registers, if an interrupt is pending.
See also:
6.2 Realm timers
This section describes the operation of architectural timers during Realm execution, including the following:
- The behavior of EL2 timers programmed by the Host
- The behavior of EL1 timers as perceived by the Realm
- The Realm timer state which is exposed to the Host on REC exit, in order to facilitate virtualization of timer interrupts
Architectural timers are available to a Realm and behave according to their architectural specification.
If the Host has programmed an EL1 timer to assert its output during Realm execution, that timer output is not guaranteed to assert.
If the Host has programmed an EL2 timer to assert its output during Realm execution, that timer output is guaranteed to assert.
Both the virtual and physical counter values are guaranteed to be monotonically increasing when read by a Realm, in accordance with the architectural counter behavior.
A read by a Realm of either the virtual or physical counter at the same place in the instruction flow would return the same value.
In order to ensure that the Realm has a consistent view of time, the virtual timer offset must be fixed for the lifetime of the Realm. The absolute value of the virtual timer offset is not important, so the value zero has been chosen for simplicity of both the specification and the implementation.
The rule that virtual and physical counter values are identical may need to be amended if a future version of the specification supports migration and / or virtualization of time based on the virtual counter differing from the physical counter.
On a change in the output of an EL1 timer which requires a Realm-observable change to the state of virtual interrupts, a REC exit occurs.
On REC exit, Realm EL1 timer state is exposed via the RmiRecExit object:
exit.cntv_ctlcontains the value ofCNTV_CTL_EL0at the time of the Realm exit.exit.cntv_cvalcontains the value ofCNTV_CVAL_EL0at the time of the Realm exit, expressed as if the virtual counter offset was zero.exit.cntp_ctlcontains the value ofCNTP_CTL_EL0at the time of the Realm exit.exit.cntp_cvalcontains the value ofCNTP_CVAL_EL0at the time of the Realm exit, expressed as if the physical counter offset was zero.
The Host should check the Realm EL1 timer state on every return from
RMI_REC_ENTER and update virtual interrupt state accordingly. This is
true regardless of the value of exit.exit_reason: even if
the return occurred for a reason unrelated to timers (for example, a REC
exit due to Data Abort), the Realm EL1 timer state should be
checked.
On REC entry, for both the EL1 Virtual Timer and the EL1 Physical Timer, if the EL1 timer asserts its output in the state described in the REC exit structure from the previous REC exit then the RMM masks the hardware timer signal before returning to the Realm.
This masking is done to allow the Realm to make forward progress, which would otherwise be prevented by the hardware timer generating a physical interrupt that would cause a Realm exit.
During Realm execution, when the hardware timer signal is masked, the Realm may write to the timer registers, causing the hardware timer to become de-asserted and possibly asserted again. Such changes in the output of the EL1 timer are not required to result in a REC exit if the RMM can infer that the change should not result in a Realm-observable change to the state of virtual interrupts.
It is only when a change in the hardware timer output means that the corresponding virtual interrupt needs to be made pending or idle, that a REC exit must occur.
7 Realm measurement and attestation
This section describes how the initial state of a Realm is measured and can be attested.
7.1 Realm measurements
This section describes how Realm measurement values are calculated.
A Realm measurement value is a rolling hash.
A Realm Hash Algorithm (RHA) is an algorithm which is used to extend a Realm measurement value.
The RHA used by a Realm is selected via the hash_algo
attribute.
7.1.1 Realm Initial Measurement
This section describes how the Realm Initial Measurement (RIM) is calculated.
The initial RIM value for a Realm is calculated from a subset of the Realm parameters.
A RIM is extended by applying the RHA to the inputs of RMM operations which are executed during Realm construction.
The following operations cause a RIM to be extended:
- Creation of a DATA Granule during Realm construction
- Creation of a runnable REC
- Changes to RIPAS of Protected IPA during Realm construction
On execution of an operation which requires extension of a RIM, the RMM first constructs a measurement descriptor structure. The measurement descriptor contents include the current RIM value. The new RIM value is computed by applying the RHA to the measurement descriptor.
A RIM is immutable while the state of the Realm is REALM_ACTIVE. This implies that a RIM reflects the configuration and contents of the Realm at the moment when it transitioned from the REALM_NEW to the REALM_ACTIVE state.
A RIM depends upon the order of the RMM operations which are executed during Realm construction.
The order in which RMM operations are executed during Realm construction must be agreed between the Realm owner (or a delegate of the Realm owner which will receive and validate the RIM) and the Host which executes the RMM commands. This ensures that a correctly-constructed Realm will have the expected measurement.
The value of a RIM can be read using the RSI_MEASUREMENT_READ command.
See also:
- Section 15.3.1.4
- Section 15.3.2725.4
- Section 15.3.3028.4
- Section 15.3.4342.4
- Section 16.3.8
7.1.2 Realm Extensible Measurement
This section describes the behavior of a Realm Extensible Measurement (REM).
A REM is extended using the RSI_MEASUREMENT_EXTEND command.
The value of a REM can be read using the RSI_MEASUREMENT_READ command.
The initial value of a REM is zero.
7.2 Realm attestation
This section describes the primitives which are used to support remote Realm attestation.
7.2.1 Attestation token
A CCA attestation token is a collection of claims about the state of a Realm and of the CCA platform on which the Realm is running.
A CCA attestation token consists of two parts:
Realm token
Contains attributes of the Realm, including:
- Realm Initial Measurement
- Realm Extensible Measurements
CCA platform token
Contains attributes of the CCA platform on which the Realm is running, including:
- CCA platform identity
- CCA platform lifecycle state
- CCA platform software component measurements
The size of a CCA attestation token may be greater than 4KB.
7.2.2 Attestation token generation
The process for a Realm to obtain an attestation token is:
- Call RSI_ATTESTATION_TOKEN_INIT once
- Call RSI_ATTESTATION_TOKEN_CONTINUE in a loop, until the result is not RSI_INCOMPLETE
Each call to RSI_ATTESTATION_TOKEN_CONTINUE retrieves up to one Granule of the attestation token.
The following pseudocode illustrates the process of a Realm obtaining an attestation token.
int get_attestation_token(...)
{
int ret;
uint64_t size, max_size;
uint64_t buf, granule;
ret = RSI_ATTESTATION_TOKEN_INIT(challenge, &max_size);
if (ret) {
return ret;
}
buf = alloc(max_size);
granule = buf;
do { // Retrieve one Granule of data per loop iteration
uint64_t offset = 0;
do { // Retrieve sub-Granule chunk of data per loop iteration
size = GRANULE_SIZE - offset;
ret = RSI_ATTESTATION_TOKEN_CONTINUE(granule, offset, size, &len);
offset += len;
} while (ret == RSI_INCOMPLETE && offset < GRANULE_SIZE);
// "offset" bytes of data are now ready for consumption from "granule"
if (ret == RSI_INCOMPLETE) {
granule += GRANULE_SIZE;
}
} while ((ret == RSI_INCOMPLETE) && (granule < buf + max_size));
return ret;
}
Up to one attestation token generation operation may be ongoing on a REC.
On execution of RSI_ATTESTATION_TOKEN_INIT, if an attestation token generation operation is ongoing on the calling REC, it is terminated.
The challenge value provided to RSI_ATTESTATION_TOKEN_INIT is included in the generated attestation token. This allows the relying party to establish freshness of the attestation token.
If the size of the challenge provided by the relying party is less than 64 bytes, it should be zero-padded prior to calling RSI_ATTESTATION_TOKEN_INIT. Arm recommends that the challenge should contain at least 32 bytes of unique data.
Generation of an attestation token can be a long-running operation, during which interrupts may need to be handled.
If a physical interrupt becomes pending during execution of RSI_ATTESTATION_TOKEN_CONTINUE, a REC exit due to IRQ can occur.
On the next entry to the REC:
- If a virtual interrupt is pending on that REC, it is taken to the REC’s exception handler
- RSI_ATTESTATION_TOKEN_CONTINUE returns RSI_INCOMPLETE
- The REC should call RSI_ATTESTATION_TOKEN_CONTINUE again
See also:
7.2.3 Attestation token format
The CCA attestation token is a profiled IETF Entity Attestation Token (EAT).
The CCA attestation token is a Concise Binary Object Representation (CBOR) map, in which the map values are the Realm token and the CCA platform token.
The Realm token contains structured data in CBOR, wrapped with a COSE_Sign1 envelope according to the CBOR Object Signing and Encryption (COSE) standard.
The Realm token is signed by the Realm Attestation Key (RAK).
The CCA platform token contains structured data in CBOR, wrapped with a COSE_Sign1 envelope according to the COSE standard.
The CCA platform token is signed by the Initial Attestation Key (IAK).
The CCA platform token contains a hash of RAK_pub. This establishes a cryptographic binding between the Realm token and the CCA platform token.
The CCA attestation token is defined as follows:
cca-token = #6.399(cca-token-collection) ; CMW Collection
; (draft-ietf-rats-msg-wrap)
cca-platform-token = bstr .cbor COSE_Sign1_Tagged
cca-realm-delegated-token = bstr .cbor COSE_Sign1_Tagged
cca-token-collection = {
44234 => cca-platform-token ; 44234 = 0xACCA
44241 => cca-realm-delegated-token
}
; EAT standard definitions
COSE_Sign1_Tagged = #6.18(COSE_Sign1)
; Deliberately shortcut these definitions until EAT is finalised and able to
; pull in the full set of definitions
COSE_Sign1 = "COSE-Sign1 placeholder"
The composition of the CCA attestation token is summarised in the following figure.
See also:
7.2.3.1 Realm claims
This section defines the format of the Realm token claim map. The format is described using a combination of Concise Data Definition Language (CDDL) and text description.
The Realm token claim map is defined as follows:
cca-realm-claims = (cca-realm-claim-map)
cca-realm-claim-map = {
cca-realm-challenge
? cca-realm-profile
cca-realm-personalization-value
cca-realm-initial-measurement
cca-realm-extensible-measurements
cca-realm-hash-algo-id
cca-realm-public-key
cca-realm-public-key-hash-algo-id
cca-realm-mec-policy
}
See also:
- Concise Data Definition Language (CDDL) [10]
- Section 7.2.3.1.1
- Section 7.2.3.1.2
- Section 7.2.3.1.3
- Section 7.2.3.1.4
- Section 7.2.3.1.5
- Section 7.2.3.1.6
- Section 7.2.3.1.7
- Section 7.2.3.1.8
- Section 7.2.3.1.9
- Section 7.2.3.1.10
- Section 7.2.3.1.11
7.2.3.1.1 Realm challenge claim
The Realm challenge claim is used to carry the challenge provided by the caller to demonstrate freshness of the generated token.
The Realm challenge claim is identified using the EAT
nonce label (10).
The length of the Realm challenge is 64 bytes.
The Realm challenge claim must be present in a Realm token.
The format of the Realm challenge claim is defined as follows:
cca-realm-challenge-label = 10
cca-realm-challenge-type = bytes .size 64
cca-realm-challenge = (
cca-realm-challenge-label => cca-realm-challenge-type
)
7.2.3.1.2 Realm profile claim
The Realm profile claim identifies the EAT profile to which the Realm token conforms.
The Realm profile claim is identified using the EAT
profile label (265).
The Realm profile claim is optional in a CCA Realm token.
If the Realm profile is not included in a CCA Realm token then the profile value used in the CCA Platform token should refer to a profile that describes both Platform and Realm claims.
The format of the Realm profile claim is defined as follows:
cca-realm-profile-label = 265 ; EAT profile
cca-realm-profile-type = "tag:arm.com,2024:realm#1.1.0"
cca-realm-profile = (
cca-realm-profile-label => cca-realm-profile-type
)
7.2.3.1.3 Realm Personalization Value claim
The Realm Personalization Value claim contains the RPV which was provided at Realm creation.
The Realm Personalization Value claim must be present in a Realm token.
The format of the Realm Personalization Value claim is defined as follows:
cca-realm-personalization-value-label = 44235
cca-realm-personalization-value-type = bytes .size 64
cca-realm-personalization-value = (
cca-realm-personalization-value-label => cca-realm-personalization-value-type
)
See also:
- Section 2.1.3
7.2.3.1.4 Realm Initial Measurement claim
The Realm Initial Measurement claim contains the values of the Realm Initial Measurement.
The Realm Initial Measurement claim must be present in a Realm token.
The format of the Realm Initial Measurement claim is defined as follows:
cca-realm-measurement-type = bytes .size 32 / bytes .size 48 / bytes .size 64
cca-realm-initial-measurement-label = 44238
cca-realm-initial-measurement = (
cca-realm-initial-measurement-label => cca-realm-measurement-type
)
7.2.3.1.5 Realm Extensible Measurements claim
The Realm Extensible Measurements claim contains the values of the Realm Extensible Measurements.
The Realm Extensible Measurements claim must be present in a Realm token.
The format of the Realm measurements claim is defined as follows:
cca-realm-measurement-type = bytes .size 32 / bytes .size 48 / bytes .size 64
cca-realm-extensible-measurements-label = 44239
cca-realm-extensible-measurements = (
cca-realm-extensible-measurements-label => [ 4*4 cca-realm-measurement-type ]
)
7.2.3.1.6 Realm hash algorithm ID claim
The Realm hash algorithm ID claim identifies the algorithm used to calculate all hash values which are present in the Realm token.
Arm recommends that the value of the Realm hash algorithm ID claim is an IANA Hash Function name IANA Named Information Hash Algorithm Registry [11].
The Realm hash algorithm ID claim must be present in a Realm token.
The format of the Realm hash algorithm ID claim is defined as follows:
cca-realm-hash-algo-id-label = 44236
cca-realm-hash-algo-id = (
cca-realm-hash-algo-id-label => text
)
7.2.3.1.7 Realm MEC policy claim
The Realm MEC policy identifies the MEC policy of the Realm.
The Realm MEC policy claim must be present in a Realm token.
On a platform which does not implement FEAT_MEC, the value of the Realm MEC policy claim is “shared”.
The format of the Realm MEC policy claim is defined as follows:
cca-realm-mec-policy-label = 44241
cca-realm-mec-policy = (
cca-realm-mec-policy-label => "shared" / "private"
)
See also:
- Section 11
7.2.3.1.8 Realm public key claim
The Realm public key claim identifies the key which is used to sign the Realm token.
The value of the Realm public key claim is a CBOR bstr of a COSE_Key structure. The parameters used for the COSE_Key are profile-specific.
The Realm public key claim must be present in a Realm token.
The format of the Realm public key claim is defined as follows:
cca-realm-public-key-label = 44237
cca-realm-public-key-type = bstr .cbor COSE_Key
cca-realm-public-key = (
cca-realm-public-key-label => cca-realm-public-key-type
)
COSE_Key-label = int / tstr
COSE_Key-values = any
; See RFC8152 for full definition of COSE_Key
COSE_Key = {
1 => tstr / int, ; kty
? 2 => bstr, ; kid
? 3 => tstr / int, ; alg
? 4 => [+ (tstr / int) ], ; key_ops
? 5 => bstr, ; Base IV
* COSE_Key-label => COSE_Key-values
}
See also:
- SEC 1: Elliptic Curve Cryptography, version 2.0 [12]
- Section 7.2.3.1.9
- Section 7.2.3.2.2
7.2.3.1.9 Realm public key hash algorithm identifier claim
The Realm public key hash algorithm identifier claim identifies the algorithm used to calculate H(RAK_pub).
The Realm public key hash algorithm identifier claim must be present in a Realm token.
The format of the Realm public key hash algorithm identifier claim is defined as follows:
cca-realm-public-key-hash-algo-id-label = 44240
cca-realm-public-key-hash-algo-id = (
cca-realm-public-key-hash-algo-id-label => text
)
See also:
- SEC 1: Elliptic Curve Cryptography, version 2.0 [12]
- Section 7.2.3.1.8
- Section 7.2.3.2.2
7.2.3.1.10 Collated CDDL for Realm claims
The format of the Realm token claim map is defined as follows:
cca-realm-claims = (cca-realm-claim-map)
cca-realm-claim-map = {
cca-realm-challenge
? cca-realm-profile
cca-realm-personalization-value
cca-realm-initial-measurement
cca-realm-extensible-measurements
cca-realm-hash-algo-id
cca-realm-public-key
cca-realm-public-key-hash-algo-id
cca-realm-mec-policy
}
cca-realm-challenge-label = 10
cca-realm-challenge-type = bytes .size 64
cca-realm-challenge = (
cca-realm-challenge-label => cca-realm-challenge-type
)
cca-realm-profile-label = 265 ; EAT profile
cca-realm-profile-type = "tag:arm.com,2024:realm#1.1.0"
cca-realm-profile = (
cca-realm-profile-label => cca-realm-profile-type
)
cca-realm-personalization-value-label = 44235
cca-realm-personalization-value-type = bytes .size 64
cca-realm-personalization-value = (
cca-realm-personalization-value-label => cca-realm-personalization-value-type
)
cca-realm-measurement-type = bytes .size 32 / bytes .size 48 / bytes .size 64
cca-realm-initial-measurement-label = 44238
cca-realm-initial-measurement = (
cca-realm-initial-measurement-label => cca-realm-measurement-type
)
cca-realm-extensible-measurements-label = 44239
cca-realm-extensible-measurements = (
cca-realm-extensible-measurements-label => [ 4*4 cca-realm-measurement-type ]
)
cca-realm-hash-algo-id-label = 44236
cca-realm-hash-algo-id = (
cca-realm-hash-algo-id-label => text
)
cca-realm-public-key-label = 44237
cca-realm-public-key-type = bstr .cbor COSE_Key
cca-realm-public-key = (
cca-realm-public-key-label => cca-realm-public-key-type
)
COSE_Key-label = int / tstr
COSE_Key-values = any
; See RFC8152 for full definition of COSE_Key
COSE_Key = {
1 => tstr / int, ; kty
? 2 => bstr, ; kid
? 3 => tstr / int, ; alg
? 4 => [+ (tstr / int) ], ; key_ops
? 5 => bstr, ; Base IV
* COSE_Key-label => COSE_Key-values
}
cca-realm-public-key-hash-algo-id-label = 44240
cca-realm-public-key-hash-algo-id = (
cca-realm-public-key-hash-algo-id-label => text
)
cca-realm-mec-policy-label = 44241
cca-realm-mec-policy = (
cca-realm-mec-policy-label => "shared" / "private"
)
7.2.3.1.11 Example Realm claims
An example Realm claim map is shown below in COSE-DIAG format:
/ Realm claim map /
{
/ cca-realm-profile /
265: "tag:arm.com,2024:realm#1.1.0",
/ cca-realm-challenge /
10: h'ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB
ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB',
/ cca-realm-personalization-value /
44235: h'ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB
ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB',
/ cca-realm-initial-measurement /
44238: h'0000000000000000000000000000000000000000000000000000000000000000',
/ cca-realm-extensible-measurements /
44239: [
h'0000000000000000000000000000000000000000000000000000000000000000',
h'0000000000000000000000000000000000000000000000000000000000000000',
h'0000000000000000000000000000000000000000000000000000000000000000',
h'0000000000000000000000000000000000000000000000000000000000000000'
],
/ cca-realm-hash-algo-id /
44236: "sha-256",
/ cca-realm-public-key /
44237: h'A50102033823200221582066EEA6A22678C3A9F83148EF349800B20ABB486F2C
C6D7ED017EC49798C8D4372258202F25DE86812374E6E8D48DEE8E230AD29CCD
839BE6E0DB8C7AB9DEDE0805D29D',
/ cca-realm-public-key-hash-algo-id /
44240: "sha-256",
/ cca-realm-mec-policy /
44241: "private"
}
7.2.3.2 CCA platform claims
This section defines the format of the CCA platform token claim map. The format is described using a combination of Concise Data Definition Language (CDDL) and text description.
The CCA platform token claim map is defined as follows:
cca-platform-claims = (cca-platform-claim-map)
cca-platform-claim-map = {
cca-platform-profile
cca-platform-challenge
cca-platform-implementation-id
cca-platform-instance-id
cca-platform-config
cca-platform-lifecycle
cca-platform-sw-components
? cca-platform-verification-service
cca-platform-hash-algo-id
}
See also:
7.2.3.2.1 CCA platform profile claim
The CCA platform profile claim identifies the EAT profile to which the CCA platform token conforms. Note that because the platform token is expected to be issued when bound to a Realm token, the profile document should also include the relevant Realm profile or a reference to that profile.
The CCA platform profile claim is identified using the EAT
profile label (265).
The CCA platform profile claim must be present in a CCA platform token.
The format of the CCA platform profile claim is defined as follows:
cca-platform-profile-label = 265 ; EAT profile
cca-platform-profile-type = "tag:arm.com,2024:cca_platform#1.1.0"
cca-platform-profile = (
cca-platform-profile-label => cca-platform-profile-type
)
7.2.3.2.2 CCA platform challenge claim
The CCA platform challenge claim contains a hash of the public key used to sign the Realm token.
The CCA platform challenge claim is identified using the EAT
nonce label (10).
The length of the CCA platform challenge is either 32, 48 or 64 bytes.
The CCA platform challenge claim must be present in a CCA platform token.
The format of the CCA platform challenge claim is defined as follows:
cca-hash-type = bytes .size 32 / bytes .size 48 / bytes .size 64
cca-platform-challenge-label = 10
cca-platform-challenge = (
cca-platform-challenge-label => cca-hash-type
)
See also:
- Section 7.2.3.1.8
7.2.3.2.3 CCA platform Implementation ID claim
The CCA platform Implementation ID claim uniquely identifies the implementation of the CCA platform.
The value of the CCA platform Implementation ID claim can be used by a verification service to locate the details of the CCA platform implementation from an endorser or manufacturer. Such details are used by a verification service to determine the security properties or certification status of the CCA platform implementation.
The semantics of the CCA platform Implementation ID value are defined by the manufacturer or a particular certification scheme. For example, the ID could take the form of a product serial number, database ID, or other appropriate identifier.
The CCA platform Implementation ID claim does not identify a particular instance of the CCA implementation.
The CCA platform Implementation ID claim must be present in a CCA platform token.
The format of the CCA platform Implementation ID claim is defined as follows:
cca-platform-implementation-id-label = 2396 ; PSA implementation ID
cca-platform-implementation-id-type = bytes .size 32
cca-platform-implementation-id = (
cca-platform-implementation-id-label => cca-platform-implementation-id-type
)
See also:
- Arm CCA Security model [4]
- Section 7.2.3.2.4
7.2.3.2.4 CCA platform Instance ID claim
The CCA platform Instance ID claim represents the unique identifier of the Initial Attestation Key (IAK) for the CCA platform.
The CCA platform Instance ID claim is identified using the EAT
ueid label (256).
The first byte of the CCA platform Instance ID value must be
0x01.
The CCA platform Instance ID claim must be present in a CCA platform token.
The format of the CCA platform Instance ID claim is defined as follows:
cca-platform-instance-id-label = 256 ; EAT ueid
; TODO: require that the first byte of cca-platform-instance-id-type is 0x01
; EAT UEIDs need to be 7 - 33 bytes
cca-platform-instance-id-type = bytes .size 33
cca-platform-instance-id = (
cca-platform-instance-id-label => cca-platform-instance-id-type
)
See also:
- Arm CCA Security model [4]
- Section 7.2.3.2.3
7.2.3.2.5 CCA platform config claim
The CCA platform config claim describes the set of chosen implementation options of the CCA platform. As an example, these may include a description of the level of physical memory protection which is provided.
The CCA platform config claim is expected to contain the System Properties field which is present in the Root Non-volatile Storage (RNVS) public parameters.
The CCA platform config claim must be present in a CCA platform token.
cca-platform-config-label = 2401 ; PSA platform range
; TBD: add to IANA registration
cca-platform-config-type = bytes
cca-platform-config = (
cca-platform-config-label => cca-platform-config-type
)
See also:
7.2.3.2.6 CCA platform lifecycle claim
The CCA platform lifecycle claim identifies the lifecycle state of the CCA platform.
The value of the CCA platform lifecycle claim is an integer which is divided as follows:
- value[15:8]: CCA platform lifecycle state
- value[7:0]: implementation defined
The CCA platform lifecycle claim must be present in a CCA platform token.
A non debugged CCA platform will be in psa-lifecycle-secured state. Realm Management Security Domain debug is always recoverable, and would therefore be represented by psa-lifecycle-non-psa-rot-debug state. Root world debug is recoverable on a HES system and would be represented by psa-lifecycle-recoverable-psa-rot state. On a non-HES system Root world debug is usually non-recoverable, and would be represented by psa-lifecycle-lifecycle-decommissioned state.
The format of the CCA platform lifecycle claim is defined as follows:
cca-platform-lifecycle-label = 2395 ; PSA lifecycle
cca-platform-lifecycle-unknown-type = 0x0000..0x00ff
cca-platform-lifecycle-assembly-and-test-type = 0x1000..0x10ff
cca-platform-lifecycle-cca-platform-rot-provisioning-type = 0x2000..0x20ff
cca-platform-lifecycle-secured-type = 0x3000..0x30ff
cca-platform-lifecycle-non-cca-platform-rot-debug-type = 0x4000..0x40ff
cca-platform-lifecycle-recoverable-cca-platform-rot-debug-type = 0x5000..0x50ff
cca-platform-lifecycle-decommissioned-type = 0x6000..0x60ff
cca-platform-lifecycle-type =
cca-platform-lifecycle-unknown-type /
cca-platform-lifecycle-assembly-and-test-type /
cca-platform-lifecycle-cca-platform-rot-provisioning-type /
cca-platform-lifecycle-secured-type /
cca-platform-lifecycle-non-cca-platform-rot-debug-type /
cca-platform-lifecycle-recoverable-cca-platform-rot-debug-type /
cca-platform-lifecycle-decommissioned-type
cca-platform-lifecycle = (
cca-platform-lifecycle-label => cca-platform-lifecycle-type
)
See also:
7.2.3.2.7 CCA platform software components claim
The CCA platform software components claim is a list of software components which can affect the behavior of the CCA platform. It is expected that an implementation will describe the expected software component values within the profile.
In some implementations, a software component may consist of a configuration data item.
The CCA platform software components claim must be present in a CCA platform token.
The format of the CCA platform software components claim is defined as follows:
cca-platform-sw-components-label = 2399 ; PSA software components
cca-platform-sw-component = {
? 1 => text, ; component type
2 => cca-hash-type, ; measurement value
? 4 => text, ; version
5 => cca-hash-type, ; signer id
? 6 => text, ; hash algorithm identifier
? 7 => bool, ; live firmware activation supported
? 8 => [ + cca-hash-type ], ; list of countersigner ids
}
cca-platform-sw-components = (
cca-platform-sw-components-label => [ + cca-platform-sw-component ]
)
7.2.3.2.7.1 CCA platform software component type
The CCA platform software component type is a string which represents the role of the software component.
The CCA platform software component type is intended for use as a hint to help the relying party understand how to evaluate the CCA platform software component measurement value.
The CCA platform software component type is optional in a CCA platform token.
If the CCA platform supports Live Firmware Activation, one entry in the platform software component table is reserved to act as a measurement register for the Firmware Activity Log. This entry is identified by having a software component type of “FAL”.
See also:
- Section 3.13
7.2.3.2.7.2 CCA platform software component measurement value
The CCA platform software component measurement value represents a hash of the state of the software component in memory at the time it was initialized.
The CCA platform software component measurement value must be a hash of 256 bits or stronger.
The CCA platform software component measurement value must be present in a CCA platform token.
7.2.3.2.7.3 CCA platform software component version
The CCA platform software component version is a text string whose meaning is defined by the software component vendor.
The CCA platform software component version is optional in a CCA platform token.
7.2.3.2.7.4 CCA platform software component signer ID
The CCA platform software component signer ID is the hash of a signing authority public key for the software component. It can be used by a verifier to ensure that the software component was signed by an expected trusted source.
The CCA platform software component signer ID value must be a hash of 256 bits or stronger.
The CCA platform software signer ID must be present in a CCA platform token.
7.2.3.2.7.5 CCA platform software component hash algorithm ID
The CCA platform software component hash algorithm ID identifies the way in which the hash algorithm used to measure the CCA platform software component.
Arm recommends that the value of the CCA platform software component hash algorithm ID is an IANA Hash Function name IANA Named Information Hash Algorithm Registry [11].
Arm recommends that the hash algorithm used to measure the CCA platform software component is one of the algorithms listed in the Arm CCA Security model [4].
The CCA platform software component hash algorithm ID is optional in a CCA platform token.
7.2.3.2.7.6 CCA platform software component Live Firmware Activation support
The CCA platform software component Live Firmware Activation support attribute declares whether an individual component is subject to Live Firmware Activation. If the attribute is False, the component will not be updated before the next CCA platform reset.
The CCA platform software component Live Firmware activation support attribute is optional in a CCA platform token.
See also:
- Section 3.13
7.2.3.2.7.7 CCA platform software component countersigner ID list
The CCA platform software component countersigner ID list contains hashes of public keys which identify signing authorities that provides additional trustworthiness information for the software component. These signatures are provided in addition to the primary signature, which is identified by the CCA platform software component signer ID.
Example use cases for CCA platform software component countersignatures include:
- An indication of approval for the component, provided by the owner of the CCA platform
- An indication of approval for the component, provided by a third party auditor
The order of multiple entries within the countersigner ID list may imply a hierarchy. The existence and meaning of any such hierarchy is implementation defined.
The CCA platform software component countersigner ID list is optional in a CCA platform token.
7.2.3.2.8 CCA platform verification service claim
The CCA platform verification service claim is a hint which can be used by a relying party to locate a verifier for the token.
The value of the CCA platform verification service claim is a text string which can be used to locate the service or a URL specifying the address of the service.
The CCA platform verification service claim may be ignored by a relying party in favor of other information.
The CCA platform verification service claim is optional in a CCA platform token.
The format of the CCA platform verification service claim is defined as follows:
cca-platform-verification-service-label = 2400 ; PSA verification service
cca-platform-verification-service-type = text
cca-platform-verification-service = (
cca-platform-verification-service-label =>
cca-platform-verification-service-type
)
7.2.3.2.9 CCA platform hash algorithm ID claim
The CCA platform hash algorithm ID claim identifies the default algorithm used to calculate measurements in the CCA platform token.
The default hash algorithm may be overridden for an individual software component, by the CCA platform software component hash algorithm ID claim.
Arm recommends that the value of the CCA platform hash algorithm ID claim is an IANA Hash Function name IANA Named Information Hash Algorithm Registry [11].
The CCA platform hash algorithm ID claim must be present in a CCA platform token.
The format of the CCA platform hash algorithm ID claim is defined as follows:
cca-platform-hash-algo-id-label = 2402 ; PSA platform range
; TBD: add to IANA registration
cca-platform-hash-algo-id = (
cca-platform-hash-algo-id-label => text
)
7.2.3.3 Attestation token format compatibility
The table below summarises the support for each claim, depending on
the version of the profile of the attestation token. The profile version
is reported in the cca-platform-profile claim as
http://arm.com/CCA-SSD/VERSION.
| Claim | Version | |
|---|---|---|
| 1.0.0 | 1.1.0 | |
| cca-platform-profile | Required | Required |
| cca-platform-challenge | Required | Required |
| cca-platform-implementation-id | Required | Required |
| cca-platform-instance-id | Required | Required |
| cca-platform-config | Required | Required |
| cca-platform-lifecycle | Required | Required |
| cca-platform-sw-components | Required:
Optional:
|
Required
Optional:
|
| cca-platform-verification-service | Optional | Optional |
| cca-platform-hash-algo-id | Required | Required |
| cca-realm-challenge | Required | Required |
| cca-realm-personalization-value | Required | Required |
| cca-realm-initial-measurement | Required | Required |
| cca-realm-extensible-measurements | Required | Required |
| cca-realm-hash-algo-id | Required | Required |
| cca-realm-mec-policy | Not supported | Required |
| cca-realm-public-key | Required | Required |
| cca-realm-public-key-hash-algo-id | Required | Required |
7.2.3.3.1 Collated CDDL for CCA platform claims
The format of the CCA platform token claim map is defined as follows:
cca-platform-claims = (cca-platform-claim-map)
cca-platform-claim-map = {
cca-platform-profile
cca-platform-challenge
cca-platform-implementation-id
cca-platform-instance-id
cca-platform-config
cca-platform-lifecycle
cca-platform-sw-components
? cca-platform-verification-service
cca-platform-hash-algo-id
}
cca-platform-profile-label = 265 ; EAT profile
cca-platform-profile-type = "tag:arm.com,2024:cca_platform#1.1.0"
cca-platform-profile = (
cca-platform-profile-label => cca-platform-profile-type
)
cca-hash-type = bytes .size 32 / bytes .size 48 / bytes .size 64
cca-platform-challenge-label = 10
cca-platform-challenge = (
cca-platform-challenge-label => cca-hash-type
)
cca-platform-implementation-id-label = 2396 ; PSA implementation ID
cca-platform-implementation-id-type = bytes .size 32
cca-platform-implementation-id = (
cca-platform-implementation-id-label => cca-platform-implementation-id-type
)
cca-platform-instance-id-label = 256 ; EAT ueid
; TODO: require that the first byte of cca-platform-instance-id-type is 0x01
; EAT UEIDs need to be 7 - 33 bytes
cca-platform-instance-id-type = bytes .size 33
cca-platform-instance-id = (
cca-platform-instance-id-label => cca-platform-instance-id-type
)
cca-platform-config-label = 2401 ; PSA platform range
; TBD: add to IANA registration
cca-platform-config-type = bytes
cca-platform-config = (
cca-platform-config-label => cca-platform-config-type
)
cca-platform-lifecycle-label = 2395 ; PSA lifecycle
cca-platform-lifecycle-unknown-type = 0x0000..0x00ff
cca-platform-lifecycle-assembly-and-test-type = 0x1000..0x10ff
cca-platform-lifecycle-cca-platform-rot-provisioning-type = 0x2000..0x20ff
cca-platform-lifecycle-secured-type = 0x3000..0x30ff
cca-platform-lifecycle-non-cca-platform-rot-debug-type = 0x4000..0x40ff
cca-platform-lifecycle-recoverable-cca-platform-rot-debug-type = 0x5000..0x50ff
cca-platform-lifecycle-decommissioned-type = 0x6000..0x60ff
cca-platform-lifecycle-type =
cca-platform-lifecycle-unknown-type /
cca-platform-lifecycle-assembly-and-test-type /
cca-platform-lifecycle-cca-platform-rot-provisioning-type /
cca-platform-lifecycle-secured-type /
cca-platform-lifecycle-non-cca-platform-rot-debug-type /
cca-platform-lifecycle-recoverable-cca-platform-rot-debug-type /
cca-platform-lifecycle-decommissioned-type
cca-platform-lifecycle = (
cca-platform-lifecycle-label => cca-platform-lifecycle-type
)
cca-platform-sw-components-label = 2399 ; PSA software components
cca-platform-sw-component = {
? 1 => text, ; component type
2 => cca-hash-type, ; measurement value
? 4 => text, ; version
5 => cca-hash-type, ; signer id
? 6 => text, ; hash algorithm identifier
? 7 => bool, ; live firmware activation supported
? 8 => [ + cca-hash-type ], ; list of countersigner ids
}
cca-platform-sw-components = (
cca-platform-sw-components-label => [ + cca-platform-sw-component ]
)
cca-platform-verification-service-label = 2400 ; PSA verification service
cca-platform-verification-service-type = text
cca-platform-verification-service = (
cca-platform-verification-service-label =>
cca-platform-verification-service-type
)
cca-platform-hash-algo-id-label = 2402 ; PSA platform range
; TBD: add to IANA registration
cca-platform-hash-algo-id = (
cca-platform-hash-algo-id-label => text
)
7.2.3.3.2 Example CCA platform claims
An example CCA platform claim map is shown below in COSE-DIAG format:
/ CCA platform claim map /
{
/ cca-platform-profile /
265: "tag:arm.com,2024:cca_platform#1.1.0",
/ cca-platform-challenge /
10: h'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
/ cca-platform-implementation-id /
2396: h'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
/ cca-platform-instance-id /
256: h'010BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BB',
/ cca-platform-config /
2401: h'CFCFCFCF',
/ cca-platform-lifecycle /
2395: 12288,
/ cca-platform-sw-components /
2399: [
{
/ measurement value /
2: h'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
/ signer id /
5: h'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB',
/ version /
4: "1.0.0",
/ hash algorithm identifier /
6: "sha-256"
},
{
/ measurement value /
2: h'CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC',
/ signer id /
5: h'DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD',
/ version /
4: "1.0.0",
/ hash algorithm identifier /
6: "sha-256"
}
],
/ cca-platform-verification-service /
2400: "https://cca_verifier.org",
/ cca-platform-hash-algo-id /
2402: "sha-256"
}
8 Realm debug and performance monitoring
This section describes the debug and performance monitoring features which are available to a Realm.
8.1 Realm PMU
This section describes the programming model for usage of PMU by a Realm.
On REC entry, Realm PMU state is restored from the REC object.
On REC exit, all Realm PMU state is saved to the REC object.
On REC exit, exit.pmu_ovf_status indicates the status of
the PMU overflow at the time of the Realm exit.
9 Realm device assignment
This section describes how devices are assigned to Realms, attested and granted permission to access Realm-owned memory.
9.1 Realm device assignment overview
The RMM allows a device to be assigned to a Realm in a trustworthy manner, allowing the Realm to attest the identity and configuration of the device before it is permitted to access the Realm’s memory.
From the Host point of view, devices are managed using two types ofthe following RMM object:objects:
Physical Device (PDEV)
Represents a communication channel between the RMM and a physical device, for example a PCIe device.
Virtual Device (VDEV)
Represents the binding between a device function and a Realm. For example, a VDEV can represent a physical function of a PCIe device or a virtual function of a multi-function PCIe device. Every VDEV is associated with one PDEV.
Virtual SMMU (VSMMU)
Stores the state of an Arm Virtual System Memory Management Unit (VSMMU) which is emulated by the RMM, allowing the Realm to apply stage 1 translation to transactions inititated by assigned device functions.
Interaction between the Host and a PDEV, VDEV and VSMMU objects is performed via RMI commands.
From the Realm point of view, an assigned device function is represented by a Realm Device (RDEV).
Interaction between the Realm and an RDEV is performed via RSI commands.
Arm expects that a VDEV and an RDEV will both refer to the same data structure inside the RMM.
9.1.1 Device protection types
Communication between a device and either the RMM or a Realm executing the PE must be protected against attack from software outside the TCB of the RMM or Realm.
Communication with a device which is physically integrated into the platform is said to be protected by system construction. For such devices, either SPDM, IDE or both may not be required, depending upon details of the device integration.
Communication with a device which is physically separate from the platform must be protected using SPDM and IDE.
9.1.2 Device attestation types
A platform-attested device is a device whose identity and firmware are attested as part of the CCA platform.
A device which is physically integrated into the platform and which does not implement its own Device Security Manager (DSM) is a platform-attested device.
An independently-attested device is a device whose identity and firmware are attested separately from the CCA platform.
An independently-attested device implements its own DSM.
9.1.2.1 Assignment of an independently-attested device
The communication channel between the RMM and an independently-attested device is managed by the Host.
Communication between the RMM and an independently-attested device is protected using the Security Protocol and Data Model (SPDM) protocol.
Identity of an independently-attested device is described by a device certificate chain.
Firmware measurements for an independently-attested device are reported in an SPDM measurement block.
Assignment of an independently-attested device to a Realm involves the following steps:
The Host creates a PDEV object, associated with the target physical device.
The Host initializes the PDEV object, causing the following to happen:
A secure channel is established between the RMM and the device.
The physical link between the device and memory is secured. For example, for an off-chip PCIe device, this is achieved using the Integrity and Data Encryption (IDE) standard. See PCI Express 6.0 specification [14].
The device certificate chain is provided to the Host. The Host is expected to store this information, and to later present it to the Realm.
A digest of the device certificate chain is stored by the RMM. This is used later to check integrity of the attestation evidence provided by the Host to the Realm.
The Host creates a VDEV object, which represents a binding between a function of the target device, and a Realm. At this stage, the target device is not granted access to the Realm-owned memory.
The Host maps memory regions of the target device function into the Protected IPA space of the Realm. At this stage, the mappings are invalid, so the Realm cannot yet access the device’s memory regions.
Device information provided by the RMM tells the Realm that the device is independently-attested. The Realm requests the RMM to retrieve device attestation evidence (device interface report and device measurements.) As with the device certificate chain, the evidence is provided to the Host for caching, and the RMM stores digests of the evidence. The Realm later requests device attestation evidence from the Host, and verifies that this matches the corresponding digests stored by the RMM.
The Realm verifies that the device identity (represented by the device certificate chain) and device measurements are acceptable.
The Realm verifies that device memory mappings created by the Host match those described in the device interface report. Once each mapping has been verified, it is made valid by the RMM, so the Realm can access the device’s memory regions.
The Realm instructs the RMM to grant the device access to Realm-owned memory.
Requiring the Host to store device attestation evidence means that storage for this information, whose size may not be known ahead of time, does not need to be allocated in RMM memory. The RMM therefore only needs to store a digest of the Host-cached data, which can be used by the Realm to check integrity of data retrieved from the Host.
Assignment of an independently-attested device to a Realm is illustrated in the following sequence diagram.
Note that “secure SPDM” means that the requester (the RMM) has verified that the responder holds the private key which was used to sign the device certificate chain. The identity and trustworthiness of the responder are not evaluated until the Realm receives attestation evidence for the device.
The device certificate chain digest computed by the RMM for an independently-attested device is computed over the concatenation of individual X.509 certificates in the chain, without SPDM header and root certificate hash. The device certificate chain must meet SPDM requirements. The leaf certificate must meet CMA-SPDM requirements.
9.1.2.2 Assignment of a platform-attested device
The communication channel between the RMM and a platform-attested device is implementation defined.
Firmware measurements for a platform-attested device are reported in the CCA platform software components claim.
Assignment of a platform-attested device to a Realm involves the following steps:
The Host creates a PDEV object, associated with the target physical device.
The Host initializes the PDEV object, causing the following to happen:
- A secure channel is established between the RMM and the device.
The Host creates a VDEV object, which represents a binding between a function of the target device, and a Realm. At this stage, the target device is not granted access to the Realm-owned memory.
The Host maps memory regions of the target device function into the Protected IPA space of the Realm. At this stage, the mappings are invalid, so the Realm cannot yet access the device’s memory regions.
Device information provided by the RMM tells the Realm that the device is platform-attested. The Realm requests the RMM to retrieve a device interface report. The device interface report is provided to the Host for caching, and the RMM stores digests of the device interface report. The Realm later requests the device interface report from the Host, and verifies that this matches the corresponding digest stored by the RMM.
The Realm retrieves device measurements from the CCA platform attestation token, and verifies that the measurements are acceptable.
The Realm verifies that device memory mappings created by the Host match those described in the device interface report. Once each mapping has been verified, it is made valid by the RMM, so the Realm can access the device’s memory regions.
The Realm instructs the RMM to grant the device access to Realm-owned memory.
Assignment of a platform-attested device to a Realm is illustrated in the following sequence diagram.
9.2 Communication between RMM and a device
9.2.1 Device requests and responses
Communication between the RMM and a device consists of a series of device requests sent from the RMM to the device and device responses returned by the device to the RMM.
A device transaction is a series of one or more (device request, device response) tuples.
At the requester side (that is, at the RMM), a device transaction is associated with either a PDEV or a VDEV, depending on the event which triggered the device transaction:
- If the device transaction was triggered by one of the following RMI
commands then the device transaction is associated with the PDEV.
- RMI_PDEV_CREATE
- RMI_PDEV_SET_PUBKEY
- RMI_PDEV_NOTIFY
- RMI_PDEV_STOP
- If the device transaction was triggered by one of the following RMI
commands then the device transaction is associated with the VDEV.
- RMI_VDEV_STOP
- If the device transaction was triggered by one of the following RSI
commands then the device transaction is associated with the VDEV.
- RSI_RDEV_GET_INTERFACE_REPORT
- RSI_RDEV_GET_MEASUREMENTS
- RSI_RDEV_LOCK
- RSI_RDEV_START
- RSI_RDEV_STOP
A PDEV is associated with at most one device transaction at a time.
A VDEV is associated with at most one device transaction at a time.
Communication between the RMM and an off-chip device consists of SPDM messages, transported via Non-secure memory.
Communication between the RMM and an on-chip device can occur via one of two paths:
- SPDM messages, transported via Non-secure memory.
- Platform communication, via an implementation defined channel.
When the RMM requires the Host to send a device request, the “send” flag is set in the DevCommExitFlags fieldset.
When the RMM sends a device request via an implementation defined channel, the “send” flag is clear and the “wait” flag is set in the DevCommExitFlags fieldset. This informs the Host that it should either:
- Register for an implementation defined notification that the request has been completed, and call RMI_PDEV_COMMUNICATE or RMI_VDEV_COMMUNICATE when this notification is received, or
- Poll for request completion by periodically calling RMI_PDEV_COMMUNICATE or RMI_VDEV_COMMUNICATE.
The states of a Device communication are listed below.
| State | Description |
|---|---|
| DEV_COMM_IDLE | The RMM is not communicating with the device. |
| DEV_COMM_PENDING | The RMM has a device request which is ready to be sent to the device. |
| DEV_COMM_ACTIVE | The RMM has initiated a device transaction. One or more device requests associated with this device transaction have been sent from the RMM to the device. The RMM has not received all the expected device responses associated with this device transaction. |
| DEV_COMM_ERROR | The RMM encountered an error during communication with the device. |
Device communication state transitions are shown in the following figure. Each arc is labeled with the events which can cause the corresponding state transition.
See also:
- Secured Messages using SPDM Specification version 1.1.0 [15]
- Section 9.5.1
- Section 15.4.9
9.2.2 Mapping from virtual device ID to VDEV object
The RMM does not maintain a mapping from virtual device ID to VDEV object. Conseqeuntly, when a Realm executes the RSI_RDEV_GET_INSTANCE_ID an RSI_RDEV command, passing a virtual device ID, the RMM must request the Host to provide a corresponding VDEV object.
The following sequence diagram shows how the virtual device ID passed by a Realm is mapped to a corresponding VDEV object.
RSI_RDEV_GET_INSTANCE_ID returns a “device instance ID” value. The device instance ID is guaranteed to be unique among VDEVs owned by the calling Realm, unlike the virtual device ID. When the Realm calls any RSI_RDEV command other than RSI_RDEV_GET_INSTANCE_ID, it passes the (virtual device ID, instance ID) tuple.
The following sequence diagram shows how the (virtual device ID, instance ID) tuple passed by a Realm is mapped to the corresponding VDEV object.
If the mapping is not completed (because either the Host provided the incorrect VDEV object, or provided no VDEV object), an error is returned to the Realm following the next REC entry.
See also:
- Section 4.3.1412
- Section 15.3.5251 Section 16.3.17 I RSI_RDEV_GET_INSTANCE_ID returns a “device instance ID” value. The device instance ID is guaranteed to be unique among VDEVs owned by the calling Realm, unlike the virtual device ID. When the Realm calls any RSI_RDEV command other than RSI_RDEV_GET_INSTANCE_ID, it passes the (virtual device ID, instance ID) tuple. I The following sequence diagram shows how the (virtual device ID, instance ID) tuple passed by a Realm is mapped to the corresponding VDEV object. If the mapping is not completed (because either the Host provided the incorrect VDEV object, or provided no VDEV object), an error is returned to the Realm following the next REC entry. See also: Section 4.3.14 Section 15.3.52
- Section 16.3.15
- Section 16.3.16
- Section 16.3.18
- Section 16.3.19
- Section 16.3.20
- Section 16.3.21
- Section 16.3.22
- Section 16.3.23
- Section 16.3.24
9.2.3 Host-side device communication flow
The RMI_PDEV_COMMUNICATE command is used to send a PDEV-associated device request from the RMM to a device, and / or to return a device response from the device to the RMM.
The RMI_VDEV_COMMUNICATE command is used to send a VDEV-associated device request from the RMM to a device, and / or to return a device response from the device to the RMM.
The RMI_PDEV_COMMUNICATE and RMI_VDEV_COMMUNICATE commands have identical programming models. Hereafter, they are referred to collectively as “device communication commands”.
For a given physical device, at most one device transaction can be active.
The RMI_PDEV_ABORT command or RMI_VDEV_ABORT command is used to abort an DEV_COMM_ACTIVE device transaction.
At the responder side (that is, at the device), device transactions associated with a PDEV and device transactions associated with its child VDEVs all terminate at the same physical device.
9.2.3.1 Communication flow for devices which use SPDM
The overall flow for communication between the RMM and a device which uses SPDM is as follows:
The RMM indicates to the Host that a device transaction, associated with a specified PDEV or VDEV, is DEV_COMM_PENDING.
- If the device transaction was triggered by execution of an RMI command, this indication is provided via the command’s output values.
- If the device transaction was triggered by execution of an RSI command, this indication is provided via a REC exit due to deviceVDEV communication.
The RMM also indicates to the Host whether the pending transaction will contain more than one (device request, device response) tuple.
The Host calls the appropriate device communication command.
Input values to the command include a device request buffer, which is a pointer to a Granule of NS memory.
The RMM writes a device request to the device request buffer and returns to the Host, indicating that data is ready to be sent to the device. The device request is guaranteed to be no larger than 4KB.
The Host sends the device request to the device.
Details of how this is performed are out of scope of this specification. For an off-chip PCIe device, this could be done by copying from the device request buffer to a Data Object Exchange (DOE) mailbox.
The device communication state becomes DEV_COMM_ACTIVE.
The device indicates to the Host that it has responded to the request.
The Host copies the device response to a device response buffer in NS memory. As with sending the request, details of how this are out of scope of this specification.
The Host calls the device communication command, providing a pointer to the device response buffer.
The return value indicates that either:
- The RMM has another device request to send within the same device transaction (in which case the flow returns to step 2), or
- The device transaction is complete.
If the device transaction is incomplete, the Host checks the device state to determine whether an error has occurred.
When multiple device transactions destined for the same physical device are DEV_COMM_PENDING, the Host is free to choose which of them to transition to DEV_COMM_ACTIVE.
When a device transaction is DEV_COMM_ACTIVE, the Host must not send to that physical device a device request associated with any other device transaction.
The SPDM session which is established between the RMM and a device has the following characteristics:
- SPDM measurements use DMTF format
- SPDM heartbeat is not supported
- SPDM key update is not supported
In order for its functions to be assignable to Realms, a device must provide the following functionality:
- SPDM version required by PCIe TDISP and IDE_KM specifications.
- Identity and authentication including key exchange.
The following sequence illustrates communication with a device which uses SPDM, taking RSI_RDEV_LOCK as the example which initiates the communication.
See also:
9.2.3.2 Communication flow for devices which do not use SPDM
The overall flow for communication between the RMM and a device which does not use SPDM is as follows:
The RMM indicates to the Host that a device transaction, associated with a specified PDEV or VDEV, is DEV_COMM_PENDING.
- If the device transaction was triggered by execution of an RMI command, this indication is provided via the command’s output values.
- If the device transaction was triggered by execution of an RSI command, this indication is provided via a REC exit due to deviceVDEV communication.
The Host calls the appropriate device communication command repeatedly, until either:
- The return value indicates that the device transaction is complete.
- The device enters an error state.
The following sequence illustrates communication with a device which does not use SPDM, taking RSI_RDEV_LOCK as the example which initiates the communication.
See also:
- Section 4.3.1113
9.2.4 Host caching of device attestation evidence
On execution of a device communication command, the RMM can indicate to the Host that the Host should cache data from the response buffer, for later retrieval by the Realm.
The identity of the data which the Host is requested to cache is implied by the command which triggered the device transaction, as follows:
- If the device transaction was triggered while the PDEV state was PDEV_NEW then the cached data is a device certificate chain.
- If the device transaction was triggered by RSI_RDEV_GET_INTERFACE_REPORT then the cached data is a device interface report.
- If the device transaction was triggered by RSI_RDEV_GET_MEASUREMENTS then the cached data is a device measurement block.
9.2.5 Device communication data structures
9.2.5.1 Device communication exit data structure
An RmiDevCommExit object is a data structure which is passed from the RMM to the Host during a device transaction.
The attributes of an RmiDevCommExit object tell the Host the following:
- Whether there is data in the device response buffer which the Host is requested to cache. This is indicated by the RmiDevCommExitFlags::cache flag.
- Whether the device request buffer contains a device request which the Host is requested to send to the device. This is indicated by the RmiDevCommExitFlags::send flag.
- Whether the RMM is waiting for a response from the device. This is indicated by the RmiDevCommExitFlags::wait flag.
- Whether the device transaction contains more than one (device request, device response) tuple. This is indicated by the RmiDevCommExitFlags::multi flag.
RmiDevCommExitFlags::send and RmiDevCommExitFlags::wait are never set together.
RmiDevCommExitFlags::multi is only set when RmiDevCommExitFlags::send is set.
During communication between the RMM and a device which uses SPDM:
- RmiDevCommExitFlags::send indicates that the Host is requested to send a device request to the device.
- RmiDevCommExitFlags::wait indicates that the Host is requested to return a device response to the RMM.
During communication between the RMM and a device which does not use SPDM:
- RmiDevCommExitFlags::wait indicates that the Host is requested to notify the RMM when a device response is available.
The attributes of an RmiDevCommExit object are summarized in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| flags | 0x0 |
RmiDevCommExitFlags | Flags indicating action(s) which the Host is requested to perform |
| cache_offset | 0x8 |
UInt64 | If flags.cache is true, offset in the device response buffer to the start of data to be cached, in bytes |
| cache_len | 0x10 |
UInt64 | If flags.cache is true, amount of data to be cached, in bytes |
| protocol | 0x18 |
RmiDevCommProtocol | If flags.send is true, protocol to use |
| req_len | 0x20 |
UInt64 | If flags.send is true, amount of valid data in request buffer in bytes |
| timeout | 0x28 |
UInt64 | If flags.wait is true, amount of time to wait for device response in milliseconds |
9.2.5.2 Device communication enter data structure
An RmiDevCommEnter object is a data structure which is passed from the Host to the RMM during a device transaction.
The attributes of an RmiDevCommEnter object tell the RMM the following:
- Whether the device reported an error.
- Whether the device response buffer contains a device response.
- The location of the device request buffer, into which the RMM can write a device request.
The attributes of an RmiDevCommEnter object are summarized in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| status | 0x0 |
RmiDevCommStatus | Status of device transaction |
| req_addr | 0x8 |
Address | Address of request buffer |
| resp_addr | 0x10 |
Address | Address of response buffer |
| resp_len | 0x18 |
UInt64 | Amount of valid data in response buffer in bytes |
See also:
- Section 15.4.7
9.3 Physical device object
A Physical Device (PDEV) represents a communication channel between the RMM and a physical device, for example a PCIe device.
9.3.1 Physical device attributes
The attributes of a PDEV are summarized in the following table.
| Name | Type | Description |
|---|---|---|
| pdev_id | Bits64 | Device identifier |
| prot_configprot | RmmPdevProtConfigRmmPdevProtection | Configuration of protection between system and device |
| segment_id | Bits8 | Segment identifier PCIe Segment identifier of the Root Port and endpoint. |
| ecam_addr | Address | ECAM base address of the PCIe configuration space. |
| root_id | Bits16 | Root Port identifier Physical PCIe routing identifier of the Root Port to which the endpoint is connected. |
| cert_id | UInt64 | Certificate identifier |
| rid_base | Bits16 | Base of requester ID range (inclusive). The value is in PCI BDF format. |
| rid_top | Bits16 | Top of requester ID range (exclusive). The value is in PCI BDF format. |
| hash_algo | RmmHashAlgorithm | Algorithm used to generate device digests |
| ide_sid | UInt64 | IDE stream ID |
| iocoh_num_addr_rangencoh_num_addr_range | UInt64 | Number of IOdevice non-coherent address ranges |
| iocoh_addr_rangencoh_addr_range | RmmAddressRange[16] | IODevice non-coherent address range |
| fcoh_num_addr_rangecoh_num_addr_range | UInt64 | Number of fully-device coherent address ranges |
| fcoh_addr_rangecoh_addr_range | RmmAddressRange[4] | Fully-Device coherent address range |
| aux | Address[32] | Addresses of auxiliary Granules |
| num_aux | UInt64 | Number of auxiliary Granules |
| state | RmmPdevState | Lifecycle state |
| comm_state | RmmDevCommState | Device communication state |
| num_vdevs | UInt64 | Number of VDEVs associated with this PDEV |
pdev.root_id and pdev.cert_id attributes are ignored for platform-attested devices.
If pdev.prot_configprot is PDEV_IOCOH_E2E_IDE or PDEV_FCOH_E2E_IDE then all of the following are true:
- The RMM checks that pdev.ide_sid is not used by any other PDEV which is connected to the same Root Port.
- The RMM configures an IDE selective stream with IDE selective stream ID pdev.ide_sid and IDE selective stream address ranges pdev.iocoh_addr_rangencoh_addr_range.
The RMM checks that all entries in (pdev.rid_base, pdev.rid_top] are not used by any other PDEV within the same PCIe segment.
The RMM checks that all entries in pdev.iocoh_addr_rangencoh_addr_range have the following properties:
- Fall within non-coherent IO ranges of the system address map.
- Not used by any other PDEV.
If pdev.prot_configprot is PDEV_FCOH_E2E_IDE or PDEV_FCOH_E2E_SYS then the RMM checks that all entries in pdev.fcoh_addr_range have the coh_addr_range have the following properties:
- Fall withinMap to device coherent IO ranges of the system address mapmemory.
- Not used by any other PDEV.
The following table summarises which PDEV attributes are valid for each value of pdev.prot_configprot.
| prot_configprot | Device type | ide_sid | (rid_base, rid_top] | iocoh_addr_rangencoh_addr_range | fcoh_addr_rangecoh_addr_range |
|---|---|---|---|---|---|
| PDEV_IOCOH_E2E_IDE | PCIe off-chip | Y | Y | Y | |
| PDEV_IOCOH_E2E_SYS | PCIe on-chip | Y | Y | ||
| PDEV_FCOH_E2E_IDE | CHI off-chip | Y | Y | Y | Y |
| PDEV_FCOH_E2E_SYS | CHI on-chip | Y | Y | Y |
See also:
- Section 2.2.1
9.3.2 Physical device lifecycle
9.3.2.1 States
The states of a PDEV are listed below.
| State | Description |
|---|---|
| PDEV_NEW | Initial state of the device. |
| PDEV_NEEDS_KEY | RMM needs device public key. |
| PDEV_HAS_KEY | RMM has device public key. |
| PDEV_READY | Secure connection between the RMM and the device has been established. Physical link between the device and memory is secured. Ready for creation of VDEV instances. |
| PDEV_IDE_RESETTING | The PDEV’s IDE link is being reset. |
| PDEV_COMMUNICATING | The RMM is communicating with the device. |
| PDEV_STOPPING | The RMM is communicating with the device to terminate the secure connection between the RMM and the device. |
| PDEV_STOPPED | Secure connection between the RMM and the device has been terminated. |
| PDEV_ERROR | Device has reported a fatal error. |
9.3.2.2 State transitions
Permitted PDEV Realm state transitions are shown in the following figure. Each arc is labeled with the events which can cause the corresponding state transition.
A transition from the pseudo-state NULL represents creation of a PDEV. A transition to the pseudo-state NULL represents destruction of a PDEV.
9.3.2.2.1 State transitions for an independently-attested device
While a PDEV associated with an independently-attested device is in PDEV_NEW state, execution of RMI_PDEV_COMMUNICATE causes the RMM to fetch the device certificate chain. The RMM stores a digest of the device certificate chain for later retrieval by the Realm. The Host is expected to cache the device certificate chain for later retrieval by the Realm.
Once device certificate chain retrieval is complete, the PDEV moves to PDEV_NEEDS_KEY state.
While a PDEV associated with an independently-attested device is in PDEV_HAS_KEY state, execution of RMI_PDEV_COMMUNICATE causes the RMM to perform secure SPDM session establishment and IDE key programming.
Once secure SPDM session establishment and IDE key programming is complete, the PDEV moves to PDEV_READY state.
9.3.2.2.2 State transitions for a platform-attested device
While a PDEV associated with an platform-attested device is in PDEV_NEW state, execution of RMI_PDEV_COMMUNICATE causes the RMM to establish a communication channel with the device.
Once device certificate chain retrieval is complete, the PDEV moves to PDEV_READY state.
9.3.2.2.3 State transitions for devices which use IDE
While a PDEV is in PDEV_READY state, the Host can notify the RMM of an event relevant to the device by executing RMI_PDEV_NOTIFY.
If the return value is RMI_DEV_COMM_PENDINGRMI_SUCCESS then the PDEV moves to PDEV_COMMUNICATING state.
While a PDEV is in PDEV_READY state, if the device class is PCIe then the Host can request the device’s IDE link to be reset by executing RMI_PDEV_IDE_RESET.
The PDEV moves to PDEV_IDE_RESETTING state.
While a PDEV is in PDEV_IDE_RESETTING state, the Host can enact the “IDE reset” device transaction by executing RMI_PDEV_COMMUNICATE.
If the return value indicates that the device transaction is complete then the PDEV moves to PDEV_READY state.
9.3.2.2.4 State transitions for all devices
While a PDEV is in PDEV_COMMUNICATING state, the Host can either:
- Transfer device requests and device responses by executing RMI_PDEV_COMMUNICATE. If the return value indicates that the device transaction is complete then the PDEV moves to PDEV_READY state.
- Abort the device transaction by executing RMI_PDEV_ABORT. On successful execution of this command, the PDEV moves to PDEV_READY state.
On execution of RMI_PDEV_COMMUNICATE, if the RMM detects a fatal error (such as an unexpected response or a protocol error) then the PDEV moves to PDEV_ERROR state.
While a PDEV is in any of the following state, the Host can request the RMM to stop the device by executing RMI_PDEV_STOP:
- PDEV_NEW
- PDEV_NEEDS_KEY
- PDEV_HAS_KEY
- PDEV_READY
- PDEV_IDE_RESETTING
- PDEV_ERROR
The PDEV moves to PDEV_STOPPING state.
While a PDEV is in PDEV_STOPPING state, the Host can enact the “stop” device transaction by executing RMI_PDEV_COMMUNICATE.
If the return value indicates that the device transaction is complete then the PDEV moves to PDEV_STOPPED state.
While a PDEV is in PDEV_STOPPING state, if the device fails to respond or reports an error then the Host can call RMI_PDEV_COMMUNICATE, passing RMI_DEV_COMM_ERROR.
On successful execution of this command, the PDEV moves to PDEV_STOPPED state.
While a PDEV is in PDEV_STOPPED state, the Host can reclaim resources by executing RMI_PDEV_DESTROY.
This command will fail if the PDEV is associated with any VDEVs.
Permitted PDEV state transitions are shown in the following table. The rightmost column lists the events which can cause the corresponding state transition.
A transition from the pseudo-state NULL represents creation of a PDEV object. A transition to the pseudo-state NULL represents destruction of a PDEV object.
| From state | To state | Events |
|---|---|---|
| NULL | PDEV_NEW | RMI_PDEV_CREATE |
| PDEV_NEW | NULL | RMI_PDEV_DESTROY |
| PDEV_NEW | PDEV_NEW | |
| PDEV_NEW | PDEV_NEEDS_KEY | RMI_PDEV_COMMUNICATE |
| PDEV_NEEDS_KEY | PDEV_HAS_KEY | RMI_PDEV_SET_PUBKEY |
| PDEV_HAS_KEY | PDEV_HAS_KEY | |
| PDEV_HAS_KEY | PDEV_READY | RMI_PDEV_COMMUNICATE |
| PDEV_READY | PDEV_COMMUNICATING | RMI_PDEV_NOTIFY |
| PDEV_COMMUNICATING | PDEV_COMMUNICATING | RMI_PDEV_COMMUNICATE |
| PDEV_COMMUNICATING | PDEV_READY | |
| PDEV_READY | PDEV_IDE_RESETTING | RMI_PDEV_IDE_RESET |
| PDEV_IDE_RESETTING | PDEV_READY | RMI_PDEV_COMMUNICATE |
| PDEV_NEW | PDEV_STOPPING | RMI_PDEV_STOP |
| PDEV_NEEDS_KEY | PDEV_STOPPING | RMI_PDEV_STOP |
| PDEV_HAS_KEY | PDEV_STOPPING | RMI_PDEV_STOP |
| PDEV_READY | PDEV_STOPPING | RMI_PDEV_STOP |
| PDEV_IDE_RESETTING | PDEV_STOPPING | RMI_PDEV_STOP |
| PDEV_ERROR | PDEV_STOPPING | RMI_PDEV_STOP |
| PDEV_STOPPING | PDEV_STOPPED | RMI_PDEV_COMMUNICATE |
| PDEV_STOPPED | NULL | RMI_PDEV_DESTROY |
See also:
See also:
9.3.3 Physical device flows
9.3.3.1 Physical device setup flow
Setup of a PDEV is illustrated in the following sequence diagram.
Mapping of the PDEV setup flow onto SPDM and IDE communication with a TDISP PCIe device is illustrated in the following sequence diagram.
IDE setup for a TDISP PCIe device is illustrated in the following sequence diagram.
See also:
9.4 Virtual device object
A virtual device (VDEV) represents the binding between a device function and a Realm.
9.4.1 Virtual device attributes
The attributes of a VDEV are summarized in the following table.
| Name | Type | Description |
|---|---|---|
| vdev_id | Bits64 | Virtual device identifier |
| tdi_id | Bits64 | TDI identifier |
| inst_id | UInt64 | Instance identifier |
| pdev | Address | PA of parent PDEV |
| realm | Address | PA of RD of Realm which owns this VDEV |
| state | RmmVdevState | Lifecycle state |
| comm_state | RmmDevCommState | Device communication state |
| aux | Address[32] | Addresses of auxiliary Granules |
| num_aux | UInt64 | Number of auxiliary Granules |
| vsmmu | RmmFeature | Whether device uses a VSMMU |
| vsmmu_addr | Address | PA of VSMMU. This field is valid if vsmmu is FEATURE_TRUE. |
| vsid | Bits64 | Virtual Stream Identifier. This field is valid if vsmmu is FEATURE_TRUE. |
A Device identifier is a value which identifies a VDEV within a Realm, and is agreed between the Host and the Realm to which the VDEV is assigned.
The choice of device identifier depends upon the interface provided by the Host to the Realm. For example, if the Host provides a PCIe interface, then identifier is a PCIe (bus, device, function) tuple.
The Host provides the device identifier when executing RMI_VDEV_CREATE.
The Realm provides the device identifier when executing any RSI_RDEV command.
9.4.2 Virtual device invariants
Providing a tdi_id which is already used by another VDEV within the same segment causes RMI_VDEV_CREATE to fail.
The RMM can track usage of tdi_id values within a segment by using SW_RESERVED bits in the SMMU Stream Table Entry.
Providing a tdi_id which is outside the RID range of the parent PDEV causes RMI_VDEV_CREATE to fail.
9.4.3 Virtual device lifecycle
9.4.3.1 States
The states of a VDEV are listed below.
| State | Description |
|---|---|
| VDEV_NEW | Initial state of the device. |
| VDEV_READY | No device transaction is associated with the VDEV. |
| VDEV_COMMUNICATING | The RMM is communicating with the VDEV. |
| VDEV_STOPPING | The RMM is communicating with the VDEV to stop the device interface. |
| VDEV_STOPPED | Device interface is stopped. |
| VDEV_ERROR | Device interface has reported a fatal error. |
9.4.3.2 State transitions
Permitted VDEV state transitions are shown in the following figure. Each arc is labeled with the events which can cause the corresponding state transition.
A transition from the pseudo-state NULL represents creation of a VDEV. A transition to the pseudo-state NULL represents destruction of a VDEV.
While a VDEV is in VDEV_READYVDEV_NEW state, on a REC exit due toexecution of RMI_PDEV_COMMUNICATE causes the RMM to initialize the device communication.
Once device initialization is complete, the VDEV moves to VDEV_COMMUNICATING VDEV_READY state.
While a VDEV is in VDEV_COMMUNICATINGVDEV_READY state, on a REC exit due to VDEV communication, the VDEV moves to VDEV_COMMUNICATING state.
While a VDEV is in VDEV_COMMUNICATING state, the Host can either:
- Transfer device requests and device responses by executing RMI_VDEV_COMMUNICATE. If the return value indicates that the device transaction is complete then the VDEV moves to VDEV_READY state.
- Abort the device transaction by executing RMI_VDEV_ABORT. On successful execution of this command, the VDEV moves to VDEV_ERROR state.
On execution of RMI_VDEV_COMMUNICATE, if the RMM detects a fatal error (such as an unexpected response or a protocol error) then the VDEV moves to VDEV_ERROR state.
While a VDEV is in VDEV_READY state or VDEV_ERROR state, the Host can request the RMM to stop the device by executing RMI_VDEV_STOP.
If the return value is RMI_DEV_COMM_PENDINGRMI_SUCCESS then the VDEV moves to VDEV_STOPPING state.
While a VDEV is in VDEV_STOPPING state, the Host can enact the “stop” device transaction by executing RMI_VDEV_COMMUNICATE.
If the return value indicates that the device transaction is complete then the VDEV moves to VDEV_STOPPED state.
While a VDEV is in VDEV_STOPPING state, if the device fails to respond or reports an error then the Host can call RMI_VDEV_COMMUNICATE, passing RMI_DEV_COMM_ERROR.
On successful execution of this command, the VDEV moves to VDEV_STOPPED state.
While a VDEV is in VDEV_STOPPED state, the Host can reclaim resources by executing RMI_VDEV_DESTROY.
Permitted VDEV state transitions are shown in the following table. The rightmost column lists the events which can cause the corresponding state transition.
A transition from the pseudo-state NULL represents creation of a VDEV object. A transition to the pseudo-state NULL represents destruction of a VDEV object.
| From state | To state | Events |
|---|---|---|
| NULL | VDEV_READYVDEV_NEW | RMI_VDEV_CREATE |
| VDEV_NEW | VDEV_NEW | |
| VDEV_NEW | VDEV_READY | RMI_VDEV_COMMUNICATE |
| VDEV_READY | VDEV_COMMUNICATING | REC exit due to deviceVDEV communication |
| VDEV_READY | VDEV_STOPPING | RMI_VDEV_STOP |
| VDEV_COMMUNICATING | VDEV_COMMUNICATING | RMI_VDEV_COMMUNICATE |
| VDEV_COMMUNICATING | VDEV_ERROR | RMI_VDEV_ABORT |
| VDEV_ERROR | VDEV_STOPPING | RMI_VDEV_STOP |
| VDEV_STOPPING | VDEV_STOPPING | RMI_VDEV_COMMUNICATE |
| VDEV_STOPPING | VDEV_STOPPED | RMI_VDEV_COMMUNICATE |
| VDEV_STOPPED | NULL | RMI_VDEV_DESTROY |
See also:
- Section 4.3.1113
9.4.4 Virtual device flows
9.4.4.1 Virtual device teardown flow
Teardown of a VDEV is illustrated in the following sequence diagram.
9.5 Realm management of an assigned device interface
This section describes interaction between a Realm and the RMM to manage an RDEV.
9.5.1 Interruptible Realm device operations
The following are interruptible Realm device operations:
- Requesting digests of device attestation evidence
- Requesting a device interface report
- Requesting device measurements
- Locking a device interface
- Starting a device interface
- Stopping a device interface
Interruptible Realm device operation are:
- Initiated by the Realm executing RSI commands
- Enacted via a REC exit due to deviceVDEV communication, and by subsequent Host calls to RMI_VDEV_COMMUNICATE.
The Realm programming model for interruptible Realm device operation consists of two phases:
The Realm initiates the operation by executing an RSI command. Successful execution of this command causes the RDEV to transition to a busy state.
The Realm executes RSI_RDEV_CONTINUE in a loop, until the result is not RSI_INCOMPLETE.
The following pseudocode illustrates this programming model, using RSI_RDEV_GET_INTERFACE_REPORT as an example.
int get_interface_report(...)
{
int ret;
ret = RSI_RDEV_GET_INTERFACE_REPORT(dev_id, ...);
if (ret) {
return ret;
}
do {
ret = RSI_RDEV_CONTINUE(dev_id);
} while (ret == RSI_INCOMPLETE);
return ret;
}
Once an interruptible Realm device operation has been initiated by the Realm, it must either be:
- Completed by the Realm, via execution of RSI_RDEV_CONTINUE and subsequent calls by the Host to RMI_VDEV_COMMUNICATE, or
- Aborted by the Host, via execution of RMI_VDEV_ABORT.
If the Realm wishes to abort an interruptible Realm device operation, it must request the Host to do so.
The set of commands which can initiate an interruptible Realm device operation are as follows:
- RSI_RDEV_GET_INTERFACE_REPORT
- RSI_RDEV_GET_MEASUREMENTS
- RSI_RDEV_LOCK
- RSI_RDEV_START
- RSI_RDEV_STOP
See also:
9.5.2 Realm retrieval of device attestation evidence
A Realm is expected to retrieve cached device attestation evidence from the Host via an RSI_HOST_CALL interface. Details of this interface are out of scope of this specification.
A Realm can retrieve digests of cached device attestation evidence from the RMM by executing the RSI_RDEV_GET_INFO command.
9.5.3 Realm validation of device memory mappings
A Realm device interface report describes the memory regions of the device. Each device memory region has the following attributes in the report:
PA base address of the region.
This is obfuscated by addition of a random offset value to the system physical address. The offset value is known to the RMM.
Size of the region.
Whether the output address of the mapping is within the system coherent memory space.
A Realm can validate by execution of RSI_RDEV_VALIDATE_MAPPING that each MMIO region in the Realm device interface report has been correctly mapped into the Realm’s Protected IPA space.
Arm recommends that RSI_RDEV_VALIDATE_MAPPING is only called for TEE_MEM devicePCIe classifies memory locations into the following categories:
“TEE memory”: must have mechanisms to ensure confidentiality of data. The RMM does not prevent validation of mappings to NON_TEE_MEM deviceMay additionally provide integrity properties on the data. In a CCA system, this category corresponds to memory locations. However, because all accesses to device memory via Protected IPA space are made with T=1, access to a NON_TEE_MEM location may be rejected by the device within Realm PAS.
“Non-TEE memory”: assumed not to have mechanisms to ensure confidentiality or integrity of data. In a CCA system, this category corresponds to memory locations in Non-Secure PAS.
Arm recommends that RSI_RDEV_VALIDATE_MAPPING is only called for TEE memory device locations. The RMM does not prevent validation of mappings to Non-TEE memory device locations. However, because all accesses to device memory via Protected IPA space are made with the IDE T-bit set to 1, access to a Non-TEE memory location may be rejected by the device. For further details, refer to PCI Express 6.0 specification [14].
Execution of RSI_RDEV_VALIDATE_MAPPING initiates a RIPAS change Device memory mapping validation request. On execution of RSI_RDEV_VALIDATE_MAPPING, the RMM records the PA base address of the region and the flags provided by the Realm in the REC. On subsequent execution of RMI_RTT_SET_RIPAS RMI_RTT_DEV_MEM_VALIDATE, the RMM validates that the contents of the target RTTE are compatible with the PA base address of the region and the flags provided by the Realm. If this validation passes then the RMM sets the RIPAS of the RTTE to DEV.
The RTTE attributes checked by RMI_RTT_SET_RIPASRMI_RTT_DEV_MEM_VALIDATE, when the target RIPAS is RIPAS_DEV, are as follows:
- The IPA to PA mapping is consistent with the PA base address of the region provided by the Realm.
- The memory attributes are consistent with the value of the “coh” flag provided by the Realm.
- The system memory space (coherent or non-coherent) of the PA is consistent with the “coh” flag provided by the Realm.
- The limited ordering properties of the PA (LOR or non-LOR) are consistent with the “order” flag provided by the Realm.
Creation and validation of device memory mappings is illustrated in the following sequence diagram.
See also:
- PCI Express 6.0 specification [14]
- Section 5.45
- Section 5.56.12
- Section 15.3.40
- Section 16.3.24
9.5.4 Realm device attributes
The attributes of an RDEV are summarized in the following table.
| Name | Type | Description |
|---|---|---|
| state | RmmRdevState | Lifecycle state |
| operation | RmmRdevOperation | Operation being performed by the RDEV |
| vdev_ptr | Address | PA of VDEV associated with this RDEV |
9.5.5 Realm device lifecycle
9.5.5.1 States
The states of a RDEV are listed below.
| State | Description |
|---|---|
| RDEV_UNLOCKED | Device interface is unlocked. |
| RDEV_UNLOCKED_BUSY | Device interface is unlocked and is handling an interruptible Realm device operation. |
| RDEV_LOCKED | Device interface is locked. |
| RDEV_LOCKED_BUSY | Device interface is locked and is handling an interruptible Realm device operation. |
| RDEV_STARTED | Device interface is started. |
| RDEV_STARTED_BUSY | Device interface is started and is handling an interruptible Realm device operation. |
| RDEV_STOPPING | Device interface is stopping. |
| RDEV_STOPPED | Device interface is stopped. |
| RDEV_ERROR | Device interface has reported a fatal error. |
9.5.5.2 State transitions
Permitted RDEV Realm state transitions are shown in the following figure. Each arc is labeled with the events which can cause the corresponding state transition.
A transition from the pseudo-state NULL represents creation of an RDEV.
The Realm discovers an assigned PCIe TDI by probing PCIe config space. Arm expects that this will be emulated by the Host, via Unprotected IPA space.
While an RDEV is in RDEV_UNLOCKED state, the Realm can execute any of the following commands:
- RSI_RDEV_GET_MEASUREMENTS
- RSI_RDEV_LOCK
On successful execution of this command, the RDEV moves to RDEV_UNLOCKED_BUSY state and records the requested operation.
Permitting RSI_RDEV_GET_MEASUREMENTS while the RDEV is in RDEV_UNLOCKED state allows the Realm to perform the following sequence:
- Request a measurement of the initial firmware present in a device.
- Transition the device to RDEV_LOCKED.
- Upload new or additional firmware to the device.
- Verify that the firmware has been successfully uploaded, by requesting a new measurement from the device.
While an RDEV is in RDEV_UNLOCKED_BUSY state, the Realm can execute RSI_RDEV_CONTINUE.
Once the requested operation is complete:
- If the requested operation was RSI_RDEV_LOCK, the RDEV moves to RDEV_LOCKED state.
- Otherwise the RDEV moves to RDEV_UNLOCKED state.
While an RDEV is in RDEV_LOCKED state, the Realm can execute any of the following commands:
- RSI_RDEV_GET_INTERFACE_REPORT
- RSI_RDEV_GET_MEASUREMENTS
- RSI_RDEV_START
On successful execution of this command, the RDEV moves to RDEV_LOCKED_BUSY state and records the requested operation.
While an RDEV is in RDEV_LOCKED_BUSY state, the Realm can execute RSI_RDEV_CONTINUE.
Once the requested operation is complete:
- If the requested operation was RSI_RDEV_START, the RDEV moves to RDEV_STARTED state.
- Otherwise the RDEV moves to RDEV_LOCKED state.
While an RDEV is in RDEV_STARTED state, the Realm can execute any of the following commands:
- RSI_RDEV_GET_INTERFACE_REPORT
- RSI_RDEV_GET_MEASUREMENTS
On successful execution of this command, the RDEV moves to RDEV_STARTED_BUSY state and records the requested operation.
While an RDEV is in RDEV_STARTED_BUSY state, the Realm can execute RSI_RDEV_CONTINUE.
Once the requested operation is complete, the RDEV moves to RDEV_STARTED state.
On execution of RSI_RDEV_CONTINUE, if the RMM detects a fatal error (such as an unexpected response or a protocol error) then the RDEV moves to RDEV_ERROR state.
While an RDEV is in any state, the Realm can execute RSI_RDEV_STOP.
On successful execution of this command the RDEV moves to RDEV_STOPPING state.
Following successful execution of this command, accesses from the device to Realm memory are blocked.
While an RDEV is in RDEV_STOPPING state, the Realm can execute RSI_RDEV_CONTINUE.
Once the requested operation is complete, the RDEV moves to RDEV_STOPPED state.
Permitted RDEV state transitions are shown in the following table. The rightmost column lists the events which can cause the corresponding state transition.
| From state | To state | Events |
|---|---|---|
| RDEV_UNLOCKED | RDEV_UNLOCKED_BUSY | |
| RDEV_UNLOCKED_BUSY | RDEV_UNLOCKED_BUSY | RSI_RDEV_CONTINUE |
| RDEV_UNLOCKED_BUSY | RDEV_LOCKED | RSI_RDEV_CONTINUE |
| RDEV_LOCKED | RDEV_LOCKED_BUSY | |
| RDEV_LOCKED_BUSY | RDEV_LOCKED_BUSY | RSI_RDEV_CONTINUE |
| RDEV_LOCKED_BUSY | RDEV_STARTED | RSI_RDEV_CONTINUE |
| RDEV_STARTED | RDEV_STARTED_BUSY | |
| RDEV_STARTED_BUSY | RDEV_STARTED_BUSY | RSI_RDEV_CONTINUE |
| RDEV_UNLOCKED | RDEV_STOPPING | RSI_RDEV_STOP |
| RDEV_LOCKED | RDEV_STOPPING | RSI_RDEV_STOP |
| RDEV_STARTED | RDEV_STOPPING | RSI_RDEV_STOP |
| RDEV_UNLOCKED | RDEV_ERROR |
Host is stopping device interface |
| RDEV_UNLOCKED_BUSY | RDEV_ERROR |
Host is stopping device interface |
| RDEV_UNLOCKED_BUSY | RDEV_UNLOCKED |
Host has stopped device interface |
| RDEV_LOCKED | RDEV_ERROR |
Host is stopping device interface |
| RDEV_LOCKED_BUSY | RDEV_ERROR |
Host is stopping device interface |
| RDEV_LOCKED_BUSY | RDEV_UNLOCKED |
Host has stopped device interface |
| RDEV_STARTED | RDEV_ERROR |
Host is stopping device interface |
| RDEV_STARTED_BUSY | RDEV_ERROR |
Host is stopping device interface |
| RDEV_STARTED_BUSY | RDEV_UNLOCKED |
Host has stopped device interface |
| RDEV_ERROR | RDEV_STOPPING | RSI_RDEV_STOP |
| RDEV_STOPPING | RDEV_STOPPING | RSI_RDEV_CONTINUE |
| RDEV_STOPPING | RDEV_UNLOCKED | RSI_RDEV_CONTINUE |
See also:
9.5.5.3 Relationship between RDEV state and TDISP TDI state
The lifecycle of an RDEV closely resembles the lifecycle of a TDISP TDI. There cannot exist a direct mapping between the two, because changes in TDI state (for example due to Host action) may not be immediately observed by either the RMM or the Realm. However, the two states are sufficiently closely coupled to provide the Realm with important guarantees regarding the TDI state.
On transition of an RDEV to RDEV_LOCKED state, the corresponding TDI transitions to CONFIG_LOCKED state.
On transition of an RDEV to RDEV_STARTED state, the corresponding TDI transitions to RUN state.
On detection by the RMM that a TDI is in ERROR state, the corresponding RDEV transitions to RDEV_ERROR state.
See also:
9.5.5.4 Relationship between RDEV state and SMMU enablement
When the state of an RDEV is RDEV_STARTED, the SMMU permits traffic from the device to the Realm’s Protected IPA space. When the state of an RDEV is not RDEV_STARTED, the SMMU blocks traffic from the device to the Realm’s Protected IPA space.
9.5.6 Realm device flows
9.5.6.1 Realm device setup flow
Setup of an RDEV is illustrated in the following sequence diagram.
9.6 Virtual SMMU
A Virtual SMMU (VSMMU) object stores the state of a Arm VSMMU which is emulated by the RMM.
A physical device which contains functions that can be assigned to Realms must access memory via a physical SMMU (PSMMU).
A PSMMU is identified by its base physical address.
For every PSMMU used by one or more device functions which are assigned to a Realm, if one or more of those device functions require stage 1 translation then a corresponding VSMMU must be created.
A VSMMU can only be created while the Realm state is NEW.
9.6.1 VSMMU lifecycle
A VSMMU is created and bound to a Realm by execution of RMI_VSMMU_CREATE. This command only permits VSMMU creation while the Realm state is NEW.
A VSMMU is destroyed by execution of RMI_VSMMU_DESTROY.
A VSMMU is bound to a VDEV by execution of RMI_VDEV_CREATE, with RmiVdevFlags::VSMMU set.
A VSMMU is unbound from a VDEV by execution of RMI_VDEV_DESTROY.
Mappings from Realm Protected IPA space to a VSMMU object are created by execution of RMI_VSMMU_MAP. This command only permits such mappings to be created within the register IPA range specified on creation of the VSMMU object. This causes the HIPAS to change from UNASSIGNED to ASSIGNED_VSMMU.
Mappings from Realm Protected IPA space to a VSMMU object are removed by execution of RMI_VSMMU_UNMAP.
See also:
9.6.2 VSMMU attributes
The attributes of a VSMMU are summarized in the following table.
The Host provides the VSMMU register IPA range when executing RMI_VSMMU_CREATE.
The Host provides the VSMMU AIDR and IDR values when executing RMI_VSMMU_CREATE.
See also:
- Section 15.3.5857
9.6.3 VSMMU liveness
VSMMU liveness is a property which means that there exists one or more mappings from Realm Protected IPA space to the VSMMU object.
If a VSMMU is live, it cannot be destroyed.
9.6.4 VSMMU validation
The Realm queries whether an IPA is the base address of a VSMMU by execution of RSI_VSMMU_GET_INFO.
The Realm activates the register interface of a VSMMU by execution of RSI_VSMMU_ACTIVATE. This causes the RIPAS of the IPA range to change from EMPTY to DEV.
The attributes of a VSMMU are guaranteed not to change between execution of RSI_VSMMU_GET_INFO and RSI_VSMMU_ACTIVATE.
The programming model for validating and activating a VSMMU is shown in the following pseudocode:
int realm_validate_vsmmu(unsigned long base, unsigned long top)
{
unsigned long new_base, response;
int ret = RSI_SUCCESS;
// Check whether "base" identifies a VSMMU
ret = rsi_vsmmu_get_info(base);
if (ret != RSI_SUCCESS) {
return ret;
}
// Activate the VSMMU register interface
while (base != top) {
ret = rsi_vsmmu_activate(base, top, &new_base);
if (ret != RSI_SUCCESS) {
return ret;
}
base = new_base;
}
return RSI_SUCCESS;
}
9.6.5 PSMMU interrupts
For a PSMMU with MSI, configuration is provided by execution of RMI_PSMMU_MSI_CONFIG.
For a PSMMU if wired interrupts are supported, no configuration is required from the RMM side. It is assumed that the RMM implementation will initialise SMMU_*IRQ_CFG0 registers to 0 to allow wired interrupts
On taking a physical SMMU interrupt, the Host notifies the RMM by execution of RMI_PSMMU_IRQ_NOTIFY. In response, the RMM may request the Host to inject a given virtual MSI into a specified Realm.
9.7 Device access to a Protected IPA
Device access to a Protected IPA follows the same rules as Realm data access to a Protected IPA.
See also:
- Section 5.2.3
10 Planes
This section describes how a Realm can be divided into multiple mutually isolated execution environments, called Planes.
Decide whether this section should be:
- Moved to the Concepts chapter, alongside the Realm section.
- Left in this position, on the grounds that, like Realm device assignment, Planes is an optional feature.
10.1 Planes overview
The following aspects and implications of Planes will be described in a future release of this specification:
- Access from Pn to a device assigned to the Realm
A Realm contains:
- a single primary Plane
- zero or more auxiliary Planes.
A Realm with a non-zero number of auxiliary Planes is said to contain multiple Planes.
The number of auxiliary Planes is specified by the Host at Realm creation.
Planes within a Realm are identified using a zero-based Plane index.
The Plane index of the primary Plane is zero.
When referring to the primary Plane of a Realm, this specification uses the term Plane 0, or P0.
When referring to any auxiliary Plane, this specification uses the term Pn.
All Planes within a Realm share a single IPA space.
Stage 2 memory access permissions for a given IPA can differ between Planes.
Each Plane has a VMID which is unique both within the owning Realm and among all Realms.
A Realm with multiple Planes may either have:
- An RTT tree per Plane, or
- A single RTT tree, with per-Plane access permissions being managed indirectly.
On REC exit due to Data Abort or Instruction Abort, Instruction Abort or the index of the RTT request, the index of the RTT tree used by the exited Plane is provided to the Host.
This allows the Host to know which RTT tree must be modified in order to service a fault.
A given VPE executes in one Plane at a time.
This is referred to as the active Plane of the VPE.
The following capabilities are available only to P0:
- Change the active Plane of the current VPE
- Read and write register state of other Planes in the current VPE
- Configure and take traps from other Planes in the current VPE
- Control delivery of virtual interrupts to other Planes in the current VPE
10.2 Planes exception model
Decide whether this section should be integrated into the main Realm exception model chapter.
10.2.1 Plane exception model overview
A Plane entry is a transition from P0 to Pn, due to execution of RSI_PLANE_ENTER.
P0 provides the index of the target Plane (Pn) as an input to the RSI_PLANE_ENTER command.
A Plane exit is return to P0 from an execution of RSI_PLANE_ENTER which caused a Plane entry.
A PlaneRun object is a data structure used to pass values between the RMM and P0 on Plane entry and on Plane exit.
A PlaneRun object is stored in Realm memory.
Between a Plane entry and a Plane exit, a REC exit and REC entry may occur.
As an example:
Running in REC A, P0 executes RSI_PLANE_ENTER, passing target Plane index 1.
This causes a Realm exit to the RMM, followed by a Realm entry to P1, within REC A.
Running in REC A, P1 accesses an IPA which is not mapped (HIPAS = UNASSIGNED, RIPAS = RAM).
This causes a REC exit to the Host.
The Host executes RMI_REC_ENTER, passing the address of REC A.
This causes the RMM to return to P1 within REC A.
Running in REC A, P1 accesses an IPA whose RIPAS is EMPTY.
This causes a Plane exit to P0.
Following a REC exit from P0, on the next entry to the same REC, control returns to P0.
Following a REC exit from Pn, on the next entry to the same REC, the Host determines whether:
Control returns to Pn. This is the default behaviour.
A Plane exit occurs, returning control to P0. This can be triggered for example due to the Host injecting a virtual interrupt into the REC.
10.2.2 Plane entry
An RsiPlaneEnter object is a data structure used to pass values from P0 to the RMM on Plane entry.
An RsiPlaneEnter object is stored in the RsiPlaneRun object which is passed by P0 as an input to the RSI_PLANE_ENTER command.
In this chapter, both plane_enter and “the RsiPlaneEnter
object” refer to the RsiPlaneEnter object which is provided to the
RSI_PLANE_ENTER command.
On Plane entry, execution state is restored from the RsiPlaneEnter object to the PE.
An RsiPlaneEnter object contains attributes which are used to manage Pn virtual interrupts.
The attributes of an RsiPlaneEnter object are summarized in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| flags | 0x0 |
RsiPlaneEnterFlags | Flags |
| pc | 0x8 |
Bits64 | Program counter |
| gprs[31] | 0x100 |
Bits64 | Registers |
| gicv3_hcr | 0x200 |
Bits64 | GICv3 Hypervisor Control Register value |
| gicv3_lrs[16] | 0x208 |
Bits64 | GICv3 List Register values |
10.2.3 Plane exit
An RsiPlaneExit object is a data structure used to pass values from the RMM to P0 on Plane exit.
An RsiPlaneExit object is stored in the RsiPlaneRun object which is passed by P0 as an input to the RSI_PLANE_ENTER command.
In this chapter, both plane_exit and “the RsiPlaneExit
object” refer to the RsiPlaneExit object which is provided to the
RSI_PLANE_ENTER command.
On Plane exit, execution state is saved from the PE to the RsiPlaneExit object.
The attributes of an RsiPlaneExit object are summarized in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| reason | 0x0 |
RsiPlaneExitReason | Exit reason |
| elr_el2 | 0x100 |
Bits64 | Exception Link Register |
| esr_el2 | 0x108 |
Bits64 | Exception Syndrome Register |
| far_el2 | 0x110 |
Bits64 | Fault Address Register |
| hpfar_el2 | 0x118 |
Bits64 | Hypervisor IPA Fault Address register |
| gprs[31] | 0x200 |
Bits64 | Registers |
| gicv3_hcr | 0x300 |
Bits64 | GICv3 Hypervisor Control Register value |
| gicv3_lrs[16] | 0x308 |
Bits64 | GICv3 List Register values |
| gicv3_misr | 0x388 |
Bits64 | GICv3 Maintenance Interrupt State Register value |
| gicv3_vmcr | 0x390 |
Bits64 | GICv3 Virtual Machine Control Register value |
| cntp_ctl | 0x400 |
Bits64 | Counter-timer Physical Timer Control Register value |
| cntp_cval | 0x408 |
Bits64 | Counter-timer Physical Timer CompareValue Register value |
| cntv_ctl | 0x410 |
Bits64 | Counter-timer Virtual Timer Control Register value |
| cntv_cval | 0x418 |
Bits64 | Counter-timer Virtual Timer CompareValue Register value |
RsiPlaneExit uses architectural encodings (of ESR, FAR, HPFAR) which are normally observable only to EL2; however, the exit is taken to P0 at EL1. This is justified on the grounds that P0 exists essentially in order to allow part of the job of the hypervisor to be performed inside the Realm.
On Plane exit, all RsiPlaneExit fields are zero unless specified otherwise.
10.2.3.1 Plane exit due to synchronous exception
An exception due to any of the following in Pn causes a Plane exit due to Synchronous Exception:
Trapped WF* instruction execution
Data Abort at a Protected IPA
- Permission fault
- Access to an IPA whose RIPAS is EMPTY
Instruction Abort at a Protected IPA
- Permission fault
- Access to an IPA whose RIPAS is EMPTY
HVC instruction execution
RSI_HOST_CALL execution, if
plane_enter.flags.trap_hc == RSI_TRAPAny other SMC instruction execution
On Plane exit due to Synchronous Exception, all of the following are true:
plane_exit.exit_reasonis RSI_EXIT_SYNC.plane_exit.esr_el2contains the value ofESR_EL2at the time of the Realm exit.- If
plane_exit.esr_el2.ECindicates Data Abort from a lower Exception level and
plane_exit.esr_el2.ISV == 1thenplane_exit.far_el2contains the value ofFAR_EL2at the time of the Realm exit. - If
plane_exit.esr_el2.ECindicates Data Abort from a lower Exception level or Instruction Abort from a lower Exception level,plane_exit.hpfar_el2contains the value ofHPFAR_EL2at the time of the Realm exit.
See also:
- Section 4.3.9
10.2.4 REC exit from Pn
An exception due to any of the following in Pn cause a REC exit to the Host:
- The following Synchronous Exceptions:
- Access to an IPA whose RIPAS is DESTROYED
- Access to an IPA whose HIPAS is UNASSIGNED and whose RIPAS is not EMPTY
- Synchronous External Abort
- The following Asynchronous Exceptions:
- IRQ
- FIQ
- SError
- RSI_HOST_CALL execution, if
plane_enter.flags.trap_hc == RSI_NO_TRAP. In this case, the result is a REC exit due to Host call.
Any other exception during execution of Pn causes a Plane exit to P0.
10.2.5 Pn execution of HVC and SMC
On Plane exit due to execution by Pn of an HVC instruction, possible actions taken by P0 include the following:
- Emulate the instruction
- Forward the request to the Host using RSI_HOST_CALL
- Return SMCCC_NOT_SUPPORTED to Pn.
On Plane exit due to execution by Pn of an RSI command, possible actions taken by P0 include the following:
- Emulate the RSI command
- Return SMCCC_NOT_SUPPORTED to Pn.
10.2.6 Pn system registers
On Realm creation, all Pn EL0 and EL1 system register values take architecturally-defined reset values.
P0 can access Pn EL0 and EL1 system register values using the RSI_PLANE_REG_READ and RSI_PLANE_REG_WRITE commands.
10.3 Planes memory management
Decide whether this section should be integrated into the main Realm memory management chapter.
All Planes within a Realm have the same IPA size.
If a given IPA x is mapped to a given PA y in one Plane, x is not mapped to a different PA z in any other Plane within the Realm.
10.3.1 Auxiliary RTT
A Realm which is configured to have an RTT tree per Plane has one primary RTT tree and (number of auxiliary Planes) auxiliary RTT trees.
For a Realm which is configured to have an RTT tree per Plane, RTT trees are identified using a zero-based RTT tree index.
The RTT tree index of the primary RTT tree is zero.
For a Realm which is configured to have an RTT tree per Plane, the mapping from Plane index to RTT tree index is as follows:
| Plane index | RTT tree index |
|---|---|
| 0 | 1 |
| 1 | 2 |
| … | … |
| n-2 | n-1 |
| n-1 | 0 |
For a Realm with no auxiliary Planes, n == 1 and
therefore the index of the single Plane (0) maps to the index of the
single RTT tree (0).
Creation, destruction and folding of primary RTTs is independent of creation, destruction and folding of auxiliary RTTs for the same IPA range.
If a primary RTT entry is live and its state is not TABLE then the Host can create a mapping to the same output address in an auxiliary RTT by executing RMI_RTT_AUX_MAP_PROTECTED or RMI_RTT_AUX_MAP_UNPROTECTED.
An IPA is auxiliary-live if any of the entries identified by that IPA in auxiliary RTTs are live.
In a Realm which is configured to have an RTT tree per Plane, a given Unprotected IPA may be mapped to different output addresses in different Planes.
The absence of a rule which states that a given Unprotected IPA must map to the same output address in different Planes avoids the need for the RMM to manage reference counts for NS Granules.
If a Protected IPA is auxiliary-live then the corresponding entry in the primary RTT is live.
This invariant is preserved by blocking any actions which would make the primary RTT entry non-live, including the following:
- RMI_DATA_DESTROY
- RMI_DEV_MEM_UNMAP
- RMI_RTT_SET_RIPAS
If an IPA is auxiliary-live then its RIPAS cannot be changed.
Specifying that RIPAS is invariant while an IPA is auxiliary-live avoids an implementation of RMI_RTT_SET_RIPAS or RMI_RTT_DEV_MEM_VALIDATE having to walk multiple auxiliary RTT trees.
See also:
10.3.2 Stage 2 Access Permissions within a multi-Plane Realm
This section describes how S2AP is controlled within a multi-Plane Realm.
10.3.3 Stage 2 Access Permissions within a multi-Plane Realm overview
The S2AP which applies to an access from Pn to a Protected IPA is controlled by P0.
The S2AP which applies to an access from Pn to a Protected IPA can be different for each Pn within the Realm.
An access by Pn to a Protected IPA which violates S2AP causes a Plane exit taken to P0.
The S2AP which applies to a Realm access to an Unprotected IPA is the same for all Planes within the Realm.
A data access by Pn to an Unprotected IPA which violates S2AP causes a REC exit taken to the Host.
An instruction fetch by Pn to an Unprotected IPA causes a Plane exit taken to P0.
On a platform which implements FEAT_S2PIE and FEAT_S2POE, the RMM can utilise these architecture features to store per-Plane S2AP in a single RTT tree.
On a platform which does not implement these architecture features, a separate RTT tree is required for each Plane.
See also:
- Section 5.56.11
10.3.3.1 Stage 2 Access Permissions for a Protected IPA within a multi-Plane Realm
The S2AP overlay index of a Protected IPA is between 0 and 14.
S2AP overlay index 15 is RESERVED.
At Realm activation, S2AP overlay indices 0 to 14 map to S2AP overlay value RW+puX for P0.
At Realm activation, S2AP overlay indices 0 to 14 map to S2AP overlay value NoAccess for all Planes other than P0.
For each S2AP overlay index there is an associated lock bit which applies to S2AP overlay values for Planes other than P0.
- If the lock bit is LOCKED then the S2AP overlay values for all Planes are immutable.
- If the lock bit is UNLOCKED then the S2AP overlay values for Planes other than P0 can be changed by P0.
At Realm activation, S2AP overlay index 0 is LOCKED.
At Realm activation, S2AP overlay indices 1 to 14 are UNLOCKED.
At Realm activation, the S2AP overlay index of all Protected IPAs is 0.
The following table summarises the attributes of all S2AP overlay indices for Protected IPA space, at Realm activation.
| S2AP overlay index | P0 S2AP overlay value | Pn S2AP overlay values | Lock status for Pn S2AP overlay values |
|---|---|---|---|
| 0 | RW+puX | NoAccess | LOCKED |
| 1 to 14 | RW+puX | NoAccess | UNLOCKED |
The RSI_MEM_SET_PERM_INDEX command can be used by P0 to change the S2AP overlay index for a Protected IPA.
The RSI_MEM_SET_PERM_VALUE command can be used by P0 to change the mapping from a { Plane, S2AP overlay index } tuple to an S2AP overlay value.
10.3.3.2 Stage 2 Access Permissions change within a multi-Plane Realm
An S2AP change is a process via which the S2AP of a region of Protected IPA space is changed.
An S2AP change consists of actions taken both by P0 within the Realm and by the Host:
- P0 issues an S2AP change request by executing
RSI_MEM_SET_PERM_INDEX.
- The input values to this command include:
- The requested IPA range:
[base, top) - The requested S2AP overlay index
- A “cookie”, whose initial value is zero. Across successive calls to RSI_MEM_SET_PERM_INDEX, the cookie is used by the RMM to store an implementation defined value which tracks progress of the request.
- The requested IPA range:
- The RMM records these values in the REC, and then performs a REC exit due to S2AP change pending.
- The input values to this command include:
- In response, the Host executes zero or more RMI_RTT_SET_S2AP commands.
- If the requested RIPAS value was not EMPTY then at the next RMI_REC_ENTER the Host can optionally indicate that it rejects the S2AP change request.
The purpose of the cookie is to record the progress of the S2AP change request across multiple RTT trees. For a Realm which is configured to use a shared RTT tree, the RMM should return a cookie value of zero.
Rejection by the Host of an S2AP change request is intended to be used if the target IPA range extends beyond the agreed DRAM range for the Realm. In this situation, accepting the request may impose unplanned resource costs on the Host, by requiring allocation of additional RTTs.
The S2AP change process ensures that a Realm can always reliably determine the maximum S2AP which can be observed at the next access to any Protected IPA.
An S2AP change is applied by one or more calls to the RMI_RTT_SET_S2AP command.
The order in which the S2AP of Planes and pages within the target IPA range are changed during execution of RSI_MEM_SET_PERM_INDEX is implementation defined.
If the input arguments of RSI_MEM_SET_PERM_INDEX are modified by the caller during the loop, it is implementation defined whether the S2AP of Planes and pages within the target IPA range are changed.
The P0 programming model for changing S2AP is to call RSI_MEM_SET_PERM_INDEX in a loop until progress reaches the top of the target IPA range, as shown in the following pseudocode:
int realm_set_s2ap(unsigned long base, unsigned long top,
unsigned int index)
{
unsigned long new_base, response;
unsigned long cookie = 0, new_cookie;
int ret = RSI_SUCCESS;
while (base != top) {
ret = rsi_mem_set_perm_index(base, top, index, cookie,
&new_base, &response,
&new_cookie);
if (ret != RSI_SUCCESS) {
return ret;
}
if (response == RSI_REJECT) {
return RSI_ERROR_INPUT;
}
base = new_base;
cookie = new_cookie;
}
return RSI_SUCCESS;
}
The Host programming model for handling an S2AP change request is to call RMI_RTT_SET_S2AP in a loop until progress reaches the top of the target IPA range, as shown in the following pseudocode:
int host_set_s2ap(unsigned long base, unsigned long top)
{
unsigned long out_top, index, rtt_tree;
int ret = RMI_SUCCESS;
while (base != top) {
ret = rmi_rtt_set_s2ap(rd, rec, base, top,
&out_top, &rtt_tree, &index);
if (ret == RMI_ERROR_RTT || ret == RMI_ERROR_AUX_RTT) {
create_rtt(ipa = out_top, level = index + 1, rtt_tree);
continue;
} else if (ret != RMI_SUCCESS) {
break;
}
base = out_top;
}
return ret;
}
On REC entry following a REC exit due to S2AP change,
rec.s2ap_response is set to the value of
enter.flags.s2ap_response.
If all of the following are true then the output value of RSI_MEM_SET_PERM_INDEX indicates “Host rejected the request”:
rec.s2ap_addris not equal torec.s2ap_top.rec.s2ap_responseis REJECT.
Otherwise, the output value of RSI_MEM_SET_PERM_INDEX indicates “Host accepted the request”.
See also:
10.3.3.3 Stage 2 Access Permissions reset due to Host action
Execution of RMI_RTT_DESTROY or RMI_RTT_AUX_DESTROY sets the S2AP overlay index of the target RTTE to 0.
The Host is permitted at any time to destroy an RTT. Destruction of an RTT causes the RMM to lose information about the S2AP for the IPA range described by that RTT. The S2AP are observable by the Realm only while the RIPAS is RAM. Therefore, this specification defines the value to which the S2AP overlay index must be reset on a RIPAS transition to RAM.
See also:
- Section 5.4
10.4 Planes interrupts
Decide whether this section should be integrated into the main Realm interrupts section.
On REC creation, the GIC owner for the REC is P0.
On Plane entry, P0 can transfer GIC ownership to the target Pn.
On Plane entry, if P0 transfer GIC ownership to the target Pn then the GIC state in RsiPlaneEnter is ignored. This means that the GIC state of the owner is preserved and is shared across GIC ownership changes between planes.
Allowing P0 to control which Plane is the GIC owner supports software usage models including the following:
P0 is the GIC owner, and P0 emulates a vGIC for Pn, similar to how the Host emulates a vGIC for the Realm.
P0 is a lightweight “Pn switcher”, which does not emulate a vGIC. GIC ownership is transferred to the Pn which contains the main Realm guest OS.
P0 can read the value of ICH_VTR_EL2 using the RSI_REALM_CONFIG command.
On Plane exit, P0 is the GIC owner. If GIC ownership was transferred to Pn on Plane entry, it returns to P0 on Plane exit.
On Plane exit, Pn’s GIC state is exposed to P0 via the RsiPlaneExit object.
On REC entry the GIC state provided by the Host is assigned to the GIC owner.
On REC entry, if the values of enter.gicv3_lrs describe
one or more Pending interrupts and the most recent REC exit was from a
Plane which is not the GIC owner then control returns to P0. This
results in a Plane exit due to synchronous exception.
On REC entry, if all of the following is true then control returns to P0, resulting in a Plane exit due to synchronous exception:
- The most recent REC exit was from Pn
- The most recent REC exit was not from the GIC owner
- The value of
ICH_MISR_EL2at the time of the REC exit was not zero.
On REC exit, the Realm GIC state of the GIC owner Plane is reported to the Host.
10.5 Planes timers
Decide whether this section should be integrated into the main Realm timers section.
On REC exit from P0, the Realm EL1 timer state reported to the Host is P0’s EL1 timer state.
A Realm EL1 timer is active if it is enabled and unmasked.
On REC exit from Pn, for each of the EL1 virtual and physical timers, if any of the following is true then the timer state reported to the Host is Pn’s EL1 timer state:
- The Pn timer is active and the P0 timer is not active.
- Both Pn and P0 timers are active and the Pn timer deadline is earlier than the P0 timer deadline.
Otherwise, the timer state reported to the Host is P0’s EL1 timer state.
The following table summarises the timer state which is reported to the Host on REC exit.
| P0 active | Pn active | Earliest CVAL | Reported to Host |
|---|---|---|---|
| 0 | 0 | P0 | P0 |
| 0 | 0 | Pn | P0 |
| 0 | 1 | P0 | Pn |
| 0 | 1 | Pn | Pn |
| 1 | 0 | P0 | P0 |
| 1 | 0 | Pn | P0 |
| 1 | 1 | P0 | P0 |
| 1 | 1 | Pn | Pn |
On Plane exit, Pn’s EL1 timer state is exposed to P0 via the RsiPlaneExit object.
P0 software should check the Realm EL1 timer state on every return
from RSI_PLANE_ENTER and update virtual interrupt state accordingly.
This is true regardless of the value of exit.exit_reason:
even if the return occurred for a reason unrelated to timers (for
example, a Plane exit due to Data Abort), the Realm EL1 timer state
should be checked.
On Plane entry, the RMM may mask the hardware timer signal, following the same logic as for REC entry.
Management of EL1 timer state for a Realm with multiple Planes can be implemented by multiplexing the following into the EL2 hardware timers:
- P0’s EL1 timers
- The Host’s EL2 timers
11 Realm memory encryption
This section describes encryption of physical memory which is accessible via Realm PAS. This encryption is transparent to Realm software, but has an impact on the security posture of a Realm.
A Memory Encryption Context (MEC) is an encryption regime used to protect the memory owned by a Realm.
The memory protected by a Realm’s MEC includes all memory which can be accessed by the Realm, and the RTTs which are owned by the Realm.
Other Granules owned by the Realm, such as REC and RD, are protected with the RMM’s MEC.
A Memory Encryption Context Identifier (MECID) is a handle which is used to identify a MEC.
The highest MECID value which the Host is permitted to pass via an RMI command is reported by the RMI_FEATURES command in RmiFeatureRegister1::MAX_MECID.
A valid MECID is a MECID in the range
[0, MAX_MECID].
On a platform which does not implement FEAT_MEC, MAX_MECID is zero.
On a platform which implements FEAT_MEC, MAX_MECID is expected to be computed as follows:
- Determine the minimum MECID width supported across all system components capable of initiating Realm PAS transactions.
- Determine the number of MECIDs which the platform needs to reserve for its own use. This is expected to be at least one, for protection of the RMM’s memory.
- Return
MAX_MECID = (2 ^ MECID_WIDTH) - (NUM_RESERVED_MECIDS + 1)
A MEC has a MEC policystate.
The MEC policystate values are shown in the following table.
| Name | Description |
|---|---|
| MEC_POLICY_PRIVATEMEC_STATE_PRIVATE_ASSIGNED | TheA Private MEC protects memory owned by a singlewhich is assigned to a Realm. A |
| MEC_STATE_PRIVATE_UNASSIGNED | A Private MEC with this policy may be referred to as a Private MECwhich is not assigned to a Realm. |
| MEC_POLICY_SHAREDMEC_STATE_SHARED | TheA Shared MEC protects memory owned by multiple Realms. A MEC with this policy may be referred to as a Shared MEC. |
If MAX_MECID is zero then at platform boot, the state of MEC zero is MEC_STATE_SHARED.
If MAX_MECID is not zero then at platform boot, the state of every
MEC in the range [0, MAX_MECID] is
MEC_STATE_PRIVATE_UNASSIGNED.
A Shared MEC has a MEC state. The MEC state values are shown in the following table. Name Description MEC_STATE_PRIVATE_ASSIGNED A Private MEC which is assigned to a Realm. MEC_STATE_PRIVATE_UNASSIGNED A Private MEC which is not assigned to a Realm. MEC_STATE_SHARED A Shared MEC. D A Shared MEC has a set of zero or more member Realms.
At platform boot, theThe input values of RMI_REALM_CREATE include a MECID.
RMI_REALM_CREATE fails if any of the following is true:
- The MECID is not valid.
- The state of the MEC zero isis MEC_STATE_PRIVATE_ASSIGNED.
On successful execution of RMI_REALM_CREATE:
- If the state of the MEC is MEC_STATE_PRIVATE_UNASSIGNED then the state becomes MEC_STATE_PRIVATE_ASSIGNED.
- If the state of the MEC is MEC_STATE_SHARED then the new Realm is added to the Shared MEC.
The RMI_MEC_SET_SHARED command changes the state of a MEC from MEC_STATE_PRIVATE_UNASSIGNED to MEC_STATE_SHARED.
At platform boot, theExecution of RMI_MEC_SET_SHARED fails if any of the following is true:
- The MECID provided by the Host is not valid.
- The MECID provided by the Host identifies a MEC whose current state of every is not MEC_STATE_PRIVATE_UNASSIGNED.
- Any valid MECID identifies a Shared MEC in the range [1, MAX_MECID] is. This means that there can be at most a single Shared MEC in existence at a time.
The RMI_MEC_SET_PRIVATE command changes the state of a MEC from MEC_STATE_SHARED to MEC_STATE_PRIVATE_UNASSIGNED.
The input values of RMI_REALM_CREATE include aExecution of RMI_MEC_SET_PRIVATE fails if any of the following is true:
- MAX_MECID is zero.
- The MECID provided by the Host is not valid.
- The MECID provided by the Host identifies a MEC whose current state is not MEC_STATE_SHARED.
- The MECID provided by the Host identifies a Shared MEC which contains a non-zero number of Realms.
RMI_REALM_CREATE fails if any of the following is true:On a platform which reports MAX_MECID to be zero, all Realms use the Shared MEC identified by MECID zero.
The MECID is not valid. The state of the MEC is MEC_STATE_PRIVATE_ASSIGNED.On successful execution of RMI_REALM_CREATE: If the state of the MEC is MEC_STATE_PRIVATE_UNASSIGNED then the state becomes MEC_STATE_PRIVATE_ASSIGNED. If the state of the MEC is MEC_STATE_SHARED then the new Realm is added to the Shared MEC. I The RMI_MEC_SET_SHARED command changes the state of a MEC from MEC_STATE_PRIVATE_UNASSIGNED to MEC_STATE_SHARED. I Execution of RMI_MEC_SET_SHARED fails if any of the following is true: The MECID provided by the Host is not valid. The MECID provided by the Host identifies a MEC whose current state is not MEC_STATE_PRIVATE_UNASSIGNED. Any valid MECID identifies a Shared MEC. This means that there can be at most a single Shared MEC in existence at a time. I The RMI_MEC_SET_PRIVATE command changes the state of a MEC from MEC_STATE_SHARED to MEC_STATE_PRIVATE_UNASSIGNED. I Execution of RMI_MEC_SET_PRIVATE fails if any of the following is true: a platform which reports MAX_MECID is zero. The MECID provided by the Host is not valid. The MECID provided by the Host identifies a MEC whose current state is not MEC_STATE_SHARED. The MECID provided by the Host identifies a Shared MEC which contains a non-zero number of Realms. I On a platform which reports MAX_MECID to be zero, all Realms use the Shared MEC identified by MECID zero. I On a platform which reports MAX_MECID to be non-zero, the Host can choose between the following approaches:
- Use the Shared MEC for all Realms.
- Assign a Private MEC to each Realm, with the total number of Realms not exceeding MAX_MECID.
- Use the Shared MEC for some Realms; for the remaining Realms, assign a Private MEC to each, with the total number of this latter set of Realms not exceeding MAX_MECID.
The Realm attestation token includes a claim which describes the MEC policy of the Realm. The MEC policy is derived from the MEC state as follows:
- If the MEC state is MEC_STATE_PRIVATE_ASSIGNED then the MEC policy is MEC_POLICY_PRIVATE.
- If the MEC state is MEC_STATE_SHARED then the MEC policy is MEC_POLICY_SHARED.
TheOn platform boot, the encryption context associated with every MEC policy of a Realm is reflected in the Realm attestation token changes.
On platform bootWhen the state of a MEC changes, the encryption context associated with every with that MEC changes.
When the state of a MEC changes, theTo illustrate the points at which encryption context associated with that MEC changes. I To illustrate the points at which encryption contexts must change, consider the following sequence:
| Step | Reason for encryption context change |
|---|---|
| Platform boot | Platform boot |
| RMI_REALM_CREATE(rd=a, mecid=0) | |
| RMI_REALM_DESTROY(rd_a) | MEC_STATE_PRIVATE_ASSIGNED to MEC_STATE_PRIVATE_UNASSIGNED |
| RMI_REALM_CREATE(rd=b, mecid=01) | |
| RMI_REALM_DESTROY(rd_b) | MEC_STATE_PRIVATE_ASSIGNED to MEC_STATE_PRIVATE_UNASSIGNED |
| RMI_MEC_SET_SHARED(mecid=0) | |
| RMI_REALM_CREATE(rd=c, mecid=0) | |
| RMI_REALM_CREATE(rd=d, mecid=0) | |
| RMI_REALM_DESTROY(rd_d) | |
| RMI_REALM_DESTROY(rd_c) | |
| RMI_MEC_SET_PRIVATE(mecid=0) | MEC_STATE_SHARED to MEC_STATE_PRIVATE_UNASSIGNED |
| RMI_REALM_CREATE(rd=ce, mecid=0) | MEC_STATE_PRIVATE_UNASSIGNED to MEC_STATE_PRIVATE_ASSIGNED |
See also:
12 Commands
This chapter describes how RMM commands are defined in this specification.
12.1 Overview
The RMM exposes the following interfaces to the Host:
- The Realm Management Interface (RMI)
The RMM exposes the following interfaces to a Realm:
- The Realm Services Interface (RSI)
- The Power State Coordination Interface (PSCI)
Any other SMC executed by a Realm returns SMCCC_NOT_SUPPORTED.
An RMM interface consists of a set of RMM commands.
An RMM interface is compliant with the SMC Calling Convention (SMCCC).
SMCCC version >= 1.2 is required.
SMCCC version 1.2 increases the number of SMC64 arguments and return values from 4 to 17. Some RMM commands use more than 4 input or output values.
On a CCA platform which implements FEAT_SVE, SMCCC version >= 1.3 is required.
SMCCC version 1.3 introduces a bit in the FID which a caller can use to indicate that SVE state does not need to be preserved across the SMC call.
On a CCA platform which implements FEAT_SME, SMCCC version >= 1.4 is required.
SMCCC version 1.4 adds support for preservation of SME state across an SMC call.
An RMM command uses the SMC64 calling convention.
To determine whether an RMM interface is implemented, software should use the following flow:
Determine whether the SMCCC_VERSION command is implemented, following the procedure described in Arm SMC Calling Convention [17].
Check that the SMCCC version is >= 1.1.
Execute the <Interface>.Version command, which returns:
- SMCCC_NOT_SUPPORTED (-1) if <Interface> is not implemented.
- A version number (>0) if <Interface> is implemented.
All data types defined in this specification are little-endian.
12.2 Command definition
The definition of an RMM command consists of:
- A function identifier (FID)
- A set of input values (referred to as “arguments” in SMCCC)
- A set of output values (referred to as “results” in SMCCC)
- A set of context values
- A partially-ordered set of failure conditions
- A set of success conditions
- A set of footprint items
Each failure condition, success condition and footprint item has an associated identifier. Identifiers are unique within each of the above groups, within each command.
An identifier has no meaning. It is only a label by which a given condition or footprint item can be referred to.
On calling an RMI or RSI command, any of X1 - X16 which are not specified as input values in the command definition SBZ.
On return from an RMI or RSI command, any of X0 - X16 which are not specified as output values in the command definition MBZ.
See also:
12.2.1 Example command
The following command, EXAMPLE_ADD, is an example of how the components of an RMM command definition are presented in this document.
This command takes as an input value the address
params_ptr of an NS Granule which contains two integer
values x and y. On successful execution of the
command:
- The output value
sumcontains the sum ofxandy - The output value
zeroindicates whether either ofxoryis zero
EXAMPLE_ADD is defined as follows:
Interface
FID
0x042
Input values
| Name | Register | Field | Type | Description |
|---|---|---|---|---|
fid |
X0 |
[63:0] | UInt64 | Command FID |
params_ptr |
X1 |
[63:0] | Address | PA of parameters |
Context
The EXAMPLE_ADD command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
params |
ExampleParams | Params(params_ptr) |
false | Parameters |
Output values
| Name | Register | Field | Type | Description |
|---|---|---|---|---|
result |
X0 |
[15:0] | CommandReturnCode | Command return status |
sum |
X1 |
[63:0] | UInt64 | Sum of x and y |
zero |
X2 |
[63:0] | UInt64 | Whether either x or y was zero |
Failure conditions
| ID | Condition |
|---|---|
params_align |
|
params_gpt |
|
Success conditions
| ID | Post-condition |
|---|---|
sum |
|
zero |
|
12.3 Command registers
An FID is a value which identifies a particular RMM command.
The FID of an RMM command is unique among the RMM commands in an RMM interface.
An FID is read from general-purpose register X0.
An input value is a value read by an RMM command from general-purpose registers.
An output value is a value written by an RMM command to general-purpose registers.
A command return code is a value which specifies whether an RMM command succeeded or failed.
A command return code is written to general-purpose register X0.
12.4 Command condition expressions
A condition expression is an expression which evaluates to a boolean value.
Following expansion of macros, a condition expression is a valid expression in Arm Specification Language (ASL).
See also:
12.5 Command context values
A context value is a value which is derived from the value of a command input register or command output register and which is used by a command condition expression.
A context value can be thought of as a local variable for use by command condition expressions.
For example, consider the following example command condition expression:
!AddrIsGranuleAligned(RealmParams(params_ptr).rtt_base)
By introducing a context value params with the value
RealmParams(params_ptr), this command condition expression
can be re-written as:
!AddrIsGranuleAligned(params.rtt_base)
The before property of a context value indicates whether
its expression is re-evaluated after the command has executed.
before = true: the expression is not re-evaluated after the command has executedbefore = false: the expression is re-evaluated after the command has executed
Specifying before = true for a context value allows
system state to be sampled before command execution, and then used after
command execution in a command success condition.
For example, the RMI_REALM_DESTROY command takes as an input value
the address rd of a Realm Descriptor. Successful execution
of the command results observable effects including the following:
- The state of the RD Granule changes from RD to DELEGATED
- The state of the RTT base Granule, whose address was previously held in the RD, changes from RTT to DELEGATED
The address of the RTT base Granule is not included in the input values of the command.
A context value is defined as follows:
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
rtt_base |
Address | Realm(rd).rtt_base |
true | RTT base address |
The state change of the RTT Granule can then be expressed as:
Granule(rtt_base).state == DELEGATED
The before property of a context value has no effect if the value is only used in command failure conditions.
An in-memory value is a value passed to a command via an in-memory data structure, the address of which is passed in an input register.
An in-memory value is a context value.
See also:
- Section 15.3.2725
12.6 Command failure conditions
An RMM command failure condition defines a way in which the command can fail.
A failure condition consists of a pre-condition and a post-condition.
A failure pre-condition can be thought of as the “trigger” of the failure: if the pre-condition is true then the command fails.
A failure post-condition can be thought of as the “effect” of the failure: if the command failed due to a particular trigger, then the post-condition defines the error code which is returned.
A failure pre-condition is a condition expression whose terms can include input values and context values.
A failure post-condition is a condition expression whose terms can include input values and context values.
Observability of the checking of command failure conditions is subject to a partial order.
An ordering relation “A precedes B” means either of the following:
The pre-condition of B is well-formed only if the pre-condition of A is false. This is referred to as a well-formedness ordering.
If the pre-conditions of A and B are both true, then the post-condition of A is observed. This is referred to as a behavioral ordering.
The absence of an ordering relation “A precedes B” means that, if the pre-conditions of A and B are both true then either the post-condition of A is observed or the post-condition of B is observed.
Orderings are specified between groups of failure conditions. For
example, the expression [A, B] < [C, D] means that both
conditions A and B precede both conditions C and D.
The same information is also presented graphically, with failure conditions represented as nodes and ordering relations represented as edges.
The specification does not state whether an individual ordering relation is a well-formedness ordering or a behavioral ordering.
A given implementation of the RMM is expected to have deterministic behavior. That is, for a runtime instance of the RMM in a particular state, two executions of a command without an interleaving of other commands, with the same input values, results in the same outcome (either success, or the same failure condition.)
If a failure pre-condition evaluates to true then the corresponding failure post-condition evaluates to true.
If a failure pre-condition evaluates to true then the command is aborted.
If a command fails then all output values except for X0 are undefined, unless stated otherwise.
If no failure pre-condition evaluates to true then the command succeeds.
12.7 Command success conditions
An RMM command success condition defines an observable effect of a successful execution of the command.
A success condition is a condition expression whose terms can include input values, context values and output values.
The order in which success conditions are listed has no architectural significance.
If an RMM command succeeds then the return code is <Interface>_SUCCESS.
If an RMM command succeeds then all of its success conditions evaluate to true.
12.8 Concrete and abstract types
A concrete type is a type which has a defined encoding.
Examples of concrete types include:
- An integer which has a defined bit width.
- An enumeration within which each label is associated with a unique binary value.
- A struct which has a defined width, and within which each member has a defined position. The type of each member of a concrete struct is a concrete type.
Concrete types are used to define command input values and output values.
An abstract type is a type which does not have a defined encoding.
Examples of concrete types include:
- An integer which does not have a defined bit width.
- An enumeration which has a set of labels, but which does not define a binary value for each label.
- A struct which has a set of members, but which does not define a struct width nor a position for each member. The type of each member of an abstract struct is an abstract type.
Abstract types are used to model the internal state of the RMM.
A command failure condition or success condition may need to test for
logical equality between a concrete type and a corresponding abstract
type. For example, the command may set the value of an internal RMM
variable to match the value of a command input. To enable such
comparisons, the specification defines an Equal() function
for each pair of corresponding concrete and abstract types.
See also:
- Section 14.26
12.9 Command footprint
The footprint of an RMM command defines the set of state items which successful execution of the command can modify.
The footprint of an RMM command may include state items which are not modified by successful execution of the command.
If an RMM command changes the state of a Granule then the footprint typically does not include all attributes of the object which is created or destroyed.
For example, the footprint of RMI_REALM_CREATE includes the state of the RD Granule, but does not include attributes of the newly-created Realm.
Except for items in the footprint of an RMM command and registers in the output values of the RMM command, execution of the command does not have any observable effects.
12.10 Command testing
Command definitions can be used to generate testbenches which check whether an implementation complies with the specified failure and success conditions.
A testbench for the EXAMPLE_ADD command presented above would look similar to the following:
// Test EXAMPLE_ADD command
Test_ExampleAdd(Registers regs_in)
// Unpack input values
RmmPa params_ptr = regs_in.X1;
// Evaluate context values
ExampleParams params = ExampleParams(params_ptr);
// Evaluate failure pre-conditions
boolean params_align_pre = !AddrIsGranuleAligned(params_ptr);
boolean params_gpt_pre = Granule(params_ptr).gpt != GPT_NS;
// Execute command
regs_out = RmiExampleAdd(regs_in);
// Pack output values
CommandReturnCode result = regs_out.X0;
integer sum = regs_out.X1;
integer zero = regs_out.X2;
// Check return code
boolean success = (result == Success);
// Evaluate failure post-conditions
boolean params_align_post = result == Status(ErrorInput, 1);
boolean params_gpt_post = result == Status(ErrorInputMemory, 0);
// Evaluate success conditions
boolean sum_post = sum == params.x + params.y;
boolean zero_post = zero == (params.x == 0) || (params.z == 0);
// Check failure conditions, in order specified
assert params_align_pre IMPLIES params_align_post;
assert (!params_align_pre && params_gpt_pre) IMPLIES params_gpt_post;
// Check that, if no failure pre-condition was violated, command succeeded
assert (!params_align_pre && !params_gpt_pre) IMPLIES success;
// Check success conditions, without any ordering
assert success IMPLIES S01_post;
assert success IMPLIES S02_post;
Note that the syntax x IMPLIES y, which is logically
equivalent to !x || y, is not yet defined in ASL.
13 Interface versioning
This section describes how the RMI and RSI interfaces are versioned, and how the caller of each can determine whether there exists a mutually acceptable revision of the interface via which it can communicate with the RMM.
Other interfaces exposed by the RMM, such as PSCI, may define their own versioning schemes which differ from that used by RMI and RSI. For details, refer to the specification of the interface concerned.
Revisions of the RMI and the RSI are identified by a (major, minor) version tuple.
The semantics of this version tuple are as follows. For two revisions
of the interface P = (majP, minP)
and
Q = (majQ, minQ):
If majP != majQ then the two interfaces may contain incompatible commands.
If majP == majQ and minP < minQ then:
Every command defined in P has the same behavior in Q, when called with input values that are specified as valid in P.
A command defined in P may accept additional input values in Q. These could be provided via any of:
- Input registers which were unused in P.
- Input memory locations which were specified as SBZ in P.
- Encodings which were specified as reserved in P.
A command defined in P may return additional output values in Q. These could be returned via any of:
- Output registers which were unused in P.
- Output memory locations which were specified as MBZ in P.
- Encodings which were specified as reserved in P.
Q may contain additional commands which are not present in P.
P is less than Q if one of the following conditions is true:
- majP < majQ
- majP == majQ and minP < minQ
For each interface, an RMM implementation supports a set of revisions. The size of this set is at least one.
If an RMM implementation supports a given interface revision (x, y) then Arm expects that it will also supports all earlier revisons with the same major version number. That is:
(x, 0), (x, 1) … (x, y-1), (x, y).
A possible exception to this may occur if a security vulnerability is discovered in a particular revision of the interface. For example, if interface revision (x, bad) is found to contain a vulnerability then an RMM implementation may choose to support the following set of revisions:
(x, 0), (x, 1) … (x, bad-1), (x, bad+1) … (x, y-1), (x, y).
The set of interface revisions supported by an RMM implementation may include revisons with different major version numbers, for example:
(1, 0), (1, 1) … (1, m)
(2, 0), (2, 1) … (2, n)
The RMI_VERSION and RSI_VERSION commands allow the caller and the RMM to determine whether there exists a mutually acceptable revision of the interface via which the two components can communicate.
In each case:
- The caller provides a requested interface revision.
- The output values include a status code and two revisions which are supported by the RMM: a lower revision and a higher revision.
- The higher revision value is the highest interface revision which is supported by the RMM.
- The lower revision is less than or equal to the higher revision.
The status code and lower revision output values indicate which of the following is true, in order of precedence:
The RMM supports an interface revision which is compatible with the requested revision.
- The status code is “success”.
- The lower revision is equal to the requested revision.
The RMM does not support an interface revision which is compatible with the requested revision. The RMM supports an interface revision which is incompatible with and less than the requested revision.
- The status code is “failure”.
- The lower revision is the highest interface revision which is both less than the requested revision and supported by the RMM.
The RMM does not support an interface revision which is compatible with the requested revision. The RMM supports an interface revision which is incompatible with and greater than the requested revision.
- The status code is “failure”.
- The lower revision is equal to the higher revision.
The following table shows how each of a set of example scenarios maps onto the above outcomes.
| Scenario | Revisions supported by RMM | Revision requested by caller | Outcome | “Lower revision” output value | “Higher revision” output value |
|---|---|---|---|---|---|
| 1 | (1, 0) | (1, 0) | Success (a) | (1, 0) | (1, 0) |
| 2 | (1, 0), (1, 1) | (1, 0) | Success (a) | (1, 0) | (1, 1) |
| 3 | (1, 0), (2, 0) | (1, 0) | Success (a) | (1, 0) | (2, 0) |
| 4 | (1, 0) | (1, 1) | Failure (b) | (1, 0) | (1, 0) |
| 5 | (1, 0), (1, 1) | (1, 2) | Failure (b) | (1, 1) | (1, 1) |
| 6 | (1, 0), (1, 1) | (2, 0) | Failure (b) | (1, 1) | (1, 1) |
| 7 | (1, 0), (1, 1), (1, 3) | (1, 2) | Failure (b) | (1, 1) | (1, 3) |
| 8 | (1, 0) | (2, 0) | Failure (b) | (1, 0) | (1, 0) |
| 9 | (1, 0) | (2, 1) | Failure (b) | (1, 0) | (1, 0) |
| 10 | (1, 0), (1, 1) | (2, 0) | Failure (b) | (1, 1) | (1, 1) |
| 11 | (1, 0), (1, 1) | (2, 1) | Failure (b) | (1, 1) | (1, 1) |
| 12 | (1, 0), (1, 1), (2, 0) | (2, 1) | Failure (b) | (2, 0) | (2, 0) |
| 13 | (2, 0) | (1, 0) | Failure (c) | (2, 0) | (2, 0) |
| 14 | (2, 0) | (1, 1) | Failure (c) | (2, 0) | (2, 0) |
| 15 | (2, 0), (2, 1) | (1, 0) | Failure (c) | (2, 1) | (2, 1) |
14 Command condition functions
This chapter describes functions which are used in command condition expressions.
See also:
- Section 12.4
14.1 AddrInRange function
Returns TRUE if addr is within
[base, base+size].
func AddrInRange(
addr : Address,
base : Address,
size : integer) => boolean
begin
return ((UInt(addr) >= UInt(base))
&& (UInt(addr) <= UInt(base) + size));
end
14.2 AddrIsAligned function
Returns TRUE if address addr is aligned to an
n byte boundary.
func AddrIsAligned(
addr : Address,
n : integer) => boolean
14.3 AddrIsAuxLive function
Returns TRUE if IPA addr is auxiliary-live,
that is live in any auxiliary RTT.
func AddrIsAuxLive(
addr : Address,
realm : RmmRealm) => boolean
14.4 AddrIsGranuleAligned function
Returns TRUE if address addr is aligned to the size of a
Granule.
func AddrIsGranuleAligned(
addr : Address) => boolean
func AddrIsGranuleAligned(
addr : integer) => boolean
See also:
- Section 2.2
14.5 AddrIsProtected function
Returns TRUE if address addr is a Protected IPA for
realm.
func AddrIsProtected(
addr : Address,
realm : RmmRealm) => boolean
begin
return UInt(addr) < 2^(realm.ipa_width - 1);
end
14.6 AddrIsRttLevelAligned function
Returns TRUE if Address addr is aligned to the size of
the address range described by an RTTE in a level level
RTT.
Returns FALSE if level is invalid.
func AddrIsRttLevelAligned(
addr : Address,
level : integer) => boolean
14.7 AddrIsWithin function
Returns TRUE if address addr is within the outer range
[base, top).
func AddrIsWithin(
addr : Address,
base : Address,
top : Address) => boolean
begin
var addr_int : integer = UInt(addr);
var top_int : integer = UInt(top);
var base_int : integer = UInt(base);
return ((UInt(addr) >= UInt(base))
&& (UInt(addr) < UInt(top)));
end
14.8 AddrRangeIsAuxLive function
Returns TRUE if any IPA in range [base, top) is
auxiliary-live, that is live in any auxiliary RTT.
func AddrRangeIsAuxLive(
base : Address,
top : Address,
realm : RmmRealm) => boolean
14.9 AddrRangeIsProtected function
Returns TRUE if all addresses in range [base, top) are
Protected IPAs for realm.
func AddrRangeIsProtected(
base : Address,
top : Address,
realm : RmmRealm) => boolean
begin
var size = UInt(top) - UInt(base);
return (AddrIsProtected(base, realm)
&& size > 0
&& size < 2^realm.ipa_width
&& AddrIsProtected(ToAddress(UInt(top) - 1), realm));
end
14.10 AddrRangeIsWithin function
Returns TRUE if all addresses in the inner range
[inner_base, inner_top) are within the outer range
[outer_range, outer_top).
func AddrRangeIsWithin(
inner_base : Address,
inner_top : Address,
outer_base : Address,
outer_top : Address) => boolean
begin
return (AddrIsWithin(inner_base, outer_base, outer_top)
&& AddrIsWithin(inner_top, outer_base, outer_top));
end
14.11 AlignDownToRttLevel function
Round down addr to align to the size of the address
range described by an RTTE in a level level RTT.
func AlignDownToRttLevel(
addr : Address,
level : integer) => Address
14.12 AlignUpToRttLevel function
Round up addr to align to the size of the address range
described by an RTTE in a level level RTT.
func AlignUpToRttLevel(
addr : Address,
level : integer) => Address
14.13 AuxAlias16 function
Returns TRUE if any of the first count entries in a list
of auxiliary Granule addresses are aliased - either among themselves, or
with the address of another RMM object.
func AuxAlias16(
obj : Address,
aux : array [16] of Address,
count : integer) => boolean
begin
assert 0 <= count && count <= 16;
var sorted = AuxSort(aux, count);
for i = 0 to count - 1 do
if sorted[i] == obj then
return TRUE;
end
if i >= 1 && sorted[i] == sorted[i - 1] then
return TRUE;
end
end
return FALSE;
end
14.14 AuxAlias32 function
Returns TRUE if any of the first count entries in a list
of auxiliary Granule addresses are aliased - either among themselves, or
with the address of another RMM object.
func AuxAlias32(
obj : Address,
aux : array [32] of Address,
count : integer) => boolean
begin
assert 0 <= count && count <= 32;
var sorted = AuxSort(aux, count);
for i = 0 to count - 1 do
if sorted[i] == obj then
return TRUE;
end
if i >= 1 && sorted[i] == sorted[i - 1] then
return TRUE;
end
end
return FALSE;
end
14.15 AuxAligned16 function
Returns TRUE if the first count entries in a list of
auxiliary Granule addresses are aligned to the size of a Granule.
func AuxAligned16(
aux : array [16] of Address,
count : integer) => boolean
begin
assert 0 <= count && count <= 16;
for i = 0 to count - 1 do
if !AddrIsGranuleAligned(aux[i]) then
return FALSE;
end
end
return TRUE;
end
14.16 AuxAligned32 function
Returns TRUE if the first count entries in a list of
auxiliary Granule addresses are aligned to the size of a Granule.
func AuxAligned32(
aux : array [32] of Address,
count : integer) => boolean
begin
assert 0 <= count && count <= 32;
for i = 0 to count - 1 do
if !AddrIsGranuleAligned(aux[i]) then
return FALSE;
end
end
return TRUE;
end
14.17 AuxEqual16 function
Returns TRUE if the first count entries in two lists of
auxiliary Granule addresses are equal.
func AuxEqual16(
aux1 : array [16] of Address,
aux2 : array [16] of Address,
count : integer) => boolean
begin
assert 0 <= count && count <= 16;
for i = 0 to count - 1 do
if aux1[i] != aux2[i] then
return FALSE;
end
end
return TRUE;
end
14.18 AuxEqual32 function
Returns TRUE if the first count entries in two lists of
auxiliary Granule addresses are equal.
func AuxEqual32(
aux1 : array [32] of Address,
aux2 : array [32] of Address,
count : integer) => boolean
begin
assert 0 <= count && count <= 32;
for i = 0 to count - 1 do
if aux1[i] != aux2[i] then
return FALSE;
end
end
return TRUE;
end
14.19 AuxSort function
Sort first count entries in array of auxiliary Granule
addresses.
func AuxSort(
addrs : array [16] of Address,
count : integer) => array [16] of Address
func AuxSort(
addrs : array [32] of Address,
count : integer) => array [32] of Address
14.20 AuxStateEqual16 function
Returns TRUE if the state of the first count entries in
a list of auxiliary Granule addresses is equal to
state.
func AuxStateEqual16(
aux : array [16] of Address,
count : integer,
state : RmmGranuleState) => boolean
begin
assert 0 <= count && count <= 16;
for i = 0 to count - 1 do
if (!PaIsDelegable(aux[i])
|| GranuleAt(aux[i]).state != state) then
return FALSE;
end
end
return TRUE;
end
14.21 AuxStateEqual32 function
Returns TRUE if the state of the first count entries in
a list of auxiliary Granule addresses is equal to
state.
func AuxStateEqual32(
aux : array [32] of Address,
count : integer,
state : RmmGranuleState) => boolean
begin
assert 0 <= count && count <= 32;
for i = 0 to count - 1 do
if (!PaIsDelegable(aux[i])
|| GranuleAt(aux[i]).state != state) then
return FALSE;
end
end
return TRUE;
end
14.22 AuxStates function
Inductive function which identifies the states of the first
count entries in a list of auxiliary Granules.
This function is used in the definition of command footprint.
func AuxStates(
aux : array [16] of Address,
count : integer)
func AuxStates(
aux : array [32] of Address,
count : integer)
14.23 CurrentRealm function
Returns the current Realm.
func CurrentRealm() => RmmRealm
14.24 CurrentRec function
Returns the current REC.
func CurrentRec() => RmmRec
14.25 DeviceCommunicate function
Process device communication data and return the new state of the device transaction.
func DeviceCommunicate(
pdev : RmmPdev,
data : RmiDevCommData) => RmmDevCommState
func DeviceCommunicate(
vdev : RmmVdev,
data : RmiDevCommData) => RmmDevCommState
func DeviceCommunicate(
vdev : RmmRdev) => RmmDevCommState
14.26 Equal function
Check whether concrete and abstract values are equal
func Equal(
abstract : RmmFeature,
concrete : RmiFeature) => boolean
func Equal(
concrete : RmiFeature,
abstract : RmmFeature) => boolean
func Equal(
abstract : RmmHashAlgorithm,
concrete : RmiHashAlgorithm) => boolean
func Equal(
concrete : RmiHashAlgorithm,
abstract : RmmHashAlgorithm) => boolean
func Equal(
abstract : RmmLfaPolicy,
concrete : RmiLfaPolicy) => boolean
func Equal(
concrete : RmiLfaPolicy,
abstract : RmmLfaPolicy) => boolean
func Equal(
abstract : RmmPdevProtConfigRmmPdevProtection,
concrete : RmiPdevProtConfigRmiPdevProtection) => boolean
func Equal(
concrete : RmiPdevProtConfigRmiPdevProtection,
abstract : RmmPdevProtConfigRmmPdevProtection) => boolean
func Equal(
abstract : RmmPdevState,
concrete : RmiPdevState) => boolean
func Equal(
concrete : RmiPdevState,
abstract : RmmPdevState) => boolean
func Equal(
abstract : RmmRecRunnable,
concrete : RmiRecRunnable) => boolean
func Equal(
concrete : RmiRecRunnable,
abstract : RmmRecRunnable) => boolean
func Equal(
abstract : RmmRipas,
concrete : RmiRipas) => boolean
func Equal(
concrete : RmiRipas,
abstract : RmmRipas) => boolean
func Equal(
abstract : RmmRttPlaneFeature,
concrete : RmiRttPlaneFeature) => boolean
func Equal(
concrete : RmiRttPlaneFeature,
abstract : RmmRttPlaneFeature) => boolean
func Equal(
abstract : RmmRttS2APEncoding,
concrete : RmiRttS2APEncoding) => boolean
func Equal( concrete : RmiRttS2APEncoding, abstract : RmmRttS2APEncoding) => boolean
func Equal( abstract : RmmVdevState, concrete : RmiVdevState) => boolean
func Equal(
concrete : RmiVdevState,
abstract : RmmVdevState) => boolean
func Equal(
abstract : RmmRdevState,
concrete : RsiDeviceState) => boolean
func Equal(
concrete : RsiDeviceState,
abstract : RmmRdevState) => boolean
func Equal(
abstract : RmmFeature,
concrete : RsiFeature) => boolean
func Equal(
concrete : RsiFeature,
abstract : RmmFeature) => boolean
func Equal(
abstract : RmmHashAlgorithm,
concrete : RsiHashAlgorithm) => boolean
func Equal(
concrete : RsiHashAlgorithm,
abstract : RmmHashAlgorithm) => boolean
func Equal(
abstract : RmmRipas,
concrete : RsiRipas) => boolean
func Equal(
concrete : RsiRipas,
abstract : RmmRipas) => boolean
func Equal(
abstract : RmmRipasChangeDestroyed,
concrete : RsiRipasChangeDestroyed) => boolean
func Equal(
concrete : RsiRipasChangeDestroyed,
abstract : RmmRipasChangeDestroyed) => boolean
See also:
- Section 12.8
14.27 FeatureToRmi function
Convert feature bit to RMI type.
func FeatureToRmi(
value : RmmFeature) => RmiFeature
begin
case value of
when FEATURE_FALSE => return RMI_FEATURE_FALSE;
when FEATURE_TRUE => return RMI_FEATURE_TRUE;
end
end
14.28 FeatureToRsi function
Convert feature bit to RSI type.
func FeatureToRsi(
value : RmmFeature) => RsiFeature
begin
case value of
when FEATURE_FALSE => return RSI_FEATURE_FALSE;
when FEATURE_TRUE => return RSI_FEATURE_TRUE;
end
end
14.29 Gicv3ConfigIsValid function
Returns TRUE if the values of all gicv3_* attributes are
valid.
func Gicv3ConfigIsValid(
gicv3_hcr : bits(64),
gicv3_lrs : array [16] of bits(64)) => boolean
14.30 GranuleAccessPermitted function
Returns TRUE if the Granule located at physical address
addr is accessible via pas.
func GranuleAccessPermitted(
addr : Address,
pas : RmmPhysicalAddressSpace) => boolean
begin
case GranuleAt(addr).gpt of
when GPT_NS => return (pas == PAS_NS);
when GPT_REALM => return (pas == PAS_REALM);
when GPT_SECURE => return (pas == PAS_SECURE);
when GPT_ROOT => return (pas == PAS_ROOT);
when GPT_AAP => return TRUE;
end
end
14.31 GranuleAt function
Returns the Granule located at physical address
addr.
func GranuleAt(
addr : Address) => RmmGranule
See also:
- Section 2.2
14.32 ImplFeatures function
Returns features supported by the implementation.
func ImplFeatures() => RmmFeatures
See also:
- Section 3
14.33 MecMembers function
Returns number of Realms which are members of a given MEC.
func MecMembers(
mecid : bits(64)) => integer
See also:
- Section 11
14.34 MecPolicy function
Returns policy associated with a given MEC.
func MecPolicy(
mecid : bits(64)) => RmmMecPolicy
begin
case MecState(mecid) of
when MEC_STATE_SHARED => return MEC_POLICY_SHARED;
when MEC_STATE_PRIVATE_ASSIGNED => return MEC_POLICY_PRIVATE;
when MEC_STATE_PRIVATE_UNASSIGNED => return MEC_POLICY_PRIVATE;
end
end
See also:
- Section 11
14.35 MecState function
Returns state of a given MEC.
func MecState(
mecid : bits(64)) => RmmMecState
See also:
- Section 11
14.36 MemPermLabelSupported function
Returns TRUE if the specified value is a valid encoding for a memory permission label and the label is supported by the implementation.
func MemPermLabelSupported(
label : bits(64)) => boolean
14.37 MinAddress function
Returns the smaller of two addresses.
func MinAddress(
addr1 : Address,
addr2 : Address) => Address
begin
return ToAddress(Min(UInt(addr1), UInt(addr2)));
end
14.38 MpidrEqual function
Returns TRUE if the specified MPIDR values are logically equivalent.
func MpidrEqual(
rmm_mpidr : bits(64),
rmi_mpidr : RmiRecMpidr) => boolean
begin
return (rmm_mpidr[ 3: 0] == rmi_mpidr.aff0
&& rmm_mpidr[15: 8] == rmi_mpidr.aff1
&& rmm_mpidr[23:16] == rmi_mpidr.aff2
&& rmm_mpidr[31:24] == rmi_mpidr.aff3);
end
14.39 MpidrIsUsed function
Returns TRUE if the specified MPIDR value identifies a REC in the current Realm.
func MpidrIsUsed(
mpidr : bits(64)) => boolean
14.40 MsiAddrIsValid function
Returns TRUE if addr is a valid MSI address.
func MsiAddrIsValid(
addr : Address) => boolean
14.41 PaIsDelegable function
Returns TRUE if the Granule located at physical address
addr is delegableDelegable memory.
func PaIsDelegable(
addr : Address) => boolean
begin
return (PaIsDelegableDevMem(addr)
|| PaIsDelegableDram(addr));
end
14.42 PdevAt PaIsDelegableCohDevMem function
Returns TRUE if the Granule located at physical address
addr is Delegable coherent device memory.
func PaIsDelegableCohDevMem( addr : Address) => boolean
14.43 PaIsDelegableDevMem function
Returns TRUE if the Granule located at physical address
addr is Delegable device memory.
func PaIsDelegableDevMem( addr : Address) => boolean begin return (PaIsDelegableCohDevMem(addr) || PaIsDelegableNonCohDevMem(addr)); end
14.44 PaIsDelegableDram function
Returns TRUE if the Granule located at physical address
addr is Delegable DRAM.
func PaIsDelegableDram( addr : Address) => boolean
14.45 PaIsDelegableNonCohDevMem function
Returns TRUE if the Granule located at physical address
addr is Delegable non-coherent device memory.
func PaIsDelegableNonCohDevMem( addr : Address) => boolean
14.46 PdevAt function
Returns the PDEV object located at physical address
addr.
func PdevAt(
addr : Address) => RmmPdev
14.4347 PdevAuxCount function
Returns the number of auxiliary Granules required for a PDEV with the specified flags.
The return value is guaranteed not to be greater than 32.
For a given flags value, this function always returns the same value.
func PdevAuxCount(
flags : RmiPdevFlags) => integer
14.4448 PdevFlags function
Get RmiPdevFlags value.
func PdevFlags(
pdev : RmmPdev) => RmiPdevFlags
begin
var flags : RmiPdevFlags;
case pdev.prot_config of
when prot of
when PDEV_IOCOH_E2E_IDE => flags.prot_configprot = RMI_PDEV_IOCOH_E2E_IDE;
when PDEV_IOCOH_E2E_SYS => flags.prot_configprot = RMI_PDEV_IOCOH_E2E_SYS;
when PDEV_FCOH_E2E_IDE => flags.prot_configprot = RMI_PDEV_FCOH_E2E_IDE;
when PDEV_FCOH_E2E_SYS => flags.prot_configprot = RMI_PDEV_FCOH_E2E_SYS;
end
return flags;
end
14.4549 PdevVsmmuIsCompatible function
Returns TRUE if the attributes of vsmmu are compatible
with pdev.
If the PSMMU associated with the PDEV does not support two stages of
translation, this function returns FALSE.
func PdevVsmmuIsCompatible(
pdev : RmmPdev,
vsmmu : RmmVsmmu) => boolean
14.4650 PlaneRegIsValid function
Whether encoding identifies a Plane register.
func PlaneRegIsValid(
realm : RmmRealm,
encoding : bits(64)) => boolean
14.4751 PlaneRegValue function
Value of a Plane register.
func PlaneRegValue(
realm : RmmRealm,
plane_idx : integer,
encoding : bits(64)) => bits(64)
14.4852 PsciReturnCodeEncode function
Return encoding for a PsciReturnCode value.
func PsciReturnCodeEncode(
value : PsciReturnCode) => bits(64)
14.4953 PsciReturnCodePermitted function
Whether a PSCI return code is permitted.
func PsciReturnCodePermitted(
calling_rec : RmmRec,
target_rec : RmmRec,
value : PsciReturnCode) => boolean
begin
if value == PSCI_SUCCESS then
return TRUE;
end
var fid : bits(64) = calling_rec.gprs[0];
// Host is permitted to deny a PSCI_CPU_ON request, if the target
// CPU is not already on.
if (fid == FID_PSCI_CPU_ON
&& target_rec.flags.runnable != RUNNABLE
&& value == PSCI_DENIED) then
return TRUE;
end
return FALSE;
end
14.5054 PsmmuAddrIsValid function
Returns TRUE if addr is the base address of a PSMMU.
func PsmmuAddrIsValid(
addr : Address) => boolean
14.5155 PsmmuSupportsMsi function
Returns TRUE if the PSMMU located at addr supports
MSI.
func PsmmuSupportsMsi(
addr : Address) => boolean
14.5256 RdevFromInstId function
Returns the RDEV identified by inst_id and assigned to
realm.
func RdevFromInstId(
realm : RmmRealm,
inst_id : integer) => RmmRdev
14.5357 RdevFromVdevId function
Returns any RDEV identified by vdev_id and assigned to
realm.
func RdevFromVdevId(
realm : RmmRealm,
vdev_id : bits(64)) => RmmRdev
14.5458 RdevIdIsValid function
Returns TRUE if vdev_id identifies a Realm device which
is assigned to realm.
func RdevIdIsValid(
realm : RmmRealm,
vdev_id : bits(64)) => boolean
14.5559 RdevIdsAreValid function
Returns TRUE if the tuple (vdev_id,
inst_id) identifies a Realm device which is assigned to
realm.
func RdevIdsAreValid(
realm : RmmRealm,
vdev_id : bits(64),
inst_id : integer) => boolean
14.5660 ReadMemory function
Read contents of memory at address range [addr + offset, addr + offset + size)
offset and size are both numbers of bytes.
func ReadMemory(
addr : bits(64),
offset : integer,
size : integer) => bits(size * 8)
14.5761 RealmAt function
Returns the Realm whose RD is located at physical address
addr.
func RealmAt(
addr : Address) => RmmRealm
See also:
- Section 2.1
14.5862 RealmIsLive function
Returns TRUE if the Realm whose RD is located at physical address
addr is live.
func RealmIsLive(
addr : Address) => boolean
See also:
- Section 2.1.4
14.5963 RealmParamsSupported function
Returns TRUE if the Realm parameters are supported by the implementation.
func RealmParamsSupported(
params : RmiRealmParams) => boolean
begin
var impl : RmmFeatures = ImplFeatures();
if (params.flags0.lpa2 == RMI_FEATURE_TRUE
&& impl.feat_lpa2 != FEATURE_TRUE) then
return FALSE;
end
if (params.flags0.sve == RMI_FEATURE_TRUE
&& impl.feat_sve != FEATURE_TRUE) then
return FALSE;
end
if (params.flags0.pmu == RMI_FEATURE_TRUE
&& impl.feat_pmu != FEATURE_TRUE) then
return FALSE;
end
if (params.flags0.da == RMI_FEATURE_TRUE
&& impl.feat_da != FEATURE_TRUE) then
return FALSE;
end
if (params.s2sz > impl.max_ipa_width) then
return FALSE;
end
if (params.sve_vl > impl.max_sve_vl) then
return FALSE;
end
if (params.num_bps == 0
|| params.num_bps + 1 > impl.num_bps) then
return FALSE;
end
if (params.num_wps == 0
|| params.num_wps + 1 > impl.num_wps) then
return FALSE;
end
if (params.pmu_num_ctrs > impl.pmu_num_ctrs) then
return FALSE;
end
if (params.hash_algo == RMI_HASH_SHA_256
&& impl.feat_sha_256 != FEATURE_TRUE) then
return FALSE;
end
if (params.hash_algo == RMI_HASH_SHA_512
&& impl.feat_sha_512 != FEATURE_TRUE) then
return FALSE;
end
if (params.num_aux_planes > impl.max_num_aux_planes) then
return FALSE;
end
if (params.num_aux_planes > 0) then
if (params.flags1.rtt_tree_per_plane == RMI_FEATURE_FALSE
&& impl.rtt_plane == RTT_PLANE_AUX) then
return FALSE;
end
if (params.flags1.rtt_tree_per_plane == RMI_FEATURE_TRUE
&& impl.rtt_plane == RTT_PLANE_SINGLE) then
return FALSE;
end
if (params.flags1.rtt_s2ap_indirectrtt_s2ap_encoding == RMI_FEATURE_TRUERMI_S2AP_INDIRECT
&& impl.rtt_s2ap_indirect == FEATURE_FALSE) then
return FALSE;
end
if ((params.flags1.rtt_tree_per_plane
! == RMI_FEATURE_TRUE
&& params.flags1.rtt_s2ap_indirectrtt_s2ap_encoding == RMI_S2AP_DIRECT)
|| (params.flags1.rtt_tree_per_plane == RMI_FEATURE_FALSE
&& params.flags1.rtt_s2ap_encoding == RMI_S2AP_INDIRECT
)) then
return FALSE;
end
end
return TRUE;
end
14.6064 RealmRttBaseEqual function
Returns TRUE if RTT base values of realm match the
provided values.
func RealmRttBaseEqual(
realm : RmmRealm,
rtt_base : Address,
aux_rtt_base : array[3] of Address) => boolean
begin
if (realm.rtt_base[0] != rtt_base) then
return FALSE;
end
for i = 0 to 2 do
if (realm.rtt_base[i + 1] != aux_rtt_base[i]) then
return FALSE;
end
end
return TRUE;
end
14.6165 RealmVmidEqual function
Returns TRUE if RTT base values of realm match the
provided values.
func RealmVmidEqual(
realm : RmmRealm,
vmid : bits(16),
aux_vmid : array[3] of bits(16)) => boolean
begin
if (realm.vmid[0] != vmid) then
return FALSE;
end
for i = 0 to 2 do
if (realm.vmid[i + 1] != aux_vmid[i]) then
return FALSE;
end
end
return TRUE;
end
14.6266 RecAt function
Returns the REC object located at physical address
addr.
func RecAt(
addr : Address) => RmmRec
See also:
- Section 2.3
14.6367 RecAuxCount function
Returns the number of auxiliary Granules required for a REC in the
Realm described by rd.
The return value is implementation defined based on the attributes of the Realm.
The return value is guaranteed not to be greater than 16.
For a given Realm, this function always returns the same value.
func RecAuxCount(
rd : Address) => integer
14.6468 RecFromMpidr RecDevMemResponseToRsi function
Returns response to Device memory mapping validation request.
func RecDevMemResponseToRsi( rec : RmmRec) => RsiResponse begin if ((rec.dev_mem_addr != rec.dev_mem_top) && (rec.dev_mem_response == REJECT)) then return RSI_REJECT; end return RSI_ACCEPT; end
14.69 RecFromMpidr function
Returns the REC object identified by the specified MPIDR value, in the current Realm.
func RecFromMpidr(
mpidr : bits(64)) => RmmRec
14.6570 RecIndex function
Returns the REC index which corresponds to mpidr.
func RecIndex(
mpidr : RmiRecMpidr) => integer
begin
return (UInt(mpidr.aff0)
+ 16 * UInt(mpidr.aff1)
+ 16 * 256 * UInt(mpidr.aff2)
+ 16 * 256 * 256 * UInt(mpidr.aff3));
end
See also:
- Section 2.3.3
14.6671 RecRipasResponseToRsi function
Returns response to RIPAS change request.
func RecRipasResponseToRsi(
rec : RmmRec) => RsiResponse
begin
if ((rec.ripas_value == RAM)
&& (rec.ripas_addr != rec.ripas_top)
&& (rec.ripas_response == REJECT)) then
return RSI_REJECT;
end
return RSI_ACCEPT;
end
See also:
- Section 5.4
14.6772 RecS2APResponseToRsi function
Returns response to S2AP change request.
func RecS2APResponseToRsi(
rec : RmmRec) => RsiResponse
begin
if ((rec.s2ap_addr != rec.s2ap_top)
&& (rec.s2ap_response == REJECT)) then
return RSI_REJECT;
end
return RSI_ACCEPT;
end
See also:
- Section 10.3.3.2
14.6873 RemExtend function
Extend a REM.
The input to the hash function is constructed by concatenating the following, usingto form a 1024-bit value:
old_value- The least significant
sizeLSBs from bits fromnew_value, with the remaining 512 - sizezero bits zero-padded to form a 512-bit
This value is hashed using the algorithm identified by
hash_algo.
func RemExtend(
hash_algo : RmmHashAlgorithm,
old_value : RmmRealmMeasurement,
new_value : RmmRealmMeasurement,
size : integer) => RmmRealmMeasurement
See also:
- Section 7.1.2
14.6974 ResultEqual function
Returns TRUE if command result matches the stated value.
func ResultEqual(
result : RmiCommandReturnCode,
status : RmiStatusCode) => boolean
func ResultEqual(
result : RmiCommandReturnCode,
status : RmiStatusCode,
index : integer) => boolean
14.7075 RimExtendData function
Extend RIM with contribution from DATA creation.
func RimExtendData(
realm : RmmRealm,
ipa : Address,
data : Address,
flags : RmiDataFlags) => RmmRealmMeasurement
See also:
- Section 15.3.1.4
14.7176 RimExtendRec function
Extend RIM with contribution from REC creation.
func RimExtendRec(
realm : RmmRealm,
params : RmiRecParams) => RmmRealmMeasurement
See also:
- Section 15.3.3028.4
14.7277 RimExtendRipas function
Extend RIM with contribution from RIPAS change for an IPA range.
func RimExtendRipas(
realm : RmmRealm,
base : Address,
top : Address,
level : integer) => RmmRealmMeasurement
begin
var rim = realm.measurements[0];
var size = RttLevelSize(level);
var addr = base;
while (UInt(addr) < UInt(top)) do
rim = RimExtendRipasForEntry(rim, addr, level);
addr = ToAddress(UInt(addr) + size);
end
return rim;
end
See also:
- Section 15.3.4342.4
14.7378 RimExtendRipasForEntry function
Extend RIM with contribution from RIPAS change for a single RTT entry.
func RimExtendRipasForEntry(
rim : RmmRealmMeasurement,
ipa : Address,
level : integer) => RmmRealmMeasurement
14.7479 RimInit function
Initialize RIM.
func RimInit(
hash_algo : RmmHashAlgorithm,
params : RmiRealmParams) => RmmRealmMeasurement
See also:
- Section 15.3.2725.4
14.7580 RipasToRmi function
Encodes a RIPAS value.
func RipasToRmi(
ripas : RmmRipas) => RmiRipas
begin
case ripas of
when EMPTY => return RMI_EMPTY;
when RAM => return RMI_RAM;
when DESTROYED => return RMI_DESTROYED;
when DEV => return RMI_DEV;
end
end
14.7681 RmiAddressRangesEqual16 function
Returns TRUE if the first count entries in two arrays of
address ranges are equal.
func RmiAddressRangesEqual16(
ranges1 : array [16] of RmmAddressRange,
ranges2 : array [16] of RmiAddressRange,
count : integer) => boolean
begin
assert 0 <= count && count <= 16;
for i = 0 to count - 1 do
if ranges1[i].base != ranges2[i].base then
return FALSE;
end
if ranges1[i].top != ranges2[i].top then
return FALSE;
end
end
return TRUE;
end
14.7782 RmiAddressRangesEqual4 function
Returns TRUE if the first count entries in two arrays of
address ranges are equal.
func RmiAddressRangesEqual4(
ranges1 : array [4] of RmmAddressRange,
ranges2 : array [4] of RmiAddressRange,
count : integer) => boolean
begin
assert 0 <= count && count <= 4;
for i = 0 to count - 1 do
if ranges1[i].base != ranges2[i].base then
return FALSE;
end
if ranges1[i].top != ranges2[i].top then
return FALSE;
end
end
return TRUE;
end
14.7883 RmiDevCommDataAt function
Returns device communication data structure stored at physical
address addr.
If the PAS of addr is not NS, the return value is unknown.
func RmiDevCommDataAt(
addr : Address) => RmiDevCommData
14.7984 RmiFeatureRegister0Decode function
Decode RmiFeatureRegister0 value.
func RmiFeatureRegister0Decode(
value : bits(64)) => RmiFeatureRegister0
14.8085 RmiFeatureRegisterEncode function
Encode feature register.
func RmiFeatureRegisterEncode(
index : integer) => bits(64)
begin
var impl : RmmFeatures = ImplFeatures();
var result : bits(64) = Zeros();
if (index == 0) then
var reg : RmiFeatureRegister0;
reg.S2SZ = impl.max_ipa_width;
reg.LPA2 = FeatureToRmi(impl.feat_lpa2);
reg.SVE = FeatureToRmi(impl.feat_sve);
reg.SVE_VL = impl.max_sve_vl;
assert impl.num_bps >= 2 && impl.num_bps <= 2^6;
reg.NUM_BPS = impl.num_bps - 1;
assert impl.num_wps >= 2 && impl.num_wps <= 2^6;
reg.NUM_WPS = impl.num_wps - 1;
reg.PMU = FeatureToRmi(impl.feat_pmu);
reg.PMU_NUM_CTRS = impl.pmu_num_ctrs;
reg.HASH_SHA_256 = FeatureToRmi(impl.feat_sha_256);
reg.HASH_SHA_512 = FeatureToRmi(impl.feat_sha_512);
reg.DA = FeatureToRmi(impl.feat_da);
case impl.rtt_plane of
when RTT_PLANE_AUX => reg.RTT_PLANE = RMI_RTT_PLANE_AUX;
when RTT_PLANE_AUX_SINGLE => reg.RTT_PLANE = RMI_RTT_PLANE_AUX_SINGLE;
when RTT_PLANE_SINGLE => reg.RTT_PLANE = RMI_RTT_PLANE_SINGLE;
end
reg.RTT_S2AP_INDIRECT = FeatureToRmi(impl.rtt_s2ap_indirect);
reg.MAX_NUM_AUX_PLANES = impl.max_num_aux_planes;
reg.MAX_RECS_ORDER = impl.max_recs_order;
assert impl.gicv3_num_lrs >= 1 && impl.gicv3_num_lrs <= 2^4;
reg.GICV3_NUM_LRS = impl.gicv3_num_lrs - 1;
// Omitted: encode reg into bits(64) value
end
if (index == 1) then
var reg : RmiFeatureRegister1;
reg.MAX_MECID = impl.max_mecid;
// Omitted: encode reg into bits(64) value
end
return result;
end
14.8186 RmiPdevEventIsValid function
Returns TRUE if ev is a valid encoding, and the event is
supported by pdev.
func RmiPdevEventIsValid(
ev : RmiPdevEvent) => boolean
begin
return (ev == RMI_IDE_KEY_REFRESH);
end
14.8287 RmiPdevFlagsDecode function
Decode RmiPdevFlags value.
func RmiPdevFlagsDecode(
value : bits(64)) => RmiPdevFlags
14.8388 RmiPdevParamsAt function
Returns PDEV parameters stored at physical address
addr.
If the PAS of addr is not NS, the return value is unknown.
func RmiPdevParamsAt(
addr : Address) => RmiPdevParams
14.8489 RmiPdevParamsIsValid function
Returns TRUE if the memory location contains a valid encoding of the RmiPdevParams type and all the following are true:
- The device identifier is valid
- The device identifier is not equal to the device identifier of another PDEV
- The Root Port identifier is valid
- The IDE stream identifier is valid
- The RID range is valid
- The RID range does not overlap the RID range of another PDEV
- The base and top of every address range is aligned to the size of a Granule
- Every address range falls within a memory range permitted by the system
- None of the address ranges overlaps another address range for this PDEV
- None of the address ranges overlaps an address range for another PDEV
func RmiPdevParamsIsValid(
addr : Address) => boolean
14.8590 RmiPublicKeyParamsAt function
Returns public key parameters stored at physical address
addr.
If the PAS of addr is not NS, the return value is unknown.
func RmiPublicKeyParamsAt(
addr : Address) => RmiPublicKeyParams
14.8691 RmiRealmParamsAt function
Returns Realm parameters stored at physical address
addr.
If the PAS of addr is not NS, the return value is unknown.
func RmiRealmParamsAt(
addr : Address) => RmiRealmParams
See also:
- Section 2.1.6
14.8792 RmiRealmParamsIsValid function
Returns TRUE if the memory location contains a valid encoding of the RmiRealmParams type.
func RmiRealmParamsIsValid(
addr : Address) => boolean
14.8893 RmiRecParamsAt function
Returns REC parameters stored at physical address
addr.
If the PAS of addr is not NS, the return value is unknown.
func RmiRecParamsAt(
addr : Address) => RmiRecParams
14.8994 RmiRecRunAt function
Returns the RecRun object stored at physical address
addr.
func RmiRecRunAt(
addr : Address) => RmiRecRun
14.9095 RmiVdevFlagsDecode function
Decode RmiVdevFlags value.
func RmiVdevFlagsDecode(
value : bits(64)) => RmiVdevFlags
14.9196 RmiVdevParamsAt function
Returns VDEV parameters stored at physical address
addr.
If the PAS of addr is not NS, the return value is unknown.
func RmiVdevParamsAt(
addr : Address) => RmiVdevParams
14.9297 RmiVdevParamsIsValid function
Returns TRUE if the memory location contains a valid encoding of the RmiPdevParams type.
func RmiVdevParamsIsValid(
addr : Address) => boolean
14.9398 RmiVersionHigherIsSupported function
Returns TRUE if the RMM supports an RMI revision which is
incompatible with and greater than version.
func RmiVersionHigherIsSupported(
version : RmiInterfaceVersion) => boolean
14.9499 RmiVersionHighest function
Returns the highest RMI revision supported by the RMM.
func RmiVersionHighest() => RmiInterfaceVersion
14.95100 RmiVersionHighestBelow function
Returns the highest RMI revision which is both less than
version and supported by the RMM.
func RmiVersionHighestBelow(
version : RmiInterfaceVersion) => RmiInterfaceVersion
14.96101 RmiVersionIsSupported function
Returns TRUE if the RMM supports an RMI revision which is compatible
with version.
func RmiVersionIsSupported(
version : RmiInterfaceVersion) => boolean
14.97102 RmiVersionLowerIsSupported function
Returns TRUE if the RMM supports an RMI revision which is
incompatible with and less than version.
func RmiVersionLowerIsSupported(
version : RmiInterfaceVersion) => boolean
14.98103 RmiVsmmuParamsAt function
Returns VSMMU parameters stored at physical address
addr.
If the PAS of addr is not NS, the return value is unknown.
func RmiVsmmuParamsAt(
addr : Address) => RmiVsmmuParams
See also:
- Section 9.6.3
14.99104 RmiVsmmuParamsIsValid function
Returns TRUE if the memory location contains a valid encoding of the RmiVsmmuParams type and all the following are true:
- aidr value is invalidnot set to an architecturally valid value.
- Any idr[] value is invalidnot set to an architecturally valid value.
Here, “architecturally valid” refers to the SMMU implementation to which this VSMMU belongs.
func RmiVsmmuParamsIsValid(
addr : Address) => boolean
See also:
14.100105 RsiDeviceInfoAt function
Returns device configuration stored at IPA addr, mapped
in the current Realm.
func RsiDeviceInfoAt(
addr : Address) => RsiDeviceInfo
14.101106 RsiFeatureRegisterEncode function
Encode feature register.
func RsiFeatureRegisterEncode(
realm : RmmRealm,
index : integer) => bits(64)
begin
var implresult : RmmFeatures = ImplFeatures();
var result : bits(64) = Zeros();
if (index == 0) then
var reg : RsiFeatureRegister0;
reg.DA = FeatureToRsi(implrealm.feat_da);
// Omitted: set reg.MRO depending on whether platform
// implements FEAT_S2PIE
// Omitted: encode reg into bits(64) value
end
return result;
end
14.102107 RsiHostCallAt function
Returns Host call data stored at IPA addr, mapped in the
current Realm.
func RsiHostCallAt(
addr : Address) => RsiHostCall
14.103108 RsiPlaneRunAt function
Returns the PlaneRun object stored at IPA addr.
func RsiPlaneRunAt(
realm : RmmRealm,
addr : Address) => RsiPlaneRun
14.104109 RsiRealmConfigAt function
Returns Realm configuration stored at IPA addr, mapped
in the current Realm.
func RsiRealmConfigAt(
addr : Address) => RsiRealmConfig
14.105110 RsiVersionHigherIsSupported function
Returns TRUE if the RMM supports an RSI revision which is
incompatible with and greater than version.
func RsiVersionHigherIsSupported(
version : RsiInterfaceVersion) => boolean
14.106111 RsiVersionHighest function
Returns the highest RSI revision supported by the RMM.
func RsiVersionHighest() => RsiInterfaceVersion
14.107112 RsiVersionHighestBelow function
Returns the highest RSI revision which is both less than
version and supported by the RMM.
func RsiVersionHighestBelow(
version : RsiInterfaceVersion) => RsiInterfaceVersion
14.108113 RsiVersionIsSupported function
Returns TRUE if the RMM supports an RSI revision which is compatible
with version.
func RsiVersionIsSupported(
version : RsiInterfaceVersion) => boolean
14.109114 RsiVersionLowerIsSupported function
Returns TRUE if the RMM supports an RSI revision which is
incompatible with and less than version.
func RsiVersionLowerIsSupported(
version : RsiInterfaceVersion) => boolean
14.110115 RttAllEntriesContiguous function
Returns TRUE if all entries in the RTT at address rtt at
level level have contiguous output addresses, starting with
addr.
func RttAllEntriesContiguous(
rtt : RmmRtt,
addr : Address,
level : integer) => boolean
See also:
- Section 5.56
14.111116 RttAllEntriesRipas function
Returns TRUE if all entries in the RTT at address rtt
have RIPAS ripas.
func RttAllEntriesRipas(
rtt : RmmRtt,
ripas : RmmRipas) => boolean
14.112117 RttAllEntriesState function
Returns TRUE if all entries in the RTT at address rtt
have state state.
func RttAllEntriesState(
rtt : RmmRtt,
state : RmmRttEntryState) => boolean
See also:
- Section 5.56
14.113118 RttAt function
Returns the RTT at address rtt.
func RttAt(
addr : Address) => RmmRtt
14.114119 RttConfigIsValid function
Returns TRUE if the RTT configuration values provided are self-consistent and are supported by the platform.
func RttConfigIsValid(
ipa_width : integer,
rtt_level_start : integer,
rtt_num_start : integer) => boolean
See also:
- Section 5.56
14.115120 RttDescriptorDecode function
Decode an RTT descriptor.
func RttDescriptorDecode(
desc : bits(64),
encoding : RmmRttS2APEncoding) => RmmRttEntry
14.121 RttDescriptorIsValidForUnprotected function
Returns TRUE if, within the descriptor desc, all of the
following are true:
- All fields which are Host-controlled Unprotected RTT attributes are set to architecturally valid values.
- All fields which are not Host-controlled Unprotected RTT attributes are set to zero.
func RttDescriptorIsValidForUnprotected( desc : bits(64)) => RmmRttEntryboolean14.116 RttDescriptorIsValidForUnprotected function Returns TRUE if, within the descriptor desc, all of the following are true: All fields which are Host-controlled Unprotected RTT attributes are set to architecturally valid values. All fields which are not Host-controlled Unprotected RTT attributes are set to zero. func RttDescriptorIsValidForUnprotected( desc : bits(64)) => boolean
See also:
- Section 5.56.12.3
14.117122 RttEntriesInRangeRipasRttEntriesInRangeCohDevMem function
Returns TRUE if all entries in the RTT at address rtt at
level level, within Protected IPA range [base, top), have
output addresses which map to coherent device memory.
func RttEntriesInRangeCohDevMem( rtt : RmmRtt, level : integer, base : Address, top : Address) => boolean begin var addr : Address = base; var size : integer = RttLevelSize(level); while (UInt(addr) < UInt(top)) do var index : integer = RttEntryIndex(addr, level); var rtte : RmmRttEntry = RttEntryAt(rtt, index); if (!PaIsDelegableCohDevMem(rtte.addr)) then return FALSE; end addr = ToAddress(UInt(addr) + size); end return TRUE; end
14.123 RttEntriesInRangeMemAttr function
Returns TRUE if all entries in the RTT at address rtt at
level level, within Protected IPA range [base, top), have
memory attributes attr.
func RttEntriesInRangeMemAttr( rtt : RmmRtt, level : integer, base : Address, top : Address, attr : RmmRttMemAttr) => boolean begin var addr : Address = base; var size : integer = RttLevelSize(level); while (UInt(addr) < UInt(top)) do var index : integer = RttEntryIndex(addr, level); var rtte : RmmRttEntry = RttEntryAt(rtt, index); if (rtte.attr_prot != attr) then return FALSE; end addr = ToAddress(UInt(addr) + size); end return TRUE; end
14.124 RttEntriesInRangeNonCohDevMem function
Returns TRUE if all entries in the RTT at address rtt at
level level, within Protected IPA range [base, top), have
output addresses which map to non-coherent device memory.
func RttEntriesInRangeNonCohDevMem( rtt : RmmRtt, level : integer, base : Address, top : Address) => boolean begin var addr : Address = base; var size : integer = RttLevelSize(level); while (UInt(addr) < UInt(top)) do var index : integer = RttEntryIndex(addr, level); var rtte : RmmRttEntry = RttEntryAt(rtt, index); if (!PaIsDelegableNonCohDevMem(rtte.addr)) then return FALSE; end addr = ToAddress(UInt(addr) + size); end return TRUE; end
14.125 RttEntriesInRangeOutputContiguous function
Returns TRUE if all entries in the RTT at address rtt at
level level, within IPA range [base, top), map to a
contiguous range of output addresses starting from out.
func RttEntriesInRangeOutputContiguous( rtt : RmmRtt, level : integer, base : Address, top : Address, out : Address) => boolean begin var in_addr : Address = base; var out_addr : Address = out; var size : integer = RttLevelSize(level); while (UInt(in_addr) < UInt(top)) do var index : integer = RttEntryIndex(in_addr, level); var rtte : RmmRttEntry = RttEntryAt(rtt, index); if (rtte.addr != out_addr) then return FALSE; end in_addr = ToAddress(UInt(in_addr) + size); out_addr = ToAddress(UInt(out_addr) + size); end return TRUE; end
14.126 RttEntriesInRangeRipas function
Returns TRUE if all entries in the RTT at address rtt at
level level, within IPA range [base, top), have RIPAS
ripas.
func RttEntriesInRangeRipas(
rtt : RmmRtt,
level : integer,
base : Address,
top : Address,
ripas : RmmRipas) => boolean
begin
var addr : Address = base;
var size : integer = RttLevelSize(level);
while (UInt(addr) < UInt(top)) do
var index : integer = RttEntryIndex(addr, level);
var rtte : RmmRttEntry = RttEntryAt(rtt, index);
if (rtte.ripas != ripas) then
return FALSE;
end
addr = ToAddress(UInt(addr) + size);
end
return TRUE;
end
14.118127 RttEntryAt function
Returns the ith entry in the RTT at address
rtt.
func RttEntryAt(
rtt : AddressRmmRtt,
i : integer) => RmmRttEntry
See also:
- Section 5.56
14.119128 RttEntryIndex function
Returns the index of the entry in a level level RTT
which is identified by addr.
func RttEntryIndex(
addr : Address,
level : integer) => integer
See also:
- Section 5.56
14.120129 RttEntryStateToRmi function
Encodes the state of an RTTE.
func RttEntryStateToRmi(
state : RmmRttEntryState) => RmiRttEntryState
begin
case state of
when UNASSIGNED => return RMI_UNASSIGNED;
when ASSIGNED => return RMI_ASSIGNED;
when UNASSIGNED_NS => return RMI_UNASSIGNED;
when ASSIGNED_NS => return RMI_ASSIGNED;
when TABLE => return RMI_TABLE;
when ASSIGNED_DEV => return RMI_ASSIGNED_DEV;
when AUX_DESTROYED => return RMI_AUX_DESTROYED;
when ASSIGNED_VSMMU => return RMI_ASSIGNED_VSMMU;
end
end
14.121130 RttFold function
Returns the RTTE which results from folding the homogeneous RTT at
address rtt.
func RttFold(
rtt : RmmRtt) => RmmRttEntry
See also:
- Section 5.6.6
14.131 RttIsHomogeneous function
Returns TRUE if the RTT at address rtt is
homogeneous.
func RttIsHomogeneous( rtt : RmmRtt) => boolean
See also:
- Section 5.6.6
14.132 RttIsLive function
Returns TRUE if the RTT at address rtt is live.
func RttIsLive( rtt : RmmRtt) => boolean
14.133 RttLevelIsBlockOrPage function
Returns TRUE if level is either a block or page RTT
level for the Realm described by rd.
func RttLevelIsBlockOrPage( realm : RmmRealm, level : integer) => boolean
See also:
- Section 5.6
14.122134 RttIsHomogeneousRttLevelIsStarting function
Returns TRUE if level is the starting level of the RTT at address
for the Realm described by rttrd is
homogeneous.
func RttIsHomogeneousRttLevelIsStarting( rttrealm : RmmRttRmmRealm, level : integer) => boolean
See also:
- Section 5.5.6
14.123135 RttIsLive RttLevelIsValid function
Returns TRUE if the RTT at address rtt is live.
func RttIsLive(
rtt : RmmRtt) => boolean
See also:
Section 5.5.8
Section 5.5.9
14.124 RttLevelIsBlockOrPage
function
Returns TRUE if level is either a block or pagea valid RTT level for the Realm
described by rd.
func RttLevelIsBlockOrPageRttLevelIsValid( realm : RmmRealm, level : integer) => boolean
See also:
- Section 5.56
14.125136 RttLevelIsStarting RttLevelSize function
Returns TRUE ifthe size of the address space described by each entry in an RTT at level.
If level is the starting level of the RTT
for the Realm described by rdinvalid, the return value is unknown.
func RttLevelIsStartingRttLevelSize( realmlevel : RmmRealm, level : integer) => booleaninteger
See also:
- Section 5.56
14.126137 RttLevelIsValidRttMemAttrEqual function
Returns TRUE if level is a validthe memory attributes of the two RTT level for the Realm described by rdentries match.
func RttLevelIsValidRttMemAttrEqual( realmrtte1 : RmmRealmRmmRttEntry, levelrtte2 : integerRmmRttEntry, prot : RmmRttProtected) => boolean See also: Section 5.5begin case prot of when RTT_PROTECTED 14.127 RttLevelSize function Returns the size of the address space described by each entry in an RTT at level. If level is invalid, the return value is unknown. func RttLevelSize( level : integer) => integer return rtte1.attr_prot == rtte2.attr_prot; when RTT_UNPROTECTED => return rtte1.attr_unprot == rtte2.attr_unprot; end endSee also: Section 5.5
14.128138 RttsAllProtectedEntriesRipas RttS2APEqual function
Returns TRUE if the S2AP of the two RTT entries match.
func RttS2APEqual( rtte1 : RmmRttEntry, rtte2 : RmmRttEntry, encoding : RmmRttS2APEncoding) => boolean begin case encoding of when S2AP_DIRECT => return ( (rtte1.s2ap_direct.read == rtte2.s2ap_direct.read) && (rtte1.s2ap_direct.write == rtte2.s2ap_direct.write)); when S2AP_INDIRECT => return ( (rtte1.s2ap_indirect.base_index == rtte2.s2ap_indirect.base_index) && (rtte1.s2ap_indirect.overlay_index == rtte2.s2ap_indirect.overlay_index)); end end
14.139 RttsAllProtectedEntriesRipas function
Returns TRUE if the RIPAS of all entries identified by Protected IPAs
in all of the starting-level RTT Granules is equal to
ripas.
func RttsAllProtectedEntriesRipas(
rtt_base : Address,
rtt_num_start : integer,
ripas : RmmRipas) => boolean
14.129140 RttsAllProtectedEntriesState function
Returns TRUE if the state of all entries identified by Protected IPAs
in all of the starting-level RTT Granules is equal to
state.
func RttsAllProtectedEntriesState(
rtt_base : Address,
rtt_num_start : integer,
state : RmmRttEntryState) => boolean
14.130141 RttsAllUnprotectedEntriesState function
Returns TRUE if the state of all entries identified by Unprotected
IPAs in all of the starting-level RTT Granules is equal to
state.
func RttsAllUnprotectedEntriesState(
rtt_base : Address,
rtt_num_start : integer,
state : RmmRttEntryState) => boolean
14.131142 RttsGranuleState function
Inductive function which identifies the states of the starting-level RTT Granules.
This function is used in the definition of command footprint.
func RttsGranuleState(
rtt_base : Address,
rtt_num_start : integer)
14.132143 RttSkipEntriesIfNotState function
Scanning rtt starting from base and
terminating at top, returns the IPA of the first entry
whose state is not state.
If no entry is found whose state is state, returns the
next IPA after the last entry in rtt.
The return value is aligned to the size of the address range
described by an entry at RTT level.
func RttSkipEntriesIfNotState(
rtt : RmmRtt,
level : integer,
base : Address,
top : Address,
state : RmmRttEntryState) => Address
14.133144 RttSkipEntriesUnlessRipas function
Scanning rtt starting from ipa, returns the
IPA of the first entry whose RIPAS is ripas.
If no entry is found whose RIPAS is ripas, returns the
next IPA after the last entry in rtt.
The return value is aligned to the size of the address range
described by an entry at RTT level.
func RttSkipEntriesUnlessRipas(
rtt : RmmRtt,
level : integer,
ipa : Address,
ripas : RmmRipas) => Address
14.134145 RttSkipEntriesUnlessState function
Scanning rtt starting from ipa, returns the
IPA of the first entry whose state is state.
If no entry is found whose state is state, returns the
next IPA after the last entry in rtt.
The return value is aligned to the size of the address range
described by an entry at RTT level.
func RttSkipEntriesUnlessState(
rtt : RmmRtt,
level : integer,
ipa : Address,
state : RmmRttEntryState) => Address
14.135146 RttSkipEntriesWithRipas function
Scan rtt starting from base and terminating
at top.
- If stop_at_destroyed is FALSE then return IPA of the first entry whose state is TABLE.
- If stop_at_destroyed is TRUE then return IPA of the first entry whose state is TABLE or whose RIPAS is DESTROYED.
If no such entry is found, returns the smaller of:
- The next IPA after the last entry in
rtt - The
topargument.
The return value is aligned to the size of the address range
described by an entry at RTT level.
func RttSkipEntriesWithRipas(
rtt : RmmRtt,
level : integer,
base : Address,
top : Address,
stop_at_destroyed : boolean) => Address
begin
var result : Address = RttSkipEntriesUnlessState(
rtt, level, base, TABLE);
if stop_at_destroyed then
result = MinAddress(result,
RttSkipEntriesUnlessRipas(
rtt, level, base, DESTROYED));
end
result = MinAddress(result, top);
return AlignDownToRttLevel(result, level);
end
14.136147 RttSkipNonLiveEntries function
Scanning rtt starting from ipa, returns the
IPA of the first live entry.
If no live entry is found, returns the next IPA after the last entry
in rtt.
The return value is aligned to the size of the address range
described by an entry at RTT level.
func RttSkipNonLiveEntries(
rtt : RmmRtt,
level : integer,
ipa : Address) => Address
begin
var result : Address = RttSkipEntriesUnlessState(
rtt, level, ipa, ASSIGNED);
result = MinAddress(result,
RttSkipEntriesUnlessState(
rtt, level, ipa, ASSIGNED_NS));
result = MinAddress(result,
RttSkipEntriesUnlessState(
rtt, level, ipa, TABLE));
result = MinAddress(result,
RttSkipEntriesUnlessState(
rtt, level, ipa, ASSIGNED_DEV));
return AlignDownToRttLevel(result, level);
end
See also:
- Section 5.56.8
14.137148 RttsStateEqual function
Returns TRUE if the state of all of the starting-level RTT Granules
is equal to state.
func RttsStateEqual(
rtt_base : Address,
rtt_num_start : integer,
state : RmmGranuleState) => boolean
begin
for i = 0 to rtt_num_start - 1 do
var addr = (UInt(rtt_base) + i * RMM_GRANULE_SIZE)[(ADDRESS_WIDTH-1):0];
if (!PaIsDelegable(addr)
|| GranuleAt(addr).state != state) then
return FALSE;
end
end
return TRUE;
end
14.138149 RttWalk function
Returns the result of an RTT walk from the base of RTT tree
index owned by rd, to address
addr.
The walk does not progress beyond level.
func RttWalk(
realm : RmmRealm,
addr : Address,
level : integer,
index : integer) => RmmRttWalkResult
See also:
- Section 5.56.10
14.139150 RttWalkAnyNotAligned function
Performs one or more RTT walks within the IPA range
[base, top), on one or more RTT trees owned by
rd.
For a Realm which is configured to use an RTT tree per Plane, it is permitted for an implementation to either walk just one of the RTTs, or to walk all of them.
It is permitted for an implementation to perform multiple walks, at successive IPAs, on the same RTT.
If one of the walks performed terminates earlier than
level then the return value indicates the RTT index and the
IPA at which the walk was performed. In this case, the result’s “valid”
value is TRUE.
If none of the walks performed terminates earlier than
level then the result’s “valid” value is FALSE.
func RttWalkAnyNotAligned(
realm : RmmRealm,
base : Address,
top : Address,
level : integer) => RmmRttWalkNotAligned
14.140151 TdiIdIsFree function
Returns TRUE if tdi_id is unused within the segment
identified by segment_id.
func TdiIdIsFree(
tdi_id : bits(64),
segment_id : bits(8)) => boolean
14.141152 ToAddress function
Convert integer to Address.
func ToAddress(value : integer) => Address begin return value[(ADDRESS_WIDTH-1):0]; end
14.142153 ToBits64 function
Convert integer to Bits64.
func ToBits64(value : integer) => bits(64)
begin
return value[63:0];
end
14.143154 VdevAt function
Returns the VDEV object located at physical address
addr.
func VdevAt(
addr : Address) => RmmVdev
14.144155 VdevAuxCount function
Returns the number of auxiliary Granules required for a VDEV with the specified flags.
The return value is guaranteed not to be greater than 32.
For a given flags value, this function always returns the same value.
func VdevAuxCount(
pdev_flags : RmiPdevFlags,
vdev_flags : RmiVdevFlags) => integer
14.145156 VersionEqual function
Returns TRUE if command result matches the stated value.
func VersionEqual(
ver1 : RmiInterfaceVersion,
ver2 : RmiInterfaceVersion) => boolean
func VersionEqual(
ver1 : RsiInterfaceVersion,
ver2 : RsiInterfaceVersion) => boolean
See also:
- Section 13
14.146157 VmidsAreFree function
Returns TRUE if vmid is unused.
func VmidsAreFree(
vmid : array[4] of bits(16)) => boolean
func VmidsAreFree(
vmid : bits(16),
aux_vmid : array [3] of bits(16)) => boolean
14.147158 VmidsAreValid function
Returns TRUE if vmid is valid on the platform.
func VmidsAreValid(
vmid : bits(16),
aux_vmid : array [3] of bits(16)) => boolean
14.148159 VsidIsFree function
Returns TRUE if vsid is unused within the VSMMU
vsmmu.
func VsidIsFree(
vsmmu : RmmVsmmu,
vsid : bits(64)) => boolean
14.149160 VsmmuAt function
Returns the VSMMU object located at physical address
addr.
func VsmmuAt(
addr : Address) => RmmVsmmu
See also:
- Section 9.6
14.150161 VsmmuIsLive function
Returns TRUE if the VSMMU located at physical address
addr is live.
func VsmmuIsLive(
addr : Address) => boolean
See also:
- Section 9.6.3
15 Realm Management Interface
This chapter defines the interface used by the Host to manage Realms.
15.1 RMI version
This specification defines version 1.1 of the Realm Management Interface.
15.2 RMI command return codes
The return code of an RMI command is a tuple which contains status and index fields.
The status field of an RMI command return code indicates whether the command
- succeeded, or
- failed, and the reason for the failure.
If an RMI command succeeds then the status of its return code is RMI_SUCCESS.
The index field of an RMI command return code can provide additional information about the reason for a command failure. The meaning of the index field depends on the status, and is described by the following table.
| Status | Description | Meaning of index |
|---|---|---|
| RMI_SUCCESS | Command completed successfully | None: index is zero. |
| RMI_ERROR_INPUT | The value of a command input value caused the command to fail | None: index is zero. |
| RMI_ERROR_REALM | An attribute of a Realm does not match the expected value | Varies between usages. See individual commands for details. |
| RMI_ERROR_REC | An attribute of a REC does not match the expected value | None: index is zero. |
| RMI_ERROR_RTT | An RTT walk terminated before reaching the target RTT level, or reached an RTTE with an unexpected value | RTT level at which the walk terminated. |
| RMI_ERROR_RTT_AUX | RTTE in an auxiliary RTT contained an unexpected value | In some cases, indicates auxiliary RTT level at which the walk terminated. See individual commands for details. |
Multiple failure conditions in an RMI command may return the same error code - that is, the same status and index values.
If an input to an RMI command uses an invalid encoding then the command fails and returns RMI_ERROR_INPUT.
Command inputs include registers and in-memory data structures.
Invalid encodings include:
- using a reserved encoding in an enumeration
See also:
- Section 15.4.3
15.3 RMI commands
The following table summarizes the FIDs of commands in the RMI interface.
15.3.1 RMI_DATA_CREATE command
Creates a Data Granule, copying contents from a Non-secure Granule provided by the caller.
15.3.1.1 Interface
15.3.1.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000153 |
| rd | X1 | 63:0 | Address | PA of the RD for the target Realm |
| data | X2 | 63:0 | Address | PA of the target Data |
| ipa | X3 | 63:0 | Address | IPA at which the Granule will be mapped in the target Realm |
| src | X4 | 63:0 | Address | PA of the source Granule |
| flags | X5 | 63:0 | RmiDataFlags | Flags |
15.3.1.1.2 Context
The RMI_DATA_CREATE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm_pre | RmmRealm | RealmAt(rd) |
true | Realm |
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| walk | RmmRttWalkResult | RttWalk( realm, ipa, RMM_RTT_PAGE_LEVEL, RMM_RTT_TREE_PRIMARY) |
false | RTT walk result |
| entry_idx | UInt64 | RttEntryIndex( ipa, walk.level) |
false | RTTE index |
15.3.1.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.1.2 Failure conditions
| ID | Condition |
|---|---|
| src_align | pre: !AddrIsGranuleAligned(src) post: ResultEqual(result, RMI_ERROR_INPUT) |
| src_pas | pre: !GranuleAccessPermitted(src, PAS_NS) post: ResultEqual(result, RMI_ERROR_INPUT) |
| data_align | pre: !AddrIsGranuleAligned(data) post: ResultEqual(result, RMI_ERROR_INPUT) |
| data_bound | pre: !PaIsDelegablePaIsDelegableDram(data) post: ResultEqual(result, RMI_ERROR_INPUT) |
| data_state | pre: GranuleAt(data).state != DELEGATED post: ResultEqual(result, RMI_ERROR_INPUT) |
| data_bound2 | pre: ((realm.feat_lpa2 == FEATURE_FALSE) && (UInt(data) >= 2^48)) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_align | pre: !AddrIsGranuleAligned(ipa) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_bound | pre: !AddrIsProtected(ipa, realm_pre) post: ResultEqual(result, RMI_ERROR_INPUT) |
| realm_state | pre: realm_pre.state != REALM_NEW post: ResultEqual(result, RMI_ERROR_REALM) |
| rtt_walk | pre: walk.level < RMM_RTT_PAGE_LEVEL post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
| rtte_state | pre: walk.rtte.state != UNASSIGNED post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
15.3.1.2.1 Failure condition ordering
[rd_bound, rd_state] < [realm_state]
[rd_bound, rd_state] < [rtt_walk, rtte_state]
[ipa_bound] < [rtt_walk, rtte_state]
15.3.1.3 Success conditions
| ID | Condition |
|---|---|
| data_state | GranuleAt(data).state == DATA |
| data_content |
Contents of target Granule are copied from source Granule.
|
| rtte_state | walk.rtte.state == ASSIGNED |
| rtte_ripas | walk.rtte.ripas == RAM |
| rtte_addr | walk.rtte.addr == data |
| rtte_memattr | walk.rtte.attr_prot == MEMATTR_CACHEABLE |
| rtte_sh | walk.rtte.sh == SHAREABILITY_INNER |
| rim | realm.measurements[0] == RimExtendData( realm_pre, ipa, data, flags) |
15.3.1.4 RMI_DATA_CREATE extension of RIM
On successful execution of RMI_DATA_CREATE, the new RIM value of the target Realm is calculated by the RMM as follows:
If flags.measure == RMI_MEASURE_CONTENT then using the RHA of the target Realm, compute the hash of the contents of the DATA Granule.
Allocate an RmmMeasurementDescriptorData data structure.
Populate the measurement descriptor:
- Set the desc_type field to the descriptor type.
- Set the len field to the descriptor length.
- Set the rim field to the current RIM value of the target Realm.
- Set the ipa field to the IPA at which the DATA Granule is mapped in the target Realm.
- Set the flags field to the flags provided by the Host.
- If flags.measure == RMI_MEASURE_CONTENT then set the content field to the hash of the contents of the DATA Granule. Otherwise, set the content field to zero.
- Using the RHA of the target Realm, compute the hash of the measurement descriptor. Set the RIM of the target Realm to this value, zero filling upper bytes if the RHA output is smaller than the size of the RIM.
15.3.1.5 Footprint
| ID | Value |
|---|---|
| data_state | GranuleAt(data).state |
| rim | realm.measurements[0] |
| rtte | RttEntryAt(RttAt(walk.rtt_addr), entry_idx) |
15.3.2 RMI_DATA_CREATE_UNKNOWN command
Creates a Data Granule with unknown contents.
15.3.2.1 Interface
15.3.2.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000154 |
| rd | X1 | 63:0 | Address | PA of the RD for the target Realm |
| data | X2 | 63:0 | Address | PA of the target Data |
| ipa | X3 | 63:0 | Address | IPA at which the Granule will be mapped in the target Realm |
15.3.2.1.2 Context
The RMI_DATA_CREATE_UNKNOWN command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| walk | RmmRttWalkResult | RttWalk( realm, ipa, RMM_RTT_PAGE_LEVEL, RMM_RTT_TREE_PRIMARY) |
false | RTT walk result |
| entry_idx | UInt64 | RttEntryIndex( ipa, walk.level) |
false | RTTE index |
15.3.2.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.2.2 Failure conditions
| ID | Condition |
|---|---|
| data_align | pre: !AddrIsGranuleAligned(data) post: ResultEqual(result, RMI_ERROR_INPUT) |
| data_bound | pre: !PaIsDelegablePaIsDelegableDram(data) post: ResultEqual(result, RMI_ERROR_INPUT) |
| data_state | pre: GranuleAt(data).state != DELEGATED post: ResultEqual(result, RMI_ERROR_INPUT) |
| data_bound2 | pre: ((realm.feat_lpa2 == FEATURE_FALSE) && (UInt(data) >= 2^48)) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_align | pre: !AddrIsGranuleAligned(ipa) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_bound | pre: !AddrIsProtected(ipa, realm) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rtt_walk | pre: walk.level < RMM_RTT_PAGE_LEVEL post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
| rtte_state | pre: walk.rtte.state != UNASSIGNED post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
15.3.2.2.1 Failure condition ordering
[rd_bound, rd_state] < [rtt_walk, rtte_state]
[ipa_bound] < [rtt_walk, rtte_state]
15.3.2.3 Success conditions
| ID | Condition |
|---|---|
| data_state | GranuleAt(data).state == DATA |
| data_content | Contents of target Granule are wiped. |
| rtte_state | walk.rtte.state == ASSIGNED |
| rtte_addr | walk.rtte.addr == data |
| rtte_memattr | walk.rtte.attr_prot == MEMATTR_CACHEABLE |
| rtte_sh | walk.rtte.sh == SHAREABILITY_INNER |
15.3.2.4 Footprint
| ID | Value |
|---|---|
| data_state | GranuleAt(data).state |
| rtte | RttEntryAt(RttAt(walk.rtt_addr), entry_idx) |
15.3.3 RMI_DATA_DESTROY command
Destroys a Data Granule.
15.3.3.1 Interface
15.3.3.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000155 |
| rd | X1 | 63:0 | Address | PA of the RD which owns the target Data |
| ipa | X2 | 63:0 | Address | IPA at which the Granule is mapped in the target Realm |
15.3.3.1.2 Context
The RMI_DATA_DESTROY command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| walk | RmmRttWalkResult | RttWalk( realm, ipa, RMM_RTT_PAGE_LEVEL, RMM_RTT_TREE_PRIMARY) |
false | RTT walk result |
| entry_idx | UInt64 | RttEntryIndex( ipa, walk.level) |
false | RTTE index |
| walk_top | Address | RttSkipNonLiveEntries( RttAt(walk.rtt_addr), walk.level, ipa) |
false | Top IPA of non-live RTT entries, from entry at which the RTT walk terminated |
15.3.3.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| data | X1 | 63:0 | Address | PA of the Data Granule which was destroyed |
| top | X2 | 63:0 | Address | Top IPA of non-live RTT entries, from entry at which the RTT walk terminated |
The data output value is valid only when the command
result is RMI_SUCCESS.
The values of the result and top output
values for different command outcomes are summarized in the following
table.
| Scenario | result | top | walk.rtte.state |
|---|---|---|---|
ipa is mapped as a page and RIPAS is RAM |
RMI_SUCCESS | > ipa | Before execution: ASSIGNED and RIPAS is RAM After execution: UNASSIGNED and RIPAS is DESTROYED |
ipa is mapped as a page and RIPAS is not RAM |
RMI_SUCCESS | > ipa | Before execution: ASSIGNED and RIPAS is not RAM After execution: UNASSIGNED and RIPAS is unchanged |
ipa is not mapped |
(RMI_ERROR_RTT, <= 3) | > ipa | UNASSIGNED |
ipa is mapped as a block |
(RMI_ERROR_RTT, 0 0 < level < 3) |
== ipa | ASSIGNED |
| RTT walk was not performed, due to any other command failure | Another error code | 0 | Unknown |
See also:
- Section 5.56.8
15.3.3.2 Failure conditions
| ID | Condition |
|---|---|
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_align | pre: !AddrIsGranuleAligned(ipa) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_bound | pre: !AddrIsProtected(ipa, realm) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rtt_walk | pre: walk.level < RMM_RTT_PAGE_LEVEL post: (ResultEqual(result, RMI_ERROR_RTT, walk.level) && (top == walk_top)) |
| rtte_state | pre: walk.rtte.state != ASSIGNED post: (ResultEqual(result, RMI_ERROR_RTT, walk.level) && (top == walk_top)) |
| aux_live | pre: AddrIsAuxLive(ipa, realm) post: ResultEqual(result, RMI_ERROR_RTT_AUX, 0) |
15.3.3.2.1 Failure condition ordering
[rd_bound, rd_state] < [rtt_walk, rtte_state, aux_live]
[ipa_bound] < [rtt_walk, rtte_state, aux_live]
15.3.3.3 Success conditions
| ID | Condition |
|---|---|
| data_state | GranuleAt(walk.rtte.addr).state == DELEGATED |
| rtte_state | walk.rtte.state == UNASSIGNED |
| ripas_ram | pre: walk.rtte.ripas == RAM post: walk.rtte.ripas == DESTROYED |
| data | data == walk.rtte.addr |
| top | top == walk_top |
15.3.3.4 Footprint
| ID | Value |
|---|---|
| data_state | GranuleAt(walk.rtte.addr).state |
| rtte | RttEntryAt(RttAt(walk.rtt_addr), entry_idx) |
15.3.4 RMI_DEV_MEM_MAP command
Maps device memory.
See also:
- Section 9
15.3.4.1 Interface
15.3.4.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000172 |
| rd | X1 | 63:0 | Address | PA of the RD for the target Realm |
| ipa | X2 | 63:0 | Address | IPA at which the Granule will be mapped in the target Realm |
| level | X3 | 63:0 | Int64 | RTT level |
| addr | X4 | 63:0 | Address | PA of the target device memory |
15.3.4.1.2 Context
The RMI_DEV_MEM_MAP command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| walk | RmmRttWalkResult | RttWalk( realm, ipa, level, RMM_RTT_TREE_PRIMARY) |
false | RTT walk result |
| entry_idx | UInt64 | RttEntryIndex( ipa, walk.level) |
false | RTTE index |
| gran_state_pre | RmmGranuleState | GranuleAt(addr).state |
true | Previous Granule state |
15.3.4.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.4.2 Failure conditions
| ID | Condition |
|---|---|
| addr_align | pre: !AddrIsGranuleAligned(addr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| addr_bound | pre: !PaIsDelegablePaIsDelegableDevMem(addr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| addr_state | pre: GranuleAt(addr).state != DEV_DELEGATEDDELEGATED post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| level_bound | pre: !RttLevelIsBlockOrPage(realm, level) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_align | pre: !AddrIsGranuleAligned(ipa) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_bound | pre: !AddrIsProtected(ipa, realm) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rtt_walk | pre: walk.level < level post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
| rtte_state | pre: walk.rtte.state != UNASSIGNED post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
15.3.4.2.1 Failure condition ordering
[rd_bound, rd_state] < [rtt_walk, rtte_state]
[level_bound, ipa_bound] < [rtt_walk, rtte_state]
15.3.4.3 Success conditions
| ID | Condition |
|---|---|
| state | GranuleAt(addr).state == DEV_MAPPED |
| rtte_state | walk.rtte.state == ASSIGNED_DEV |
| rtte_addr | walk.rtte.addr == addr |
| rtte_attr_ncoh | pre: PaIsDelegableNonCohDevMem(addr) post: walk.rtte.attr_prot == MEMATTR_NON_CACHEABLE |
| rtte_attr_coh | pre: PaIsDelegableCohDevMem(addr) post: walk.rtte.attr_prot == MEMATTR_PASSTHROUGH |
| rtte_sh_ncoh | pre: PaIsDelegableNonCohDevMem(addr) post: walk.rtte.sh == SHAREABILITY_OUTER |
| rtte_sh_coh | pre: PaIsDelegableCohDevMem(addr) post: walk.rtte.sh == SHAREABILITY_INNER |
15.3.4.4 Footprint
| ID | Value |
|---|---|
| state | GranuleAt(addr).state |
| rtte | RttEntryAt(RttAt(walk.rtt_addr), entry_idx) |
15.3.5 RMI_DEV_MEM_UNMAP command
Unmaps device memory.
Consider how teardown of DRAM mappings (via RMI_DATA_DESTROY) composes with teardown of device memory mappings (via RMI_DEV_MEM_UNMAP). In each case, the command returns the IPA of the next live entry - but it doesn’t tell the caller whether this is DRAM or IO. How then can the caller know which of the two commands to call next, while still avoiding a (race-prone) call to RMI_RTT_READ_ENTRY?
See also:
- Section 9
15.3.5.1 Interface
15.3.5.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000173 |
| rd | X1 | 63:0 | Address | PA of the RD which owns the target device memory Granule |
| ipa | X2 | 63:0 | Address | IPA at which the Granule is mapped in the target Realm |
| level | X3 | 63:0 | Int64 | RTT level |
15.3.5.1.2 Context
The RMI_DEV_MEM_UNMAP command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| walk | RmmRttWalkResult | RttWalk( realm, ipa, RMM_RTT_PAGE_LEVEL level, RMM_RTT_TREE_PRIMARY) |
false | RTT walk result |
| rtte_state_pre | RmmRttEntryState | walk.rtte.state |
true | RTT entry state |
| entry_idx | UInt64 | RttEntryIndex( ipa, walk.level) |
false | RTTE index |
| walk_top | Address | RttSkipNonLiveEntries( RttAt(walk.rtt_addr), walk.level, ipa) |
false | Top IPA of non-live RTT entries, from entry at which the RTT walk terminated |
15.3.5.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| iopa | X1 | 63:0 | Address | PA of the device memory Granule which was unmapped |
| top | X2 | 63:0 | Address | Top IPA of non-live RTT entries, from entry at which the RTT walk terminated |
The values of the result and top output
values for different command outcomes are summarized in the following
table.
| Scenario | result | top | walk.rtte.state |
|---|---|---|---|
ipa is mapped at the target level |
RMI_SUCCESS | > ipa | Before execution: ASSIGNED_DEV After execution: UNASSIGNED |
ipa is not mapped |
(RMI_ERROR_RTT, <= level) | > ipa | UNASSIGNED |
ipa is mapped at a lower level |
(RMI_ERROR_RTT, < level) | == ipa | ASSIGNED_DEV |
| RTT walk was not performed, due to any other command failure | Another error code | 0 | Unknown |
See also:
- Section 5.6.8
15.3.5.2 Failure conditions
| ID | Condition |
|---|---|
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_alignlevel_bound | pre: !AddrIsGranuleAlignedRttLevelIsBlockOrPage(iparealm, level) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_align | pre: !AddrIsRttLevelAligned(ipa, level) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_bound | pre: !AddrIsProtected(ipa, realm) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rtt_walk | pre: walk.level < RMM_RTT_PAGE_LEVELlevel post: (ResultEqual(result, RMI_ERROR_RTT, walk.level) && (top == walk_top)) |
| rtte_state | pre: walk.rtte.state != ASSIGNED_DEV post: (ResultEqual(result, RMI_ERROR_RTT, walk.level) && (top == walk_top)) |
15.3.5.2.1 Failure condition ordering
[rd_bound, rd_state] < [rtt_walk, rtte_state]
[ipa_bound][level_bound, ipa_bound] < [rtt_walk, rtte_state]
15.3.5.3 Success conditions
| ID | Condition |
|---|---|
| state | GranuleAt(walk.rtte.addr).state == DEV_DELEGATEDDELEGATED |
| rtte_state | walk.rtte.state == UNASSIGNED |
| ripas_dev | pre: walk.rtte.ripas == DEV post: walk.rtte.ripas == DESTROYED |
| iopa | iopa == walk.rtte.addr |
| top | top == walk_top |
15.3.5.4 Footprint
| ID | Value |
|---|---|
| state | GranuleAt(walk.rtte.addr).state |
| rtte | RttEntryAt(RttAt(walk.rtt_addr), entry_idx) |
15.3.6 RMI_FEATURES command
Read feature register.
The following table indicates which feature register is returned depending on the index provided.
| Index | Feature register |
|---|---|
| 0 | RMI feature register 0 |
| 1 | RMI feature register 1 |
See also:
- Section 3
15.3.6.1 Interface
15.3.6.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000165 |
| index | X1 | 63:0 | UInt64 | Feature register index |
15.3.6.1.2 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| value | X1 | 63:0 | Bits64 | Feature register value |
15.3.6.2 Failure conditions
The RMI_FEATURES command does not have any failure conditions.
15.3.6.3 Success conditions
| ID | Condition |
|---|---|
| value | value == RmiFeatureRegisterEncode(index) |
15.3.6.4 Footprint
The RMI_FEATURES command does not have any footprint.
15.3.7 RMI_GRANULE_DELEGATE command
Delegates a Granule.
15.3.7.1 Interface
15.3.7.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000151 |
| addr | X1 | 63:0 | Address | PA of the target Granule |
15.3.7.1.2 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.7.2 Failure conditions
| ID | Condition |
|---|---|
| gran_align | pre: !AddrIsGranuleAligned(addr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| gran_bound | pre: !PaIsDelegable(addr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| gran_state | pre: GranuleAt(addr).state != UNDELEGATED post: ResultEqual(result, RMI_ERROR_INPUT) |
15.3.7.2.1 Failure condition ordering
The RMI_GRANULE_DELEGATE command does not have any failure condition orderings.
15.3.7.3 Success conditions
| ID | Condition |
|---|---|
| gran_state | GranuleAt(addr).state == DELEGATED |
| gran_gpt | GranuleAt(addr).gpt == GPT_REALM |
15.3.7.4 Footprint
15.3.8 RMI_GRANULE_DEV_DELEGATERMI_GRANULE_UNDELEGATE command
DelegateUndelegates a Granule of device memory.
15.3.8.1 Interface
15.3.8.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001700xC4000152 |
| addr | X1 | 63:0 | Address | PA of the target Granule |
15.3.8.1.2 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.8.2 Failure conditions
| ID | Condition |
|---|---|
| gran_align | pre: !AddrIsGranuleAligned(addr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| gran_bound | pre: !PaIsDelegable(addr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| gran_state | pre: GranuleAt(addr).state != DEV_UNDELEGATEDDELEGATED post: ResultEqual(result, RMI_ERROR_INPUT) |
15.3.8.2.1 Failure condition ordering
The RMI_GRANULE_DEV_DELEGATERMI_GRANULE_UNDELEGATE command does not have any failure condition orderings.
15.3.8.3 Success conditions
| ID | Condition |
|---|---|
| stategran_gpt | GranuleAt(addr).gpt != GPT_REALM |
| gran_state | GranuleAt(addr).state == DEV_DELEGATEDUNDELEGATED |
| gptgran_content | GranuleAt(addr)Contents of target Granule are wiped.gpt == GPT_REALM |
See also:
- Section 2.2.5
15.3.8.4 Footprint
15.3.9 RMI_GRANULE_DEV_UNDELEGATERMI_MEC_SET_PRIVATE command
Undelegate a Granule of device memoryChange state of a MEC to Private.
15.3.9.1 Interface
15.3.9.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001710xC400018D |
| addrmecid | X1 | 63:0 | AddressBits64 | PA of the target GranuleMECID |
15.3.9.1.2 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.9.2 Failure conditions
| ID | Condition |
|---|---|
| gran_alignmecid_bound | pre: !AddrIsGranuleAlignedUInt(mecid) > UInt(ImplFeatures(addr).max_mecid) post: ResultEqual(result, RMI_ERROR_INPUT) |
| gran_boundstate | pre: !PaIsDelegableMecState(addrmecid) != MEC_STATE_SHARED post: ResultEqual(result, RMI_ERROR_INPUT) |
| gran_statemembers | pre: GranuleAtMecMembers(addrmecid).state != DEV_DELEGATED0 post: ResultEqual(result, RMI_ERROR_INPUT) |
15.3.9.2.1 Failure condition ordering
The RMI_GRANULE_DEV_UNDELEGATERMI_MEC_SET_PRIVATE command does not have any failure condition orderings.
15.3.9.3 Success conditions
| ID | Condition |
|---|---|
| gptmec_state | GranuleAtMecState(addrmecid).gpt ! = GPT_REALM= MEC_STATE_PRIVATE_UNASSIGNED |
15.3.9.4 Footprint
ID Value gpt GranuleAt(addr)The RMI_MEC_SET_PRIVATE command does not have any footprint.gpt state GranuleAt(addr).state
15.3.10 RMI_GRANULE_UNDELEGATERMI_MEC_SET_SHARED command
Undelegates a GranuleChange state of a MEC to Shared.
15.3.10.1 Interface
15.3.10.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001520xC400018C |
| addrmecid | X1 | 63:0 | AddressBits64 | PA of the target GranuleMECID |
15.3.10.1.2 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.10.2 Failure conditions
| ID | Condition |
|---|---|
| gran_alignmecid_bound | pre: !AddrIsGranuleAlignedUInt(mecid) > UInt(ImplFeatures(addr).max_mecid) post: ResultEqual(result, RMI_ERROR_INPUT) |
| gran_boundstate | pre: !PaIsDelegableMecState(addrmecid) != MEC_STATE_PRIVATE_UNASSIGNED post: ResultEqual(result, RMI_ERROR_INPUT) |
15.3.10.2.1 Failure condition ordering
The RMI_GRANULE_UNDELEGATERMI_MEC_SET_SHARED command does not have any failure condition orderings.
15.3.10.3 Success conditions
| ID | Condition |
|---|---|
| gran_gptmec_state | GranuleAtMecState(addrmecid).gpt ! = GPT_REALM= MEC_STATE_SHARED |
15.3.10.4 Footprint
ID Value gran_gpt GranuleAt(addr)The RMI_MEC_SET_SHARED command does not have any footprint.gpt gran_state GranuleAt(addr).state
15.3.11 RMI_MEC_SET_PRIVATE RMI_PDEV_ABORT command
Change state of a MEC to PrivateAbort device communication associated with a PDEV.
See also:
- Section 119 Section 15.3.12
15.3.11.1 Interface
15.3.11.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400018D0xC4000174 |
| mecidpdev_ptr | X1 | 63:0 | Bits64Address | MECIDPA of the PDEV |
15.3.11.1.2 Output valuesContext
The RMI_PDEV_ABORT command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| pdev | RmmPdev | PdevAt(pdev_ptr) |
false | PDEV |
| pdev_state_pre | RmmPdevState |
pdev.state
|
true | Previous state |
15.3.11.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.11.2 Failure conditions
| ID | Condition |
|---|---|
| mecid_boundda_supp | pre: UInt(mecid) > UInt(ImplFeatures().max_mecid)feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_NOT_SUPPORTED) |
| statepdev_align | pre: MecState!AddrIsGranuleAligned(mecidpdev_ptr) != MEC_STATE_SHARED post: ResultEqual(result, RMI_ERROR_INPUT) |
| memberspdev_bound | pre: MecMembers!PaIsDelegable(mecidpdev_ptr) != 0 post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_gran_state | pre: GranuleAt(pdev_ptr).state != PDEV post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_state | pre: (pdev.state != PDEV_NEW && pdev.state != PDEV_HAS_KEY && pdev.state != PDEV_COMMUNICATING) post: ResultEqual(result, RMI_ERROR_DEVICE) |
15.3.11.2.1 Failure condition ordering
[da_supp] < [pdev_align, pdev_bound, pdev_gran_state]
[pdev_gran_state] < [pdev_state]
The RMI_MEC_SET_PRIVATE command does not have any failure condition
orderings.
15.3.11.3 Success conditions
| ID | Condition |
|---|---|
| mec_statecomm | MecState(mecid)pre: pdev_state_pre == MEC_STATE_PRIVATE_UNASSIGNEDPDEV_COMMUNICATING post: (pdev.state == PDEV_READY && pdev.comm_state == DEV_COMM_IDLE) |
| not_comm | pre: pdev_state_pre != PDEV_COMMUNICATING post: pdev.comm_state == DEV_COMM_PENDING |
15.3.11.4 Footprint
The RMI_MEC_SET_PRIVATE command does not have any footprint| ID | Value |
|---|---|
| state | pdev.state |
| comm_state |
pdev.comm_state
|
15.3.12 RMI_MEC_SET_SHAREDRMI_PDEV_AUX_COUNT command
Change state of a MEC to SharedGet number of auxiliary Granules required for a PDEV.
See also: Section 11 Section 15.3.1115.3.12.1 Interface
15.3.12.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400018C0xC4000156 |
| mecidflags | X1 | 63:0 | Bits64 | MECIDPDEV flags |
15.3.12.1.2 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| aux_count | X1 | 63:0 | UInt64 | Number of auxiliary Granules required for a PDEV |
15.3.12.2 Failure conditions
| ID | Condition |
|---|---|
| mecid_boundda_supp | pre: UInt(mecid) > UInt(ImplFeatures().max_mecid)feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_NOT_SUPPORTED) |
15.3.12.3 Success conditions
| ID | Condition |
|---|---|
| mec_stateaux_count | MecStateaux_count == PdevAuxCount(mecidRmiPdevFlagsDecode(flags) == MEC_STATE_SHARED) |
15.3.12.4 Footprint
The RMI_MEC_SET_SHAREDRMI_PDEV_AUX_COUNT command does not have any footprint.
15.3.13 RMI_PDEV_ABORT RMI_PDEV_COMMUNICATE command
AbortPerform device communication associated with a PDEV.
See also:
- Section 9
15.3.13.1 Interface
15.3.13.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001740xC4000175 |
| pdev_ptr | X1 | 63:0 | Address | PA of the PDEV |
| data_ptr | X2 | 63:0 | Address | PA of the communication data structure |
15.3.13.1.2 Context
The RMI_PDEV_ABORTRMI_PDEV_COMMUNICATE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| pdev | RmmPdev | PdevAt(pdev_ptr) |
false | PDEV |
| pdev_state_pre | RmmPdevState | pdevPdevAt(pdev_ptr).state |
true | PreviousPDEV previous state |
| data | RmiDevCommData | RmiDevCommDataAt(data_ptr) |
false | Device communication object |
15.3.13.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.13.2 Failure conditions
| ID | Condition |
|---|---|
| da_supp | pre: ImplFeatures().feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_NOT_SUPPORTED) |
| pdev_align | pre: !AddrIsGranuleAligned(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_bound | pre: !PaIsDelegable(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_gran_state | pre: GranuleAt(pdev_ptr).state != PDEV post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_statedata_align | pre: !AddrIsGranuleAligned(pdev.state != PDEV_NEW && pdev.state != PDEV_HAS_KEY && pdev.state != PDEV_COMMUNICATINGdata_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| data_pas | pre: !GranuleAccessPermitted(data_ptr, PAS_NS) post: ResultEqual(result, RMI_ERROR_INPUT) |
| req_align | pre: !AddrIsGranuleAligned(data.enter.req_addr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| req_pas | pre: !GranuleAccessPermitted(data.enter.req_addr, PAS_NS) post: ResultEqual(result, RMI_ERROR_INPUT) |
| resp_align | pre: !AddrIsGranuleAligned(data.enter.resp_addr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| resp_pas | pre: !GranuleAccessPermitted(data.enter.resp_addr, PAS_NS) post: ResultEqual(result, RMI_ERROR_INPUT) |
| resp_len | pre: data.enter.resp_len > RMM_GRANULE_SIZE post: ResultEqual(result, RMI_ERROR_INPUT) |
| comm_state | pre: (pdev.comm_state == DEV_COMM_IDLE || pdev.comm_state == DEV_COMM_ERROR) post: ResultEqual(result, RMI_ERROR_DEVICE) |
15.3.13.2.1 Failure condition ordering
[da_supp] < [pdev_align, pdev_bound, pdev_gran_state]pdev_gran_state, data_align,
data_pas, req_align, req_pas, resp_align, resp_pas, resp_len]
[pdev_gran_state] < [pdev_state][comm_state]
15.3.13.3 Success conditions
| ID | Condition |
|---|---|
| commcomm_state | pre: pdev_state_prepdev.comm_state == PDEV_COMMUNICATINGDeviceCommunicate post: (pdev.state, data) |
| error | pre: (DeviceCommunicate(pdev, data) == PDEV_READYDEV_COMM_ERROR && pdev.comm_statestate != PDEV_STOPPING) post: pdev.state == PDEV_ERROR |
| new | pre: (DeviceCommunicate(pdev, data) == DEV_COMM_IDLE && pdev_state_pre == PDEV_NEW) post: pdev.state == PDEV_NEEDS_KEY |
| not_commhas_key | pre: (DeviceCommunicate(pdev, data) == DEV_COMM_IDLE && pdev_state_pre == PDEV_HAS_KEY) post: pdev.state == PDEV_READY |
| ready | pre: (DeviceCommunicate(pdev, data) == DEV_COMM_IDLE && pdev_state_pre == PDEV_READY) post: pdev.state == PDEV_READY |
| stopped | pre: (DeviceCommunicate(pdev, data) != DEV_COMM_ACTIVE && pdev_state_pre == PDEV_STOPPING) post: pdev.state == PDEV_STOPPED |
| communicating | pre: (DeviceCommunicate(pdev, data) == DEV_COMM_IDLE && pdev_state_pre == PDEV_COMMUNICATING) post: pdev.comm_statestate == DEV_COMM_PENDINGPDEV_READY |
| ide_resetting | pre: (DeviceCommunicate(pdev, data) == DEV_COMM_IDLE && pdev_state_pre == PDEV_IDE_RESETTING) post: pdev.state == PDEV_READY |
15.3.13.4 Footprint
| ID | Value |
|---|---|
| state | pdev.state |
| comm_state | pdev.comm_state |
15.3.14 RMI_PDEV_AUX_COUNTRMI_PDEV_CREATE command
Get number of auxiliary Granules required forCreate a PDEV.
See also:
- Section 9
15.3.14.1 Interface
15.3.14.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001560xC4000176 |
| flagspdev_ptr | X1 | 63:0 | Bits64Address | PA of the PDEV flags |
| params_ptr | X2 | 63:0 | Address | PA of PDEV parameters |
15.3.14.1.2 Output valuesContext
The RMI_PDEV_CREATE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| pdev | RmmPdev | PdevAt(pdev_ptr) |
false | PDEV |
| params | RmiPdevParams | RmiPdevParamsAt(params_ptr) |
false | PDEV parameters |
15.3.14.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.14.2 Failure conditions
| ID | Condition |
|---|---|
| da_supp | pre: ImplFeatures().feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_NOT_SUPPORTED) |
| pdev_align | pre: !AddrIsGranuleAligned(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_bound | pre: !PaIsDelegableDram(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_state | pre: GranuleAt(pdev_ptr).state != DELEGATED post: ResultEqual(result, RMI_ERROR_INPUT) |
| params_align | pre: !AddrIsGranuleAligned(params_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| params_pas | pre: !GranuleAccessPermitted(params_ptr, PAS_NS) post: ResultEqual(result, RMI_ERROR_INPUT) |
| params_valid | pre: !RmiPdevParamsIsValid(params_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| num_aux | pre: params.num_aux != PdevAuxCount(params.flags) post: ResultEqual(result, RMI_ERROR_INPUT) |
| aux_align | pre: !AuxAligned32(params.aux, params.num_aux) post: ResultEqual(result, RMI_ERROR_INPUT) |
| aux_alias | pre: AuxAlias32(pdev_ptr, params.aux, params.num_aux) post: ResultEqual(result, RMI_ERROR_INPUT) |
| aux_state | pre: !AuxStateEqual32( params.aux, params.num_aux, DELEGATED) post: ResultEqual(result, RMI_ERROR_INPUT) |
15.3.14.2.1 Failure condition ordering
[da_supp] < [pdev_align, pdev_bound, pdev_state, params_align,
params_pas, params_valid, num_aux, aux_align, aux_alias,
aux_state]
15.3.14.3 Success conditions
| ID | Condition |
|---|---|
| aux_countgran_state | aux_countGranuleAt(pdev_ptr).state == PDEV |
| pdev_id |
pdev.pdev_id == params.pdev_id
|
| prot | Equal(pdev.prot, params.flags.prot) |
| segment_id |
pdev.segment_id == params.segment_id
|
| ecam_addr |
pdev.ecam_addr == params.ecam_addr
|
| root_id |
pdev.root_id == params.root_id
|
| cert_id |
pdev.cert_id == params.cert_id
|
| rid_base |
pdev.rid_base == params.rid_base
|
| rid_top |
pdev.rid_top == params.rid_top
|
| hash_algo | Equal(pdev.hash_algo, params.hash_algo) |
| ide_sid |
pdev.ide_sid == params.ide_sid
|
| ncoh_num_addr_range |
pdev.ncoh_num_addr_range == params.ncoh_num_addr_range
|
| ncoh_addr_range | RmiAddressRangesEqual16( pdev.ncoh_addr_range, params.ncoh_addr_range, params.ncoh_num_addr_range) |
| coh_num_addr_range |
pdev.coh_num_addr_range == params.coh_num_addr_range
|
| coh_addr_range | RmiAddressRangesEqual4( pdev.coh_addr_range, params.coh_addr_range, params.coh_num_addr_range) |
| state | pdev.state == PDEV_NEW |
| comm_state | pdev.comm_state == DEV_COMM_PENDING |
| num_vdevs |
pdev.num_vdevs == 0
|
| aux | AuxEqual32( pdev.aux, params.aux, PdevAuxCount(RmiPdevFlagsDecode(params.flags)) |
| num_aux | pdev.num_aux == PdevAuxCount(params.flags) |
| aux_state | AuxStateEqual32( pdev.aux, PdevAuxCount(params.flags), PDEV_AUX) |
15.3.14.4 Footprint
The RMI_PDEV_AUX_COUNT command does not have any footprint| ID | Value |
|---|---|
| state | GranuleAt(pdev_ptr).state |
| aux_state | AuxStates( pdev.aux, PdevAuxCount(params.flags)) |
15.3.15 RMI_PDEV_COMMUNICATERMI_PDEV_DESTROY command
Perform device communication associated withDestroy a PDEV.
See also:
- Section 9
15.3.15.1 Interface
15.3.15.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001750xC4000177 |
| pdev_ptr | X1 | 63:0 | Address | PA of the PDEV |
15.3.15.1.2 Context
The RMI_PDEV_COMMUNICATERMI_PDEV_DESTROY command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| pdevpdev_pre | RmmPdev | PdevAt(pdev_ptr) |
falsetrue | PDEV |
15.3.15.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.15.2 Failure conditions
| ID | Condition |
|---|---|
| da_supp | pre: ImplFeatures().feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_NOT_SUPPORTED) |
| pdev_align | pre: !AddrIsGranuleAligned(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_bound | pre: !PaIsDelegable(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_gran_state | pre: GranuleAt(pdev_ptr).state != PDEV post: ResultEqual(result, RMI_ERROR_INPUT) |
| data_alignpdev_state | pre: pdev_pre.state !AddrIsGranuleAligned= PDEV_STOPPED(data_ptr) post: ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_DEVICE) |
| data_boundpdev_live | pre: pdev_pre.num_vdevs !PaIsDelegable(data_ptr)= 0 post: ResultEqual(result, RMI_ERROR_INPUT) data_pas pre: !GranuleAccessPermitted(data_ptr, PAS_NS) post: ResultEqual(result, RMI_ERROR_INPUT) req_align pre: !AddrIsGranuleAligned(data.enter.req_addr) post: ResultEqual(result, RMI_ERROR_INPUT) req_bound pre: !PaIsDelegable(data.enter.req_addr) post: ResultEqual(result, RMI_ERROR_INPUT) req_pas pre: !GranuleAccessPermitted(data.enter.req_addr, PAS_NS) post: ResultEqual(result, RMI_ERROR_INPUT) resp_align pre: !AddrIsGranuleAligned(data.enter.resp_addr) post: ResultEqual(result, RMI_ERROR_INPUT) resp_bound pre: !PaIsDelegable(data.enter.resp_addr) post: ResultEqual(result, RMI_ERROR_INPUT) resp_pas pre: !GranuleAccessPermitted(data.enter.resp_addr, PAS_NS) post: ResultEqual(result, RMI_ERROR_INPUT) resp_len pre: data.enter.resp_len > RMM_GRANULE_SIZE post: ResultEqual(result, RMI_ERROR_INPUT) comm_state pre: (pdev.comm_state == DEV_COMM_IDLE || pdev.comm_state == DEV_COMM_ERROR) post: ResultEqual(result, RMI_ERROR_DEVICE) |
15.3.15.2.1 Failure condition ordering
[da_supp][pdev_gran_state] < [pdev_align, pdev_bound, pdev_gran_state, data_align,
data_bound, data_pas, req_align, req_bound, req_pas, resp_align,
resp_bound, resp_pas, resp_len]
[pdev_gran_state][pdev_state]
[da_supp] < [comm_state][pdev_align, pdev_bound, pdev_gran_state, pdev_state,
pdev_live]
15.3.15.3 Success conditions
| ID | Condition |
|---|---|
| comm_stategran_state | pdevGranuleAt(pdev_ptr).comm_statestate == DeviceCommunicateDELEGATED |
| aux_state | AuxStateEqual32(pdev pdev_pre.aux, datapdev_pre.num_aux, DELEGATED) |
15.3.15.4 Footprint
15.3.16 RMI_PDEV_CREATERMI_PDEV_GET_STATE command
CreateGet state of a PDEV.
See also:
- Section 9
15.3.16.1 Interface
15.3.16.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001760xC4000178 |
| pdev_ptr | X1 | 63:0 | Address | PA of the PDEV |
15.3.16.1.2 Context
The RMI_PDEV_CREATERMI_PDEV_GET_STATE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| pdev | RmmPdev | PdevAt(pdev_ptr) |
false | PDEV |
15.3.16.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| state | X1 | 7:0 | RmiPdevState | PDEV state |
The following unused bits of RMI_PDEV_GET_STATE output values MBZ: X1[63:8].
15.3.16.2 Failure conditions
| ID | Condition |
|---|---|
| da_supp | pre: ImplFeatures().feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_NOT_SUPPORTED) |
| pdev_align | pre: !AddrIsGranuleAligned(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_bound | pre: !PaIsDelegable(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_statepdev_gran_state | pre: GranuleAt(pdev_ptr).state != DELEGATEDPDEV post: ResultEqual(result, RMI_ERROR_INPUT) |
15.3.16.2.1 Failure condition ordering
[da_supp] < [pdev_align, pdev_bound, pdev_state, params_align,
params_bound, params_pas, params_valid, num_aux, aux_align,
aux_alias, aux_state]pdev_gran_state]
15.3.16.3 Success conditions
| ID | Condition |
|---|---|
| gran_statestate | GranuleAt(pdev_ptr).state == PDEV pdev_id pdev.pdev_id == params.pdev_id prot_config Equal(pdev.prot_configstate, params.flags.prot_config) segment_id pdev.segment_id == params.segment_id ecam_addr pdev.ecam_addr == params.ecam_addr root_id pdev.root_id == params.root_id cert_id pdev.cert_id == params.cert_id rid_base pdev.rid_base == params.rid_base rid_top pdev.rid_top == params.rid_top hash_algo Equal(pdev.hash_algo, params.hash_algo) ide_sid pdev.ide_sid == params.ide_sid iocoh_num_addr_range pdev.iocoh_num_addr_range == params.iocoh_num_addr_range iocoh_addr_range RmiAddressRangesEqual16( pdev.iocoh_addr_range, params.iocoh_addr_range, params.iocoh_num_addr_range) fcoh_num_addr_range pdev.fcoh_num_addr_range == params.fcoh_num_addr_range fcoh_addr_range RmiAddressRangesEqual4( pdev.fcoh_addr_range, params.fcoh_addr_range, params.fcoh_num_addr_range) state pdev.state == PDEV_NEW) |
15.3.16.4 Footprint
ID Value state GranuleAt(pdev_ptr)The RMI_PDEV_GET_STATE command does not have any footprint.state aux_state AuxStates( pdev.aux, PdevAuxCount(params.flags))
15.3.17 RMI_PDEV_DESTROYRMI_PDEV_IDE_RESET command
DestroyReset the IDE link of a PDEV.
See also: Section 915.3.17.1 Interface
15.3.17.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001770xC4000179 |
| pdev_ptr | X1 | 63:0 | Address | PA of the PDEV |
15.3.17.1.2 Context
The RMI_PDEV_DESTROYRMI_PDEV_IDE_RESET command operates on the following context.
15.3.17.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.17.2 Failure conditions
| ID | Condition |
|---|---|
| da_supp | pre: ImplFeatures().feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_NOT_SUPPORTED) |
| pdev_align | pre: !AddrIsGranuleAligned(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_bound | pre: !PaIsDelegable(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_gran_state | pre: GranuleAt(pdev_ptr).state != PDEV post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_state | pre: pdev_prepdev.state != PDEV_STOPPEDPDEV_READY post: ResultEqual(result, RMI_ERROR_DEVICE) |
15.3.17.2.1 Failure condition ordering
[pdev_gran_state][da_supp] < [pdev_state]
[da_supp][pdev_align, pdev_bound, pdev_gran_state]
[pdev_gran_state] < [pdev_align, pdev_bound, pdev_gran_state, pdev_state,
pdev_live][pdev_state]
15.3.17.3 Success conditions
| ID | Condition |
|---|---|
| gran_statepdev_state | GranuleAt(pdev_ptr)pdev.state == DELEGATEDPDEV_IDE_RESETTING |
| aux_statecomm_state | AuxStateEqual32pdev.comm_state == DEV_COMM_PENDING( pdev_pre.aux, pdev_pre.num_aux, DELEGATED) |
15.3.17.4 Footprint
| ID | Value |
|---|---|
| state | GranuleAt(pdev_ptr)pdev.state |
| aux_statecomm_state | AuxStates(pdev_prepdev.aux, prev_pre._num_aux)comm_state |
15.3.18 RMI_PDEV_GET_STATERMI_PDEV_NOTIFY command
Get state ofNotify the RMM of an event related to a PDEV.
See also:
- Section 9
15.3.18.1 Interface
15.3.18.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001780xC400017A |
| pdev_ptr | X1 | 63:0 | Address | PA of the PDEV |
| ev | X2 | 7:0 | RmiPdevEvent | Event type |
The following unused bits of RMI_PDEV_NOTIFY input values SBZ: X2[63:8].
15.3.18.1.2 Context
The RMI_PDEV_GET_STATERMI_PDEV_NOTIFY command operates on the following context.
15.3.18.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.18.2 Failure conditions
| ID | Condition |
|---|---|
| da_supp | pre: ImplFeatures().feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_NOT_SUPPORTED) |
| pdev_align | pre: !AddrIsGranuleAligned(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_bound | pre: !PaIsDelegable(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_gran_state | pre: GranuleAt(pdev_ptr).state != PDEV post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_state | pre: pdev.state != PDEV_READY post: ResultEqual(result, RMI_ERROR_DEVICE) |
| ev_valid | pre: !RmiPdevEventIsValid(ev) post: ResultEqual(result, RMI_ERROR_INPUT) |
15.3.18.2.1 Failure condition ordering
[da_supp] < [pdev_align, pdev_bound, pdev_gran_state]
[pdev_gran_state] < [pdev_state]
[pdev_state] < [ev_valid]
15.3.18.3 Success conditions
| ID | Condition |
|---|---|
| statepdev_state | Equal(state, pdev.state) == PDEV_COMMUNICATING |
| comm_state | pdev.comm_state == DEV_COMM_PENDING |
15.3.18.4 Footprint
The RMI_PDEV_GET_STATE command does not have any footprint| ID | Value |
|---|---|
| state | pdev.state |
| comm_state |
pdev.comm_state
|
15.3.19 RMI_PDEV_IDE_RESETRMI_PDEV_SET_PUBKEY command
Reset the IDE link ofProvide public key associated with a PDEV.
See also:
- Section 9
15.3.19.1 Interface
15.3.19.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001790xC400017B |
| pdev_ptr | X1 | 63:0 | Address | PA of the PDEV |
| params_ptr | X2 | 63:0 | Address | PA of the key parameters |
15.3.19.1.2 Context
The RMI_PDEV_IDE_RESETRMI_PDEV_SET_PUBKEY command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| pdev | RmmPdev | PdevAt(pdev_ptr) |
false | PDEV |
| params | RmiPublicKeyParams | RmiPublicKeyParamsAt(params_ptr) |
false | Public key parameters |
15.3.19.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.19.2 Failure conditions
| ID | Condition |
|---|---|
| da_supp | pre: ImplFeatures().feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_NOT_SUPPORTED) |
| pdev_align | pre: !AddrIsGranuleAligned(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_bound | pre: !PaIsDelegable(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_gran_state | pre: GranuleAt(pdev_ptr).state != PDEV post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_stateparams_align | pre: pdev.state != PDEV_READYAddrIsGranuleAligned(params_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| params_pas | pre: !GranuleAccessPermitted(params_ptr, PAS_NS) post: ResultEqual(result, RMI_ERROR_INPUT) |
| key_len_oflow | pre: params.key_len > 0x1000 post: ResultEqual(result, RMI_ERROR_INPUT) |
| metadata_len_of low | pre: params.metadata_len > 0x1000 post: ResultEqual(result, RMI_ERROR_INPUT) |
| key_invalid | pre: Key is invalid, for example length is invalid for specified signature algorithm. post: ResultEqual(result, RMI_ERROR_INPUT) |
| metadata_invali d | pre: Metadata is invalid, for example length is invalid for specified signature algorithm. post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_state | pre: pdev.state != PDEV_NEEDS_KEY post: ResultEqual(result, RMI_ERROR_DEVICE) |
15.3.19.2.1 Failure condition ordering
[da_supp] < [pdev_align, pdev_bound, pdev_gran_state]pdev_gran_state, params_align,
params_pas, key_len_oflow, key_invalid, metadata_len_oflow,
metadata_invalid]
[pdev_gran_state] < [pdev_state]
15.3.19.3 Success conditions
| ID | Condition |
|---|---|
| pdev_statestate | pdev.state == PDEV_IDE_RESETTINGPDEV_HAS_KEY |
| comm_state | pdev.comm_state == DEV_COMM_PENDING |
15.3.19.4 Footprint
| ID | Value |
|---|---|
| state | pdev.state |
| comm_state | pdev.comm_state |
15.3.20 RMI_PDEV_NOTIFY RMI_PDEV_STOP command
Notify the RMM of an event related toStop a PDEV.
See also:
- Section 9
15.3.20.1 Interface
15.3.20.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400017A0xC400017C |
| pdev_ptr | X1 | 63:0 | Address | PA of the PDEV |
15.3.20.1.2 Context
The RMI_PDEV_NOTIFYRMI_PDEV_STOP command operates on the following context.
15.3.20.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.20.2 Failure conditions
| ID | Condition |
|---|---|
| da_supp | pre: ImplFeatures().feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_NOT_SUPPORTED) |
| pdev_align | pre: !AddrIsGranuleAligned(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_bound | pre: !PaIsDelegable(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_gran_state | pre: GranuleAt(pdev_ptr).state != PDEV post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_state | pre: (pdev.state !== PDEV_READYPDEV_COMMUNICATING || pdev.state == PDEV_STOPPING || pdev.state == PDEV_STOPPED) post: ResultEqual(result, RMI_ERROR_DEVICE) |
| ev_validnum_vdevs | pre: pdev.num_vdevs !RmiPdevEventIsValid(ev)= 0 post: ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_DEVICE) |
15.3.20.2.1 Failure condition ordering
[da_supp] < [pdev_align, pdev_bound, pdev_gran_state]
[pdev_gran_state] < [pdev_state]
[pdev_state] < [ev_valid][pdev_state, num_vdevs]
15.3.20.3 Success conditions
| ID | Condition |
|---|---|
| pdev_state | pdev.state == PDEV_COMMUNICATINGPDEV_STOPPING |
| comm_state | pdev.comm_state == DEV_COMM_PENDING |
15.3.20.4 Footprint
| ID | Value |
|---|---|
| state | pdev.state |
| comm_state | pdev.comm_state |
15.3.21 RMI_PDEV_SET_PUBKEYRMI_PSCI_COMPLETE command
Provide public key associated with a PDEVCompletes a pending PSCI command which was called with an MPIDR argument, by providing the corresponding REC.
15.3.21.1 Interface
15.3.21.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400017B0xC4000164 |
| pdev_ptrcalling_rec_ptr | X1 | 63:0 | Address | PA of the PDEVcalling REC |
| params_ptrtarget_rec_ptr | X2 | 63:0 | Address | PA of the key parameterstarget REC |
| status | X3 | 63:0 | PsciReturnCode | Status of the PSCI request |
15.3.21.1.2 Context
The RMI_PDEV_SET_PUBKEYRMI_PSCI_COMPLETE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| pdevcalling_rec | RmmPdevRmmRec | PdevAtRecAt(pdev_ptrcalling_rec_ptr) |
false | PDEVCalling REC |
| paramstarget_rec | RmiPublicKeyParamsRmmRec | RmiPublicKeyParamsAtRecAt(params_ptrtarget_rec_ptr) |
false | Public key parametersTarget REC |
15.3.21.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.21.2 Failure conditions
| ID | Condition |
|---|---|
| da_suppalias | pre: ImplFeatures().feat_da !calling_rec_ptr = FEATURE_TRUE= target_rec_ptr post: ResultEqual(result, RMI_ERROR_NOT_SUPPORTEDRMI_ERROR_INPUT) |
| pdev_aligncalling_align | pre: !AddrIsGranuleAligned(pdev_ptrcalling_rec_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_boundcalling_bound | pre: !PaIsDelegable(pdev_ptrcalling_rec_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_gran_statecalling_state | pre: GranuleAt(pdev_ptrcalling_rec_ptr).state != PDEVREC post: ResultEqual(result, RMI_ERROR_INPUT) |
| params_aligntarget_align | pre: !AddrIsGranuleAligned(params_ptrtarget_rec_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| params_boundtarget_bound | pre: !PaIsDelegable(params_ptrtarget_rec_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| params_pastarget_state | pre: !GranuleAccessPermittedGranuleAt(params_ptr, PAS_NStarget_rec_ptr).state != REC) post: ResultEqual(result, RMI_ERROR_INPUT) |
| key_len_oflowpending | pre: paramscalling_rec.key_len > 0x1000pending != REC_PENDING_PSCI post: ResultEqual(result, RMI_ERROR_INPUT) |
| metadata_len_of lowowner | pre: paramstarget_rec.metadata_len > 0x1000owner != calling_rec.owner post: ResultEqual(result, RMI_ERROR_INPUT) |
| key_invalidtarget | pre: Key is invalid, for example length is invalid for specified signature algorithmtarget_rec.mpidr != calling_rec.gprs[1] post: ResultEqual(result, RMI_ERROR_INPUT) |
| metadata_invali dstatus | pre: Metadata is invalid!PsciReturnCodePermitted( calling_rec, for example length is invalid for specified signature algorithm.target_rec, status) post: ResultEqual(result, RMI_ERROR_INPUT) |
15.3.21.2.1 Failure condition ordering
[da_supp] < [pdev_align, pdev_bound, pdev_gran_state, params_align, params_bound, params_pas, key_len_oflow, key_invalid, metadata_len_oflow, metadata_invalid] [pdev_gran_state] < [pdev_state]The RMI_PSCI_COMPLETE command does not have any failure condition orderings.
15.3.21.3 Success conditions
| ID | Condition |
|---|---|
| statepending | pdevcalling_rec.statepending == PDEV_HAS_KEYREC_PENDING_NONE |
| comm_stateon_already | pdev.comm_statepre: (status == DEV_COMM_PENDINGPSCI_SUCCESS && calling_rec.gprs[0] == FID_PSCI_CPU_ON && target_rec.flags.runnable == RUNNABLE) post: (calling_rec.gprs[0] == PsciReturnCodeEncode(PSCI_ALREADY_ON)) |
| on_success | pre: (status == PSCI_SUCCESS && calling_rec.gprs[0] == FID_PSCI_CPU_ON && target_rec.flags.runnable != RUNNABLE) post: (target_rec.gprs[0] == calling_rec.gprs[3] && target_rec.gprs[1] == Zeros(64) && target_rec.gprs[2] == Zeros(64) && target_rec.gprs[3] == Zeros(64) && target_rec.gprs[4] == Zeros(64) && target_rec.gprs[5] == Zeros(64) && target_rec.gprs[6] == Zeros(64) && target_rec.gprs[7] == Zeros(64) && target_rec.gprs[8] == Zeros(64) && target_rec.gprs[9] == Zeros(64) && target_rec.gprs[10] == Zeros(64) && target_rec.gprs[11] == Zeros(64) && target_rec.gprs[12] == Zeros(64) && target_rec.gprs[13] == Zeros(64) && target_rec.gprs[14] == Zeros(64) && target_rec.gprs[15] == Zeros(64) && target_rec.gprs[16] == Zeros(64) && target_rec.gprs[17] == Zeros(64) && target_rec.gprs[18] == Zeros(64) && target_rec.gprs[19] == Zeros(64) && target_rec.gprs[20] == Zeros(64) && target_rec.gprs[21] == Zeros(64) && target_rec.gprs[22] == Zeros(64) && target_rec.gprs[23] == Zeros(64) && target_rec.gprs[24] == Zeros(64) && target_rec.gprs[25] == Zeros(64) && target_rec.gprs[26] == Zeros(64) && target_rec.gprs[27] == Zeros(64) && target_rec.gprs[28] == Zeros(64) && target_rec.gprs[29] == Zeros(64) && target_rec.gprs[30] == Zeros(64) && target_rec.gprs[31] == Zeros(64) && target_rec.pc == calling_rec.gprs[2] && target_rec.flags.runnable == RUNNABLE && calling_rec.gprs[0] == PsciReturnCodeEncode(PSCI_SUCCESS)) |
| affinity_on | pre: (status == PSCI_SUCCESS && calling_rec.gprs[0] == FID_PSCI_AFFINITY_INFO && target_rec.flags.runnable == RUNNABLE) post: (calling_rec.gprs[0] == PsciReturnCodeEncode(PSCI_SUCCESS)) |
| affinity_off | pre: (status == PSCI_SUCCESS && calling_rec.gprs[0] == FID_PSCI_AFFINITY_INFO && target_rec.flags.runnable != RUNNABLE) post: (calling_rec.gprs[0] == PsciReturnCodeEncode(PSCI_OFF)) |
| status | pre: status != PSCI_SUCCESS post: (calling_rec.gprs[0] == PsciReturnCodeEncode(status)) |
| args |
(calling_rec.gprs[1] == Zeros(64)
&& calling_rec.gprs[2] == Zeros(64)
&& calling_rec.gprs[3] == Zeros(64))
|
15.3.21.4 Footprint
| ID | Value |
|---|---|
| statetarget_flags | pdevtarget_rec.stateflags |
| comm_statetarget_gprs | pdevtarget_rec.comm_stategprs |
| target_pc |
target_rec.pc
|
| calling_pend |
calling_rec.pending
|
| calling_gprs |
calling_rec.gprs
|
15.3.22 RMI_PDEV_STOP RMI_PSMMU_IRQ_NOTIFY command
Stop a PDEVNotify RMM of an SMMU interrupt.
See also:
- Section 9.6.5
15.3.22.1 Interface
15.3.22.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400017C0xC400016F |
| pdev_ptrpsmmu | X1 | 63:0 | Address | PA of the PDEVPSMMU |
| irq | X2 | 1:0 | RmiSmmuIrq | SMMU IRQ |
The following unused bits of RMI_PSMMU_IRQ_NOTIFY input values SBZ: X2[63:2].
15.3.22.1.2 ContextOutput values
The RMI_PDEV_STOP command operates on the following context.| Name | Register | Bits | Type | Value BeforeDescription |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| action | X1 | 0:0 | RmiSmmuAction | Action required by Host |
| rd | X2 | 63:0 | Address | PA of RD. This is valid if action == RMI_SMMU_ACTION_VIRQ. |
| vsmmu | X3 | 63:0 | Address | PA of VSMMU. This is valid if action == RMI_SMMU_ACTION_VIRQ. |
| msi_addr | X4 | 63:0 | Address | MSI address. This is valid if action == RMI_SMMU_ACTION_VIRQ. |
| msi_data | X5 | 63:0 | Bits64 | MSI data. This is valid if action == RMI_SMMU_ACTION_VIRQ. |
The following unused bits of RMI_PSMMU_IRQ_NOTIFY output values MBZ: X1[63:1].
15.3.22.2 Failure conditions
| ID | Condition |
|---|---|
| da_supppsmmu_valid | pre: ImplFeatures!PsmmuAddrIsValid(psmmu).feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_NOT_SUPPORTED) pdev_align pre: !AddrIsGranuleAligned(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
15.3.22.3 Success conditions
ID Condition pdev_state pdevThe RMI_PSMMU_IRQ_NOTIFY command does not have any success conditions.state == PDEV_STOPPING comm_state pdev.comm_state == DEV_COMM_PENDING
15.3.22.4 Footprint
ID Value state pdevThe RMI_PSMMU_IRQ_NOTIFY command does not have any footprint.state comm_state pdev.comm_state
15.3.23 RMI_PSCI_COMPLETERMI_PSMMU_MSI_CONFIG command
Completes a pending PSCI command which was called with an MPIDR argument, by providing the corresponding RECProgram the MSI configuration for the Realm side of the physical SMMU.
See also:
- Section 49.36.75 Section 17.3.1 Section 17.3.3 Section 21.4
15.3.23.1 Interface
15.3.23.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001640xC400016E |
| calling_rec_ptrpsmmu | X1 | 63:0 | Address | PA of the calling RECPSMMU |
| target_rec_ptrgerr_addr | X2 | 63:0 | Address | PA of the target RECMSI address of the GERROR interrupt |
| statusgerr_data | X3 | 63:0 | PsciReturnCodeBits64 | Status of the PSCI requestMSI data of the GERROR interrupt |
| eventq_addr | X4 | 63:0 | Address | MSI address of the EVENTQ interrupt |
| eventq_data | X5 | 63:0 | Bits64 | MSI data of the EVENTQ interrupt |
| priq_addr | X6 | 63:0 | Address | MSI address of the PRIQ interrupt |
| priq_data | X7 | 63:0 | Bits64 | MSI data of the PRIQ interrupt |
15.3.23.1.2 ContextOutput values
The RMI_PSCI_COMPLETE command operates on the following context.| Name | Register | Bits | Type | Value BeforeDescription |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.23.2 Failure conditions
| ID | Condition |
|---|---|
| aliaspsmmu_valid | pre: calling_rec_ptr == target_rec_ptr!PsmmuAddrIsValid(psmmu) post: ResultEqual(result, RMI_ERROR_INPUT) |
| calling_alignpsmmu_msi | pre: !AddrIsGranuleAlignedPsmmuSupportsMsi(calling_rec_ptrpsmmu) post: ResultEqual(result, RMI_ERROR_INPUT) |
| calling_boundgerror_valid | pre: !PaIsDelegableMsiAddrIsValid(calling_rec_ptrgerr_addr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| calling_stateeventq_valid | pre: GranuleAt!MsiAddrIsValid(calling_rec_ptreventq_addr).state != REC post: ResultEqual(result, RMI_ERROR_INPUT) |
| target_alignpriq_valid | pre: !AddrIsGranuleAlignedMsiAddrIsValid(target_rec_ptrpriq_addr) post: ResultEqual(result, RMI_ERROR_INPUT) |
15.3.23.2.1 Failure condition ordering
The RMI_PSCI_COMPLETERMI_PSMMU_MSI_CONFIG command does not have any failure condition orderings.
15.3.23.3 Success conditions
| ID | Condition |
|---|---|
| pendinggerr_addr | calling_recgerr_addr is programmed to SMMU_R_GERROR_IRQ_CFG0 with NS bit set.pending == REC_PENDING_NONE |
| on_alreadygerr_data | pre: (status == PSCI_SUCCESS && calling_recgerr_data is programmed to SMMU_R_GERROR_IRQ_CFG1.gprs[0] == FID_PSCI_CPU_ON && target_rec.flags.runnable == RUNNABLE) post: (calling_rec.gprs[0] == PsciReturnCodeEncode(PSCI_ALREADY_ON)) |
| on_successeventq_addr | pre: (status == PSCI_SUCCESS && calling_receventq_addr is programmed to SMMU_R_EVENTQ_IRQ_CFG0 with NS bit set.gprs[0] == FID_PSCI_CPU_ON && target_rec.flags.runnable != RUNNABLE) post: (target_rec.gprs[0] == calling_rec.gprs[3] && target_rec.gprs[1] == Zeros(64) && target_rec.gprs[2] == Zeros(64) && target_rec.gprs[3] == Zeros(64) && target_rec.gprs[4] == Zeros(64) && target_rec.gprs[5] == Zeros(64) && target_rec.gprs[6] == Zeros(64) && target_rec.gprs[7] == Zeros(64) && target_rec.gprs[8] == Zeros(64) && target_rec.gprs[9] == Zeros(64) && target_rec.gprs[10] == Zeros(64) && target_rec.gprs[11] == Zeros(64) && target_rec.gprs[12] == Zeros(64) && target_rec.gprs[13] == Zeros(64) && target_rec.gprs[14] == Zeros(64) && target_rec.gprs[15] == Zeros(64) && target_rec.gprs[16] == Zeros(64) && target_rec.gprs[17] == Zeros(64) && target_rec.gprs[18] == Zeros(64) && target_rec.gprs[19] == Zeros(64) && target_rec.gprs[20] == Zeros(64) && target_rec.gprs[21] == Zeros(64) && target_rec.gprs[22] == Zeros(64) && target_rec.gprs[23] == Zeros(64) && target_rec.gprs[24] == Zeros(64) && target_rec.gprs[25] == Zeros(64) && target_rec.gprs[26] == Zeros(64) && target_rec.gprs[27] == Zeros(64) && target_rec.gprs[28] == Zeros(64) && target_rec.gprs[29] == Zeros(64) && target_rec.gprs[30] == Zeros(64) && target_rec.gprs[31] == Zeros(64) && target_rec.pc == calling_rec.gprs[2] && target_rec.flags.runnable == RUNNABLE && calling_rec.gprs[0] == PsciReturnCodeEncode(PSCI_SUCCESS)) |
| affinity_oneventq_data | pre: (status == PSCI_SUCCESS && calling_receventq_data is programmed to SMMU_R_EVENTQ_IRQ_CFG1.gprs[0] == FID_PSCI_AFFINITY_INFO && target_rec.flags.runnable == RUNNABLE) post: (calling_rec.gprs[0] == PsciReturnCodeEncode(PSCI_SUCCESS)) |
| affinity_offpriq_addr | pre: (status == PSCI_SUCCESS && calling_recpriq_addr is programmed to SMMU_R_PRIQ_IRQ_CFG0 with NS bit set.gprs[0] == FID_PSCI_AFFINITY_INFO && target_rec.flags.runnable != RUNNABLE) post: (calling_rec.gprs[0] == PsciReturnCodeEncode(PSCI_OFF)) |
| statuspriq_data | pre: status != PSCI_SUCCESS post: (calling_recpriq_data is programmed to SMMU_R_PRIQ_IRQ_CFG1.gprs[0] == PsciReturnCodeEncode(status)) |
15.3.23.4 Footprint
ID Value target_flags target_recThe RMI_PSMMU_MSI_CONFIG command does not have any footprint.flags target_gprs target_rec.gprs target_pc target_rec.pc calling_pend calling_rec.pending calling_gprs calling_rec.gprs
15.3.24 RMI_PSMMU_IRQ_NOTIFYRMI_REALM_ACTIVATE command
Notify RMM of an SMMU interruptActivates a Realm.
See also:
- Section 92.6.51
15.3.24.1 Interface
15.3.24.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400016F0xC4000157 |
| psmmurd | X1 | 63:0 | Address | PA of PSMMUthe RD |
15.3.24.1.2 Output valuesContext
The RMI_REALM_ACTIVATE command operates on the following context.
15.3.24.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.24.2 Failure conditions
| ID | Condition |
|---|---|
| psmmu_validrd_align | pre: !PsmmuAddrIsValidAddrIsGranuleAligned(psmmurd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| realm_state | pre: realm.state != REALM_NEW post: ResultEqual(result, RMI_ERROR_REALM) |
15.3.24.2.1 Failure condition ordering
[rd_bound, rd_state] < [realm_state]
15.3.24.3 Success conditions
The RMI_PSMMU_IRQ_NOTIFY command does not have any success conditions| ID | Condition |
|---|---|
| realm_state | realm. state == REALM_ACTIVE |
15.3.24.4 Footprint
The RMI_PSMMU_IRQ_NOTIFY command does not have any footprint| ID | Value |
|---|---|
| realm_state | realm.state |
15.3.25 RMI_PSMMU_MSI_CONFIGRMI_REALM_CREATE command
Program the MSI configuration for theCreates a Realm side of the physical SMMU.
15.3.25.1 Interface
15.3.25.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400016E0xC4000158 |
| psmmurd | X1 | 63:0 | Address | PA of PSMMUthe RD |
| gerr_addrparams_ptr | X2 | 63:0 | Address | MSI address of the GERROR interruptPA of Realm parameters |
15.3.25.1.2 Output valuesContext
The RMI_REALM_CREATE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| params | RmiRealmParams | RmiRealmParamsAt( params_ptr) |
false | Realm parameters |
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| mec_members_pre | UInt64 | MecMembers(params.mecid) |
true | Number of Realms which are members of the Realm’s MEC |
| mec_state_pre | RmmMecState | MecState(params.mecid) |
true | MECID state |
15.3.25.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.25.2 Failure conditions
| ID | Condition |
|---|---|
| psmmu_validparams_align | pre: !PsmmuAddrIsValidAddrIsGranuleAligned(psmmuparams_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| psmmu_msiparams_pas | pre: !PsmmuSupportsMsiGranuleAccessPermitted(psmmuparams_ptr, PAS_NS) post: ResultEqual(result, RMI_ERROR_INPUT) |
| gerror_validparams_valid | pre: !MsiAddrIsValidRmiRealmParamsIsValid(gerr_addrparams_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| eventq_validparams_supp | pre: !MsiAddrIsValidRealmParamsSupported(eventq_addrparams) post: ResultEqual(result, RMI_ERROR_INPUT) |
| priq_validalias | pre: !MsiAddrIsValidAddrInRange(priq_addrrd, params.rtt_base, (params.rtt_num_start - 1) * RMM_GRANULE_SIZE) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegableDram(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != DELEGATED post: ResultEqual(result, RMI_ERROR_INPUT) |
| rtt_align | pre: !AddrIsAligned(params.rtt_base, params.rtt_num_start * RMM_GRANULE_SIZE) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rtt_num_level | pre: !RttConfigIsValid( params.s2sz, params.rtt_level_start, params.rtt_num_start) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rtt_state | pre: !RttsStateEqual( params.rtt_base, params.rtt_num_start, DELEGATED) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vmid_valid | pre: (!VmidsAreValid(params.vmid, params.aux_vmid) || !VmidsAreFree(params.vmid, params.aux_vmid)) post: ResultEqual(result, RMI_ERROR_INPUT) |
| mecid_bound | pre: UInt(params.mecid) > UInt(ImplFeatures().max_mecid) post: ResultEqual(result, RMI_ERROR_INPUT) |
| mecid_state | pre: MecState(params.mecid) == MEC_STATE_PRIVATE_ASSIGNED post: ResultEqual(result, RMI_ERROR_INPUT) |
15.3.25.2.1 Failure condition ordering
The RMI_PSMMU_MSI_CONFIGRMI_REALM_CREATE command does not have any failure condition orderings.
15.3.25.3 Success conditions
| ID | Condition |
|---|---|
| gerr_addrrd_state | gerr_addr is programmed to SMMU_R_GERROR_IRQ_CFG0 with NS bit setGranuleAt(rd).state == RD |
| gerr_datarealm_state | gerr_data is programmed to SMMU_R_GERROR_IRQ_CFG1realm.state == REALM_NEW |
| eventq_addrrec_index | eventq_addr is programmed to SMMU_R_EVENTQ_IRQ_CFG0 with NS bit setrealm.rec_index == 0 |
| eventq_datartt_base | eventq_data is programmed to SMMU_R_EVENTQ_IRQ_CFG1RealmRttBaseEqual( realm, params.rtt_base, params.aux_rtt_base) |
| priq_addrrtt_state | priq_addr is programmed to SMMU_R_PRIQ_IRQ_CFG0 with NS bit setRttsStateEqual( realm.rtt_base[0], realm.rtt_num_start, RTT) |
| priq_datartte_p_states | priq_data is programmed to SMMU_R_PRIQ_IRQ_CFG1RttsAllProtectedEntriesState( realm.rtt_base[0], realm.rtt_num_start, UNASSIGNED) |
| rtte_up_states | RttsAllUnprotectedEntriesState( realm.rtt_base[0], realm.rtt_num_start, UNASSIGNED_NS) |
| rtte_ripas | RttsAllProtectedEntriesRipas( realm.rtt_base[0], realm.rtt_num_start, EMPTY) |
| lpa2 | Equal(realm.feat_lpa2, params.flags0.lpa2) |
| ipa_width |
realm.ipa_width == params.s2sz
|
| hash_algo | Equal(realm.hash_algo, params.hash_algo) |
| rim | realm.measurements[0] == RimInit( realm.hash_algo, params) |
| rem |
(realm.measurements[1] == Zeros(RMM_REALM_MEASUREMENT_WIDTH)
&& realm.measurements[2] == Zeros(RMM_REALM_MEASUREMENT_WIDTH)
&& realm.measurements[3] == Zeros(RMM_REALM_MEASUREMENT_WIDTH)
&& realm.measurements[4] == Zeros(RMM_REALM_MEASUREMENT_WIDTH))
|
| rtt_level |
realm.rtt_level_start == params.rtt_level_start
|
| rtt_num |
realm.rtt_num_start == params.rtt_num_start
|
| vmid | RealmVmidEqual( realm, params.vmid, params.aux_vmid) |
| rpv |
realm.rpv == params.rpv
|
| da | Equal(realm.feat_da, params.flags0.da) |
| rtt_tree_per_plane | Equal(realm.rtt_tree_per_plane, params.flags1.rtt_tree_per_plane) |
| num_aux_planes |
realm.num_aux_planes == params.num_aux_planes
|
| rtt_s2ap_encoding | Equal(realm.rtt_s2ap_encoding, params.flags1.rtt_s2ap_encoding) |
| lfa_policy | Equal(realm.lfa_policy, params.flags0.lfa_policy) |
| mecid |
realm.mecid == params.mecid
|
| mec_policy | realm.mec_policy == MecPolicy(realm.mecid) |
| mecid_private | pre: mec_state_pre == MEC_STATE_PRIVATE_UNASSIGNED post: MecState(params.mecid) == MEC_STATE_PRIVATE_ASSIGNED |
| mec_members | pre: mec_state_pre == MEC_STATE_SHARED post: MecMembers(params.mecid) == mec_members_pre + 1 |
| num_recs |
realm.num_recs == 0
|
| num_vdevs |
realm.num_vdevs == 0
|
| vdev_count |
realm.vdev_count == 0
|
15.3.25.4 RMI_REALM_CREATE initialization of RIM
On successful execution of RMI_REALM_CREATE, the initial RIM value of the target Realm is calculated by the RMM as follows:
Allocate a zero-filled RmiRealmParams data structure to hold the measured Realm parameters.
Copy the following attributes from the Host-provided RmiRealmParams data structure into the measured Realm parameters data structure:
- flags0
- s2sz
- sve_vl
- num_bps
- num_wps
- pmu_num_ctrs
- hash_algo
- Using the RHA of the target Realm, compute the hash of the measured Realm parameters data structure. Set the RIM of the target Realm to this value, zero filling upper bytes if the RHA output is smaller than the size of the RIM.
15.3.25.5 Footprint
The RMI_PSMMU_MSI_CONFIG command does not have any footprint| ID | Value |
|---|---|
| rd_state | GranuleAt(rd).state |
| rtt_state | RttsGranuleState( realm.rtt_base[0], realm.rtt_num_start) |
15.3.26 RMI_REALM_ACTIVATERMI_REALM_DESTROY command
ActivatesDestroys a Realm.
15.3.26.1 Interface
15.3.26.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001570xC4000159 |
| rd | X1 | 63:0 | Address | PA of the RD |
15.3.26.1.2 Context
The RMI_REALM_ACTIVATERMI_REALM_DESTROY command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realmrealm_pre | RmmRealm | RealmAt(rd) |
falsetrue | Realm |
| mec_members_pre | UInt64 | MecMembers(realm_pre.mecid) |
true | Number of Realms which are members of the Realm’s MEC |
15.3.26.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.26.2 Failure conditions
| ID | Condition |
|---|---|
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| realm_staterealm_live | pre: realm.state != REALM_NEWRealmIsLive(rd) post: ResultEqual(result, RMI_ERROR_REALM) |
15.3.26.2.1 Failure condition ordering
[rd_bound, rd_state] < [realm_state][realm_live]
15.3.26.3 Success conditions
| ID | Condition |
|---|---|
| realm_statertt_state | realmRttsStateEqual( realm_pre.rtt_base[0], realm_pre.rtt_num_start, DELEGATED) |
| rd_state | GranuleAt(rd).state == REALM_ACTIVEDELEGATED |
| vmid | VmidsAreFree(realm_pre.vmid) |
| mecid_private | pre: realm_pre.mec_policy == MEC_POLICY_PRIVATE post: MecState(realm_pre.mecid) == MEC_STATE_PRIVATE_UNASSIGNED |
| mec_members | pre: realm_pre.mec_policy == MEC_POLICY_SHARED post: MecMembers(realm_pre.mecid) == mec_members_pre - 1 |
15.3.26.4 Footprint
| ID | Value |
|---|---|
| realm_staterd_state | realmGranuleAt(rd).state |
| rtt_state | RttsGranuleState( realm_pre.rtt_base[0], realm_pre.rtt_num_start) |
15.3.27 RMI_REALM_CREATERMI_REC_AUX_COUNT command
Creates a RealmGet number of auxiliary Granules required for a REC.
15.3.27.1 Interface
15.3.27.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001580xC4000167 |
| rd | X1 | 63:0 | Address | PA of the RD for the target Realm |
15.3.27.1.2 ContextOutput values
The RMI_REALM_CREATE command operates on the following context.| Name | Register | Bits | Type | Value BeforeDescription |
|---|---|---|---|---|
| paramsresult | RmiRealmParamsX0 | 63:0 | RmiCommandReturnCode | RmiRealmParamsAt( params_ptr) Command return status |
| falseaux_count | Realm parametersX1 | realm63:0 | RmmRealm RealmAt(rd) false Realm mec_members_preUInt64 | MecMembers(params.mecid) trueNumber of Realms which are members of the Realm’s MECauxiliary Granules required for a REC |
15.3.27.2 Failure conditions
| ID | Condition |
|---|---|
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != DELEGATEDRD post: ResultEqual(result, RMI_ERROR_INPUT) |
15.3.27.2.1 Failure condition ordering
The RMI_REALM_CREATERMI_REC_AUX_COUNT command does not have any failure condition orderings.
15.3.27.3 Success conditions
| ID | Condition |
|---|---|
| rd_stateaux_count | GranuleAtaux_count == RecAuxCount(rd).state == RD |
15.3.27.4 RMI_REALM_CREATE initialization of RIMFootprint
On successful execution of RMI_REALM_CREATE, the initial RIM value of the target Realm is calculated by the RMM as follows: Allocate a zero-filled RmiRealmParams data structure to hold the measured Realm parametersThe RMI_REC_AUX_COUNT command does not have any footprint.
Copy the following attributes from the Host-provided RmiRealmParams data structure into the measured Realm parameters data structure: flags0 s2sz sve_vl num_bps num_wps pmu_num_ctrs hash_algo Using the RHA of the target Realm, compute the hash of the measured Realm parameters data structure. Set the RIM of the target Realm to this value, zero filling upper bytes if the RHA output is smaller than the size of the RIM. See also: Section 7.1.1 Section 14.74 Section 15.4.2915.3.28 RMI_REALM_DESTROY RMI_REC_CREATE command
Destroys a RealmCreates a REC.
15.3.28.1 Interface
15.3.28.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001590xC400015A |
| rd | X1 | 63:0 | Address | PA of the RD for the target Realm |
| rec_ptr | X2 | 63:0 | Address | PA of the target REC |
| params_ptr | X3 | 63:0 | Address | PA of REC parameters |
15.3.28.1.2 Context
The RMI_REALM_DESTROYRMI_REC_CREATE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm_pre | RmmRealm | RealmAt(rd) |
true | Realm |
| mec_members_prerealm | UInt64RmmRealm | MecMembersRealmAt(realm_pre.mecidrd) |
truefalse | Number of Realms which are members of the Realm’s MECRealm |
| params | RmiRecParams | RmiRecParamsAt(params_ptr) |
false | REC parameters |
| rec | RmmRec | RecAt(rec_ptr) |
false | REC |
15.3.28.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.28.2 Failure conditions
| ID | Condition |
|---|---|
| params_align | pre: !AddrIsGranuleAligned(params_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| params_pas | pre: !GranuleAccessPermitted(params_ptr, PAS_NS) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_align | pre: !AddrIsGranuleAligned(rec_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_bound | pre: !PaIsDelegableDram(rec_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_state | pre: GranuleAt(rec_ptr).state != DELEGATED post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| realm_liverealm_state | pre: RealmIsLiverealm_pre.state != REALM_NEW(rd) post: ResultEqual(result, RMI_ERROR_REALM) |
| num_recs | pre: realm_pre.num_recs == (2 ^ ImplFeatures().max_recs_order) - 1 post: ResultEqual(result, RMI_ERROR_REALM) |
| mpidr_index | pre: RecIndex(params.mpidr) != realm_pre.rec_index post: ResultEqual(result, RMI_ERROR_INPUT) |
| num_aux | pre: params.num_aux != RecAuxCount(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| aux_align | pre: !AuxAligned16(params.aux, params.num_aux) post: ResultEqual(result, RMI_ERROR_INPUT) |
| aux_alias | pre: AuxAlias16(rec_ptr, params.aux, params.num_aux) post: ResultEqual(result, RMI_ERROR_INPUT) |
| aux_state | pre: !AuxStateEqual16( params.aux, params.num_aux, DELEGATED) post: ResultEqual(result, RMI_ERROR_INPUT) |
15.3.28.2.1 Failure condition ordering
[rd_bound, rd_state] < [realm_live][realm_state, num_recs]
15.3.28.3 Success conditions
| ID | Condition |
|---|---|
| rtt_staterec_index | RttsStateEqual( realm.rec_index == realm_pre.rtt_base[0], realm_pre.rtt_num_start, DELEGATED)rec_index + 1 |
| rd_staterec_gran_state | GranuleAt(rdrec_ptr).state == DELEGATEDREC |
| vmidrec_owner | VmidsAreFreerec.owner == rd |
| rec_attest | rec.attest_state == NO_ATTEST_IN_PROGRESS |
| rec_mpidr | MpidrEqual(rec.mpidr, params.mpidr) |
| rec_state | rec.state == REC_READY |
| runnable | pre: params.flags.runnable == RMI_RUNNABLE post: rec.flags.runnable == RUNNABLE |
| not_runnable | pre: params.flags.runnable == RMI_NOT_RUNNABLE post: rec.flags.runnable == NOT_RUNNABLE |
| rec_gprs |
(rec.gprs[0] == params.gprs[0]
&& rec.gprs[1] == params.gprs[1]
&& rec.gprs[2] == params.gprs[2]
&& rec.gprs[3] == params.gprs[3]
&& rec.gprs[4] == params.gprs[4]
&& rec.gprs[5] == params.gprs[5]
&& rec.gprs[6] == params.gprs[6]
&& rec.gprs[7] == params.gprs[7]
&& rec.gprs[8] == Zeros(64)
&& rec.gprs[9] == Zeros(64)
&& rec.gprs[10] == Zeros(64)
&& rec.gprs[11] == Zeros(64)
&& rec.gprs[12] == Zeros(64)
&& rec.gprs[13] == Zeros(64)
&& rec.gprs[14] == Zeros(64)
&& rec.gprs[15] == Zeros(64)
&& rec.gprs[16] == Zeros(64)
&& rec.gprs[17] == Zeros(64)
&& rec.gprs[18] == Zeros(64)
&& rec.gprs[19] == Zeros(64)
&& rec.gprs[20] == Zeros(64)
&& rec.gprs[21] == Zeros(64)
&& rec.gprs[22] == Zeros(64)
&& rec.gprs[23] == Zeros(64)
&& rec.gprs[24] == Zeros(64)
&& rec.gprs[25] == Zeros(64)
&& rec.gprs[26] == Zeros(64)
&& rec.gprs[27] == Zeros(64)
&& rec.gprs[28] == Zeros(64)
&& rec.gprs[29] == Zeros(64)
&& rec.gprs[30] == Zeros(64)
&& rec.gprs[31] == Zeros(64))
|
| rec_pc |
rec.pc == params.pc
|
| rim | pre: params.flags.runnable == RMI_RUNNABLE post: realm.measurements[0] == RimExtendRec( realm_pre, params) |
| rec_aux | AuxEqual16( rec.aux, params.aux, RecAuxCount(rd)) |
| rec_aux_state | AuxStateEqual16( rec.aux, RecAuxCount(rd), REC_AUX) |
| ripas_addr |
rec.ripas_addr == Zeros(ADDRESS_WIDTH)
|
| ripas_top |
rec.ripas_top == Zeros(ADDRESS_WIDTH)
|
| pending | rec.pending == REC_PENDING_NONE |
| num_recs | realm.num_recs == realm_pre.vmid)num_recs + 1 |
| mecid_privategic_owner | pre: realm_prerec.mec_policygic_owner == MEC_POLICY_PRIVATE post: MecState(realm_pre.mecid) == MEC_STATE_PRIVATE_UNASSIGNED0 |
15.3.28.4 FootprintRMI_REC_CREATE extension of RIM
ID Value rd_state GranuleAtOn successful execution of RMI_REC_CREATE, if the new REC is runnable then the new RIM value of the target Realm is calculated by the RMM as follows:
Allocate a zero-filled RmiRecParams(rd).state rtt_state RttsGranuleState( realm_pre.rtt_base[0], realm_pre.rtt_num_start) 15.3.29 RMI_REC_AUX_COUNT command Get number of auxiliary Granules required for a data structure to hold the measured REC parameters.
Copy the following attributes from the Host-provided RmiRecParams data structure into the measured REC parameters data structure:
- gprs
- pc
- flags
Using the RHA of the target Realm, compute the hash of the measured REC parameters data structure.
Allocate an RmmMeasurementDescriptorRec data structure.
Populate the measurement descriptor:
- Set the desc_type field to the descriptor type.
- Set the len field to the descriptor length.
- Set the rim field to the current RIM value of the target Realm.
- Set the content field to the hash of the measured REC parameters.
- Using the RHA of the target Realm, compute the hash of the measurement descriptor. Set the RIM of the target Realm to this value, zero filling upper bytes if the RHA output is smaller than the size of the RIM.
15.3.28.5 Footprint
| ID | Value |
|---|---|
| rec_index |
realm.rec_index
|
| rec_state | GranuleAt(rec).state |
| rec_aux_state | AuxStates(rec.aux, RecAuxCount(rd)) |
| rim |
realm.measurements[0]
|
| num_recs |
realm.num_recs
|
15.3.29 RMI_REC_DESTROY command
Destroys a REC.
15.3.29.1 Interface
15.3.29.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001670xC400015B |
| rdrec_ptr | X1 | 63:0 | Address | PA of the RD for the target RealmREC |
15.3.29.1.2 Output valuesContext
The RMI_REC_DESTROY command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| rd_pre | Address | RecAt(rec_ptr).owner |
true | RD address |
| realm_pre | RmmRealm | RealmAt(rd_pre) |
true | Realm |
| realm | RmmRealm | RealmAt(rd_pre) |
false | Realm |
| rec_pre | RmmRec | RecAt(rec_ptr) |
true | REC |
| rec | RmmRec | RecAt(rec_ptr) |
false | REC |
15.3.29.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.29.2 Failure conditions
| ID | Condition |
|---|---|
| rd_alignrec_align | pre: !AddrIsGranuleAligned(rdrec_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_boundrec_bound | pre: !PaIsDelegable(rdrec_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_staterec_gran_state | pre: GranuleAt(rdrec_ptr).state != RDREC post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_state | pre: rec.state == REC_RUNNING post: ResultEqual(result, RMI_ERROR_REC) |
15.3.29.2.1 Failure condition ordering
[rec_bound, rec_gran_state] < [rec_state]
The RMI_REC_AUX_COUNT command does not have any failure condition
orderings.
15.3.29.3 Success conditions
| ID | Condition |
|---|---|
| aux_countrec_gran_state | aux_countGranuleAt(rec_ptr).state == DELEGATED |
| rec_aux_state | AuxStateEqual16( rec_pre.aux, RecAuxCount(rdrd_pre), DELEGATED) |
| num_recs |
realm.num_recs == realm_pre.num_recs - 1
|
15.3.29.4 Footprint
The RMI_REC_AUX_COUNT command does not have any footprint| ID | Value |
|---|---|
| rec_state | GranuleAt(rec_ptr).state |
| rec_aux_state | AuxStates(rec_pre.aux, RecAuxCount(rd_pre)) |
| num_recs |
realm.num_recs
|
15.3.30 RMI_REC_CREATERMI_REC_ENTER command
CreatesEnter a REC.
15.3.30.1 Interface
15.3.30.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400015A0xC400015C |
| rdrec_ptr | X1 | 63:0 | Address | PA of the RD for the target RealmREC |
| rec_ptrrun_ptr | X2 | 63:0 | Address | PA of the target RECRecRun object |
The number of GICv3 List Register values which can be provided by the Host in RmiRecEnter, and which are returned in RmiRecExit, is reported by the RMI_FEATURES command.
See also:
- Section 3.14 PA of REC parameters
15.3.30.1.2 Context
The RMI_REC_CREATERMI_REC_ENTER command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm_prerun | RmmRealmRmiRecRun | RealmAtRmiRecRunAt(rdrun_ptr) |
true
Realm
realm
RmmRealm
RealmAt(rd)
false | RealmRecRun object |
| rec | RmmRec | RecAt(rec_ptr) |
false | REC |
| realm | RmmRealm | RealmAt(rec.owner) |
false | Realm |
15.3.30.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.30.2 Failure conditions
| ID | Condition |
|---|---|
| params_alignrun_align | pre: !AddrIsGranuleAligned(params_ptrrun_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| params_boundrun_pas | pre: !PaIsDelegableGranuleAccessPermitted(params_ptrrun_ptr, PAS_NS) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_align | pre: !AddrIsGranuleAligned(rec_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_bound | pre: !PaIsDelegable(rec_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_staterec_gran_state | pre: GranuleAt(rec_ptr).state != DELEGATEDREC post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_alignrealm_new | pre: !AddrIsGranuleAlignedrealm.state == REALM_NEW(rd) post: ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_REALM, 0) |
| rd_boundsystem_off | pre: !PaIsDelegablerealm.state == REALM_SYSTEM_OFF(rd) post: ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_REALM, 1) |
| rd_staterec_state | pre: GranuleAt(rd)rec.state != RD= REC_RUNNING post: ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_REC) |
| realm_staterec_runnable | pre: realm_prerec.state !flags.runnable = REALM_NEW= NOT_RUNNABLE post: ResultEqual(result, RMI_ERROR_REALMRMI_ERROR_REC) |
| num_recsrec_mmio | pre: realm_pre(run.num_recsenter.flags.emul_mmio == (2 ^ ImplFeaturesRMI_EMULATED_MMIO( && rec.emulatable_abort != EMULATABLE_ABORT).max_recs_order) - 1 post: ResultEqual(result, RMI_ERROR_REALMRMI_ERROR_REC) |
| mpidr_indexrec_gicv3 | pre: RecIndex!Gicv3ConfigIsValid(params run.mpidrenter.gicv3_hcr, run.enter.gicv3_lrs) != realm_pre.rec_index post: ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_REC) |
| num_auxrec_pending | pre: paramsrec.num_auxpending != RecAuxCountREC_PENDING_NONE(rd) post: ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_REC) |
15.3.30.2.1 Failure condition ordering
[rd_bound[rec_align, rd_state]rec_bound, rec_gran_state, run_pas, run_align] < [realm_state
[rec_state, num_recs]rec_runnable, rec_mmio, realm_new, system_off,
rec_gicv3, rec_pending]
15.3.30.3 Success conditions
| ID | Condition |
|---|---|
| rec_indexrec_exit | realmrun.rec_index == realm_preexit contains Realm exit syndrome information.rec_index + 1 |
| rec_gran_staterec_emul_abt | GranuleAt(rec_ptr)rec.state == RECemulatable_abort is updated. |
15.3.30.4 RMI_REC_CREATE extension of RIM On successful execution of RMI_REC_CREATE, if the new REC is runnable then the new RIM value of the target Realm is calculated by the RMM as follows: Allocate a zero-filled RmiRecParams data structure to hold the measured REC parameters. Copy the following attributes from the Host-provided RmiRecParams data structure into the measured REC parameters data structure: gprs pc flags Using the RHA of the target Realm, compute the hash of the measured REC parameters data structure. Allocate an RmmMeasurementDescriptorRec data structure. Populate the measurement descriptor: Set the desc_type field to the descriptor type. Set the len field to the descriptor length. Set the rim field to the current RIM value of the target Realm. Set the content field to the hash of the measured REC parameters. Using the RHA of the target Realm, compute the hash of the measurement descriptor. Set the RIM of the target Realm to this value, zero filling upper bytes if the RHA output is smaller than the size of the RIM. See also: Section 7.1.1 Section 14.71 Section 15.4.36 Section 19.15 15.3.30.5 Footprint
| ID | Value |
|---|---|
| rec_indexemul_abt | realmrec.rec_indexemulatable_abort |
15.3.31 RMI_REC_DESTROYRMI_RTT_AUX_CREATE command
Destroys a RECCreates an auxiliary RTT.
15.3.31.1 Interface
15.3.31.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400015B0xC400017D |
| rec_ptrrd | X1 | 63:0 | Address | PA of the RD for the target RECRealm |
| rtt | X2 | 63:0 | Address | PA of the target RTT |
| ipa | X3 | 63:0 | Address | Base of the IPA range described by the RTT |
| level | X4 | 63:0 | Int64 | RTT level |
| index | X5 | 63:0 | UInt64 | RTT tree index |
15.3.31.1.2 Context
The RMI_REC_DESTROYRMI_RTT_AUX_CREATE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| rd_prerealm | Address RecAt(rec_ptr).owner true RD address realm_preRmmRealm | RealmAt(rd_prerd) |
false | Realm |
| walk | RmmRttWalkResult | RttWalk( realm, ipa, level - 1, index) |
false | RTT walk result |
| entry_idx | UInt64 | RttEntryIndex( ipa, walk.level) |
false | RTTE index |
| unfold | RmmRttEntry | RttWalk( realm, ipa, level - 1, index).rtte |
true | RealmRTTE before command execution |
15.3.31.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.31.2 Failure conditions
| ID | Condition |
|---|---|
| rec_alignrd_align | pre: !AddrIsGranuleAligned(rec_ptrrd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_boundrd_bound | pre: !PaIsDelegable(rec_ptrrd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_gran_staterd_state | pre: GranuleAt(rec_ptrrd).state != RECRD post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_statelevel_bound | pre: rec.state == REC_RUNNING(!RttLevelIsValid(realm, level) || RttLevelIsStarting(realm, level)) post: ResultEqual(result, RMI_ERROR_RECRMI_ERROR_INPUT) |
| ipa_align | pre: !AddrIsRttLevelAligned(ipa, level - 1) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_bound | pre: UInt(ipa) >= (2 ^ realm.ipa_width) post: ResultEqual(result, RMI_ERROR_INPUT) |
| index_bound | pre: (realm.rtt_tree_per_plane == FEATURE_FALSE || index == RMM_RTT_TREE_PRIMARY || index > realm.num_aux_planes) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rtt_align | pre: !AddrIsGranuleAligned(rtt) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rtt_bound | pre: !PaIsDelegableDram(rtt) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rtt_state | pre: GranuleAt(rtt).state != DELEGATED post: ResultEqual(result, RMI_ERROR_INPUT) |
| rtt_bound2 | pre: ((realm.feat_lpa2 == FEATURE_FALSE) && (UInt(rtt) >= 2^48)) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rtt_walk | pre: walk.level < level - 1 post: ResultEqual(result, RMI_ERROR_RTT_AUX, walk.level) |
| rtte_state | pre: walk.rtte.state == TABLE post: ResultEqual(result, RMI_ERROR_RTT_AUX, walk.level) |
15.3.31.2.1 Failure condition ordering
[rec_bound[rd_bound, rec_gran_state]rd_state] < [rec_state][rtt_walk, rtte_state]
[level_bound, ipa_bound] < [rtt_walk, rtte_state]
15.3.31.3 Success conditions
| ID | Condition |
|---|---|
| rec_gran_statertt_state | GranuleAt(rec_ptrrtt).state == DELEGATEDRTT |
| rec_aux_statertte_state | AuxStateEqual16walk.rtte.state == TABLE |
| rtte_addr |
walk.rtte.addr == rtt
|
| rtte_c_ripas | pre: AddrIsProtected( rec_pre.auxipa, RecAuxCountrealm) post: RttAllEntriesRipas(rd_preRttAt(rtt), DELEGATEDunfold.ripas) |
| rtte_c_state | RttAllEntriesState(RttAt(rtt), unfold.state) |
| rtte_c_addr | pre: (unfold.state != UNASSIGNED && unfold.state != UNASSIGNED_NS) post: RttAllEntriesContiguous(RttAt(rtt), unfold.addr, level) |
15.3.31.4 Footprint
| ID | Value |
|---|---|
| rec_statertt_state | GranuleAt(rec_ptrrtt).state |
| rec_aux_statertte | AuxStatesRttEntry(rec_prewalk.auxrtt_addr, RecAuxCount(rd_preentry_idx)) |
15.3.32 RMI_REC_ENTER RMI_RTT_AUX_DESTROY command
Enter a RECDestroys an auxiliary RTT.
15.3.32.1 Interface
15.3.32.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400015C0xC400017E |
| rec_ptrrd | X1 | 63:0 | Address | PA of the RD for the target RECRealm |
| run_ptripa | X2 | 63:0 | Address | PA of RecRun objectBase of the IPA range described by the RTT |
| level | X3 | 63:0 | Int64 | RTT level |
| index | X4 | 63:0 | UInt64 | RTT tree index |
15.3.32.1.2 Context
The RMI_REC_ENTERRMI_RTT_AUX_DESTROY command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rec.ownerrd) |
false | Realm |
| walk | RmmRttWalkResult | RttWalk( realm, ipa, level - 1, index) |
false | RTT walk result |
| entry_idx | UInt64 | RttEntryIndex( ipa, walk.level) |
false | RTTE index |
| walk_top | Address | RttSkipNonLiveEntries( RttAt(walk.rtt_addr), walk.level, ipa) |
false | Top IPA of non-live RTT entries, from entry at which the RTT walk terminated |
15.3.32.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| rtt | X1 | 63:0 | Address | PA of the RTT which was destroyed |
| top | X2 | 63:0 | Address | Top IPA of non-live RTT entries, from entry at which the RTT walk terminated |
15.3.32.2 Failure conditions
| ID | Condition |
|---|---|
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| level_bound | pre: (!RttLevelIsValid(realm, level) || RttLevelIsStarting(realm, level)) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_align | pre: !AddrIsRttLevelAligned(ipa, level - 1) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_bound | pre: UInt(ipa) >= (2 ^ realm.ipa_width) post: ResultEqual(result, RMI_ERROR_INPUT) |
| index_bound | pre: (realm.rtt_tree_per_plane == FEATURE_FALSE || index == RMM_RTT_TREE_PRIMARY || index > realm.num_aux_planes) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rtt_walk | pre: walk.level < level - 1 post: ResultEqual(result, RMI_ERROR_RTT_AUX, walk.level) rtte_state pre: walk.rtte.state == TABLE post: ResultEqual(result, RMI_ERROR_RTT_AUX, walk.level) 15.3.33.2.1 Failure condition ordering [rd_bound, rd_state] < [rtt_walk, rtte_state] [level_bound, ipa_bound] < [rtt_walk, rtte_state] 15.3.33.3 Success conditions ID Condition rtt_state GranuleAt(rtt).state == RTT rtte_state walk.rtte.state == TABLE rtte_addr walk.rtte.addr == rtt rtte_c_ripas pre: AddrIsProtected(ipa, realm) post: RttAllEntriesRipas(RttAt(rtt), unfold.ripas) rtte_c_state RttAllEntriesState(RttAt(rtt), unfold.state) rtte_c_addr pre: (unfold.state != UNASSIGNED && unfold.state != UNASSIGNED_NS) post: RttAllEntriesContiguous(RttAt(rtt), unfold.addr, level) 15.3.33.4 Footprint ID Value rtt_state GranuleAt(rtt).state rtte RttEntry(walk.rtt_addr, entry_idx) 15.3.34 RMI_RTT_AUX_DESTROY command Destroys an auxiliary RTT. See also: Section 10.3.1 Section 15.3.33 Section 15.3.35 15.3.34.1 Interface 15.3.34.1.1 Input values Name Register Bits Type Description fid X0 63:0 UInt64 FID, value 0xC400017E rd X1 63:0 Address PA of the RD for the target Realm ipa X2 63:0 Address Base of the IPA range described by the RTT level X3 63:0 Int64 RTT level index X4 63:0 UInt64 RTT tree index 15.3.34.1.2 Context The RMI_RTT_AUX_DESTROY command operates on the following context. Name Type Value Before Description realm RmmRealm RealmAt(rd) false Realm walk RmmRttWalkResult RttWalk( realm, ipa, level - 1, index) false RTT walk result entry_idx UInt64 RttEntryIndex( ipa, walk.level) false RTTE index walk_top Address RttSkipNonLiveEntries( RttAt(walk.rtt_addr), walk.level, ipa) false Top IPA of non-live RTT entries, from entry at which the RTT walk terminated 15.3.34.1.3 Output values Name Register Bits Type Description result X0 63:0 RmiCommandReturnCode Command return status rtt X1 63:0 Address PA of the RTT which was destroyed top X2 63:0 Address Top IPA of non-live RTT entries, from entry at which the RTT walk terminated 15.3.34.2 Failure conditions ID Condition rd_align pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) rd_bound pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) rd_state pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) level_bound pre: (!RttLevelIsValid(realm, level) || RttLevelIsStarting(realm, level)) post: ResultEqual(result, RMI_ERROR_INPUT) ipa_align pre: !AddrIsRttLevelAligned(ipa, level - 1) post: ResultEqual(result, RMI_ERROR_INPUT) ipa_bound pre: UInt(ipa) >= (2 ^ realm.ipa_width) post: ResultEqual(result, RMI_ERROR_INPUT) index_bound pre: (realm.rtt_tree_per_plane == FEATURE_FALSE || index == RMM_RTT_TREE_PRIMARY || index > realm.num_aux_planes) post: ResultEqual(result, RMI_ERROR_INPUT) rtt_walk pre: walk.level < level - 1 post: (ResultEqual(result, RMI_ERROR_RTT_AUX, walk.level) && (top == walk_top)) |
| rtte_state | pre: walk.rtte.state != TABLE post: (ResultEqual(result, RMI_ERROR_RTT_AUX, walk.level) && (top == walk_top)) |
| rtt_live | pre: RttIsLive(RttAt(walk.rtte.addr)) post: (ResultEqual(result, RMI_ERROR_RTT_AUX, level) && (top == ipa)) |
15.3.3432.2.1 Failure condition ordering
[rd_bound, rd_state] < [rtt_walk, rtte_state, rtt_live]
[level_bound, ipa_bound] < [rtt_walk, rtte_state]
15.3.3432.3 Success conditions
| ID | Condition |
|---|---|
| rtte_state | walk.rtte.state == AUX_DESTROYED |
| ripas | walk.rtte.ripas == DESTROYED |
| rtt_state | GranuleAt(walk.rtte.addr).state == DELEGATED |
| rtt | rtt == walk.rtte.addr |
| top | top == walk_top |
15.3.3432.4 Footprint
| ID | Value |
|---|---|
| rtt_state | GranuleAt(walk.rtte.addr).state |
| rtte | RttEntry(walk.rtt_addr, entry_idx) |
15.3.3533 RMI_RTT_AUX_FOLD command
Destroys a homogeneous auxiliary RTT.
15.3.3533.1 Interface
15.3.3533.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400017F |
| rd | X1 | 63:0 | Address | PA of the RD for the target Realm |
| ipa | X2 | 63:0 | Address | Base of the IPA range described by the RTT |
| level | X3 | 63:0 | Int64 | RTT level |
| index | X4 | 63:0 | UInt64 | RTT tree index |
15.3.3533.1.2 Context
The RMI_RTT_AUX_FOLD command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| walk | RmmRttWalkResult | RttWalk( realm, ipa, level - 1, index) |
false | RTT walk result |
| entry_idx | UInt64 | RttEntryIndex( ipa, walk.level) |
false | RTTE index |
| fold_pre | RmmRttEntry | RttFold( RttAt(walk.rtte.addr)) |
true | Result of folding RTT |
15.3.3533.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| rtt | X1 | 63:0 | Address | PA of the RTT which was destroyed |
15.3.3533.2 Failure conditions
| ID | Condition |
|---|---|
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| level_bound | pre: (!RttLevelIsValid(realm, level) || RttLevelIsStarting(realm, level)) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_align | pre: !AddrIsRttLevelAligned(ipa, level - 1) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_bound | pre: UInt(ipa) >= (2 ^ realm.ipa_width) post: ResultEqual(result, RMI_ERROR_INPUT) |
| index_bound | pre: (realm.rtt_tree_per_plane == FEATURE_FALSE || index == RMM_RTT_TREE_PRIMARY || index > realm.num_aux_planes) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rtt_walk | pre: walk.level < level - 1 post: ResultEqual(result, RMI_ERROR_RTT_AUX, walk.level) |
| rtte_state | pre: walk.rtte.state != TABLE post: ResultEqual(result, RMI_ERROR_RTT_AUX, walk.level) |
| rtt_homo | pre: !RttIsHomogeneous(RttAt(walk.rtte.addr)) post: ResultEqual(result, RMI_ERROR_RTT_AUX, level) |
15.3.3533.2.1 Failure condition ordering
[rd_bound, rd_state] < [rtt_walk, rtte_state, rtt_homo]
[level_bound, ipa_bound] < [rtt_walk, rtte_state]
15.3.3533.3 Success conditions
| ID | Condition |
|---|---|
| rtte_state | walk.rtte.state == fold_pre.state |
| rtte_addr | pre: (fold_pre.state != UNASSIGNED && fold_pre.state != UNASSIGNED_NS) post: walk.rtte.addr == fold_pre.addr |
| rtte_attrrtte_attr_prot | pre: (fold_pre.state == ASSIGNED || fold_pre.state == ASSIGNED_NS post: (RttMemAttrEqual) post: ( walk.rtte.MemAttr ==, fold_pre.MemAttr, RTT_PROTECTED) && RttS2APEqual( walk.rtte, fold_pre, S2AP_INDIRECT)) |
| rtte_attr_unprot | pre: fold_pre.s2ap_basestate == ASSIGNED_NS post: (RttMemAttrEqual( walk.rtte, fold_pre.s2ap_base, RTT_UNPROTECTED) && RttS2APEqual( walk.rtte, fold_pre, realm.s2ap_overlay == fold_pre.s2ap_overlayrtt_s2ap_encoding)) |
| rtte_ripas | pre: AddrIsProtected(ipa, realm) post: walk.rtte.ripas == fold_pre.ripas |
| rtt_state | GranuleAt(walk.rtte.addr).state == DELEGATED |
| rtt | rtt == walk.rtte.addr |
15.3.3533.4 Footprint
| ID | Value |
|---|---|
| rtt_state | GranuleAt(walk.rtte.addr).state |
| rtte | RttEntry(walk.rtt_addr, entry_idx) |
15.3.3634 RMI_RTT_AUX_MAP_PROTECTED command
Creates a mapping from an Protected IPA in an auxiliary RTT.
15.3.34.1 Interface
15.3.34.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000180 |
| rd | X1 | 63:0 | Address | PA of the RD for the target Realm |
| ipa | X2 | 63:0 | Address | IPA in the target Realm |
| index | X3 | 63:0 | UInt64 | RTT tree index |
15.3.34.1.2 Context
The RMI_RTT_AUX_MAP_PROTECTED command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| walk_pri | RmmRttWalkResult | RttWalk( realm, ipa, RMM_RTT_PAGE_LEVEL, RMM_RTT_TREE_PRIMARY) |
false | Primary RTT walk result |
| walk_aux | RmmRttWalkResult | RttWalk( realm, ipa, RMM_RTT_PAGE_LEVEL, index) |
false | Auxiliary RTT walk result |
| entry_idx | UInt64 | RttEntryIndex( ipa, walk_aux.level) |
false | RTTE index |
15.3.34.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| fail_index | X1 | 63:0 | UInt64 | Index of RTT tree whose contents caused command to fail with RMI_ERROR_RTT |
| level_pri | X2 | 63:0 | Int64 | Level of RTTE reached by walk of primary RTT tree |
| state | X3 | 7:0 | RmiRttEntryState | State of RTT entry whose contents caused command to fail with RMI_ERROR_RTT |
| ripas | X4 | 7:0 | RmiRipas | RIPAS of RTT entry which caused command to fail with RMI_ERROR_RTT |
The following unused bits of RMI_RTT_AUX_MAP_PROTECTED output values MBZ: X3[63:8], X4[63:8].
15.3.34.2 Failure conditions
| ID | Condition |
|---|---|
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_align | pre: !AddrIsGranuleAligned(ipa) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_bound | pre: !AddrIsProtected(ipa, realm) post: ResultEqual(result, RMI_ERROR_INPUT) |
| index_bound | pre: (realm.rtt_tree_per_plane == FEATURE_FALSE || index == RMM_RTT_TREE_PRIMARY || index > realm.num_aux_planes) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pri_unassigned | pre: (walk_pri.rtte.state != ASSIGNED && walk_pri.rtte.state != ASSIGNED_DEV) post: (ResultEqual(result, RMI_ERROR_RTT, walk_pri.level) && (fail_index == RMM_RTT_TREE_PRIMARY) && (level_pri == walk_pri.level) && (state == RttEntryStateToRmi( walk_pri.rtte.state)) && (ripas == RipasToRmi( walk_pri.rtte.ripas))) |
| pri_ram | pre: (walk_pri.rtte.state == ASSIGNED && walk_pri.rtte.ripas != RAM) post: (ResultEqual(result, RMI_ERROR_RTT, walk_pri.level) && (fail_index == RMM_RTT_TREE_PRIMARY) && (level_pri == walk_pri.level) && (state == RttEntryStateToRmi( walk_pri.rtte.state)) && (ripas == RipasToRmi( walk_pri.rtte.ripas))) |
| pri_dev | pre: (walk_pri.rtte.state == ASSIGNED_DEV && walk_pri.rtte.ripas != DEV) post: (ResultEqual(result, RMI_ERROR_RTT, walk_pri.level) && (fail_index == RMM_RTT_TREE_PRIMARY) && (level_pri == walk_pri.level) && (state == RttEntryStateToRmi( walk_pri.rtte.state)) && (ripas == RipasToRmi( walk_pri.rtte.ripas))) |
| aux_destroyed | pre: walk_aux.rtte.state == AUX_DESTROYED post: (ResultEqual(result, RMI_ERROR_RTT_AUX, walk_aux.level) && (fail_index == index) && (level_pri == walk_pri.level) && (state == RttEntryStateToRmi( walk_aux.rtte.state)) && (ripas == RipasToRmi( walk_pri.rtte.ripas))) |
| level | pre: walk_aux.level < walk_pri.level post: (ResultEqual(result, RMI_ERROR_RTT_AUX, walk_aux.level) && (fail_index == index) && (level_pri == walk_pri.level) && (state == RttEntryStateToRmi( walk_aux.rtte.state)) && (ripas == RipasToRmi( walk_pri.rtte.ripas))) |
15.3.34.2.1 Failure condition ordering
[rd_bound, rd_state] < [pri_unassigned, pri_ram, pri_dev,
aux_destroyed, level]
[ipa_bound, index_bound] < [pri_unassigned, pri_ram, pri_dev,
aux_destroyed, level]
15.3.34.3 Success conditions
| ID | Condition |
|---|---|
| rtte_state | walk_aux.rtte.state == ASSIGNED |
| rtte_attr |
walk_aux.rtte.attr_prot == walk_pri.rtte.attr_prot
|
| rtte_sh |
walk_aux.rtte.sh == walk_pri.rtte.sh
|
| rtte_addr | walk_aux.rtte.addr == walk_pri.rtte.addr + (entry_idx * RttLevelSize(walk_aux.level)) |
15.3.34.4 Footprint
| ID | Value |
|---|---|
| rtte |
RttEntry(walk_aux.rtt_addr, entry_idx)
|
15.3.35 RMI_RTT_AUX_MAP_UNPROTECTED command
Creates a mapping from an Unprotected IPA in an auxiliary RTT.
15.3.35.1 Interface
15.3.35.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000181 |
| rd | X1 | 63:0 | Address | PA of the RD for the target Realm |
| ipa | X2 | 63:0 | Address | IPA in the target Realm |
| index | X3 | 63:0 | UInt64 | RTT tree index |
15.3.35.1.2 Context
The RMI_RTT_AUX_MAP_UNPROTECTED command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| walk_pri | RmmRttWalkResult | RttWalk( realm, ipa, RMM_RTT_PAGE_LEVEL, RMM_RTT_TREE_PRIMARY) |
false | Primary RTT walk result |
| walk_aux | RmmRttWalkResult | RttWalk( realm, ipa, RMM_RTT_PAGE_LEVEL, index) |
false | Auxiliary RTT walk result |
| entry_idx | UInt64 | RttEntryIndex( ipa, walk_aux.level) |
false | RTTE index |
15.3.35.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| fail_index | X1 | 63:0 | UInt64 | Index of RTT tree whose contents caused command to fail with RMI_ERROR_RTT |
| level_pri | X2 | 63:0 | Int64 | Level of RTTE reached by walk of primary RTT tree |
| state | X3 | 7:0 | RmiRttEntryState | State of RTT entry whose contents caused command to fail with RMI_ERROR_RTT |
The following unused bits of RMI_RTT_AUX_MAP_UNPROTECTED output values MBZ: X3[63:8].
15.3.35.2 Failure conditions
| ID | Condition |
|---|---|
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_align | pre: !AddrIsGranuleAligned(ipa) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_bound | pre: (UInt(ipa) >= (2 ^ realm.ipa_width) || AddrIsProtected(ipa, realm)) post: ResultEqual(result, RMI_ERROR_INPUT) |
| index_bound | pre: (realm.rtt_tree_per_plane == FEATURE_FALSE || index == RMM_RTT_TREE_PRIMARY || index > realm.num_aux_planes) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pri_state | pre: walk_pri.rtte.state != ASSIGNED_NS post: (ResultEqual(result, RMI_ERROR_RTT, walk_pri.level) && (fail_index == RMM_RTT_TREE_PRIMARY) && (state == RttEntryStateToRmi( walk_pri.rtte.state)) && (level_pri == walk_pri.level)) |
| level | pre: walk_aux.level < walk_pri.level post: (ResultEqual(result, RMI_ERROR_RTT_AUX, walk_aux.level) && (fail_index == index) && (level_pri == walk_pri.level) && (state == RttEntryStateToRmi( walk_aux.rtte.state))) |
15.3.35.2.1 Failure condition ordering
[rd_bound, rd_state] < [pri_state, level]
[ipa_bound, index_bound] < [pri_state, level]
15.3.35.3 Success conditions
| ID | Condition |
|---|---|
| rtte_state | walk_aux.rtte.state == ASSIGNED_NS |
| rtte_attr_prot | pre: AddrIsProtected(ipa, realm) post: (RttMemAttrEqual( walk_aux.rtte, walk_pri.rtte, RTT_PROTECTED) && RttS2APEqual( walk_aux.rtte, walk_pri.rtte, realm.rtt_s2ap_encoding)) |
| rtte_attr_unprot | pre: !AddrIsProtected(ipa, realm) post: (RttMemAttrEqual( walk_aux.rtte, walk_pri.rtte, RTT_UNPROTECTED) && RttS2APEqual( walk_aux.rtte, walk_pri.rtte, realm.rtt_s2ap_encoding)) |
| rtte_addr | walk_aux.rtte.addr == walk_pri.rtte.addr + (entry_idx * RttLevelSize(walk_aux.level)) |
15.3.35.4 Footprint
| ID | Value |
|---|---|
| rtte |
RttEntry(walk_aux.rtt_addr, entry_idx)
|
15.3.36 RMI_RTT_AUX_UNMAP_PROTECTED command
Removes a mapping from an Protected IPA in an auxiliary RTT.
15.3.36.1 Interface
15.3.36.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001800xC4000183 |
| rd | X1 | 63:0 | Address | PA of the RD for the target Realm |
| ipa | X2 | 63:0 | Address | IPA in the target Realm |
| index | X3 | 63:0 | UInt64 | RTT tree index |
15.3.36.1.2 Context
The RMI_RTT_AUX_MAP_PROTECTEDRMI_RTT_AUX_UNMAP_PROTECTED command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| walk_priwalk | RmmRttWalkResult | RttWalk( realm, ipa, RMM_RTT_PAGE_LEVEL, RMM_RTT_TREE_PRIMARYindex) |
false | PrimaryAuxiliary RTT walk result |
| entry_idx | UInt64 | RttEntryIndex( ipa, walk_auxwalk.level) |
false | RTTE index |
| walk_top | Address | RttSkipNonLiveEntries( RttAt(walk.rtt_addr), walk.level, ipa) |
false | Top IPA of non-live RTT entries, from entry at which the RTT walk terminated |
15.3.36.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| fail_indextop | X1 | 63:0 | UInt64Address | Index ofTop IPA of non-live RTT tree whose contents caused command to fail with RMI_ERROR_RTTentries, from entry at which the RTT walk terminated |
| level_prilevel | X2 | 63:0 | Int64 | Level of RTTERTT level reached by the RTT walk of primary RTT tree |
15.3.36.2 Failure conditions
| ID | Condition |
|---|---|
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_align | pre: !AddrIsGranuleAligned(ipa) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_bound | pre: !AddrIsProtected(ipa, realm) post: ResultEqual(result, RMI_ERROR_INPUT) |
| index_bound | pre: (realm.rtt_tree_per_plane == FEATURE_FALSE || index == RMM_RTT_TREE_PRIMARY || index > realm.num_aux_planes) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pri_unassignedrtte_state | pre: (walk_priwalk.rtte.state != ASSIGNED && walk_pri.rtte.state != ASSIGNED_DEV) post: (ResultEqual(result, RMI_ERROR_RTTRMI_ERROR_RTT_AUX, walk_priwalk.level) && (fail_indextop == RMM_RTT_TREE_PRIMARY) && (level_pri == walk_pri.level) && (state == RttEntryStateToRmi( walk_pri.rtte.statewalk_top)) && (ripas == RipasToRmi( walk_pri.rtte.ripas))) |
15.3.36.2.1 Failure condition ordering
[rd_bound, rd_state] < [pri_unassigned, pri_ram, pri_dev,
aux_destroyed, level][rtte_state]
[ipa_bound, index_bound] < [pri_unassigned, pri_ram, pri_dev,
aux_destroyed, level][rtte_state]
15.3.36.3 Success conditions
| ID | Condition |
|---|---|
| rtte_state | walk_auxwalk.rtte.state == ASSIGNEDUNASSIGNED |
| rtte_attrtop | walk_aux.rtte.MemAttrtop == walk_pri.rtte.MemAttrwalk_top |
| rtte_addrlevel | walk_aux.rtte.addrlevel == walk_pri.rtte.addr + (entry_idx * RttLevelSize(walk_aux walk.level)) |
15.3.36.4 Footprint
| ID | Value |
|---|---|
| rtte | RttEntry(walk_auxwalk.rtt_addr, entry_idx) |
15.3.37 RMI_RTT_AUX_MAP_UNPROTECTED RMI_RTT_AUX_UNMAP_UNPROTECTED command
CreatesRemoves a mapping from an Unprotected IPA in an auxiliary RTT.
15.3.37.1 Interface
15.3.37.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001810xC4000184 |
| rd | X1 | 63:0 | Address | PA of the RD for the target Realm |
| ipa | X2 | 63:0 | Address | IPA in the target Realm |
| index | X3 | 63:0 | UInt64 | RTT tree index |
15.3.37.1.2 Context
The RMI_RTT_AUX_MAP_UNPROTECTEDRMI_RTT_AUX_UNMAP_UNPROTECTED command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| walk_priwalk | RmmRttWalkResult | RttWalk( realm, ipa, RMM_RTT_PAGE_LEVEL, RMM_RTT_TREE_PRIMARYindex) |
false | PrimaryAuxiliary RTT walk result |
| entry_idx | UInt64 | RttEntryIndex( ipa, walk_auxwalk.level) |
false | RTTE index |
| walk_top | Address | RttSkipNonLiveEntries( RttAt(walk.rtt_addr), walk.level, ipa) |
false | Top IPA of non-live RTT entries, from entry at which the RTT walk terminated |
15.3.37.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| fail_indextop | X1 | 63:0 | UInt64Address | Index ofTop IPA of non-live RTT tree whose contents caused command to fail with RMI_ERROR_RTTentries, from entry at which the RTT walk terminated |
| level_prilevel | X2 | 63:0 | Int64 | Level of RTTERTT level reached by the RTT walk of primary RTT tree |
15.3.37.2 Failure conditions
| ID | Condition |
|---|---|
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_align | pre: !AddrIsGranuleAligned(ipa) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_bound |
pre: (UInt(ipa) >= (2 ^ realm.ipa_width)
|| AddrIsProtected(ipa, realm))
post: ResultEqual(result, RMI_ERROR_INPUT)
|
| index_bound | pre: (realm.rtt_tree_per_plane == FEATURE_FALSE || index == RMM_RTT_TREE_PRIMARY || index > realm.num_aux_planes) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pri_statertte_state | pre: walk_priwalk.rtte.state != ASSIGNED_NS post: (ResultEqual(result, RMI_ERROR_RTTRMI_ERROR_RTT_AUX, walk_priwalk.level) && (fail_indextop == RMM_RTT_TREE_PRIMARY) && (state == RttEntryStateToRmi( walk_pri.rtte.statewalk_top)) && (level_pri == walk_pri.level)) |
15.3.37.2.1 Failure condition ordering
[rd_bound, rd_state] < [pri_state, level][rtte_state]
[ipa_bound, index_bound] < [pri_state, level][rtte_state]
15.3.37.3 Success conditions
| ID | Condition |
|---|---|
| rtte_state | walk_auxwalk.rtte.state == ASSIGNED_NSUNASSIGNED_NS |
| rtte_attrtop | (walk_aux.rtte.MemAttrtop == walk_pri.rtte.MemAttr && walk_aux.rtte.s2ap_basewalk_top |
| level | level == walk_priwalk.rtte.s2ap_base && walk_aux.rtte.s2ap_overlay == walk_pri.rtte.s2ap_overlay)level |
15.3.37.4 Footprint
| ID | Value |
|---|---|
| rtte | RttEntry(walk_auxwalk.rtt_addr, entry_idx) |
15.3.38 RMI_RTT_AUX_UNMAP_PROTECTED RMI_RTT_CREATE command
Removes a mapping from an Protected IPA in an auxiliaryCreates a primary RTT.
15.3.38.1 Interface
15.3.38.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001830xC400015D |
| rd | X1 | 63:0 | Address | PA of the RD for the target Realm |
| ipartt | X2 | 63:0 | Address | IPA inPA of the target RealmRTT |
| indexipa | X3 | 63:0 | UInt64Address | Base of the IPA range described by the RTT |
| level | X4 | 63:0 | Int64 | RTT tree indexlevel |
15.3.38.1.2 Context
The RMI_RTT_AUX_UNMAP_PROTECTEDRMI_RTT_CREATE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| walk | RmmRttWalkResult | RttWalk( realm, ipa, RMM_RTT_PAGE_LEVELlevel - 1, RMM_RTT_TREE_PRIMARY, index) |
false | Auxiliary RTT walk result |
| entry_idx | UInt64 | RttEntryIndex( ipa, walk.level) |
false | RTTE index |
| walk_topwalk_pre | AddressRmmRttWalkResult | RttSkipNonLiveEntriesRttWalk( RttAtrealm, ipa, level - 1, RMM_RTT_TREE_PRIMARY(walk.rtt_addr), walk.level, ipa) |
falsetrue | Top IPA of non-live RTT entries, from entry at which the RTT walk terminated result before command execution |
| rtte_pre | RmmRttEntry |
walk_pre.rtte
|
true | RTTE before command execution |
15.3.38.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.38.2 Failure conditions
| ID | Condition |
|---|---|
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_alignlevel_bound | pre: (!AddrIsGranuleAlignedRttLevelIsValid(iparealm, level) || RttLevelIsStarting(realm, level)) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_boundipa_align | pre: !AddrIsProtectedAddrIsRttLevelAligned(ipa, realmlevel - 1) post: ResultEqual(result, RMI_ERROR_INPUT) |
| index_boundipa_bound | pre: UInt(realm.rtt_tree_per_plane == FEATURE_FALSE || index == RMM_RTT_TREE_PRIMARY || indexipa) >= (2 ^ realm.num_aux_planesipa_width) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rtte_statertt_align | pre: walk.rtte.state != ASSIGNEDAddrIsGranuleAligned(rtt) post: (ResultEqual(result, RMI_ERROR_RTT_AUXRMI_ERROR_INPUT) |
| rtt_bound | pre: !PaIsDelegableDram(rtt) post: ResultEqual(result, walkRMI_ERROR_INPUT) |
| rtt_state | pre: GranuleAt(rtt).levelstate != DELEGATED post: ResultEqual(result, RMI_ERROR_INPUT) |
| rtt_bound2 | pre: ((realm.feat_lpa2 == FEATURE_FALSE) && (topUInt(rtt) >= 2^48)) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rtt_walk | pre: walk.level < level - 1 post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
| rtte_state | pre: walk.rtte.state == walk_topTABLE post: ResultEqual(result, RMI_ERROR_RTT, walk.level)) |
15.3.38.2.1 Failure condition ordering
[rd_bound, rd_state] < [rtte_state]
[ipa_bound[rtt_walk, index_bound]rtte_state]
[level_bound, ipa_bound] < [rtte_state][rtt_walk, rtte_state]
15.3.38.3 Success conditions
| ID | Condition |
|---|---|
| rtt_state | GranuleAt(rtt).state == RTT |
| rtte_state | walk.rtte.state == TABLE |
| rtte_addr |
walk.rtte.addr == rtt
|
| rtte_c_ripas | pre: AddrIsProtected(ipa, realm) post: RttAllEntriesRipas(RttAt(rtt), rtte_pre.ripas) |
| rtte_c_state | RttAllEntriesState(RttAt(rtt), rtte_pre.state) |
| rtte_c_addr | pre: (rtte_pre.state != UNASSIGNED && rtte_pre.state != UNASSIGNED_NS) post: RttAllEntriesContiguous(RttAt(rtt), rtte_pre.addr, level) |
15.3.38.4 Footprint
| ID | Value |
|---|---|
| rtt_state | GranuleAt(rtt).state |
| rtte | RttEntryRttEntryAt(RttAt(walk.rtt_addr), entry_idx) |
15.3.39 RMI_RTT_AUX_UNMAP_UNPROTECTED RMI_RTT_DESTROY command
Removes a mapping from an Unprotected IPA in an auxiliaryDestroys a primary RTT.
15.3.39.1 Interface
15.3.39.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001840xC400015E |
| rd | X1 | 63:0 | Address | PA of the RD for the target Realm |
| ipa | X2 | 63:0 | Address | Base of the IPA in the target Realmrange described by the RTT |
| indexlevel | X3 | 63:0 | UInt64Int64 | RTT tree indexlevel |
15.3.39.1.2 Context
The RMI_RTT_AUX_UNMAP_UNPROTECTEDRMI_RTT_DESTROY command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| walk | RmmRttWalkResult | RttWalk( realm, ipa, RMM_RTT_PAGE_LEVELlevel - 1, RMM_RTT_TREE_PRIMARY, index) |
false | Auxiliary RTT walk result |
| entry_idx | UInt64 | RttEntryIndex( ipa, walk.level) |
false | RTTE index |
| walk_top | Address | RttSkipNonLiveEntries( RttAt(walk.rtt_addr), walk.level, ipa) |
false | Top IPA of non-live RTT entries, from entry at which the RTT walk terminated |
15.3.39.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| toprtt | X1 | 63:0 | Address | PA of the RTT which was destroyed |
| top | X2 | 63:0 | Address | Top IPA of non-live RTT entries, from entry at which the RTT walk terminated |
The rtt output value is valid only when the command
result is RMI_SUCCESS.
The values of the result and top output
values for different command outcomes are summarized in the following
table.
| Scenario | result | top | walk.rtte.state |
|---|---|---|---|
| Target RTT exists and is not live | RMI_SUCCESS | > ipa | Before execution: TABLE After execution: UNASSIGNED and RIPAS is DESTROYED |
| Missing RTT | (RMI_ERROR_RTT, < level) | > ipa | UNASSIGNED or UNASSIGNED_NS |
| Block mapping at lower level | X2(RMI_ERROR_RTT, < level) | 63:0== ipa | Int64ASSIGNED or ASSIGNED_NS |
| Live RTT at target level | (RMI_ERROR_RTT, level) | == ipa | TABLE |
| RTT level reached by the RTT walk was not performed, due to any other command failure | Another error code | 0 | Unknown |
See also:
- Section 5.6.8
15.3.39.2 Failure conditions
| ID | Condition |
|---|---|
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| level_bound | pre: (!RttLevelIsValid(realm, level) || RttLevelIsStarting(realm, level)) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_align | pre: !AddrIsRttLevelAligned(ipa, level - 1) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_bound | pre: UInt(ipa) >= (2 ^ realm.ipa_width) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rtt_walk | pre: walk.level < level - 1 post: ResultEqual(result, RMI_ERROR_RTT, walk.level) rtte_state pre: walk.rtte.state == TABLE post: ResultEqual(result, RMI_ERROR_RTT, walk.level) 15.3.40.2.1 Failure condition ordering [rd_bound, rd_state] < [rtt_walk, rtte_state] [level_bound, ipa_bound] < [rtt_walk, rtte_state] 15.3.40.3 Success conditions ID Condition rtt_state GranuleAt(rtt).state == RTT rtte_state walk.rtte.state == TABLE rtte_addr walk.rtte.addr == rtt rtte_c_ripas pre: AddrIsProtected(ipa, realm) post: RttAllEntriesRipas(RttAt(rtt), rtte_pre.ripas) rtte_c_state RttAllEntriesState(RttAt(rtt), rtte_pre.state) rtte_c_addr pre: (rtte_pre.state != UNASSIGNED && rtte_pre.state != UNASSIGNED_NS) post: RttAllEntriesContiguous(RttAt(rtt), rtte_pre.addr, level) 15.3.40.4 Footprint ID Value rtt_state GranuleAt(rtt).state rtte RttEntryAt(walk.rtt_addr, entry_idx) 15.3.41 RMI_RTT_DESTROY command Destroys a primary RTT. See also: Section 5.5 Section 5.5.9 Section 15.3.40 Section 15.3.42 15.3.41.1 Interface 15.3.41.1.1 Input values Name Register Bits Type Description fid X0 63:0 UInt64 FID, value 0xC400015E rd X1 63:0 Address PA of the RD for the target Realm ipa X2 63:0 Address Base of the IPA range described by the RTT level X3 63:0 Int64 RTT level 15.3.41.1.2 Context The RMI_RTT_DESTROY command operates on the following context. Name Type Value Before Description realm RmmRealm RealmAt(rd) false Realm walk RmmRttWalkResult RttWalk( realm, ipa, level - 1, RMM_RTT_TREE_PRIMARY) false RTT walk result entry_idx UInt64 RttEntryIndex( ipa, walk.level) false RTTE index walk_top Address RttSkipNonLiveEntries( RttAt(walk.rtt_addr), walk.level, ipa) false Top IPA of non-live RTT entries, from entry at which the RTT walk terminated 15.3.41.1.3 Output values Name Register Bits Type Description result X0 63:0 RmiCommandReturnCode Command return status rtt X1 63:0 Address PA of the RTT which was destroyed top X2 63:0 Address Top IPA of non-live RTT entries, from entry at which the RTT walk terminated The rtt output value is valid only when the command result is RMI_SUCCESS. The values of the result and top output values for different command outcomes are summarized in the following table. Scenario result top walk.rtte.state Target RTT exists and is not live RMI_SUCCESS > ipa Before execution: TABLE After execution: UNASSIGNED and RIPAS is DESTROYED Missing RTT (RMI_ERROR_RTT, < level) > ipa UNASSIGNED or UNASSIGNED_NS Block mapping at lower level (RMI_ERROR_RTT, < level) == ipa ASSIGNED or ASSIGNED_NS Live RTT at target level (RMI_ERROR_RTT, level) == ipa TABLE RTT walk was not performed, due to any other command failure Another error code 0 Unknown See also: Section 5.5.8 15.3.41.2 Failure conditions ID Condition rd_align pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) rd_bound pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) rd_state pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) level_bound pre: (!RttLevelIsValid(realm, level) || RttLevelIsStarting(realm, level)) post: ResultEqual(result, RMI_ERROR_INPUT) ipa_align pre: !AddrIsRttLevelAligned(ipa, level - 1) post: ResultEqual(result, RMI_ERROR_INPUT) ipa_bound pre: UInt(ipa) >= (2 ^ realm.ipa_width) post: ResultEqual(result, RMI_ERROR_INPUT) rtt_walk pre: walk.level < level - 1 post: (ResultEqual(result, RMI_ERROR_RTT, walk.level) && (top == walk_top)) |
| rtte_state | pre: walk.rtte.state != TABLE post: (ResultEqual(result, RMI_ERROR_RTT, walk.level) && (top == walk_top)) |
| rtt_live | pre: RttIsLive(RttAt(walk.rtte.addr)) post: (ResultEqual(result, RMI_ERROR_RTT, level) && (top == ipa)) |
15.3.4139.2.1 Failure condition ordering
[rd_bound, rd_state] < [rtt_walk, rtte_state]
[rtte_state] < [rtt_live]
[level_bound, ipa_bound] < [rtt_walk, rtte_state]
15.3.4139.3 Success conditions
| ID | Condition |
|---|---|
| state_prot | pre: AddrIsProtected(ipa, realm) post: walk.rtte.state == UNASSIGNED |
| ripas | pre: AddrIsProtected(ipa, realm) post: walk.rtte.ripas == DESTROYED |
| state_unprot | pre: !AddrIsProtected(ipa, realm) post: walk.rtte.state == UNASSIGNEDUNASSIGNED_NS |
| rtt_state | GranuleAt(walk.rtte.addr).state == DELEGATED |
| rtt | rtt == walk.rtte.addr |
| top | top == walk_top |
15.3.4139.4 Footprint
| ID | Value |
|---|---|
| rtt_state | GranuleAt(walk.rtte.addr).state |
| rtte | RttEntryAt(RttAt(walk.rtt_addr), entry_idx) |
15.3.4240 RMI_RTT_FOLD RMI_RTT_DEV_MEM_VALIDATE command
Completes a request made by the Realm to validate mappings to device memory from a target IPA range.
15.3.40.1 Interface
15.3.40.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000163 |
| rd | X1 | 63:0 | Address | PA of the RD for the target Realm |
| rec_ptr | X2 | 63:0 | Address | PA of the target REC |
| base | X3 | 63:0 | Address | Base of target IPA region |
| top | X4 | 63:0 | Address | Top of target IPA region |
15.3.40.1.2 Context
The RMI_RTT_DEV_MEM_VALIDATE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| realm_pre | RmmRealm | RealmAt(rd) |
true | Realm |
| rec | RmmRec | RecAt(rec_ptr) |
false | REC |
| pa_pre | Address |
rec.dev_mem_pa
|
true | Output base address |
| walk | RmmRttWalkResult | RttWalk( realm, base, RMM_RTT_PAGE_LEVEL, RMM_RTT_TREE_PRIMARY) |
false | RTT walk result |
| walk_top_pre | Address | RttSkipEntriesWithRipas( RttAt(walk.rtt_addr), walk.level, base, top, FALSE) |
true | Top IPA of entries which have associated RIPAS values, starting from entry at which the RTT walk terminated |
15.3.40.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| out_top | X1 | 63:0 | Address | Top IPA of range whose RIPAS was modified |
The out_top output value is valid only when the command
result is RMI_SUCCESS.
15.3.40.2 Failure conditions
| ID | Condition |
|---|---|
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_align | pre: !AddrIsGranuleAligned(rec_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_bound | pre: !PaIsDelegable(rec_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_gran_state | pre: GranuleAt(rec_ptr).state != REC post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_state | pre: rec.state == REC_RUNNING post: ResultEqual(result, RMI_ERROR_REC) |
| rec_owner | pre: rec.owner != rd post: ResultEqual(result, RMI_ERROR_REC) |
| size_valid | pre: UInt(top) <= UInt(base) post: ResultEqual(result, RMI_ERROR_INPUT) |
| base_bound | pre: base != rec.dev_mem_addr post: ResultEqual(result, RMI_ERROR_INPUT) |
| top_bound | pre: UInt(top) > UInt(rec.dev_mem_top) post: ResultEqual(result, RMI_ERROR_INPUT) |
| base_align | pre: !AddrIsRttLevelAligned(base, walk.level) post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
| top_gran_align | pre: !AddrIsGranuleAligned(top) post: ResultEqual(result, RMI_ERROR_INPUT) |
| no_progress | pre: UInt(base) == UInt(walk_top_pre) post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
| ncoh_attr | pre: (rec.dev_mem_flags.coh == DEV_MEM_NON_COHERENT && !RttEntriesInRangeMemAttr( RttAt(walk.rtt_addr), walk.level, base, walk_top_pre, MEMATTR_NON_CACHEABLE)) post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
| ncoh_pa | pre: (rec.dev_mem_flags.coh == DEV_MEM_NON_COHERENT && !RttEntriesInRangeNonCohDevMem( RttAt(walk.rtt_addr), walk.level, base, walk_top_pre)) post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
| coh_attr | pre: (rec.dev_mem_flags.coh == DEV_MEM_COHERENT && !RttEntriesInRangeMemAttr( RttAt(walk.rtt_addr), walk.level, base, walk_top_pre, MEMATTR_PASSTHROUGH)) post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
| coh_pa | pre: (rec.dev_mem_flags.coh == DEV_MEM_COHERENT && !RttEntriesInRangeCohDevMem( RttAt(walk.rtt_addr), walk.level, base, walk_top_pre)) post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
| linear_map | pre: !RttEntriesInRangeOutputContiguous( RttAt(walk.rtt_addr), walk.level, base, walk_top_pre, rec.dev_mem_pa) post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
| aux_live | pre: AddrRangeIsAuxLive(base, top, realm_pre) post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
15.3.40.2.1 Failure condition ordering
[rd_bound, rd_state] < [base_align]
[rd_bound, rd_state] < [no_progress]
[rec_bound, rec_gran_state] < [rec_state, rec_owner]
[base_bound] < [base_align]
[top_gran_align] < [no_progress]
15.3.40.3 Success conditions
| ID | Condition |
|---|---|
| rtte_ripas | RttEntriesInRangeRipas( RttAt(walk.rtt_addr), walk.level, base, walk_top_pre, DEV) |
| dev_mem_addr | rec.dev_mem_addr == MinAddress(top, walk_top_pre) |
| dev_mem_pa | rec.dev_mem_pa == ToAddress( UInt(pa_pre) + (UInt(walk_top_pre) - UInt(base))) |
| out_top | out_top == MinAddress(top, walk_top_pre) |
15.3.40.4 Footprint
| ID | Value |
|---|---|
| rtte | RttAt(walk.rtt_addr) |
| dev_mem_addr |
rec.dev_mem_addr
|
15.3.41 RMI_RTT_FOLD command
Destroys a homogeneous primary RTT.
15.3.4241.1 Interface
15.3.4241.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000166 |
| rd | X1 | 63:0 | Address | PA of the RD for the target Realm |
| ipa | X2 | 63:0 | Address | Base of the IPA range described by the RTT |
| level | X3 | 63:0 | Int64 | RTT level |
15.3.4241.1.2 Context
The RMI_RTT_FOLD command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| walk | RmmRttWalkResult | RttWalk( realm, ipa, level - 1, RMM_RTT_TREE_PRIMARY) |
false | RTT walk result |
| entry_idx | UInt64 | RttEntryIndex( ipa, walk.level) |
false | RTTE index |
| fold_pre | RmmRttEntry | RttFold( RttAt(walk.rtte.addr)) |
true | Result of folding RTT |
15.3.4241.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| rtt | X1 | 63:0 | Address | PA of the RTT which was destroyed |
The rtt output value is valid only when the command
result is RMI_SUCCESS.
15.3.4241.2 Failure conditions
| ID | Condition |
|---|---|
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| level_bound | pre: (!RttLevelIsValid(realm, level) || RttLevelIsStarting(realm, level)) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_align | pre: !AddrIsRttLevelAligned(ipa, level - 1) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_bound | pre: UInt(ipa) >= (2 ^ realm.ipa_width) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rtt_walk | pre: walk.level < level - 1 post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
| rtte_state | pre: walk.rtte.state != TABLE post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
| rtt_homo | pre: !RttIsHomogeneous(RttAt(walk.rtte.addr)) post: ResultEqual(result, RMI_ERROR_RTT, level) |
15.3.4241.2.1 Failure condition ordering
[rd_bound, rd_state] < [rtt_walk, rtte_state, rtt_homo]
[level_bound, ipa_bound] < [rtt_walk, rtte_state]
15.3.4241.3 Success conditions
| ID | Condition |
|---|---|
| rtte_state | walk.rtte.state == fold_pre.state |
| rtte_addr | pre: (fold_pre.state != UNASSIGNED && fold_pre.state != UNASSIGNED_NS) post: walk.rtte.addr == fold_pre.addr |
| rtte_attrrtte_attr_prot | pre: (fold_pre.state == ASSIGNED || fold_pre.state == ASSIGNED_NS post: (RttMemAttrEqual) post: ( walk.rtte.MemAttr ==, fold_pre.MemAttr, RTT_PROTECTED) && RttS2APEqual( walk.rtte, fold_pre, S2AP_INDIRECT)) |
| rtte_attr_unprot | pre: fold_pre.s2ap_basestate == ASSIGNED_NS post: (RttMemAttrEqual( walk.rtte, fold_pre.s2ap_base, RTT_UNPROTECTED) && RttS2APEqual( walk.rtte, fold_pre, realm.s2ap_overlay == fold_pre.s2ap_overlayrtt_s2ap_encoding)) |
| rtte_ripas | pre: AddrIsProtected(ipa, realm) post: walk.rtte.ripas == fold_pre.ripas |
| rtt_state | GranuleAt(walk.rtte.addr).state == DELEGATED |
| rtt | rtt == walk.rtte.addr |
15.3.4241.4 Footprint
| ID | Value |
|---|---|
| rtt_state | GranuleAt(walk.rtte.addr).state |
| rtte | RttEntryAt(RttAt(walk.rtt_addr), entry_idx) |
15.3.4342 RMI_RTT_INIT_RIPAS command
Set the RIPAS of a target IPA range to RAM, for a Realm in the REALM_NEW state.
15.3.42.1 Interface
15.3.42.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000168 |
| rd | X1 | 63:0 | Address | PA of the RD for the target Realm |
| base | X2 | 63:0 | Address | Base of target IPA region |
| top | X3 | 63:0 | Address | Top of target IPA region |
15.3.42.1.2 Context
The RMI_RTT_INIT_RIPAS command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm_pre | RmmRealm | RealmAt(rd) |
true | Realm |
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| walk | RmmRttWalkResult | RttWalk( realm, base, RMM_RTT_PAGE_LEVEL, RMM_RTT_TREE_PRIMARY) |
false | RTT walk result |
| walk_top | Address | RttSkipEntriesIfNotState( RttAt(walk.rtt_addr), walk.level, base, top, UNASSIGNED) |
false | Top IPA of UNASSIGNED entries, starting from entry at which the RTT walk terminated |
15.3.42.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| out_top | X1 | 63:0 | Address | Top IPA of range whose RIPAS was modified |
The out_top output value is valid only when the command
result is RMI_SUCCESS.
When the out_top output value is valid, it is aligned to
the size of the address range described by the RTT entry at the level
where the RTT walk terminated.
15.3.42.2 Failure conditions
| ID | Condition |
|---|---|
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| size_valid | pre: UInt(top) <= UInt(base) post: ResultEqual(result, RMI_ERROR_INPUT) |
| top_bound | pre: !AddrIsProtected( ToAddress(UInt(top) - RMM_GRANULE_SIZE), realm_pre) post: ResultEqual(result, RMI_ERROR_INPUT) |
| realm_state | pre: realm_pre.state != REALM_NEW post: ResultEqual(result, RMI_ERROR_REALM) |
| base_align | pre: !AddrIsRttLevelAligned(base, walk.level) post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
| rtte_state | pre: walk.rtte.state != UNASSIGNED post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
| top_gran_align | pre: !AddrIsGranuleAligned(top) post: ResultEqual(result, RMI_ERROR_INPUT) |
| no_progress | pre: UInt(base) == UInt(walk_top) post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
15.3.42.2.1 Failure condition ordering
[rd_bound, rd_state] < [realm_state]
[rd_bound, rd_state] < [base_align, rtte_state]
[rd_bound, rd_state] < [no_progress]
[top_gran_align] < [no_progress]
15.3.42.3 Success conditions
| ID | Condition |
|---|---|
| rtte_ripas | RttEntriesInRangeRipas( RttAt(walk.rtt_addr), walk.level, base, walk_top, RAM) |
| rim | realm.measurements[0] == RimExtendRipas( realm_pre, base, walk_top, walk.level) |
| out_top |
out_top == walk_top
|
15.3.42.4 RMI_RTT_INIT_RIPAS extension of RIM
On successful execution of RMI_RTT_INIT_RIPAS, the new RIM value of the target Realm is calculated by the RMM as follows:
Allocate an RmmMeasurementDescriptorRipas data structure.
For each RTT entry in the range
[base, top)described by the RMI_RTT_INIT_RIPAS input values:
- Populate the measurement descriptor:
- Set the desc_type field to the descriptor type.
- Set the len field to the descriptor length.
- Set the base field to the IPA of the RTT entry.
- Set the top field to
Min(ipa + size, top), whereipais the IPA of the RTT entrysizeis the size in bytes of the IPA region described by the RTT entrytopis the input value provided to the command
- Using the RHA of the target Realm, compute the hash of the measurement descriptor. Set the RIM of the target Realm to this value, zero filling upper bytes if the RHA output is smaller than the size of the RIM.
15.3.42.5 Footprint
| ID | Value |
|---|---|
| rtte | RttAt(walk.rtt_addr) |
| rim |
realm.measurements[0]
|
15.3.43 RMI_RTT_MAP_UNPROTECTED command
Creates a mapping from an Unprotected IPA to a Non-secure PA in a primary RTT.
15.3.43.1 Interface
15.3.43.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001680xC400015F |
| rd | X1 | 63:0 | Address | PA of the RD for the target Realm |
| baseipa | X2 | 63:0 | Address | Base ofIPA at which the Granule will be mapped in the target IPA regionRealm |
| toplevel | X3 | 63:0 | AddressInt64 | Top of target IPA regionRTT level |
| desc | X4 | 63:0 | Bits64 | RTTE descriptor |
The layout and encoding of fields in the desc input
value match “Attribute fields in stage 2 VMSAv8-64 Block and Page
descriptors” in Arm Architecture Reference
Manual for A-Profile architecture [3].
See also:
- Arm Architecture Reference Manual for A-Profile architecture [3]
- Section 5.6.11.3
- Section 5.6.12.3
- Section 14.121
15.3.43.1.2 Context
The RMI_RTT_INIT_RIPASRMI_RTT_MAP_UNPROTECTED command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm_prerealm | RmmRealm | RealmAt(rd) |
truefalse | Realm |
| walk | RmmRttWalkResult | RttWalk( realm, baseipa, RMM_RTT_PAGE_LEVEL level, RMM_RTT_TREE_PRIMARY) |
false | RTT walk result |
| walk_topentry_idx | AddressUInt64 | RttSkipEntriesIfNotStateRttEntryIndex( RttAt(walk.rtt_addr)ipa, walk.level, base, top, UNASSIGNED) |
false | Top IPA of UNASSIGNED entriesRTTE index |
| rtte | RmmRttEntry | RttDescriptorDecode( desc, starting from realm.rtt_s2ap_encoding) |
false | RTT entry at which the RTT walk terminated |
15.3.43.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.43.2 Failure conditions
| ID | Condition |
|---|---|
| attr_valid | pre: !RttDescriptorIsValidForUnprotected(desc) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| size_validlevel_bound | pre: UInt!RttLevelIsBlockOrPage(toprealm, level) <= UInt(base) post: ResultEqual(result, RMI_ERROR_INPUT) |
| top_boundaddr_align | pre: !AddrIsProtectedAddrIsRttLevelAligned( ToAddress(UInt(toprtte.addr, level) - RMM_GRANULE_SIZE), realm_pre) post: ResultEqual(result, RMI_ERROR_INPUT) |
| realm_stateaddr_bound | pre: realm_pre((realm.state !feat_lpa2 = REALM_NEW= FEATURE_FALSE) && (UInt(rtte.addr) >= 2^48)) post: ResultEqual(result, RMI_ERROR_REALMRMI_ERROR_INPUT) |
| base_alignipa_align | pre: !AddrIsRttLevelAligned(baseipa, walk.level) post: ResultEqual(result, RMI_ERROR_RTTRMI_ERROR_INPUT, walk.level) |
| rtte_stateipa_bound | pre: walk(UInt(ipa) >= (2 ^ realm.rtte.state != UNASSIGNEDipa_width) || AddrIsProtected(ipa, realm)) post: ResultEqual(result, RMI_ERROR_RTTRMI_ERROR_INPUT, ) |
| rtt_walk | pre: walk.level) top_gran_align pre: !AddrIsGranuleAligned(top) < level post: ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_RTT, walk.level) |
| no_progressrtte_state | pre: UInt(base) walk.rtte.state !== UInt(walk_top) UNASSIGNED_NS post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
15.3.43.2.1 Failure condition ordering
[rd_bound, rd_state] < [realm_state]
[rd_bound[rtt_walk, rd_state]rtte_state]
[level_bound, ipa_bound] < [base_align[rtt_walk, rtte_state]
[rd_bound, rd_state] < [no_progress]
[top_gran_align] < [no_progress]
15.3.43.3 Success conditions
| ID | Condition |
|---|---|
| rtte_ripasrtte_state | RttEntriesInRangeRipaswalk.rtte.state == ASSIGNED_NS |
| rtte_attr |
walk.rtte.attr_unprot == rtte.attr_unprot
|
| rtte_s2ap_direct | pre: realm.rtt_s2ap_encoding == S2AP_DIRECT post: (walk.rtte.s2ap_direct.read == rtte.s2ap_direct.read && walk.rtte.s2ap_direct.write == rtte.s2ap_direct.write) |
| rtte_s2ap_indirect | pre: realm.rtt_s2ap_encoding == S2AP_INDIRECT post: (walk.rtte.s2ap_indirect.base_index == rtte.s2ap_indirect.base_index && walk.rtte.s2ap_indirect.overlay_index == 15) |
| rtte_addr |
walk.rtte.addr == rtte.addr
|
15.3.43.4 Footprint
| ID | Value |
|---|---|
| rtte | RttEntryAt( RttAt(walk.rtt_addr), walk.level, base, walk_top, RAM entry_idx) |
15.3.44 RMI_RTT_MAP_UNPROTECTEDRMI_RTT_READ_ENTRY command
Creates a mapping from an Unprotected IPA to a Non-secure PA in a Reads an entry from a primary RTT.
See also:
- Section 5.56 Section 15.3.48
15.3.44.1 Interface
15.3.44.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400015F0xC4000161 |
| rd | X1 | 63:0 | Address | PA of the RD for the target Realm |
| ipa | X2 | 63:0 | Address | IPA atRealm Address for which the Granule will be mapped in the target Realmto read the RTTE |
| level | X3 | 63:0 | Int64 | RTT level at which to read the RTTE |
15.3.44.1.2 Context
The RMI_RTT_MAP_UNPROTECTEDRMI_RTT_READ_ENTRY command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| walk | RmmRttWalkResult | RttWalk( realm, ipa, level, RMM_RTT_TREE_PRIMARY) |
false | RTT walk result |
| rtte | RmmRttEntry | RttDescriptorDecode( desc, realm.rtt_s2ap_encoding) |
false | RTT entry value returned to Host |
15.3.44.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| walk_level | X1 | 63:0 | UInt64 | RTT level reached by the RTT walk |
| state | X2 | 7:0 | RmiRttEntryState | State of RTTE reached by the walk |
| desc | X3 | 63:0 | Bits64 | RTTE descriptor |
| ripas | X4 | 7:0 | RmiRipas | RIPAS of RTTE reached by the walk |
The following unused bits of RMI_RTT_READ_ENTRY output values MBZ: X2[63:8], X4[63:8].
The layout and encoding of fields in the rtte output
value match “Attribute fields in stage 2 VMSAv8-64 Block and Page
descriptors” in Arm Architecture Reference
Manual for A-Profile architecture [3].
See also:
15.3.44.2 Failure conditions
| ID | Condition |
|---|---|
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| level_bound | pre: !RttLevelIsBlockOrPageRttLevelIsValid(realm, level) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_align | pre: !AddrIsRttLevelAligned(ipa, level) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_bound | pre: (UInt(ipa) >= (2 ^ realm.ipa_width) || AddrIsProtected(ipa, realm)) post: ResultEqual(result, RMI_ERROR_INPUT) |
15.3.44.2.1 Failure condition ordering
[rd_bound, rd_state] < [rtt_walk, rtte_state] [level_bound, ipa_bound] < [rtt_walk, rtte_state]The RMI_RTT_READ_ENTRY command does not have any failure condition orderings.
15.3.44.3 Success conditions
| ID | Condition |
|---|---|
| rtte_statewalk_level |
walk_level == walk.level
|
| state | state == RttEntryStateToRmi(walk.rtte.state == ASSIGNED_NS) |
| rtte_contentsstate_invalid | pre: (walk.rtte.MemAttrstate == UNASSIGNED || walk.rtte.MemAttr state == UNASSIGNED_NS) post: (rtte.attr_unprot == Zeros(3) && walk.rtte.s2ap_bases2ap_indirect.base_index == rtte.s2ap_base 0 && walk.rtte.s2ap_overlays2ap_indirect.overlay_index == 15 0 && rtte.s2ap_direct.read == RMM_FALSE && rtte.s2ap_direct.write == RMM_FALSE && rtte.addr == Zeros(ADDRESS_WIDTH)) |
| state_prot | pre: (walk.rtte.state == ASSIGNED || walk.rtte.state == ASSIGNED_DEV || walk.rtte.state == ASSIGNED_VSMMU || walk.rtte.state == TABLE) post: (rtte.attr_unprot == Zeros(3) && rtte.s2ap_indirect.base_index == 0 && rtte.s2ap_indirect.overlay_index == 0 && rtte.s2ap_direct.read == RMM_FALSE && rtte.s2ap_direct.write == RMM_FALSE && rtte.addr == walk.rtte.addr) |
| state_unprot | pre: walk.rtte.state == ASSIGNED_NS post: (rtte.attr_unprot == walk.rtte.attr_unprot && rtte.s2ap_indirect.base_index == walk.rtte.s2ap_indirect.base_index && rtte.s2ap_indirect.overlay_index == 0 && rtte.s2ap_direct.read == walk.rtte.s2ap_direct.read && rtte.s2ap_direct.write == walk.rtte.s2ap_direct.write && rtte.addr == walk.rtte.addr) |
| state_io | pre: walk.rtte.state == ASSIGNED_DEV post: (rtte.attr_unprot == Zeros(3) && rtte.s2ap_indirect.base_index == 0 && rtte.s2ap_indirect.overlay_index == 0 && rtte.s2ap_direct.read == RMM_FALSE && rtte.s2ap_direct.write == RMM_FALSE && rtte.addr == walk.rtte.addr) |
| state_vsmmu | pre: walk.rtte.state == ASSIGNED_VSMMU post: (rtte.attr_unprot == Zeros(3) && rtte.s2ap_indirect.base_index == 0 && rtte.s2ap_indirect.overlay_index == 0 && rtte.s2ap_direct.read == RMM_FALSE && rtte.s2ap_direct.write == RMM_FALSE && rtte.addr == walk.rtte.addr) |
| ripas_prot | pre: (walk.rtte.state == UNASSIGNED || walk.rtte.state == ASSIGNED) post: ripas == RipasToRmi(walk.rtte.ripas) |
| ripas_unprot | pre: (walk.rtte.state == UNASSIGNED_NS || walk.rtte.state == ASSIGNED_NS) post: ripas == RMI_EMPTY |
15.3.44.4 Footprint
ID Value rtte RttEntryAt(walkThe RMI_RTT_READ_ENTRY command does not have any footprint.rtt_addr, entry_idx)
15.3.45 RMI_RTT_READ_ENTRYRMI_RTT_SET_RIPAS command
Reads an entry from a primary RTTCompletes a request made by the Realm to change the RIPAS of a target IPA range.
See also:
- Section 5.54
15.3.45.1 Interface
15.3.45.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001610xC4000169 |
| rd | X1 | 63:0 | Address | PA of the RD for the target Realm |
| iparec_ptr | X2 | 63:0 | Address | Realm Address for which to read the RTTEPA of the target REC |
| levelbase | X3 | 63:0 | Int64Address | RTT level at which to read the RTTEBase of target IPA region |
| top | X4 | 63:0 | Address | Top of target IPA region |
15.3.45.1.2 Context
The RMI_RTT_READ_ENTRYRMI_RTT_SET_RIPAS command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| realm_pre | RmmRealm | RealmAt(rd) |
true | Realm |
| rec | RmmRec | RecAt(rec_ptr) |
false | REC |
| walk | RmmRttWalkResult | RttWalk( realm, ipabase, level RMM_RTT_PAGE_LEVEL, RMM_RTT_TREE_PRIMARY) |
false | RTT walk result |
| rtteripas_pre | RmmRttEntryRmmRipas | RttDescriptorDecodewalk.rtte.ripas |
true | RIPAS before the command executed |
| walk_top_pre | Address | RttSkipEntriesWithRipas(desc RttAt(walk.rtt_addr), walk.level, base, top, rec.ripas_destroyed != CHANGE_DESTROYED) |
falsetrue | Top IPA of entries which have associated RIPAS values, starting from entry at which the RTT entry value returned to Hostwalk terminated |
15.3.45.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| walk_levelout_top | X1 | 63:0 | UInt64Address | RTT level reached by the RTT walkTop IPA of range whose RIPAS was modified |
The following unused bits of RMI_RTT_READ_ENTRYout_top output values MBZ:
X2[63:8], X4[63:8]value is valid only when the command
result is RMI_SUCCESS.
15.3.45.2 Failure conditions
| ID | Condition |
|---|---|
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| level_boundrec_align | pre: !RttLevelIsValidAddrIsGranuleAligned(realm, levelrec_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_alignrec_bound | pre: !AddrIsRttLevelAlignedPaIsDelegable(ipa, levelrec_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_boundrec_gran_state | pre: UIntGranuleAt(iparec_ptr) >.state != (2 ^ realm.ipa_width)REC post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_state | pre: rec.state == REC_RUNNING post: ResultEqual(result, RMI_ERROR_REC) |
| rec_owner | pre: rec.owner != rd post: ResultEqual(result, RMI_ERROR_REC) |
| size_valid | pre: UInt(top) <= UInt(base) post: ResultEqual(result, RMI_ERROR_INPUT) |
| base_bound | pre: base != rec.ripas_addr post: ResultEqual(result, RMI_ERROR_INPUT) |
| top_bound | pre: UInt(top) > UInt(rec.ripas_top) post: ResultEqual(result, RMI_ERROR_INPUT) |
| base_align | pre: (!AddrIsRttLevelAligned(base, walk.level) && ripas_pre != rec.ripas_value) post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
| top_gran_align | pre: !AddrIsGranuleAligned(top) post: ResultEqual(result, RMI_ERROR_INPUT) |
| no_progress | pre: (UInt(base) == UInt(walk_top_pre) && ripas_pre != rec.ripas_value) post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
| aux_live | pre: AddrRangeIsAuxLive(base, top, realm_pre) post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
15.3.45.2.1 Failure condition ordering
[rd_bound, rd_state] < [base_align]
[rd_bound, rd_state] < [no_progress]
[rec_bound, rec_gran_state] < [rec_state, rec_owner]
[base_bound] < [base_align]
[top_gran_align] < [no_progress]
The RMI_RTT_READ_ENTRY command does not have any failure condition
orderings.
15.3.45.3 Success conditions
| ID | Condition |
|---|---|
| walk_levelrtte_ripas | walk_level == walk.level state state == RttEntryStateToRmiRttEntriesInRangeRipas( RttAt(walk.rttertt_addr), walk.statelevel, base, walk_top_pre, rec.ripas_value) |
| state_invalidripas_addr | pre: (walkrec.rtte.stateripas_addr == UNASSIGNEDMinAddress || walk.rtte.state(top, walk_top_pre) |
| out_top | out_top == UNASSIGNED_NSMinAddress(top, walk_top_pre) post: (rtte.MemAttr == Zeros(3) && rtte.s2ap_base == 0 && rtte.s2ap_overlay == 0 && rtte.addr == Zeros(ADDRESS_WIDTH)) |
15.3.45.4 Footprint
The RMI_RTT_READ_ENTRY command does not have any footprint. 15.3.46 RMI_RTT_SET_RIPAS command Completes a request made by the Realm to change the RIPAS of a target IPA range. Issue In RMI_RTT_SET_RIPAS, consider how to combine: Modification of a range of RTT entries in a single command, and Checking of output address and HIPAS values against rec.ripas_dev_pa. See also: Section 5.4 Section 9.5.3 15.3.46.1 Interface 15.3.46.1.1 Input values| NameID | Register Bits Type Description fid X0 63:0 UInt64 FID, value 0xC4000169 rd X1 63:0 Address PA of the RD for the target Realm rec_ptr X2 63:0 Address PA of the target REC base X3 63:0 Address Base of target IPA region top X4 63:0 Address Top of target IPA region 15.3.46.1.2 Context The RMI_RTT_SET_RIPAS command operates on the following context. Name TypeValue | Before Description
|---|---|
| realmrtte | RmmRealmRealmAt(rd) false Realm realm_pre RmmRealm RealmAt(rd) true Realm rec RmmRec RecAt(rec_ptr) false REC walk RmmRttWalkResult RttWalk( realm, base, RMM_RTT_PAGE_LEVEL, RMM_RTT_TREE_PRIMARY) false RTT walk result ripas_pre RmmRipas walk.rtte.ripas true RIPAS before the command executed walk_top_pre Address RttSkipEntriesWithRipas( RttAt(walk.rtt_addr), walk.level, base, top, |
| ripas_addr | rec.ripas_destroyed != CHANGE_DESTROYED)ripas_addr |
true
Top IPA of entries which have associated RIPAS values, starting from
entry at which the RTT walk terminated
15.3.46.1.3 Output values Name Register Bits Type Description result X0 63:0 RmiCommandReturnCode Command return status out_top X1 63:0 Address Top IPA of range whose RIPAS was modified The out_top output value is valid only when the command result is RMI_SUCCESS. 15.3.46.2 Failure conditions ID Condition rd_align pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) rd_bound pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) rd_state pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) rec_align pre: !AddrIsGranuleAligned(rec_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) rec_bound pre: !PaIsDelegable(rec_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) rec_gran_state pre: GranuleAt(rec_ptr).state != REC post: ResultEqual(result, RMI_ERROR_INPUT) rec_state pre: rec.state == REC_RUNNING post: ResultEqual(result, RMI_ERROR_REC) rec_owner pre: rec.owner != rd post: ResultEqual(result, RMI_ERROR_REC) size_valid pre: UInt(top) <= UInt(base) post: ResultEqual(result, RMI_ERROR_INPUT) base_bound pre: base != rec.ripas_addr post: ResultEqual(result, RMI_ERROR_INPUT) top_bound pre: UInt(top) > UInt(rec.ripas_top) post: ResultEqual(result, RMI_ERROR_INPUT) base_align pre: (!AddrIsRttLevelAligned(base, walk.level) && ripas_pre != rec.ripas_value) post: ResultEqual(result, RMI_ERROR_RTT, walk.level) top_gran_align pre: !AddrIsGranuleAligned(top) post: ResultEqual(result, RMI_ERROR_INPUT) no_progress pre: (UInt(base) == UInt(walk_top_pre) && ripas_pre != rec.ripas_value) post: ResultEqual(result, RMI_ERROR_RTT, walk.level) dev_pa pre: Output address does not match value required by rec.ripas_dev_pa. post: ResultEqual(result, RMI_ERROR_RTT, walk.level) aux_live pre: AddrRangeIsAuxLive(base, top, realm_pre) post: ResultEqual(result, RMI_ERROR_RTT, walk.level) 15.3.46.2.1 Failure condition ordering [rd_bound, rd_state] < [base_align] [rd_bound, rd_state] < [no_progress] [rec_bound, rec_gran_state] < [rec_state, rec_owner] [base_bound] < [base_align] [top_gran_align] < [no_progress] 15.3.46.3 Success conditions ID Condition rtte_ripas RttEntriesInRangeRipas( RttAt(walk.rtt_addr), walk.level, base, walk_top_pre, rec.ripas_value) ripas_addr rec.ripas_addr == MinAddress(top, walk_top_pre) out_top out_top == MinAddress(top, walk_top_pre) 15.3.46.4 Footprint ID Value rtte RttAt(walk.rtt_addr) ripas_addr rec.ripas_addr 15.3.47 RMI_RTT_SET_S2AP command
Completes a request made by the Realm to change the S2AP of a target IPA range.
See also:
- Section 10.3.3.2
15.3.46.1 Interface
15.3.46.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400018B |
| rd | X1 | 63:0 | Address | PA of the RD for the target Realm |
| rec_ptr | X2 | 63:0 | Address | PA of the target REC |
| base | X3 | 63:0 | Address | Base of target IPA region |
| top | X4 | 63:0 | Address | Top of target IPA region |
15.3.46.1.2 Context
The RMI_RTT_SET_S2AP command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| realm_pre | RmmRealm | RealmAt(rd) |
true | Realm |
| rec | RmmRec | RecAt(rec_ptr) |
false | REC |
| not_aligned | RmmRttWalkNotAligned | RttWalkAnyNotAligned( realm, base, top, RMM_RTT_PAGE_LEVEL) |
false | RTT walk result which is not aligned to page level |
15.3.46.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| out_top | X1 | 63:0 | Address | Top IPA of range whose S2AP was modified |
| rtt_tree | X2 | 63:0 | UInt64 | Index of RTT tree in which base alignment check failed |
If result is RMI_ERROR_RTT or RMI_ERROR_RTT_AUX then the
following are true:
out_topis the IPA of the RTTE at which the base alignment check failed.rtt_treeis the index of the RTT in which the base alignment check failed.
15.3.46.2 Failure conditions
| ID | Condition |
|---|---|
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_align | pre: !AddrIsGranuleAligned(rec_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_bound | pre: !PaIsDelegable(rec_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_gran_state | pre: GranuleAt(rec_ptr).state != REC post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_state | pre: rec.state == REC_RUNNING post: ResultEqual(result, RMI_ERROR_REC) |
| rec_owner | pre: rec.owner != rd post: ResultEqual(result, RMI_ERROR_REC) |
| size_valid | pre: UInt(top) <= UInt(base) post: ResultEqual(result, RMI_ERROR_INPUT) |
| base_bound | pre: base != rec.s2ap_addr post: ResultEqual(result, RMI_ERROR_INPUT) |
| top_bound | pre: UInt(top) > UInt(rec.s2ap_top) post: ResultEqual(result, RMI_ERROR_INPUT) |
| top_gran_align | pre: !AddrIsGranuleAligned(top) post: ResultEqual(result, RMI_ERROR_INPUT) |
| base_align_pri | pre: (not_aligned.valid == RMM_TRUE && !AddrRangeIsWithin( base, top, AlignDownToRttLevel( not_aligned.addr, not_aligned.walk.level ), AlignUpToRttLevel( not_aligned.addr, not_aligned.walk.level )) && not_aligned.index == RMM_RTT_TREE_PRIMARY && not_aligned.walk.rtte.s2ap_indirect.overlay_index != rec.s2ap_overlay_index) post: ResultEqual( result, RMI_ERROR_RTT, not_aligned.walk.level) |
| base_align_aux | pre: (not_aligned.valid == RMM_TRUE && !AddrRangeIsWithin( base, top, AlignDownToRttLevel( not_aligned.addr, not_aligned.walk.level ), AlignUpToRttLevel( not_aligned.addr, not_aligned.walk.level )) && not_aligned.index != RMM_RTT_TREE_PRIMARY && not_aligned.walk.rtte.s2ap_indirect.overlay_index != rec.s2ap_overlay_index) post: ResultEqual( result, RMI_ERROR_RTT_AUX, not_aligned.walk.level) |
15.3.46.2.1 Failure condition ordering
The RMI_RTT_SET_S2AP command does not have any failure condition orderings.
15.3.46.3 Success conditions
| ID | Condition |
|---|---|
| s2ap_addr |
rec.s2ap_addr == out_top
|
15.3.46.4 Footprint
The RMI_RTT_SET_S2AP command does not have any footprint.
15.3.47 RMI_RTT_UNMAP_UNPROTECTED command
Removes a mapping at an Unprotected IPA.
15.3.47.1 Interface
15.3.47.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400018B0xC4000162 |
| rd | X1 | 63:0 | Address | PA of the RD for the target Realm |
| rec_ptripa | X2 | 63:0 | Address | PA ofIPA at which the Granule is mapped in the target RECRealm |
| baselevel | X3 | 63:0 | AddressInt64 | Base of target IPA regionRTT level |
15.3.47.1.2 Context
The RMI_RTT_SET_S2APRMI_RTT_UNMAP_UNPROTECTED command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| realm_prewalk | RmmRealmRmmRttWalkResult | RealmAtRttWalk(rd realm, ipa, level, RMM_RTT_TREE_PRIMARY) |
true
Realm
rec
RmmRec
RecAt(rec_ptr)
false | RECRTT walk result |
| not_alignedentry_idx | RmmRttWalkNotAlignedUInt64 | RttWalkAnyNotAlignedRttEntryIndex( realmipa, base, top, RMM_RTT_PAGE_LEVELwalk.level) |
false | RTTE index |
| walk_top | Address | RttSkipNonLiveEntries( RttAt(walk.rtt_addr), walk.level, ipa) |
false | Top IPA of non-live RTT entries, from entry at which the RTT walk result which is not aligned to page level terminated |
15.3.47.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| out_toptop | X1 | 63:0 | Address | Top IPA of range whose S2AP was modifiednon-live RTT entries, from entry at which the RTT walk terminated |
IfThe values of the result is and top output
values for different command outcomes are summarized in the following
table.
| Scenario | result | top | walk.rtte.state |
|---|---|---|---|
ipa is mapped at the target level |
RMI_SUCCESS | > ipa | Before execution: ASSIGNED_NS After execution: UNASSIGNED_NS |
ipa is not mapped |
(RMI_ERROR_RTT or RMI_ERROR_RTT_AUX then the following are true:, <= level) | > ipa | UNASSIGNED_NS |
ipa is mapped at a lower level |
(RMI_ERROR_RTT, < level) | == ipa | ASSIGNED_NS |
| RTT walk was not performed, due to any other command failure | Another error code | 0 | Unknown |
See also:
- out_top is the IPA of the RTTE at which the base alignment check failedSection 5.6.8 rtt_tree is the index of the RTT in which the base alignment check failed.
15.3.47.2 Failure conditions
| ID | Condition |
|---|---|
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_alignlevel_bound | pre: !AddrIsGranuleAlignedRttLevelIsBlockOrPage(rec_ptrrealm, level) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_boundipa_align | pre: !PaIsDelegableAddrIsRttLevelAligned(rec_ptripa, level) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_gran_stateipa_bound | pre: GranuleAt(UInt(ipa) >= (2 ^ realm.ipa_width) || AddrIsProtected(rec_ptripa, realm).state != REC) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rec_statertt_walk | pre: recwalk.state == REC_RUNNINGlevel < level post: (ResultEqual(result, RMI_ERROR_RECRMI_ERROR_RTT, walk.level) && (top == walk_top)) |
| rec_ownerrtte_state | pre: recwalk.ownerrtte.state != rdASSIGNED_NS post: (ResultEqual(result, RMI_ERROR_RECRMI_ERROR_RTT, walk.level) size_valid pre: UInt(top) <= UInt(base) post: ResultEqual(result, RMI_ERROR_INPUT) base_bound pre: base != rec.s2ap_addr post: ResultEqual(result, RMI_ERROR_INPUT) top_bound pre: UInt(top) > UInt(rec.s2ap_top) post: ResultEqual(result, RMI_ERROR_INPUT) top_gran_align pre: !AddrIsGranuleAligned(top) post: ResultEqual(result, RMI_ERROR_INPUT) base_align_pri pre: (not_aligned.valid == RMM_TRUE && !AddrRangeIsWithin( base, top, AlignDownToRttLevel( not_aligned.addr, not_aligned.walk.level ), AlignUpToRttLevel( not_aligned.addr, not_aligned.walk.level == walk_top)) && not_aligned.index == RMM_RTT_TREE_PRIMARY && not_aligned.walk.rtte.s2ap_overlay != rec.s2ap_overlay) post: ResultEqual( result, RMI_ERROR_RTT, not_aligned.walk.level) |
15.3.47.2.1 Failure condition ordering
[rd_bound, rd_state] < [rtt_walk, rtte_state]
[level_bound, ipa_bound] < [rtt_walk, rtte_state]
The RMI_RTT_SET_S2AP command does not have any failure condition
orderings.
15.3.47.3 Success conditions
The RMI_RTT_SET_S2AP command does not have any success conditions| ID | Condition |
|---|---|
| rtte_state | walk. rtte.state == UNASSIGNED_NS |
| top |
top == walk_top
|
15.3.47.4 Footprint
The RMI_RTT_SET_S2AP command does not have any footprint| ID | Value |
|---|---|
| rtte | RttEntryAt(RttAt(walk.rtt_addr), entry_idx) |
15.3.48 RMI_RTT_UNMAP_UNPROTECTED RMI_VDEV_ABORT command
Removes a mapping at an Unprotected IPAAbort device communication associated with a VDEV.
See also:
- Section 5.59 Section 15.3.44
15.3.48.1 Interface
15.3.48.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001620xC4000185 |
| rdvdev_ptr | X1 | 63:0 | Address | PA of the RD for the target RealmVDEV |
15.3.48.1.2 Context
The RMI_RTT_UNMAP_UNPROTECTEDRMI_VDEV_ABORT command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realmvdev | RmmRealmRmmVdev | RealmAtVdevAt(rdvdev_ptr) |
false | RealmVDEV |
15.3.48.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.48.2 Failure conditions
| ID | Condition |
|---|---|
| rd_alignda_supp | pre: !AddrIsGranuleAlignedImplFeatures(rd).feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_NOT_SUPPORTED) |
| rd_boundvdev_align | pre: !PaIsDelegableAddrIsGranuleAligned(rdvdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_statevdev_bound | pre: GranuleAt!PaIsDelegable(rdvdev_ptr).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| level_boundvdev_gran_state | pre: !RttLevelIsBlockOrPageGranuleAt(realm, levelvdev_ptr).state != VDEV post: ResultEqual(result, RMI_ERROR_INPUT) |
| ipa_alignvdev_state | pre: vdev.state !AddrIsRttLevelAligned= VDEV_COMMUNICATING(ipa, level) post: ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_DEVICE) |
15.3.48.2.1 Failure condition ordering
[rd_bound, rd_state][da_supp] < [rtt_walk[vdev_align, rtte_state]
[level_boundvdev_bound, ipa_bound]vdev_gran_state]
[vdev_gran_state] < [rtt_walk, rtte_state][vdev_state]
15.3.48.3 Success conditions
| ID | Condition |
|---|---|
| rtte_statestate | walk.rttevdev.state == UNASSIGNED_NSVDEV_READY |
| topcomm_state | topvdev.comm_state == walk_topDEV_COMM_IDLE |
15.3.48.4 Footprint
| ID | Value |
|---|---|
| rttestate | RttEntryAt(walkvdev.rtt_addr, entry_idx)state |
| comm_state |
vdev.comm_state
|
15.3.49 RMI_VDEV_ABORT RMI_VDEV_AUX_COUNT command
Abort device communication associated withGet number of auxiliary Granules required for a VDEV.
See also: Section 915.3.49.1 Interface
15.3.49.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001850xC4000160 |
| vdev_ptrpdev_flags | X1 | 63:0 | AddressBits64 | PA of the PDEV flags |
| vdev_flags | X2 | 63:0 | Bits64 | VDEV flags |
15.3.49.1.2 ContextOutput values
The RMI_VDEV_ABORT command operates on the following context.| Name | Register | Bits | Type | Value BeforeDescription |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| aux_count | X1 | 63:0 | UInt64 | Number of auxiliary Granules required for a VDEV |
15.3.49.2 Failure conditions
| ID | Condition |
|---|---|
| da_supp | pre: ImplFeatures().feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_NOT_SUPPORTED) |
15.3.49.3 Success conditions
| ID | Condition |
|---|---|
| stateaux_count | vdev.stateaux_count == VDEV_READYVdevAuxCount( RmiPdevFlagsDecode(pdev_flags), RmiVdevFlagsDecode(vdev_flags)) |
15.3.49.4 Footprint
ID Value state vdevThe RMI_VDEV_AUX_COUNT command does not have any footprint.state comm_state vdev.comm_state
15.3.50 RMI_VDEV_AUX_COUNTRMI_VDEV_COMMUNICATE command
Get number of auxiliary Granules required forPerform device communication associated with a VDEV.
See also:
- Section 9
15.3.50.1 Interface
15.3.50.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001600xC4000186 |
| pdev_flagspdev_ptr | X1 | 63:0 | Bits64Address | PA of the PDEV flags |
| vdev_flagsvdev_ptr | X2 | 63:0 | Bits64Address | PA of the VDEV flags |
| data_ptr | X3 | 63:0 | Address | PA of the communication data structure |
An implementation may store state in a PDEV object which is required for communication with the child VDEVs. For this reason, and to simplify locking of PDEV and VDEV objects which may be performed by the implementation, a PDEV pointer is passed to RMI_VDEV_COMMUNICATE.
15.3.50.1.2 Output valuesContext
The RMI_VDEV_COMMUNICATE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| pdev | RmmPdev | PdevAt(pdev_ptr) |
false | PDEV |
| vdev | RmmVdev | VdevAt(vdev_ptr) |
false | VDEV |
| data | RmiDevCommData | RmiDevCommDataAt(data_ptr) |
false | Device communication object |
15.3.50.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.50.2 Failure conditions
| ID | Condition |
|---|---|
| da_supp | pre: ImplFeatures().feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_NOT_SUPPORTED) |
| pdev_align | pre: !AddrIsGranuleAligned(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_bound | pre: !PaIsDelegable(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_gran_state | pre: GranuleAt(pdev_ptr).state != PDEV post: ResultEqual(result, RMI_ERROR_INPUT) |
| vdev_align | pre: !AddrIsGranuleAligned(vdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vdev_bound | pre: !PaIsDelegable(vdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vdev_gran_state | pre: GranuleAt(vdev_ptr).state != VDEV post: ResultEqual(result, RMI_ERROR_INPUT) |
| data_align | pre: !AddrIsGranuleAligned(data_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| data_pas | pre: !GranuleAccessPermitted(data_ptr, PAS_NS) post: ResultEqual(result, RMI_ERROR_INPUT) |
| req_align | pre: !AddrIsGranuleAligned(data.enter.req_addr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| req_pas | pre: !GranuleAccessPermitted(data.enter.req_addr, PAS_NS) post: ResultEqual(result, RMI_ERROR_INPUT) |
| resp_align | pre: !AddrIsGranuleAligned(data.enter.resp_addr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| resp_pas | pre: !GranuleAccessPermitted(data.enter.resp_addr, PAS_NS) post: ResultEqual(result, RMI_ERROR_INPUT) |
| resp_len | pre: data.enter.resp_len > RMM_GRANULE_SIZE post: ResultEqual(result, RMI_ERROR_INPUT) |
| vdev_pdev | pre: vdev.pdev != pdev_ptr post: ResultEqual(result, RMI_ERROR_DEVICE) |
| vdev_state | pre: (vdev.state != VDEV_COMMUNICATING && vdev.state != VDEV_STOPPING) post: ResultEqual(result, RMI_ERROR_DEVICE) |
15.3.50.2.1 Failure condition ordering
[da_supp] < [pdev_align, pdev_bound, pdev_gran_state, vdev_align,
vdev_bound, vdev_gran_state, data_align, data_pas, req_align,
req_pas, resp_align, resp_pas, resp_len]
[pdev_gran_state, vdev_gran_state] < [vdev_pdev, vdev_state]
15.3.50.3 Success conditions
| ID | Condition |
|---|---|
| aux_countcomm_state | aux_countvdev.comm_state == VdevAuxCountDeviceCommunicate( RmiPdevFlagsDecodevdev, data) |
| error | pre: (DeviceCommunicate(pdev_flagsvdev, data), RmiVdevFlagsDecode == DEV_COMM_ERROR && vdev.state == VDEV_COMMUNICATING) post: vdev.state == VDEV_ERROR |
| ready | pre: (DeviceCommunicate(vdev_flagsvdev, data) == DEV_COMM_IDLE && vdev.state == VDEV_COMMUNICATING) post: vdev.state == VDEV_READY |
| stopped | pre: (DeviceCommunicate(vdev, data) != DEV_COMM_ACTIVE && vdev.state == VDEV_STOPPING) post: vdev.state == VDEV_STOPPED |
15.3.50.4 Footprint
The RMI_VDEV_AUX_COUNT command does not have any footprint| ID | Value |
|---|---|
| state | vdev.state |
| comm_state |
vdev.comm_state
|
15.3.51 RMI_VDEV_COMMUNICATERMI_VDEV_COMPLETE command
Perform device communication associated with aCompletes a pending VDEV request.
15.3.51.1 Interface
15.3.51.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001860xC400018E |
| pdev_ptrrec_ptr | X1 | 63:0 | Address | PA of the PDEVREC |
| vdev_ptr | X2 | 63:0 | Address | PA of the VDEV |
15.3.51.1.2 Context
The RMI_VDEV_COMMUNICATERMI_VDEV_COMPLETE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| pdevrec | RmmPdevRmmRec | PdevAtRecAt(pdev_ptrrec_ptr) |
false | PDEVREC |
| vdev | RmmVdev | VdevAt(vdev_ptr) |
false | VDEV |
15.3.51.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.51.2 Failure conditions
| ID | Condition |
|---|---|
| da_supprec_align | pre: ImplFeatures!AddrIsGranuleAligned(rec_ptr).feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_NOT_SUPPORTEDRMI_ERROR_INPUT) |
| pdev_alignrec_bound | pre: !AddrIsGranuleAlignedPaIsDelegable(pdev_ptrrec_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_boundrecv_state | pre: !PaIsDelegableGranuleAt(pdev_ptrrec_ptr).state != REC post: ResultEqual(result, RMI_ERROR_INPUT) |
| vdev_align | pre: !AddrIsGranuleAligned(vdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vdev_bound | pre: !PaIsDelegable(vdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vdev_gran_statevdev_state | pre: GranuleAt(vdev_ptr).state != VDEV post: ResultEqual(result, RMI_ERROR_INPUT) |
| data_alignpending | pre: rec.pending !AddrIsGranuleAligned= REC_PENDING_VDEV_REQUEST(data_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| data_boundowner | pre: rec.owner !PaIsDelegable(data_ptr)= vdev.realm post: ResultEqual(result, RMI_ERROR_INPUT) |
| data_pasvdev_id | pre: rec.vdev_id !GranuleAccessPermitted(data_ptr, PAS_NS)= vdev.vdev_id post: ResultEqual(result, RMI_ERROR_INPUT) |
| req_aligninst_id | pre: (rec.inst_id_valid == RMM_TRUE && rec.inst_id !AddrIsGranuleAligned(data= vdev.enter.req_addrinst_id) post: ResultEqual(result, RMI_ERROR_INPUT) |
15.3.51.2.1 Failure condition ordering
[da_supp] < [pdev_align, pdev_bound, pdev_gran_state, vdev_align, vdev_bound, vdev_gran_state, data_align, data_bound, data_pas, req_align, req_bound, req_pas, resp_align, resp_bound, resp_pas, resp_len] [pdev_gran_state, vdev_gran_state] < [vdev_pdev, vdev_state]The RMI_VDEV_COMPLETE command does not have any failure condition orderings.
15.3.51.3 Success conditions
| ID | Condition |
|---|---|
| comm_statepending | vdevrec.comm_statepending == DeviceCommunicateREC_PENDING_NONE(vdev, data) |
15.3.51.4 Footprint
| ID | Value |
|---|---|
| statepend | vdevrec.statepending |
15.3.52 RMI_VDEV_COMPLETERMI_VDEV_CREATE command
Completes a pendingCreate a VDEV request.
See also:
- Section 4.3.149 Section 9.2.2
15.3.52.1 Interface
15.3.52.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400018E0xC4000187 |
| rec_ptrrd | X1 | 63:0 | Address | PA of the RECRD |
| vdev_ptrpdev_ptr | X2 | 63:0 | Address | PA of the PDEV |
| vdev_ptr | X3 | 63:0 | Address | PA of the VDEV |
| params_ptr | X4 | 63:0 | Address | PA of VDEV parameters |
15.3.52.1.2 Context
The RMI_VDEV_COMPLETERMI_VDEV_CREATE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| recrealm_pre | RmmRecRmmRealm | RecAtRealmAt(rec_ptrrd) |
true | Realm |
| realm | RmmRealm | RealmAt(rd) |
false | RECRealm |
| pdev | RmmPdev | PdevAt(pdev_ptr) |
false | PDEV |
| num_vdevs_pre | UInt64 |
pdev.num_vdevs
|
true | Number of VDEVs associated with the PDEV |
| vdev | RmmVdev | VdevAt(vdev_ptr) |
false | VDEV |
| params | RmiVdevParams | RmiVdevParamsAt(params_ptr) |
false | VDEV parameters |
| num_aux | UInt64 | VdevAuxCount( PdevFlags(pdev), params.flags) |
false | Number of auxiliary Granules |
| rdev | RmmRdev | RdevFromInstId( realm, realm_pre.vdev_count) |
false | RDEV |
15.3.52.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.52.2 Failure conditions
| ID | Condition |
|---|---|
| rec_alignda_supp | pre: !AddrIsGranuleAlignedImplFeatures(rec_ptr).feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_NOT_SUPPORTED) |
| rec_boundrd_align | pre: !PaIsDelegableAddrIsGranuleAligned(rec_ptrrd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| recv_staterd_bound | pre: GranuleAt!PaIsDelegable(rec_ptrrd).state != REC post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_align | pre: !AddrIsGranuleAligned(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_bound | pre: !PaIsDelegable(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_gran_state | pre: GranuleAt(pdev_ptr).state != PDEV post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_state | pre: pdev.state != PDEV_READY post: ResultEqual(result, RMI_ERROR_DEVICE) |
| vdev_align | pre: !AddrIsGranuleAligned(vdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vdev_bound | pre: !PaIsDelegablePaIsDelegableDram(vdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vdev_statevdev_gran_state | pre: GranuleAt(vdev_ptr).state != VDEVDELEGATED post: ResultEqual(result, RMI_ERROR_INPUT) |
| pendingparams_align | pre: rec.pending != REC_PENDING_VDEV_REQUESTAddrIsGranuleAligned(params_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| ownerparams_pas | pre: rec.owner != vdev.realmGranuleAccessPermitted(params_ptr, PAS_NS) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vdev_idparams_valid | pre: rec.vdev_id != vdev.vdev_idRmiVdevParamsIsValid(params_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| inst_idda_en | pre: realm.feat_da != FEATURE_TRUE post: ResultEqual(recresult, RMI_ERROR_REALM) |
| num_aux | pre: params.inst_id_validnum_aux != num_aux post: ResultEqual(result, RMI_ERROR_INPUT) |
| aux_align | pre: !AuxAligned32(params.aux, params.num_aux) post: ResultEqual(result, RMI_ERROR_INPUT) |
| aux_alias | pre: AuxAlias32(vdev_ptr, params.aux, params.num_aux) post: ResultEqual(result, RMI_ERROR_INPUT) |
| aux_state | pre: !AuxStateEqual32( params.aux, params.num_aux, DELEGATED) post: ResultEqual(result, RMI_ERROR_INPUT) |
| tdi_id_free | pre: !TdiIdIsFree(params.tdi_id, pdev.segment_id) post: ResultEqual(result, RMI_ERROR_INPUT) |
| tdi_id_bound | pre: (UInt(params.tdi_id) < UInt(pdev.rid_base) || UInt(params.tdi_id) >= UInt(pdev.rid_top)) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vsmmu_align | pre: (params.flags.VSMMU == RMM_TRUERMI_FEATURE_TRUE && rec!AddrIsGranuleAligned(params.inst_id != vdev.inst_idvsmmu_addr)) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vsmmu_bound | pre: (params.flags.VSMMU == RMI_FEATURE_TRUE && !PaIsDelegable(params.vsmmu_addr)) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vsmmu_state | pre: (params.flags.VSMMU == RMI_FEATURE_TRUE && GranuleAt(params.vsmmu_addr).state != VSMMU) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vsid_free | pre: (params.flags.VSMMU == RMI_FEATURE_TRUE && !VsidIsFree( VsmmuAt(params.vsmmu_addr), params.vsid)) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vsmmu_compat | pre: (params.flags.VSMMU == RMI_FEATURE_TRUE && !PdevVsmmuIsCompatible( pdev, VsmmuAt(params.vsmmu_addr))) post: ResultEqual(result, RMI_ERROR_INPUT) |
15.3.52.2.1 Failure condition ordering
[da_supp] < [rd_align, rd_bound, pdev_bound, pdev_gran_state,
vdev_align, vdev_bound, vdev_gran_state, params_align,
params_pas, params_valid, num_aux, aux_align, aux_alias,
aux_state, vsmmu_align, vsmmu_bound, vsmmu_state, vsid_free]
[da_supp] < [pdev_gran_state]
[da_supp] < [rd_state]
[pdev_gran_state, vsmmu_state] < [vsmmu_compat]
[pdev_gran_state] < [pdev_state]
[rd_state] < [da_en]
The RMI_VDEV_COMPLETE command does not have any failure condition
orderings.
15.3.52.3 Success conditions
| ID | Condition |
|---|---|
| pendingpdev_num_vdevs | recpdev.pendingnum_vdevs == REC_PENDING_NONEnum_vdevs_pre + 1 |
| gran_state | GranuleAt(vdev_ptr).state == VDEV |
| vdev_id |
vdev.vdev_id == params.vdev_id
|
| tdi_id |
vdev.tdi_id == params.tdi_id
|
| pdev |
vdev.pdev == pdev_ptr
|
| realm |
vdev.realm == rd
|
| state | vdev.state == VDEV_READY |
| comm_state | vdev.comm_state == DEV_COMM_IDLE |
| rdev_state | rdev.state == RDEV_UNLOCKED |
| rdev_op | rdev.operation == RDEV_OP_NONE |
| rdev_vdev_ptr |
rdev.vdev_ptr == vdev_ptr
|
| aux | AuxEqual32(vdev.aux, params.aux, num_aux) |
| num_aux |
vdev.num_aux == num_aux
|
| aux_state | AuxStateEqual32( vdev.aux, num_aux, VDEV_AUX) |
| tdi_id_used | !TdiIdIsFree(params.tdi_id, pdev.segment_id) |
| inst_id |
vdev.inst_id == realm_pre.vdev_count
|
| vsmmu | Equal(vdev.vsmmu, params.flags.VSMMU) |
| vsmmu_addr | pre: params.flags.VSMMU == RMI_FEATURE_TRUE post: vdev.vsmmu_addr == params.vsmmu_addr |
| vsid | pre: params.flags.VSMMU == RMI_FEATURE_TRUE post: vdev.vsid == params.vsid |
| vsid_alloc | pre: params.flags.VSMMU == RMI_FEATURE_TRUE post: !VsidIsFree( VsmmuAt(params.vsmmu_addr), params.vsid) |
| realm_num_vdevs |
realm.num_vdevs == realm_pre.num_vdevs + 1
|
| realm_vdev_count |
realm.vdev_count == realm_pre.vdev_count + 1
|
15.3.52.4 Footprint
15.3.53 RMI_VDEV_CREATERMI_VDEV_DESTROY command
CreateDestroy a VDEV.
See also:
- Section 9
15.3.53.1 Interface
15.3.53.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001870xC4000188 |
| rd | X1 | 63:0 | Address | PA of the RD |
| pdev_ptr | X2 | 63:0 | Address | PA of the PDEV |
| vdev_ptr | X3 | 63:0 | Address | PA of the VDEV |
15.3.53.1.2 Context
The RMI_VDEV_CREATERMI_VDEV_DESTROY command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm_pre | RmmRealm | RealmAt(rd) |
true | Realm |
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| pdevvdev_pre | RmmVdev | VdevAt(vdev_ptr) |
true | VDEV |
| pdev_pre | RmmPdev | PdevAt(pdev_ptr) |
true | PDEV |
| pdev | RmmPdev | PdevAt(pdev_ptr) |
false | PDEV |
15.3.53.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.53.2 Failure conditions
| ID | Condition |
|---|---|
| da_supp | pre: ImplFeatures().feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_NOT_SUPPORTED) |
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_staterd_gran_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_align | pre: !AddrIsGranuleAligned(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_bound | pre: !PaIsDelegable(pdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| pdev_gran_state | pre: GranuleAt(pdev_ptr).state != PDEV post: ResultEqual(result, RMI_ERROR_INPUT) |
| vdev_align | pre: !AddrIsGranuleAligned(vdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vdev_bound | pre: !PaIsDelegable(vdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vdev_gran_state | pre: GranuleAt(vdev_ptr).state != DELEGATEDVDEV post: ResultEqual(result, RMI_ERROR_INPUT) |
| params_alignvdev_realm | pre: vdev_pre.realm !AddrIsGranuleAligned(params_ptr)= rd post: ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_DEVICE) |
| params_boundvdev_pdev | pre: vdev_pre.pdev !PaIsDelegable(params_ptr)= pdev_ptr post: ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_DEVICE) |
| params_pasvdev_state | pre: vdev_pre.state !GranuleAccessPermitted= VDEV_STOPPED(params_ptr, PAS_NS) post: ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_DEVICE) |
15.3.53.2.1 Failure condition ordering
[da_supp] < [rd_align, rd_bound, rd_gran_state, pdev_align,
pdev_bound, pdev_gran_state, vdev_align, vdev_bound, vdev_gran_state
vdev_gran_state]
[rd_gran_state, params_alignpdev_gran_state,
params_bound, params_pas, params_valid, num_aux, aux_align,
aux_alias, aux_state, vsmmu_align, vsmmu_bound, vsmmu_state,
vsid_free]
[da_supp] vdev_gran_state] < [pdev_gran_state]
[da_supp] < [rd_state]
[pdev_gran_state[vdev_realm, vsmmu_state] < [vsmmu_compat]
[pdev_gran_state] < [pdev_state]
[rd_state] < [da_en]
vdev_pdev, vdev_state]
15.3.53.3 Success conditions
| ID | Condition |
|---|---|
| gran_state | GranuleAt(vdev_ptr).state == VDEVDELEGATED |
| aux_state | AuxStateEqual32( vdevvdev_pre.aux, vdev_pre.num_aux, VDEV_AUXDELEGATED) |
| tdi_id_usedtdi_id_free | !TdiIdIsFree(paramsvdev_pre.tdi_id, pdevpdev_pre.segment_id) |
| inst_idrealm_num_vdevs | vdevrealm.inst_idnum_vdevs == realm_pre.vdev_countnum_vdevs - 1 |
| vsmmupdev_num_vdevs | Equal(vdevpdev.num_vdevs == pdev_pre.num_vdevs - 1 |
| vsid_free | pre: vdev_pre.vsmmu, params.flags.VSMMU) vsmmu_addr pre: params.flags.VSMMU == RMI_FEATURE_TRUEFEATURE_TRUE post: vdev.vsmmu_addr == params.vsmmu_addr vsid pre: params.flags.VSMMU == RMI_FEATURE_TRUE post: vdev.vsid == params.vsid vsid_alloc pre: params.flags.VSMMU == RMI_FEATURE_TRUE post: !VsidIsFree( VsmmuAt(paramsvdev_pre.vsmmu_addr), params vdev_pre.vsid) |
15.3.53.4 Footprint
15.3.54 RMI_VDEV_DESTROYRMI_VDEV_GET_STATE command
DestroyGet state of a VDEV.
See also:
- Section 9
15.3.54.1 Interface
15.3.54.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001880xC4000189 |
| rdvdev_ptr | X1 | 63:0 | Address | PA of the RD pdev_ptr X2 63:0 Address PA of the PDEV vdev_ptr X3 63:0 Address PA of the VDEV |
15.3.54.1.2 Context
The RMI_VDEV_DESTROYRMI_VDEV_GET_STATE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm_prevdev | RmmRealm RealmAt(rd) true Realm realm RmmRealm RealmAt(rd) false Realm vdev_preRmmVdev | VdevAt(vdev_ptr) |
truefalse | VDEV |
15.3.54.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| state | X1 | 7:0 | RmiVdevState | VDEV state |
The following unused bits of RMI_VDEV_GET_STATE output values MBZ: X1[63:8].
15.3.54.2 Failure conditions
| ID | Condition |
|---|---|
| da_supp | pre: ImplFeatures().feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_NOT_SUPPORTED) |
| vdev_align | pre: !AddrIsGranuleAligned(vdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vdev_bound | pre: !PaIsDelegable(vdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vdev_gran_state | pre: GranuleAt(vdev_ptr).state != VDEV post: ResultEqual(result, RMI_ERROR_INPUT) |
15.3.54.2.1 Failure condition ordering
[da_supp] < [rd_align[vdev_align, rd_bound, rd_gran_state, pdev_align,
pdev_bound, pdev_gran_state, vdev_align, vdev_bound, vdev_gran_state]
[rd_gran_state, pdev_gran_state, vdev_gran_state] < [vdev_realm,
vdev_pdev, vdev_state]
15.3.54.3 Success conditions
| ID | Condition |
|---|---|
| gran_statestate | GranuleAtEqual(vdev_ptr)state, vdev.state == DELEGATED) |
15.3.54.4 Footprint
ID Value state GranuleAt(vdev_ptr)The RMI_VDEV_GET_STATE command does not have any footprint.state aux_state AuxStates(vdev_pre.aux, vdev_pre.num_aux) realm_num_vdevs realm.num_vdevs pdev_num_vdevs pdev.num_vdevs
15.3.55 RMI_VDEV_GET_STATE RMI_VDEV_STOP command
Get state ofStop a VDEV.
See also:
- Section 9
15.3.55.1 Interface
15.3.55.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001890xC400018A |
| vdev_ptr | X1 | 63:0 | Address | PA of the VDEV |
15.3.55.1.2 Context
The RMI_VDEV_GET_STATERMI_VDEV_STOP command operates on the following context.
15.3.55.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.55.2 Failure conditions
| ID | Condition |
|---|---|
| da_supp | pre: ImplFeatures().feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_NOT_SUPPORTED) |
| vdev_align | pre: !AddrIsGranuleAligned(vdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vdev_bound | pre: !PaIsDelegable(vdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vdev_gran_state | pre: GranuleAt(vdev_ptr).state != VDEV post: ResultEqual(result, RMI_ERROR_INPUT) |
| vdev_state | pre: (vdev.state != VDEV_READY && vdev.state != VDEV_ERROR) post: ResultEqual(result, RMI_ERROR_DEVICE) |
15.3.55.2.1 Failure condition ordering
[da_supp] < [vdev_align, vdev_bound, vdev_gran_state]
[vdev_gran_state] < [vdev_state]
15.3.55.3 Success conditions
| ID | Condition |
|---|---|
| state | Equal(state, vdev.state) == VDEV_STOPPING |
| comm_state | vdev.comm_state == DEV_COMM_PENDING |
15.3.55.4 Footprint
The RMI_VDEV_GET_STATE command does not have any footprint| ID | Value |
|---|---|
| state | vdev.state |
| comm_state |
vdev.comm_state
|
15.3.56 RMI_VDEV_STOPRMI_VERSION command
Stop a VDEVAllows the Host and the RMM to determine whether there exists a mutually acceptable revision of the RMM via which the two components can communicate.
On calling this command, the Host provides a requested RMI version.
The output values include a status code and two revisions which are supported by the RMM: a lower revision and a higher revision.
- The higher revision value is the highest interface revision which is supported by the RMM.
- The lower revision is less than or equal to the higher revision.
The status code and lower revision output values indicate which of the following is true, in order of precedence:
The RMM supports an interface revision which is compatible with the requested revision.
- The status code is RMI_SUCCESS.
- The lower revision is equal to the requested revision.
The RMM does not support an interface revision which is compatible with the requested revision. The RMM supports an interface revision which is incompatible with and less than the requested revision.
- The status code is RMI_ERROR_INPUT.
- The lower revision is the highest interface revision which is both less than the requested revision and supported by the RMM.
The RMM does not support an interface revision which is compatible with the requested revision. The RMM supports an interface revision which is incompatible with and greater than the requested revision.
- The status code is RMI_ERROR_INPUT.
- The lower revision is equal to the higher revision.
15.3.56.1 Interface
15.3.56.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400018A0xC4000150 |
| vdev_ptrreq | X1 | 63:0 | AddressRmiInterfaceVersion | PA of the VDEVRequested interface revision |
15.3.56.1.2 ContextOutput values
The RMI_VDEV_STOP command operates on the following context.| Name | Register | Bits | Type | Value BeforeDescription |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| lower | X1 | 63:0 | RmiInterfaceVersion | Lower supported interface revision |
| higher | X2 | 63:0 | RmiInterfaceVersion | Higher supported interface revision |
15.3.56.2 Failure conditions
| ID | Condition |
|---|---|
| da_suppincompat_lower | pre: ImplFeatures(!RmiVersionIsSupported(req).feat_da != FEATURE_TRUE && RmiVersionLowerIsSupported(req)) post: (ResultEqual(result, RMI_ERROR_NOT_SUPPORTEDRMI_ERROR_INPUT) && VersionEqual(lower, RmiVersionHighestBelow(req)) && VersionEqual(higher, RmiVersionHighest())) |
| vdev_alignincompat_higher | pre: (!AddrIsGranuleAlignedRmiVersionIsSupported(vdev_ptrreq) && !RmiVersionLowerIsSupported(req) && RmiVersionHigherIsSupported(req)) post: (ResultEqual(result, RMI_ERROR_INPUT) vdev_bound pre: !PaIsDelegable(vdev_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) vdev_gran_state pre: GranuleAt(vdev_ptr).state != VDEV post: ResultEqual(result, RMI_ERROR_INPUT) vdev_state pre: (vdev.state != VDEV_READY && vdev.state != VDEV_ERROR) post: ResultEqualVersionEqual(resultlower, RMI_ERROR_DEVICEhigher) && VersionEqual(higher, RmiVersionHighest())) |
15.3.56.2.1 Failure condition ordering
[da_supp] < [vdev_align, vdev_bound, vdev_gran_state] [vdev_gran_state] < [vdev_state]The RMI_VERSION command does not have any failure condition orderings.
15.3.56.3 Success conditions
| ID | Condition |
|---|---|
| statelower | vdev.state == VDEV_STOPPINGVersionEqual(lower, req) |
| comm_statehigher | vdev.comm_state == DEV_COMM_PENDINGVersionEqual(higher, RmiVersionHighest()) |
15.3.56.4 Footprint
ID Value state vdevThe RMI_VERSION command does not have any footprint.state comm_state vdev.comm_state
15.3.57 RMI_VERSION RMI_VSMMU_CREATE command
Allows the Host and the RMM to determine whether there exists a mutually acceptable revision of the RMM via which the two components can communicateCreate a VSMMU.
On calling this command, the Host provides a requested RMI version. The output values include a status code and two revisions which are supported by the RMM: a lower revision and a higher revision. The higher revision value is the highest interface revision which is supported by the RMM. The lower revision is less than or equal to the higher revision. The status code and lower revision output values indicate which of the following is true, in order of precedence: The RMM supports an interface revision which is compatible with the requested revision. The status code is RMI_SUCCESS. The lower revision is equal to the requested revision. The RMM does not support an interface revision which is compatible with the requested revision The RMM supports an interface revision which is incompatible with and less than the requested revision. The status code is RMI_ERROR_INPUT. The lower revision is the highest interface revision which is both less than the requested revision and supported by the RMM. The RMM does not support an interface revision which is compatible with the requested revision The RMM supports an interface revision which is incompatible with and greater than the requested revision. The status code is RMI_ERROR_INPUT. The lower revision is equal to the higher revision.15.3.57.1 Interface
15.3.57.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001500xC400016A |
| reqrd | X1 | 63:0 | RmiInterfaceVersionAddress | Requested interface revisionPA of the RD |
| vsmmu_ptr | X2 | 63:0 | Address | PA of the VSMMU |
| params_ptr | X3 | 63:0 | Address | PA of VSMMU parameters |
15.3.57.1.2 Output valuesContext
The RMI_VSMMU_CREATE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| vsmmu | RmmVsmmu | VsmmuAt(vsmmu_ptr) |
false | VSMMU |
| params | RmiVsmmuParams | RmiVsmmuParamsAt( params_ptr) |
false | VSMMU parameters |
15.3.57.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.57.2 Failure conditions
| ID | Condition |
|---|---|
| incompat_lowerda_supp | pre: (!RmiVersionIsSupportedImplFeatures(req) && RmiVersionLowerIsSupported.feat_da != FEATURE_TRUE(req)) post: (ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_NOT_SUPPORTED) && VersionEqual |
| rd_align | pre: !AddrIsGranuleAligned(lower, RmiVersionHighestBelow(reqrd)) && VersionEqual(higher, RmiVersionHighest())) incompat_higher pre: (!RmiVersionIsSupported(req) && !RmiVersionLowerIsSupported(req) && RmiVersionHigherIsSupported(req)) post: (ResultEqual(result, RMI_ERROR_INPUT) && VersionEqual |
| rd_bound | pre: !PaIsDelegable(lower, higherrd) && VersionEqual post: ResultEqual(higherresult, RmiVersionHighestRMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| realm_state | pre: realm.state != REALM_NEW post: ResultEqual(result, RMI_ERROR_INPUT) |
| vsmmu_align | pre: !AddrIsGranuleAligned(vsmmu_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vsmmu_bound | pre: !PaIsDelegableDram(vsmmu_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vsmmu_state | pre: GranuleAt(vsmmu_ptr).state != DELEGATED post: ResultEqual(result, RMI_ERROR_INPUT) |
| params_align | pre: !AddrIsGranuleAligned(params_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| params_pas | pre: !GranuleAccessPermitted(params_ptr, PAS_NS) post: ResultEqual(result, RMI_ERROR_INPUT) |
| params_valid | pre: !RmiVsmmuParamsIsValid(params_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| reg_base_align | pre: (!AddrIsGranuleAligned(params.reg_base) || !AddrIsGranuleAligned(params.reg_top)) post: ResultEqual(result, RMI_ERROR_INPUT) |
| reg_base_bound | pre: (!AddrIsProtected(params.reg_base, realm) || !AddrIsProtected(params.reg_top, realm) || UInt(params.reg_top) <= UInt(params.reg_base)) post: ResultEqual(result, RMI_ERROR_INPUT) |
15.3.57.2.1 Failure condition ordering
[rd_bound, rd_state] < [realm_state]
[da_supp] < [rd_align, rd_bound, rd_state, vsmmu_align, vsmmu_bound,
vsmmu_state, params_align, params_pas, params_valid,
reg_base_align, reg_base_bound]
The RMI_VERSION command does not have any failure condition
orderings.
15.3.57.3 Success conditions
| ID | Condition |
|---|---|
| lowergran_state | VersionEqualGranuleAt(lower, reqvsmmu_ptr).state == VSMMU |
| higherrealm | VersionEqual(higher, RmiVersionHighest())vsmmu.realm == rd |
| reg_base |
vsmmu.reg_base == params.reg_base
|
| reg_top |
vsmmu.reg_top == params.reg_top
|
| aidr |
vsmmu.aidr == params.aidr
|
| idr |
(vsmmu.idr[0] == params.idr[0]
&& vsmmu.idr[1] == params.idr[1]
&& vsmmu.idr[2] == params.idr[2]
&& vsmmu.idr[3] == params.idr[3]
&& vsmmu.idr[4] == params.idr[4]
&& vsmmu.idr[5] == params.idr[5]
&& vsmmu.idr[6] == params.idr[6])
|
15.3.57.4 Footprint
The RMI_VERSION command does not have any footprint| ID | Value |
|---|---|
| state | GranuleAt(vsmmu_ptr).state |
15.3.58 RMI_VSMMU_CREATERMI_VSMMU_DESTROY command
CreateDestroy a VSMMU.
15.3.58.1 Interface
15.3.58.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400016A0xC400016B |
| rd | X1 | 63:0 | Address | PA of the RD |
| vsmmu_ptr | X2 | 63:0 | Address | PAIPA of the VSMMU |
15.3.58.1.2 Context
The RMI_VSMMU_CREATERMI_VSMMU_DESTROY command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| vsmmu | RmmVsmmu | VsmmuAt(vsmmu_ptr) |
false | VSMMU |
15.3.58.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.58.2 Failure conditions
| ID | Condition |
|---|---|
| da_supp | pre: ImplFeatures().feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_NOT_SUPPORTED) |
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| vsmmu_align | pre: !AddrIsGranuleAligned(vsmmu_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vsmmu_bound | pre: !PaIsDelegable(vsmmu_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vsmmu_state | pre: GranuleAt(vsmmu_ptr).state != DELEGATEDVSMMU post: ResultEqual(result, RMI_ERROR_INPUT) |
| params_alignvsmmu_live | pre: !AddrIsGranuleAlignedVsmmuIsLive(params_ptrvsmmu_ptr) post: ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_DEVICE) |
15.3.58.2.1 Failure condition ordering
[rd_bound[vsmmu_bound, rd_state]vsmmu_state] < [realm_state]
[da_supp] < [rd_align, rd_bound, rd_state, vsmmu_align, vsmmu_bound,
vsmmu_state, params_align, params_bound, params_pas,
params_valid, reg_base_align, reg_base_bound][vsmmu_live]
15.3.58.3 Success conditions
| ID | Condition |
|---|---|
| gran_state | GranuleAt(vsmmu_ptr).state == VSMMUDELEGATED |
15.3.58.4 Footprint
| ID | Value |
|---|---|
| state | GranuleAt(vsmmu_ptr).state |
15.3.59 RMI_VSMMU_DESTROY RMI_VSMMU_MAP command
DestroyCreate a VSMMU mapping.
15.3.59.1 Interface
15.3.59.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400016B0xC400016C |
| rd | X1 | 63:0 | Address | PA of the RD |
| vsmmu_ptr | X2 | 63:0 | Address | PA of the VSMMU |
| ipa | X3 | 63:0 | Address | IPA of the VSMMUat which to create the mapping |
15.3.59.1.2 Context
The RMI_VSMMU_DESTROYRMI_VSMMU_MAP command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| vsmmu | RmmVsmmu | VsmmuAt(vsmmu_ptr) |
false | VSMMU |
| walk | RmmRttWalkResult | RttWalk( realm, ipa, RMM_RTT_PAGE_LEVEL, RMM_RTT_TREE_PRIMARY) |
false | RTT walk result |
| entry_idx | UInt64 | RttEntryIndex( ipa, walk.level) |
false | RTTE index |
15.3.59.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
15.3.59.2 Failure conditions
| ID | Condition |
|---|---|
| da_supp | pre: ImplFeatures().feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_NOT_SUPPORTED) |
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| realm_state | pre: realm.state != REALM_NEW post: ResultEqual(result, RMI_ERROR_INPUT) |
| vsmmu_align | pre: !AddrIsGranuleAligned(vsmmu_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vsmmu_bound | pre: !PaIsDelegable(vsmmu_ptr) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vsmmu_state | pre: GranuleAt(vsmmu_ptr).state != VSMMU post: ResultEqual(result, RMI_ERROR_INPUT) |
| vsmmu_liveipa_bound | pre: VsmmuIsLiveUInt(vsmmu_ptripa) < UInt(vsmmu.reg_base) post: ResultEqual(result, RMI_ERROR_DEVICERMI_ERROR_INPUT) |
| rtt_walk | pre: walk.level < RMM_RTT_PAGE_LEVEL post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
| rtte_state | pre: walk.rtte.state != UNASSIGNED post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
| rtte_ripas | pre: walk.rtte.ripas != EMPTY post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
| rtte_bound | pre: (UInt(ipa) + (RttLevelSize(walk.level) - 1) >= UInt(vsmmu.reg_top)) post: ResultEqual(result, RMI_ERROR_RTT, walk.level) |
15.3.59.2.1 Failure condition ordering
[vsmmu_bound[rd_bound, vsmmu_state]rd_state] < [vsmmu_live][realm_state]
[rd_bound, rd_state] < [rtt_walk, rtte_state, rtte_ripas, rtte_bound]
[vsmmu_state] < [rtte_bound]
[da_supp] < [vsmmu_align, vsmmu_bound, vsmmu_state]
15.3.59.3 Success conditions
| ID | Condition |
|---|---|
| gran_statertte_state | GranuleAt(vsmmu_ptr)walk.rtte.state == DELEGATEDASSIGNED_VSMMU |
| rtte_addr |
walk.rtte.addr == vsmmu_ptr
|
15.3.59.4 Footprint
| ID | Value |
|---|---|
| statertte | GranuleAtRttEntryAt(vsmmu_ptrRttAt(walk.rtt_addr).state, entry_idx) |
15.3.60 RMI_VSMMU_MAP RMI_VSMMU_UNMAP command
CreateRemove a VSMMU mapping.
15.3.60.1 Interface
15.3.60.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400016C0xC400016D |
| rd | X1 | 63:0 | Address | PA of the RD |
| vsmmu_ptripa | X2 | 63:0 | Address | PA of the VSMMU ipa X3 63:0 AddressIPA at which to createremove the mapping |
15.3.60.1.2 Context
The RMI_VSMMU_MAPRMI_VSMMU_UNMAP command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | RealmAt(rd) |
false | Realm |
| walk | RmmRttWalkResult | RttWalk( realm, ipa, RMM_RTT_PAGE_LEVEL, RMM_RTT_TREE_PRIMARY) |
false | RTT walk result |
| entry_idx | UInt64 | RttEntryIndex( ipa, walk.level) |
false | RTTE index |
| walk_top | Address | RttSkipNonLiveEntries( RttAt(walk.rtt_addr), walk.level, ipa) |
false | Top IPA of non-live RTT entries, from entry at which the RTT walk terminated |
15.3.60.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RmiCommandReturnCode | Command return status |
| vsmmu | X1 | 63:0 | Address | PA of the VSMMU Granule which was unmapped |
| top | X2 | 63:0 | Address | Top IPA of non-live RTT entries, from entry at which the RTT walk terminated |
15.3.60.2 Failure conditions
| ID | Condition |
|---|---|
| da_supp | pre: ImplFeatures().feat_da != FEATURE_TRUE post: ResultEqual(result, RMI_ERROR_NOT_SUPPORTED) |
| rd_align | pre: !AddrIsGranuleAligned(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_bound | pre: !PaIsDelegable(rd) post: ResultEqual(result, RMI_ERROR_INPUT) |
| rd_state | pre: GranuleAt(rd).state != RD post: ResultEqual(result, RMI_ERROR_INPUT) |
| realm_stateipa_align | pre: realm.state != REALM_NEWAddrIsGranuleAligned(ipa) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vsmmu_alignipa_bound | pre: !AddrIsGranuleAlignedAddrIsProtected(vsmmu_ptripa, realm) post: ResultEqual(result, RMI_ERROR_INPUT) |
| vsmmu_boundrtt_walk | pre: !PaIsDelegablewalk.level < RMM_RTT_PAGE_LEVEL post: (vsmmu_ptr) post: ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_RTT, walk.level) && (top == walk_top)) |
| vsmmu_statertte_state | pre: GranuleAt(vsmmu_ptr)walk.rtte.state != DELEGATEDASSIGNED_VSMMU post: (ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_RTT, walk.level) && (top == walk_top)) |
| ipa_boundaux_live | pre: (UIntAddrIsAuxLive(ipa, realm) < UInt(vsmmu.reg_base) || UInt(ipa) >= UInt(vsmmu.reg_top)) post: ResultEqual(result, RMI_ERROR_INPUTRMI_ERROR_RTT_AUX, 0) |
15.3.60.2.1 Failure condition ordering
[rd_bound, rd_state] < [realm_state]
[rd_bound[rtt_walk, rd_state]rtte_state, aux_live]
[ipa_bound] < [rtt_walk, rtte_state, rtte_ripas, rtte_bound]
[vsmmu_state] < [rtte_bound]
[da_supp] < [vsmmu_align, vsmmu_bound, vsmmu_state]aux_live]
15.3.60.3 Success conditions
| ID | Condition |
|---|---|
| rtte_state | walk.rtte.state == ASSIGNED_VSMMUUNASSIGNED |
| rtte_addrripas_ram | pre: walk.rtte.ripas == DEV post: walk.rtte.ripas == DESTROYED |
| vsmmu |
vsmmu == walk.rtte.addr
|
| top | top == vsmmu_ptrwalk_top |
15.3.60.4 Footprint
| ID | Value |
|---|---|
| data_state | GranuleAt(walk.rtte.addr).state |
| rtte | RttEntryAt(RttAt(walk.rtt_addr), entry_idx) |
15.4 RMI types
This section defines types which are used in the RMI interface.
15.4.1 RmiAddressRange type
The RmiAddressRange structure contains address range.
The RmiAddressRange structure is a concrete type.
The width of the RmiAddressRange structure is 16 (0x10)
bytes.
The members of the RmiAddressRange structure are shown in the following table.
The RmiAddressRange structure is used in the following types:
15.4.2 RmiBoolean type
The RmiBoolean enumeration represents a boolean value.
The RmiBoolean enumeration is a concrete type.
The width of the RmiBoolean enumeration is 1 bits.
The values of the RmiBoolean enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_FALSE | False |
| 1 | RMI_TRUE | True |
The RmiBoolean enumeration is used in the following types:
15.4.3 RmiCommandReturnCode type
The RmiCommandReturnCode fieldset contains a return code from an RMI command.
The RmiCommandReturnCode fieldset is a concrete type.
The width of the RmiCommandReturnCode fieldset is 64 bits.
See also:
- Section 12
The fields of the RmiCommandReturnCode fieldset are shown in the following diagram.
The fields of the RmiCommandReturnCode fieldset are shown in the following table.
| Name | Bits | Description | Value |
|---|---|---|---|
| status | 7:0 | Status of the command | RmiStatusCode |
| index | 15:8 | Index which identifies the reason for a command failure | UInt8 |
| 63:16 | Reserved | MBZ |
15.4.4 RmiDataFlags type
The RmiDataFlags fieldset contains flags provided by the Host during DATA Granule creation.
The RmiDataFlags fieldset is a concrete type.
The width of the RmiDataFlags fieldset is 64 bits.
The fields of the RmiDataFlags fieldset are shown in the following diagram.
The fields of the RmiDataFlags fieldset are shown in the following table.
| Name | Bits | Description | Value |
|---|---|---|---|
| measure | 0 | Whether to measure DATA Granule contents | RmiDataMeasureContent |
| 63:1 | Reserved | SBZ |
15.4.5 RmiDataMeasureContent type
The RmiDataMeasureContent enumeration represents whether to measure DATA Granule contents.
The RmiDataMeasureContent enumeration is a concrete type.
The width of the RmiDataMeasureContent enumeration is 1 bits.
The values of the RmiDataMeasureContent enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_NO_MEASURE_CONTENT | Do not measure DATA Granule contents. |
| 1 | RMI_MEASURE_CONTENT | Measure DATA Granule contents. |
The RmiDataMeasureContent enumeration is used in the following types:
15.4.6 RmiDevCommData type
The RmiDevCommData structure contains data structure shared between Host and RMM for device communication.
The RmiDevCommData structure is a concrete type.
The width of the RmiDevCommData structure is 4096
(0x1000) bytes.
The members of the RmiDevCommData structure are shown in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| enter | 0x0 |
RmiDevCommEnter | Entry information |
| exit | 0x800 |
RmiDevCommExit | Exit information |
Unused bits of the RmiDevCommData structure SBZ.
15.4.7 RmiDevCommEnter type
The RmiDevCommEnter structure contains data passed from the Host to the RMM during device communication.
The RmiDevCommEnter structure is a concrete type.
The width of the RmiDevCommEnter structure is 256
(0x100) bytes.
See also:
- Section 9.2.5.2
The members of the RmiDevCommEnter structure are shown in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| status | 0x0 |
RmiDevCommStatus | Status of device transaction |
| req_addr | 0x8 |
Address | Address of request buffer |
| resp_addr | 0x10 |
Address | Address of response buffer |
| resp_len | 0x18 |
UInt64 | Amount of valid data in response buffer in bytes |
Unused bits of the RmiDevCommEnter structure SBZ.
The RmiDevCommEnter structure is used in the following types:
15.4.8 RmiDevCommExit type
The RmiDevCommExit structure contains data passed from the RMM to the Host during device communication.
The RmiDevCommExit structure is a concrete type.
The width of the RmiDevCommExit structure is 256 (0x100)
bytes.
See also:
- Section 9.2.5.1
The members of the RmiDevCommExit structure are shown in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| flags | 0x0 |
RmiDevCommExitFlags | Flags indicating action(s) which the Host is requested to perform |
| cache_offset | 0x8 |
UInt64 | If flags.cache is true, offset in the device response buffer to the start of data to be cached, in bytes |
| cache_len | 0x10 |
UInt64 | If flags.cache is true, amount of data to be cached, in bytes |
| protocol | 0x18 |
RmiDevCommProtocol | If flags.send is true, protocol to use |
| req_len | 0x20 |
UInt64 | If flags.send is true, amount of valid data in request buffer in bytes |
| timeout | 0x28 |
UInt64 | If flags.wait is true, amount of time to wait for device response in milliseconds |
Unused bits of the RmiDevCommExit structure MBZ.
The RmiDevCommExit structure is used in the following types:
15.4.9 RmiDevCommExitFlags type
The RmiDevCommExitFlags fieldset contains flags provided by the RMM during a device transaction.
The RmiDevCommExitFlags fieldset is a concrete type.
The width of the RmiDevCommExitFlags fieldset is 64 bits.
The fields of the RmiDevCommExitFlags fieldset are shown in the following diagram.
The fields of the RmiDevCommExitFlags fieldset are shown in the following table.
| Name | Bits | Description | Value |
|---|---|---|---|
| cache | 0 | Whether the Host is requested to cache data from the device response buffer | RmiBoolean |
| send | 1 | Whether the Host is requested to send data from the device request buffer to the device | RmiBoolean |
| wait | 2 | Whether the RMM is waiting for a response from the device | RmiBoolean |
| multi | 3 | Whether the device transaction contains more than one (device request, device response) tuple | RmiBoolean |
| 63:4 | Reserved | MBZ |
The RmiDevCommExitFlags fieldset is used in the following types:
15.4.10 RmiDevCommProtocol type
The RmiDevCommProtocol enumeration represents protocol used for device communication.
The RmiDevCommProtocol enumeration is a concrete type.
The width of the RmiDevCommProtocol enumeration is 8 bits.
The values of the RmiDevCommProtocol enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_PROTOCOL_SPDM | SPDM |
| 1 | RMI_PROTOCOL_SECURE_SPDM | Secure SPDM |
Unused encodings for the RmiDevCommProtocol enumeration are reserved for use by future versions of this specification.
The RmiDevCommProtocol enumeration is used in the following types:
15.4.11 RmiDevCommStatus type
The RmiDevCommStatus enumeration represents status passed from the Host to the RMM during device communication.
The RmiDevCommStatus enumeration is a concrete type.
The width of the RmiDevCommStatus enumeration is 8 bits.
The values of the RmiDevCommStatus enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_DEV_COMM_SUCCESSRMI_DEV_COMM_NONE | No device response has been received from the device. Either:
|
| 1 | RMI_DEV_COMM_RESPONSE | The device transaction is ACTIVE and a device response has been received from the device. |
| 2 | RMI_DEV_COMM_ERROR | Either:
|
Unused encodings for the RmiDevCommStatus enumeration are reserved for use by future versions of this specification.
The RmiDevCommStatus enumeration is used in the following types:
15.4.12 RmiEmulatedMmio type
The RmiEmulatedMmio enumeration represents whether the host has completed emulation for an Emulatable Abort.
The RmiEmulatedMmio enumeration is a concrete type.
The width of the RmiEmulatedMmio enumeration is 1 bits.
The values of the RmiEmulatedMmio enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_NOT_EMULATED_MMIO | Host has not completed emulation for an Emulatable Abort. |
| 1 | RMI_EMULATED_MMIO | Host has completed emulation for an Emulatable Abort. |
The RmiEmulatedMmio enumeration is used in the following types:
15.4.13 RmiFeature type
The RmiFeature enumeration represents whether a feature is supported or enabled.
The RmiFeature enumeration is a concrete type.
The width of the RmiFeature enumeration is 1 bits.
The values of the RmiFeature enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_FEATURE_FALSE |
|
| 1 | RMI_FEATURE_TRUE |
|
The RmiFeature enumeration is used in the following types:
- RmiRealmFlags0
- RmiVdevFlags
- RmiFeatureRegister0
- RmiRealmFlags1 RmiRealmFlags0 RmiFeatureRegister0 RmiVdevFlags
15.4.14 RmiFeatureRegister0 type
The RmiFeatureRegister0 fieldset contains RMI feature register 0.
The RmiFeatureRegister0 fieldset is a concrete type.
The width of the RmiFeatureRegister0 fieldset is 64 bits.
The fields of the RmiFeatureRegister0 fieldset are shown in the following diagram.
The fields of the RmiFeatureRegister0 fieldset are shown in the following table.
| Name | Bits | Description | Value |
|---|---|---|---|
| S2SZ | 7:0 | Maximum Realm IPA width supported by the RMM. Specifies the input address size for stage 2 translation to be
|
UInt8 |
| LPA2 | 8 | Whether LPA2 is supported. | RmiFeature |
| SVE | 9 | Whether SVE is supported. | RmiFeature |
| SVE_VL | 13:10 | Maximum SVE vector length supported by the RMM. The effective vector length supported by the RMM is
|
UInt4 |
| NUM_BPS | 19:14 | Number of breakpoints available, minus one. The value 0 is reserved. |
UInt6 |
| NUM_WPS | 25:20 | Number of watchpoints available, minus one. The value 0 is reserved. |
UInt6 |
| PMU | 26 | Whether PMU is supported | RmiFeature |
| PMU_NUM_CTRS | 31:27 | Number of PMU counters available | UInt5 |
| HASH_SHA_256 | 32 | Whether SHA-256 is supported | RmiFeature |
| HASH_SHA_512 | 33 | Whether SHA-512 is supported | RmiFeature |
| GICV3_NUM_LRS | 37:34 | Number of GICv3 List Registers which are available, minus one. | UInt4 |
| MAX_RECS_ORDER | 41:38 | Order of the maximum number of RECs which can be created per Realm. The maximum number of RECs is computed as follows:
|
UInt4 |
| DA | 42 | Whether Realm device assignment is supported | RmiFeature |
| RTT_PLANE | 44:43 | RTT usage models supported for multi-Plane Realms. If only a single Plane is supported (that is, MAX_NUM_AUX_PLANES is 0), this field is res0. |
RmiRttPlaneFeature |
| MAX_NUM_AUX_PLANES | 48:45 | Maximum number of auxiliary Planes | UInt4 |
| RTT_S2AP_INDIRECT | 49 | Whether the Realm uses S2AP indirect encoding | RmiFeature |
| 63:50 | Reserved | MBZ |
15.4.15 RmiFeatureRegister1 type
The RmiFeatureRegister1 fieldset contains RMI feature register 1.
The RmiFeatureRegister1 fieldset is a concrete type.
The width of the RmiFeatureRegister1 fieldset is 64 bits.
The fields of the RmiFeatureRegister1 fieldset are shown in the following diagram.
The fields of the RmiFeatureRegister1 fieldset are shown in the following table.
| Name | Bits | Description | Value |
|---|---|---|---|
| MAX_MECID | 63:0 | Maximum MECID. | Bits64 |
15.4.16 RmiHashAlgorithm type
The RmiHashAlgorithm enumeration represents hash algorithm.
The RmiHashAlgorithm enumeration is a concrete type.
The width of the RmiHashAlgorithm enumeration is 8 bits.
The values of the RmiHashAlgorithm enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_HASH_SHA_256 | SHA-256 (Secure Hash Standard (SHS) [20]) |
| 1 | RMI_HASH_SHA_512 | SHA-512 (Secure Hash Standard (SHS) [20]) |
Unused encodings for the RmiHashAlgorithm enumeration are reserved for use by future versions of this specification.
The RmiHashAlgorithm enumeration is used in the following types:
15.4.17 RmiInjectSea type
The RmiInjectSea enumeration represents whether to inject a Synchronous External Abort into the Realm.
The RmiInjectSea enumeration is a concrete type.
The width of the RmiInjectSea enumeration is 1 bits.
The values of the RmiInjectSea enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_NO_INJECT_SEA | Do not inject an SEA into the Realm. |
| 1 | RMI_INJECT_SEA | Inject an SEA into the Realm. |
The RmiInjectSea enumeration is used in the following types:
15.4.18 RmiInterfaceVersion type
The RmiInterfaceVersion fieldset contains an RMI interface version.
The RmiInterfaceVersion fieldset is a concrete type.
The width of the RmiInterfaceVersion fieldset is 64 bits.
The fields of the RmiInterfaceVersion fieldset are shown in the following diagram.
The fields of the RmiInterfaceVersion fieldset are shown in the following table.
15.4.19 RmiLfaPolicy type
The RmiLfaPolicy enumeration represents a Live Firmware Activation policy.
The RmiLfaPolicy enumeration is a concrete type.
The width of the RmiLfaPolicy enumeration is 2 bits.
See also:
- Section 3.13
The values of the RmiLfaPolicy enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_LFA_DISALLOW | LFA is not permitted. |
| 1 | RMI_LFA_ALLOW | LFA is permitted. |
Unused encodings for the RmiLfaPolicy enumeration are reserved for use by future versions of this specification.
The RmiLfaPolicy enumeration is used in the following types:
15.4.20 RmiPdevEvent type
The RmiPdevEvent enumeration represents physical device event.
The RmiPdevEvent enumeration is a concrete type.
The width of the RmiPdevEvent enumeration is 8 bits.
The values of the RmiPdevEvent enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_IDE_KEY_REFRESH | IDE key refresh. |
Unused encodings for the RmiPdevEvent enumeration are reserved for use by future versions of this specification.
15.4.21 RmiPdevFlags type
The RmiPdevFlags fieldset contains flags provided by the Host during PDEV creation.
The RmiPdevFlags fieldset is a concrete type.
The width of the RmiPdevFlags fieldset is 64 bits.
The fields of the RmiPdevFlags fieldset are shown in the following diagram.
The fields of the RmiPdevFlags fieldset are shown in the following table.
| Name | Bits | Description | Value |
|---|---|---|---|
| prot_configprot | 1:0 | Configuration of protection between system and device | RmiPdevProtConfigRmiPdevProtection |
| 63:2 | Reserved | SBZ |
The RmiPdevFlags fieldset is used in the following types:
15.4.22 RmiPdevParams type
The RmiPdevParams structure contains parameters provided by the Host during PDEV creation.
The RmiPdevParams structure is a concrete type.
The width of the RmiPdevParams structure is 4096
(0x1000) bytes.
The members of the RmiPdevParams structure are shown in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| flags | 0x0 |
RmiPdevFlags | Flags |
| pdev_id | 0x8 |
Bits64 | Physical device identifier For a PCIe device:
|
| segment_id | 0x10 |
Bits8 | Segment identifier PCIe Segment identifier to be used in IDE address association. |
| ecam_addr | 0x18 |
Address | ECAM base address of the PCIe configuration space. |
| root_id | 0x20 |
Bits16 | Root Port identifier Physical PCIe routing identifier of the Root Port to which the endpoint is connected. The value is in PCI BDF format. |
| cert_id | 0x28 |
UInt64 | Certificate identifier |
| rid_base | 0x30 |
Bits16 | Base of requester ID range (inclusive). The value is in PCI BDF format. |
| rid_top | 0x38 |
Bits16 | Top of requester ID range (exclusive). The value is in PCI BDF format. |
| hash_algo | 0x40 |
RmiHashAlgorithm | Algorithm used to generate device digests |
| num_aux | 0x48 |
UInt64 | Number of auxiliary Granules |
| ide_sid | 0x50 |
UInt64 | IDE stream ID |
| iocoh_num_addr_rangencoh_num_addr_range | 0x58 |
UInt64 | Number of IOdevice non-coherent address ranges |
| fcoh_num_addr_rangecoh_num_addr_range | 0x60 |
UInt64 | Number of fully-device coherent address ranges. |
| aux[32] | 0x100 |
Address | Addresses of auxiliary Granules |
| iocoh_addr_range[16]ncoh_addr_range[16] | 0x200 |
RmiAddressRange | IODevice non-coherent address range |
| fcoh_addr_range[4]coh_addr_range[4] | 0x300 |
RmiAddressRange | Fully-Device coherent address range |
Unused bits of the RmiPdevParams structure SBZ.
15.4.23 RmiPdevProtConfigRmiPdevProtection type
The RmiPdevProtConfigRmiPdevProtection enumeration represents configuration of protection between system and device.
The RmiPdevProtConfigRmiPdevProtection enumeration is a concrete type.
The width of the RmiPdevProtConfigRmiPdevProtection enumeration is 2 bits.
See also:
- Section 9.1.1
The values of the RmiPdevProtConfigRmiPdevProtection enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_PDEV_IOCOH_E2E_IDE | IO-coherent device with end-to-end protection provided by IDE. |
| 1 | RMI_PDEV_IOCOH_E2E_SYS | IO-coherent device with end-to-end protection provided by system construction. |
| 2 | RMI_PDEV_FCOH_E2E_IDE | Fully-coherent device with end-to-end protection provided by IDE. |
| 3 | RMI_PDEV_FCOH_E2E_SYS | Fully-coherent device with end-to-end protection provided by system construction. |
The RmiPdevProtConfigRmiPdevProtection enumeration is used in the following types:
15.4.24 RmiPdevState type
The RmiPdevState enumeration represents the state of a PDEV.
The RmiPdevState enumeration is a concrete type.
The width of the RmiPdevState enumeration is 8 bits.
The values of the RmiPdevState enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_PDEV_NEW | Initial state of the device. |
| 1 | RMI_PDEV_NEEDS_KEY | RMM needs device public key. |
| 2 | RMI_PDEV_HAS_KEY | RMM has device public key. |
| 3 | RMI_PDEV_READY | Secure connection between the RMM and the device has been established. Physical link between the device and memory is secured. Ready for creation of VDEV instances. |
| 4 | RMI_PDEV_COMMUNICATING | The RMM is communicating with the device. |
| 5 | RMI_PDEV_STOPPING | The RMM is communicating with the device to terminate the secure connection between the RMM and the device. |
| 6 | RMI_PDEV_STOPPED | Secure connection between the RMM and the device has been terminated. |
| 7 | RMI_PDEV_ERROR | Device has reported a fatal error. |
Unused encodings for the RmiPdevState enumeration are reserved for use by future versions of this specification.
15.4.25 RmiPmuOverflowStatus type
The RmiPmuOverflowStatus enumeration represents PMU overflow status.
The RmiPmuOverflowStatus enumeration is a concrete type.
The width of the RmiPmuOverflowStatus enumeration is 8 bits.
The values of the RmiPmuOverflowStatus enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_PMU_OVERFLOW_NOT_ACTIVE | PMU overflow is not active. |
| 1 | RMI_PMU_OVERFLOW_ACTIVE | PMU overflow is active. |
Unused encodings for the RmiPmuOverflowStatus enumeration are reserved for use by future versions of this specification.
The RmiPmuOverflowStatus enumeration is used in the following types:
15.4.26 RmiPublicKeyParams type
The RmiPublicKeyParams structure contains public key parameters.
The RmiPublicKeyParams structure is a concrete type.
The width of the RmiPublicKeyParams structure is 4096
(0x1000) bytes.
The members of the RmiPublicKeyParams structure are shown in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| key[1024] | 0x0 |
Bits8 | Key data |
| metadata[1024] | 0x400 |
Bits8 | Key metadata |
| key_len | 0x800 |
UInt64 | Length of key data in bytes |
| metadata_len | 0x808 |
UInt64 | Length of key metadata in bytes |
| algo | 0x810 |
RmiSignatureAlgorithm | Signature algorithm |
Unused bits of the RmiPublicKeyParams structure SBZ.
15.4.27 RmiRealmFlags0 type
The RmiRealmFlags0 fieldset contains flags provided by the Host during Realm creation, which are reflected in Realm Initial Measurement.
The RmiRealmFlags0 fieldset is a concrete type.
The width of the RmiRealmFlags0 fieldset is 64 bits.
The fields of the RmiRealmFlags0 fieldset are shown in the following diagram.
The fields of the RmiRealmFlags0 fieldset are shown in the following table.
| Name | Bits | Description | Value |
|---|---|---|---|
| lpa2 | 0 | Whether LPA2 is enabled | RmiFeature |
| sve | 1 | Whether SVE is enabled | RmiFeature |
| pmu | 2 | Whether PMU is enabled | RmiFeature |
| da | 3 | Whether Realm device assignment is enabled | RmiFeature |
| 4 | Reserved | SBZ | |
| lfa_policy | 6:5 | Live Firmware Activation policy for components within the Realm’s TCB | RmiLfaPolicy |
| 63:7 | Reserved | SBZ |
The RmiRealmFlags0 fieldset is used in the following types:
15.4.28 RmiRealmFlags1 type
The RmiRealmFlags1 fieldset contains flags provided by the Host during Realm creation, which are not reflected in Realm Initial Measurement.
The RmiRealmFlags1 fieldset is a concrete type.
The width of the RmiRealmFlags1 fieldset is 64 bits.
The fields of the RmiRealmFlags1 fieldset are shown in the following diagram.
The fields of the RmiRealmFlags1 fieldset are shown in the following table.
| Name | Bits | Description | Value |
|---|---|---|---|
| rtt_tree_per_plane | 0 | RMI_FEATURE_FALSE: all Planes share a single RTT tree RMI_FEATURE_TRUE: each Plane has a separate RTT tree If the Realm has no auxiliary Planes then this field is ignored. |
RmiFeature |
| rtt_s2ap_indirectrtt_s2ap_encoding | 1 | RMI_FEATURE_FALSE: S2AP values are encoded directly in the RTT descriptor RMI_FEATURE_TRUE: S2AP values are encoded indirectly in the RTT descriptorencoding | RmiFeatureRmiRttS2APEncoding |
| 63:2 | Reserved | SBZ |
The RmiRealmFlags1 fieldset is used in the following types:
15.4.29 RmiRealmParams type
The RmiRealmParams structure contains parameters provided by the Host during Realm creation.
The RmiRealmParams structure is a concrete type.
The width of the RmiRealmParams structure is 4096
(0x1000) bytes.
The members of the RmiRealmParams structure are shown in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| flags0 | 0x0 |
RmiRealmFlags0 | Flags |
| s2sz | 0x8 |
UInt8 | IPA width. Specifies the input address size for stage 2 translation to be
|
| sve_vl | 0x10 |
UInt8 | SVE vector length. The effective vector length requested is
|
| num_bps | 0x18 |
UInt8 | Number of breakpoints, minus one. The value 0 is reserved. |
| num_wps | 0x20 |
UInt8 | Number of watchpoints, minus one. The value 0 is reserved. |
| pmu_num_ctrs | 0x28 |
UInt8 | Number of PMU counters |
| hash_algo | 0x30 |
RmiHashAlgorithm | Algorithm used to measure the initial state of the Realm |
| num_aux_planes | 0x38 |
UInt64 | Number of auxiliary Planes |
| rpv | 0x400 |
Bits512 | Realm Personalization Value |
| vmid | 0x800 |
Bits16 | Primary Virtual Machine Identifier |
| rtt_base | 0x808 |
Address | Base address of primary RTT |
| rtt_level_start | 0x810 |
Int64 | RTT starting level |
| rtt_num_start | 0x818 |
UInt32 | Number of starting level RTTs |
| flags1 | 0x820 |
RmiRealmFlags1 | Flags |
| mecid | 0x828 |
Bits64 | MECID |
| aux_vmid[3] | 0xf00 |
Bits16 | Auxiliary Virtual Machine Identifiers |
| aux_rtt_base[3] | 0xf80 |
Address | Base address of auxiliary RTTs |
Unused bits of the RmiRealmParams structure SBZ.
15.4.30 RmiRecCreateFlags type
The RmiRecCreateFlags fieldset contains flags provided by the Host during REC creation.
The RmiRecCreateFlags fieldset is a concrete type.
The width of the RmiRecCreateFlags fieldset is 64 bits.
The fields of the RmiRecCreateFlags fieldset are shown in the following diagram.
The fields of the RmiRecCreateFlags fieldset are shown in the following table.
| Name | Bits | Description | Value |
|---|---|---|---|
| runnable | 0 | Whether REC is eligible for execution | RmiRecRunnable |
| 63:1 | Reserved | SBZ |
The RmiRecCreateFlags fieldset is used in the following types:
15.4.31 RmiRecEnter type
The RmiRecEnter structure contains data passed from the Host to the RMM on REC entry.
The RmiRecEnter structure is a concrete type.
The width of the RmiRecEnter structure is 2048 (0x800)
bytes.
The members of the RmiRecEnter structure are shown in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| flags | 0x0 |
RmiRecEnterFlags | Flags |
| gprs[31] | 0x200 |
Bits64 | Registers |
| gicv3_hcr | 0x300 |
Bits64 | GICv3 Hypervisor Control Register value |
| gicv3_lrs[16] | 0x308 |
Bits64 | GICv3 List Register values |
Unused bits of the RmiRecEnter structure SBZ.
The RmiRecEnter structure is used in the following types:
15.4.32 RmiRecEnterFlags type
The RmiRecEnterFlags fieldset contains flags provided by the Host during REC entry.
The RmiRecEnterFlags fieldset is a concrete type.
The width of the RmiRecEnterFlags fieldset is 64 bits.
The fields of the RmiRecEnterFlags fieldset are shown in the following diagram.
The fields of the RmiRecEnterFlags fieldset are shown in the following table.
| Name | Bits | Description | Value |
|---|---|---|---|
| emul_mmio | 0 | Whether the host has completed emulation for an Emulatable Data Abort | RmiEmulatedMmio |
| inject_sea | 1 | Whether to inject a Synchronous External Abort into the Realm. | RmiInjectSea |
| trap_wfi | 2 | Whether to trap WFI execution by the Realm. | RmiTrap |
| trap_wfe | 3 | Whether to trap WFE execution by the Realm. | RmiTrap |
| ripas_response | 4 | Host response to RIPAS change request. | RmiResponse |
| s2ap_response | 5 | Host response to S2AP change request. | RmiResponse |
| dev_mem_response | 6 | Host response to device memory mapping validation request. | RmiResponse |
| 63:663:7 | Reserved | SBZ |
The RmiRecEnterFlags fieldset is used in the following types:
15.4.33 RmiRecExit type
The RmiRecExit structure contains data passed from the RMM to the Host on REC exit.
The RmiRecExit structure is a concrete type.
The width of the RmiRecExit structure is 2048 (0x800)
bytes.
The members of the RmiRecExit structure are shown in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| exit_reason | 0x0 |
RmiRecExitReason | Exit reason |
| esr | 0x100 |
Bits64 | Exception Syndrome Register |
| far | 0x108 |
Bits64 | Fault Address Register |
| hpfar | 0x110 |
Bits64 | Hypervisor IPA Fault Address register |
| rtt_tree | 0x118 |
UInt64 | Index of RTT tree active at time of the exit |
| rtt_level | 0x120 |
Int64 | Level of requested RTT |
| gprs[31] | 0x200 |
Bits64 | Registers |
| gicv3_hcr | 0x300 |
Bits64 | GICv3 Hypervisor Control Register value |
| gicv3_lrs[16] | 0x308 |
Bits64 | GICv3 List Register values |
| gicv3_misr | 0x388 |
Bits64 | GICv3 Maintenance Interrupt State Register value |
| gicv3_vmcr | 0x390 |
Bits64 | GICv3 Virtual Machine Control Register value |
| cntp_ctl | 0x400 |
Bits64 | Counter-timer Physical Timer Control Register value |
| cntp_cval | 0x408 |
Bits64 | Counter-timer Physical Timer CompareValue Register value |
| cntv_ctl | 0x410 |
Bits64 | Counter-timer Virtual Timer Control Register value |
| cntv_cval | 0x418 |
Bits64 | Counter-timer Virtual Timer CompareValue Register value |
| ripas_base | 0x500 |
Bits64 | Base addressIPA of target region for pending RIPAS change |
| ripas_top | 0x508 |
Bits64 | Top addressIPA of target region for pending RIPAS change |
| ripas_value | 0x510 |
RmiRipas | RIPAS value of pending RIPAS change |
| ripas_dev_pas2ap_base | 0x5180x520 |
Bits64 | Base IPA of target region for pending S2AP change |
| s2ap_top | 0x528 |
Bits64 | Top IPA of target region for pending S2AP change |
| vdev_id | 0x530 |
Bits64 | Virtual device ID |
| imm | 0x600 |
Bits16 | Host call immediate value |
| plane | 0x608 |
UInt64 | Plane index |
| vdev | 0x610 |
Address | Base PA of device memory region, if RIPAS change is pendingVDEV which triggered REC exit due to exection of RSI_RDEV_VALIDATE_MAPPING VDEV communication |
| s2ap_basevdev_action | 0x5200x618 |
RmiVdevAction | Action which triggered REC exit due to VDEV communication |
| dev_mem_base | 0x620 |
Bits64 | Base addressIPA of target region for pending S2AP changedevice memory mapping validation |
| s2ap_topdev_mem_top | 0x5280x628 |
Bits64 | Top addressIPA of target region for pending S2AP changedevice memory mapping validation |
| vdev_iddev_mem_pa | 0x5300x630 |
Bits64
Virtual device ID
imm
0x600
Bits16
Host call immediate value
plane
0x608
UInt64
Plane index
vdev
0x610
Address | VDEV which triggered REC exit due toBase PA of device communicationmemory region |
| pmu_ovf_status | 0x700 |
RmiPmuOverflowStatus | PMU overflow status |
Unused bits of the RmiRecExit structure MBZ.
The RmiRecExit structure is used in the following types:
15.4.34 RmiRecExitReason type
The RmiRecExitReason enumeration represents the reason for a REC exit.
The RmiRecExitReason enumeration is a concrete type.
The width of the RmiRecExitReason enumeration is 8 bits.
The values of the RmiRecExitReason enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_EXIT_SYNC | REC exit due to synchronous exception |
| 1 | RMI_EXIT_IRQ | REC exit due to IRQ |
| 2 | RMI_EXIT_FIQ | REC exit due to FIQ |
| 3 | RMI_EXIT_PSCI | REC exit due to PSCI |
| 4 | RMI_EXIT_RIPAS_CHANGE | REC exit due to RIPAS change pending |
| 5 | RMI_EXIT_HOST_CALL | REC exit due to Host call |
| 6 | RMI_EXIT_SERROR | REC exit due to SError |
| 7 | RMI_EXIT_DEV_COMMRMI_EXIT_S2AP_CHANGE | REC exit due to device communicationS2AP change pending |
| 8 | RMI_EXIT_RTT_REQUESTRMI_EXIT_VDEV_REQUEST | REC exit due to RTTVDEV request |
| 9 | RMI_EXIT_S2AP_CHANGERMI_EXIT_VDEV_COMM | REC exit due to S2AP change pendingVDEV communication |
| 10 | RMI_EXIT_VDEV_REQUESTRMI_EXIT_DEV_MEM_MAP | REC exit due to VDEV requestdevice memory mapping validation |
Unused encodings for the RmiRecExitReason enumeration are reserved for use by future versions of this specification.
The RmiRecExitReason enumeration is used in the following types:
15.4.35 RmiRecMpidr type
The RmiRecMpidr fieldset contains MPIDR value which identifies a REC.
The RmiRecMpidr fieldset is a concrete type.
The width of the RmiRecMpidr fieldset is 64 bits.
The fields of the RmiRecMpidr fieldset are shown in the following diagram.
The fields of the RmiRecMpidr fieldset are shown in the following table.
The RmiRecMpidr fieldset is used in the following types:
15.4.36 RmiRecParams type
The RmiRecParams structure contains parameters provided by the Host during REC creation.
The RmiRecParams structure is a concrete type.
The width of the RmiRecParams structure is 4096 (0x1000)
bytes.
The number of valid entries in the aux array is
determined by the return value from the RMI_REC_AUX_COUNT command.
See also:
- Section 15.3.2927
The members of the RmiRecParams structure are shown in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| flags | 0x0 |
RmiRecCreateFlags | Flags |
| mpidr | 0x100 |
RmiRecMpidr | MPIDR of the REC |
| pc | 0x200 |
Bits64 | Program counter |
| gprs[8] | 0x300 |
Bits64 | General-purpose registers |
| num_aux | 0x800 |
UInt64 | Number of auxiliary Granules |
| aux[16] | 0x808 |
Address | Addresses of auxiliary Granules |
Unused bits of the RmiRecParams structure SBZ.
15.4.37 RmiRecRun type
The RmiRecRun structure contains fields used to share information between RMM and Host during REC entry and REC exit.
The RmiRecRun structure is a concrete type.
The width of the RmiRecRun structure is 4096 (0x1000)
bytes.
The members of the RmiRecRun structure are shown in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| enter | 0x0 |
RmiRecEnter | Entry information |
| exit | 0x800 |
RmiRecExit | Exit information |
15.4.38 RmiRecRunnable type
The RmiRecRunnable enumeration represents whether a REC is eligible for execution.
The RmiRecRunnable enumeration is a concrete type.
The width of the RmiRecRunnable enumeration is 1 bits.
The values of the RmiRecRunnable enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_NOT_RUNNABLE | Not eligible for execution. |
| 1 | RMI_RUNNABLE | Eligible for execution. |
The RmiRecRunnable enumeration is used in the following types:
15.4.39 RmiResponse type
The RmiResponse enumeration represents whether the Host accepted or rejected a Realm request.
The RmiResponse enumeration is a concrete type.
The width of the RmiResponse enumeration is 1 bits.
The values of the RmiResponse enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_ACCEPT | Host accepted the Realm request. |
| 1 | RMI_REJECT | Host rejected the Realm request. |
The RmiResponse enumeration is used in the following types:
15.4.40 RmiRipas type
The RmiRipas enumeration represents realm IPA state.
The RmiRipas enumeration is a concrete type.
The width of the RmiRipas enumeration is 8 bits.
The values of the RmiRipas enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_EMPTY | Address where no Realm resources are mapped. |
| 1 | RMI_RAM | Address where private code or data owned by the Realm is mapped. |
| 2 | RMI_DESTROYED | Address which is inaccessible to the Realm due to an action taken by the Host. |
| 3 | RMI_DEV | Address where memory of an assigned Realm device is mapped. |
Unused encodings for the RmiRipas enumeration are reserved for use by future versions of this specification.
The RmiRipas enumeration is used in the following types:
15.4.41 RmiRttEntryState type
The RmiRttEntryState enumeration represents the state of an RTTE.
The RmiRttEntryState enumeration is a concrete type.
The width of the RmiRttEntryState enumeration is 8 bits.
The values of the RmiRttEntryState enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_UNASSIGNED | This RTTE is not associated with any Granule. |
| 1 | RMI_ASSIGNED | The output address of this RTTE points to:
|
| 2 | RMI_TABLE | The output address of this RTTE points to the next-level RTT. |
| 3 | RMI_ASSIGNED_DEV | The output address of this RTTE points to an DEV_MAPPED Granule. |
| 4 | RMI_AUX_DESTROYED | An auxiliary RTT was destroyed. |
| 5 | RMI_ASSIGNED_VSMMU | The output address of this RTTE points to a VSMMU Granule. |
Unused encodings for the RmiRttEntryState enumeration are reserved for use by future versions of this specification.
15.4.42 RmiRttPlaneFeature type
The RmiRttPlaneFeature enumeration represents RTT usage models supported for multi-Plane Realms.
The RmiRttPlaneFeature enumeration is a concrete type.
The width of the RmiRttPlaneFeature enumeration is 2 bits.
See also:
- Section 3.11
The values of the RmiRttPlaneFeature enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_RTT_PLANE_AUX | A multi-Plane Realm uses auxiliary RTTs |
| 1 | RMI_RTT_PLANE_AUX_SINGLE | A multi-Plane Realm can be configured to either use auxiliary RTTs, or a single RTT |
| 2 | RMI_RTT_PLANE_SINGLE | A multi-Plane Realm uses a single RTT |
Unused encodings for the RmiRttPlaneFeature enumeration are reserved for use by future versions of this specification.
The RmiRttPlaneFeature enumeration is used in the following types:
15.4.43 RmiSignatureAlgorithmRmiRttS2APEncoding type
The RmiSignatureAlgorithmRmiRttS2APEncoding enumeration represents signature algorithmS2AP encoding.
The RmiSignatureAlgorithmRmiRttS2APEncoding enumeration is a concrete type.
The width of the RmiSignatureAlgorithmRmiRttS2APEncoding enumeration is 81 bits.
The values of the RmiSignatureAlgorithmRmiRttS2APEncoding enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_SIG_RSASSA_3072RMI_S2AP_DIRECT | SSA-3072 (RSA Cryptography Specifications Version 2S2AP direct encoding.2 [21]) |
| 1 | RMI_SIG_ECDSA_P256RMI_S2AP_INDIRECT | ECDSA-P256 (Deterministic Usage of the Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA) [22])S2AP indirect encoding. |
Unused encodings for the RmiSignatureAlgorithmThe RmiRttS2APEncoding enumeration are reserved for use by future versions of this specification. The RmiSignatureAlgorithm enumeration is used in the following types:
- RmiPublicKeyParamsRmiRealmFlags1
15.4.44 RmiSmmuAction RmiSignatureAlgorithm type
The RmiSmmuActionRmiSignatureAlgorithm enumeration represents action required by Host in response to an SMMU interruptsignature algorithm.
The RmiSmmuActionRmiSignatureAlgorithm enumeration is a concrete type.
The width of the RmiSmmuActionRmiSignatureAlgorithm enumeration is 18 bits.
The values of the RmiSmmuActionRmiSignatureAlgorithm enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_SMMU_ACTION_NONERMI_SIG_RSASSA_3072 | No action requiredSSA-3072 (RSA Cryptography Specifications Version 2.2 [21]) |
| 1 | RMI_SMMU_ACTION_VIRQRMI_SIG_ECDSA_P256 | Inject a virtual interrupt into a RealmECDSA-P256 (Deterministic Usage of the Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA) [22]) |
| 2 | RMI_SIG_ECDSA_P384 | ECDSA-P384 (Deterministic Usage of the Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA) [22]) |
Unused encodings for the RmiSignatureAlgorithm enumeration are reserved for use by future versions of this specification.
The RmiSignatureAlgorithm enumeration is used in the following types:
15.4.45 RmiSmmuIrqRmiSmmuAction type
The RmiSmmuIrqRmiSmmuAction enumeration represents action required by Host in response to an SMMU IRQinterrupt.
The RmiSmmuIrqRmiSmmuAction enumeration is a concrete type.
The width of the RmiSmmuIrqRmiSmmuAction enumeration is 21 bits.
The values of the RmiSmmuIrqRmiSmmuAction enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_SMMU_IRQ_GERRORRMI_SMMU_ACTION_NONE | GERROR interruptNo action required. |
| 1 | RMI_SMMU_IRQ_EVENTQRMI_SMMU_ACTION_VIRQ | EVENTQInject a virtual interrupt into a Realm. |
15.4.46 RmiStatusCodeRmiSmmuIrq type
The RmiStatusCodeRmiSmmuIrq enumeration represents the status of an RMI operationSMMU IRQ.
The RmiStatusCodeRmiSmmuIrq enumeration is a concrete type.
The width of the RmiStatusCodeRmiSmmuIrq enumeration is 82 bits.
The values of the RmiSmmuIrq enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_SMMU_IRQ_GERROR | GERROR interrupt. |
| 1 | RMI_SMMU_IRQ_EVENTQ | EVENTQ interrupt. |
| 2 | RMI_SMMU_IRQ_PRIQ | PRIQ interrupt. |
Unused encodings for the RmiSmmuIrq enumeration are reserved for use by future versions of this specification.
15.4.47 RmiStatusCode type
The RmiStatusCode enumeration represents the status of an RMI operation.
The RmiStatusCode enumeration is a concrete type.
The width of the RmiStatusCode enumeration is 8 bits.
The values of the RmiStatusCode enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_SUCCESS | Command completed successfully |
| 1 | RMI_ERROR_INPUT | The value of a command input value caused the command to fail |
| 2 | RMI_ERROR_REALM | An attribute of a Realm does not match the expected value |
| 3 | RMI_ERROR_REC | An attribute of a REC does not match the expected value |
| 4 | RMI_ERROR_RTT | An RTT walk terminated before reaching the target RTT level, or reached an RTTE with an unexpected value |
| 5 | RMI_ERROR_NOT_SUPPORTED | The command is not supported |
| 6 | RMI_ERROR_DEVICE | An attribute of a device does not match the expected value |
| 7 | RMI_ERROR_RTT_AUX | RTTE in an auxiliary RTT contained an unexpected value |
Unused encodings for the RmiStatusCode enumeration are reserved for use by future versions of this specification.
The RmiStatusCode enumeration is used in the following types:
15.4.47 RmiTrap type The RmiTrap enumeration represents whether a trap is enabled. The RmiTrap enumeration is a concrete type. The width of the RmiTrap enumeration is 1 bits. The values of the RmiTrap enumeration are shown in the following table. Encoding Name Description 0 RMI_NO_TRAP Trap is disabled. 1 RMI_TRAP Trap is enabled. The RmiTrap enumeration is used in the following types: RmiRecEnterFlags15.4.48 RmiVdevActionRmiTrap type
The RmiVdevActionRmiTrap enumeration represents realm action which triggered REC exit due to device communicationwhether a trap is enabled.
The RmiVdevActionRmiTrap enumeration is a concrete type.
The width of the RmiVdevActionRmiTrap enumeration is 81 bits.
The values of the RmiVdevActionRmiTrap enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RMI_VDEV_ACTION_GET_INTERFACE_REPORTRMI_NO_TRAP | Exit triggered by RSI_RDEV_GET_INTERFACE_REPORTTrap is disabled. |
| 1 | RMI_VDEV_ACTION_GET_MEASUREMENTSRMI_TRAP | Exit triggered by RSI_RDEV_GET_MEASUREMENTSTrap is enabled. |
Unused encodings for the RmiVdevActionThe RmiTrap enumeration are reserved for use by future versions of this specification. The RmiVdevAction enumeration is used in the following types:
- RmiRecExitRmiRecEnterFlags
15.4.49 RmiVdevFlagsRmiVdevAction type
The RmiVdevFlags fieldset contains flags provided by the Host during RmiVdevAction enumeration represents realm action which triggered REC exit due to VDEV creationcommunication.
The RmiVdevFlags fieldsetRmiVdevAction enumeration is a concrete type.
The width of the RmiVdevFlags fieldset is 64RmiVdevAction enumeration is 8 bits.
The fields of the RmiVdevFlags fieldsetvalues of the RmiVdevAction enumeration are shown in the following diagram. The fields of the RmiVdevFlags fieldset are shown in the following table.
| Encoding | Name | BitsDescription | Value
|---|---|---|
| 0 | Whether device uses a VSMMURMI_VDEV_ACTION_GET_INTERFACE_REPORT | RmiFeatureExit triggered by RSI_RDEV_GET_INTERFACE_REPORT |
| 1 | 63:1RMI_VDEV_ACTION_GET_MEASUREMENTS | ReservedExit triggered by RSI_RDEV_GET_MEASUREMENTS |
| SBZ2 | RMI_VDEV_ACTION_LOCK | Exit triggered by RSI_RDEV_LOCK |
| 3 | RMI_VDEV_ACTION_START | Exit triggered by RSI_RDEV_START |
| 4 | RMI_VDEV_ACTION_STOP | Exit triggered by RSI_RDEV_STOP |
The RmiVdevFlags fieldsetUnused encodings for the RmiVdevAction enumeration are reserved for use by future versions of this specification.
The RmiVdevAction enumeration is used in the following types:
- RmiVdevParamsRmiRecExit
15.4.50 RmiVdevParamsRmiVdevFlags type
The RmiVdevParams structureRmiVdevFlags fieldset contains parametersflags provided by the Host during VDEV creation.
The RmiVdevParams structureRmiVdevFlags fieldset is a concrete type.
The width of the RmiVdevParams structure is 4096 (0x1000) bytesRmiVdevFlags fieldset is 64 bits.
The members of the RmiVdevParams structurefields of the RmiVdevFlags fieldset are shown in the following diagram.
The fields of the RmiVdevFlags fieldset are shown in the following table.
| Name | Byte offsetBits | TypeDescription | Value |
|---|---|---|---|
| flagsVSMMU | 0x00 | RmiVdevFlagsWhether device uses a VSMMU | RmiFeature |
| Flags | 63:1 | Reserved | SBZ |
The RmiVdevFlags fieldset is used in the following types:
- RmiVdevParams Virtual device identifier For a PCIe device this is the PCIe routing identifier of the virtual endpoint. tdi_id 0x10 Bits64 TDI identifier num_aux 0x18 UInt64 Number of auxiliary Granules vsmmu_addr 0x20 Address PA of VSMMU. This field is ignored unless flags.VSMMU is RMI_TRUE. vsid 0x28 Bits64 Virtual Stream Identifier. This field is ignored unless flags.VSMMU is RMI_TRUE. aux[32] 0x100 Address Addresses of auxiliary Granules Unused bits of the RmiVdevParams structure SBZ.
15.4.51 RmiVdevStateRmiVdevParams type
The RmiVdevState enumeration represents the state of aRmiVdevParams structure contains parameters provided by the Host during VDEV creation.
The RmiVdevState enumerationRmiVdevParams structure is a concrete type.
The width of the RmiVdevState enumeration is 8 bitsRmiVdevParams structure is 4096
(0x1000) bytes.
The values of the RmiVdevState enumerationmembers of the RmiVdevParams structure are shown in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| 0flags | RMI_VDEV_READY0x0 |
NoRmiVdevFlags | Flags |
| vdev_id | 0x8 |
Bits64 | Virtual device transaction is associated with the VDEVidentifier For a PCIe device this is the PCIe routing identifier of the virtual endpoint. |
| tdi_id | 0x10 |
Bits64 | TDI identifier |
| 1num_aux | RMI_VDEV_COMMUNICATING0x18 |
The RMM is communicating with the VDEVUInt64 | Number of auxiliary Granules |
| vsmmu_addr | 0x20 |
Address | PA of VSMMU. This field is ignored unless flags.VSMMU is RMI_TRUE. |
| vsid | 0x28 |
Bits64 | Virtual Stream Identifier. This field is ignored unless flags.VSMMU is RMI_TRUE. |
| 2aux[32] | RMI_VDEV_STOPPING0x100 |
The RMM is communicating with the VDEV to stop the device interface.Address | Addresses of auxiliary Granules |
Unused encodings for the RmiVdevState enumeration are reserved for use by future versions of this specificationbits of the RmiVdevParams structure SBZ.
15.4.52 RmiVsmmuFlagsRmiVdevState type
The RmiVsmmuFlags fieldset contains flags provided by the Host during PDEV creationRmiVdevState enumeration represents the state of a VDEV.
The RmiVsmmuFlags fieldsetRmiVdevState enumeration is a concrete type.
The width of the RmiVsmmuFlags fieldset is 64RmiVdevState enumeration is 8 bits.
The fields of the RmiVsmmuFlags fieldsetvalues of the RmiVdevState enumeration are shown in the following diagram. The fields of the RmiVsmmuFlags fieldset are shown in the following table.
| Encoding | Name | BitsDescription | Value
|---|---|---|
| 0 | 63:0RMI_VDEV_NEW | ReservedInitial state of the device. |
| SBZ1 | RMI_VDEV_READY | No device transaction is associated with the VDEV. |
| 2 | RMI_VDEV_COMMUNICATING | The RMM is communicating with the VDEV. |
| 3 | RMI_VDEV_STOPPING | The RMM is communicating with the VDEV to stop the device interface. |
| 4 | RMI_VDEV_STOPPED | Device interface is stopped. |
| 5 | RMI_VDEV_ERROR | Device interface has reported a fatal error. |
The RmiVsmmuFlags fieldset is used in the following types:Unused encodings for the RmiVdevState enumeration are reserved for use by future versions of this specification.
RmiVsmmuParams15.4.53 RmiVsmmuParamsRmiVsmmuFlags type
The RmiVsmmuParams structureRmiVsmmuFlags fieldset contains parametersflags provided by the Host during VSMMU PDEV creation.
The RmiVsmmuParams structureRmiVsmmuFlags fieldset is a concrete type.
The width of the RmiVsmmuFlags fieldset is 64 bits.
The fields of the RmiVsmmuFlags fieldset are shown in the following diagram.
The fields of the RmiVsmmuFlags fieldset are shown in the following table.
| Name | Bits | Description | Value |
|---|---|---|---|
| 63:0 | Reserved | SBZ |
The RmiVsmmuFlags fieldset is used in the following types:
15.4.54 RmiVsmmuParams type
The RmiVsmmuParams structure contains parameters provided by the Host during VSMMU creation.
The RmiVsmmuParams structure is a concrete type.
The width of the RmiVsmmuParams structure is 4096
(0x1000) bytes.
The members of the RmiVsmmuParams structure are shown in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| flags | 0x0 |
RmiVsmmuFlags | Flags |
| reg_base | 0x8 |
Address | Base IPA of register base in Realm’s Protected IPA space |
| reg_top | 0x10 |
Address | Top IPA of register base in Realm’s Protected IPA space |
| aidr | 0x18 |
Bits64 | SMMU_AIDR register value |
| idr[7] | 0x20 |
Bits64 | SMMU_IDR |
Unused bits of the RmiVsmmuParams structure SBZ.
16 Realm Services Interface
This chapter defines the interface used by Realm software to request services from the RMM.
16.1 RSI version
This specification defines version 1.1 of the Realm Services Interface.
16.2 RSI command return codes
An RSI command return code indicates whether the command
- succeeded, or
- failed, and the reason for the failure.
If an RSI command succeeds then it returns RSI_SUCCESS.
Multiple failure conditions in an RSI command may return the same return code.
If an input to an RSI command uses an invalid encoding then the command fails and returns RSI_ERROR_INPUT.
Command inputs include registers and in-memory data structures.
Invalid encodings include:
- using a reserved encoding in an enumeration
See also:
- Section 16.4.2
16.3 RSI commands
The following table summarizes the FIDs of commands in the RSI interface.
| FID | Command |
|---|---|
0xC4000190 |
RSI_VERSION |
0xC4000191 |
RSI_FEATURES |
0xC4000192 |
RSI_MEASUREMENT_READ |
0xC4000193 |
RSI_MEASUREMENT_EXTEND |
0xC4000194 |
RSI_ATTESTATION_TOKEN_INIT |
0xC4000195 |
RSI_ATTESTATION_TOKEN_CONTINUE |
0xC4000196 |
RSI_REALM_CONFIG |
0xC4000197 |
RSI_IPA_STATE_SET |
0xC4000198 |
RSI_IPA_STATE_GET |
0xC4000199 |
RSI_HOST_CALL |
0xC400019A |
RSI_VSMMU_GET_INFO |
0xC400019B |
RSI_VSMMU_ACTIVATE |
0xC400019C |
RSI_RDEV_GET_INSTANCE_ID |
| … | |
0xC40001A0 |
RSI_MEM_GET_PERM_VALUE |
0xC40001A1 |
RSI_MEM_SET_PERM_INDEX |
0xC40001A2 |
RSI_MEM_SET_PERM_VALUE |
0xC40001A3 |
RSI_PLANE_ENTER |
0xC40001A4 |
RSI_RDEV_CONTINUE |
0xC40001A5 |
RSI_RDEV_GET_INFO |
0xC40001A6 |
RSI_RDEV_GET_INTERFACE_REPORT |
0xC40001A7 |
RSI_RDEV_GET_MEASUREMENTS |
0xC40001A8 |
RSI_RDEV_GET_STATE |
0xC40001A9 |
RSI_RDEV_LOCK |
0xC40001AA |
RSI_RDEV_START |
0xC40001AB |
RSI_RDEV_STOP |
0xC40001AC |
RSI_RDEV_VALIDATE_MAPPING |
| … | |
0xC40001AE |
RSI_PLANE_REG_READ |
0xC40001AF |
RSI_PLANE_REG_WRITE |
16.3.1 RSI_ATTESTATION_TOKEN_CONTINUE command
Continue the operation to retrieve an attestation token.
16.3.1.1 Interface
16.3.1.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000195 |
| addr | X1 | 63:0 | Address | IPA of the Granule to which the token will be written |
| offset | X2 | 63:0 | UInt64 | Offset within Granule to start of buffer in bytes |
| size | X3 | 63:0 | UInt64 | Size of buffer in bytes |
16.3.1.1.2 Context
The RSI_ATTESTATION_TOKEN_CONTINUE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
| rec | RmmRec | CurrentRec() |
false | Current REC |
| walk | RmmRttWalkResult | RttWalk( realm, addr, RMM_RTT_PAGE_LEVEL, RMM_RTT_TREE_PRIMARY) |
false | RTT walk result |
16.3.1.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
| len | X1 | 63:0 | UInt64 | Number of bytes written to buffer |
16.3.1.2 Failure conditions
| ID | Condition |
|---|---|
| addr_align | pre: !AddrIsGranuleAligned(addr) post: result == RSI_ERROR_INPUT |
| addr_bound | pre: !AddrIsProtected(addr, realm) post: result == RSI_ERROR_INPUT |
| addr_empty | pre: walk.rtte.ripas == EMPTY post: result == RSI_ERROR_INPUT |
| offset_bound | pre: offset >= RMM_GRANULE_SIZE post: result == RSI_ERROR_INPUT |
| size_overflow | pre: offset + size < offset post: result == RSI_ERROR_INPUT |
| size_bound | pre: offset + size > RMM_GRANULE_SIZE post: result == RSI_ERROR_INPUT |
| state | pre: rec.attest_state != ATTEST_IN_PROGRESS post: result == RSI_ERROR_STATE |
| unknown | pre: Token generation failed for an unknown or IMPDEF reason. post: result == RSI_ERROR_UNKNOWN |
16.3.1.2.1 Failure condition ordering
The RSI_ATTESTATION_TOKEN_CONTINUE command does not have any failure condition orderings.
16.3.1.3 Success conditions
| ID | Condition |
|---|---|
| incomplete | pre: Token generation is not complete. post: result == RSI_INCOMPLETE |
| complete | pre: Token generation is complete. post: rec.attest_state == NO_ATTEST_IN_PROGRESS |
16.3.1.4 Footprint
| ID | Value |
|---|---|
| state | rec.attest_state |
16.3.2 RSI_ATTESTATION_TOKEN_INIT command
Initialize the operation to retrieve an attestation token.
16.3.2.1 Interface
16.3.2.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000194 |
| challenge_0 | X1 | 63:0 | Bits64 | Doubleword 0 of the challenge value |
| challenge_1 | X2 | 63:0 | Bits64 | Doubleword 1 of the challenge value |
| challenge_2 | X3 | 63:0 | Bits64 | Doubleword 2 of the challenge value |
| challenge_3 | X4 | 63:0 | Bits64 | Doubleword 3 of the challenge value |
| challenge_4 | X5 | 63:0 | Bits64 | Doubleword 4 of the challenge value |
| challenge_5 | X6 | 63:0 | Bits64 | Doubleword 5 of the challenge value |
| challenge_6 | X7 | 63:0 | Bits64 | Doubleword 6 of the challenge value |
| challenge_7 | X8 | 63:0 | Bits64 | Doubleword 7 of the challenge value |
16.3.2.1.2 Context
The RSI_ATTESTATION_TOKEN_INIT command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
| rec | RmmRec | CurrentRec() |
false | Current REC |
16.3.2.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
| size | X1 | 63:0 | UInt64 | Upper bound on attestation token size in bytes |
16.3.2.2 Failure conditions
The RSI_ATTESTATION_TOKEN_INIT command does not have any failure conditions.
16.3.2.3 Success conditions
| ID | Condition |
|---|---|
| state | rec.attest_state == ATTEST_IN_PROGRESS |
| challenge |
rec.attest_challenge == [
challenge_0,
challenge_1,
challenge_2,
challenge_3,
challenge_4,
challenge_5,
challenge_6,
challenge_7
]
|
16.3.2.4 Footprint
| ID | Value |
|---|---|
| state | rec.attest_state |
| challenge | rec.attest_challenge |
16.3.3 RSI_FEATURES command
Read feature register.
The following table indicates which feature register is returned depending on the index provided.
| Index | Feature register |
|---|---|
| 0 | RSI feature register 0 |
See also:
- Section 3
16.3.3.1 Interface
16.3.3.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000191 |
| index | X1 | 63:0 | UInt64 | Feature register index |
16.3.3.1.2 Output valuesContext
The RSI_FEATURES command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
16.3.3.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
| value | X1 | 63:0 | Bits64 | Feature register value |
16.3.3.2 Failure conditions
The RSI_FEATURES command does not have any failure conditions.
16.3.3.3 Success conditions
| ID | Condition |
|---|---|
| value | value == RsiFeatureRegisterEncode(realm, index) |
16.3.3.4 Footprint
The RSI_FEATURES command does not have any footprint.
16.3.4 RSI_HOST_CALL command
Make a Host call.
16.3.4.1 Interface
16.3.4.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000199 |
| addr | X1 | 63:0 | Address | IPA of the Host call data structure |
16.3.4.1.2 Context
The RSI_HOST_CALL command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
| rec | RmmRec | CurrentRec() |
false | Current REC |
| data | RsiHostCall | RsiHostCallAt(addr) |
false | Host call data structure |
| walk | RmmRttWalkResult | RttWalk( realm, addr, RMM_RTT_PAGE_LEVEL, RMM_RTT_TREE_PRIMARY) |
false | RTT walk result |
16.3.4.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
16.3.4.2 Failure conditions
| ID | Condition |
|---|---|
| addr_align | pre: !AddrIsAligned(addr, 256) post: result == RSI_ERROR_INPUT |
| addr_bound | pre: !AddrIsProtected(addr, realm) post: result == RSI_ERROR_INPUT |
| addr_empty | pre: walk.rtte.ripas == EMPTY post: result == RSI_ERROR_INPUT |
16.3.4.2.1 Failure condition ordering
The RSI_HOST_CALL command does not have any failure condition orderings.
16.3.4.3 Success conditions
The RSI_HOST_CALL command does not have any success conditions.
16.3.4.4 Footprint
| ID | Value |
|---|---|
| pendinggprs | recdata.pendinggprs |
16.3.5 RSI_IPA_STATE_GET command
Get RIPAS of a target IPA range.
16.3.5.1 Interface
16.3.5.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000198 |
| base | X1 | 63:0 | Address | Base of target IPA region |
| top | X2 | 63:0 | Address | End of target IPA region |
16.3.5.1.2 Context
The RSI_IPA_STATE_GET command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
16.3.5.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
| out_top | X1 | 63:0 | Address | Top of IPA region which has the reported RIPAS value |
| ripas | X2 | 7:0 | RsiRipas | RIPAS value |
The following unused bits of RSI_IPA_STATE_GET output values MBZ: X2[63:8].
If result == RSI_SUCCESS then all of the following are
true:
out_top > baseout_top <= top- All addresses within the range
[base, out_top)have the RIPAS valueripas.
Note that the RIPAS of a Protected IPA can change at any time to DESTROYED without the Realm taking any action.
See also:
- Section 5.2.6
16.3.5.2 Failure conditions
| ID | Condition |
|---|---|
| base_align | pre: !AddrIsGranuleAligned(base) post: result == RSI_ERROR_INPUT |
| end_align | pre: !AddrIsGranuleAligned(top) post: result == RSI_ERROR_INPUT |
| size_valid | pre: UInt(top) <= UInt(base) post: result == RSI_ERROR_INPUT |
| rgn_bound | pre: !AddrRangeIsProtected(base, top, realm) post: result == RSI_ERROR_INPUT |
16.3.5.2.1 Failure condition ordering
The RSI_IPA_STATE_GET command does not have any failure condition orderings.
16.3.5.3 Success conditions
The RSI_IPA_STATE_GET command does not have any success conditions.
16.3.5.4 Footprint
The RSI_IPA_STATE_GET command does not have any footprint.
16.3.6 RSI_IPA_STATE_SET command
Request RIPAS of a target IPA range to be changed to a specified value.
16.3.6.1 Interface
16.3.6.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000197 |
| base | X1 | 63:0 | Address | Base of target IPA region |
| top | X2 | 63:0 | Address | Top of target IPA region |
| ripas | X3 | 7:0 | RsiRipas | RIPAS value |
| flags | X4 | 63:0 | RsiRipasChangeFlags | Flags |
The following unused bits of RSI_IPA_STATE_SET input values SBZ: X3[63:8].
16.3.6.1.2 Context
The RSI_IPA_STATE_SET command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
| rec | RmmRec | CurrentRec() |
false | Current REC |
16.3.6.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
| new_base | X1 | 63:0 | Address | Base of IPA region which was not modified by the command |
| response | X2 | 0:0 | RsiResponse | Whether the Host accepted or rejected the request |
The following unused bits of RSI_IPA_STATE_SET output values MBZ: X2[63:1].
If the Host rejects the request then:
result == RSI_SUCCESSnew_base == baseresponse == RSI_REJECT
16.3.6.2 Failure conditions
| ID | Condition |
|---|---|
| base_align | pre: !AddrIsGranuleAligned(base) post: result == RSI_ERROR_INPUT |
| top_align | pre: !AddrIsGranuleAligned(top) post: result == RSI_ERROR_INPUT |
| size_valid | pre: UInt(top) <= UInt(base) post: result == RSI_ERROR_INPUT |
| rgn_bound | pre: !AddrRangeIsProtected(base, top, realm) post: result == RSI_ERROR_INPUT |
| ripas_valid | pre: (ripas != RSI_EMPTY) && (ripas != RSI_RAM) post: result == RSI_ERROR_INPUT |
16.3.6.2.1 Failure condition ordering
The RSI_IPA_STATE_SET command does not have any failure condition orderings.
16.3.6.3 Success conditions
| ID | Condition |
|---|---|
| new_base | new_base == rec.ripas_addr |
| response | response == RecRipasResponseToRsi(rec) |
16.3.6.4 Footprint
The RSI_IPA_STATE_SET command does not have any footprint.
16.3.7 RSI_MEASUREMENT_EXTEND command
Extend Realm Extensible Measurement (REM) value.
16.3.7.1 Interface
16.3.7.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000193 |
| index | X1 | 63:0 | UInt64 | Measurement index |
| size | X2 | 63:0 | UInt64 | Measurement size in bytes |
| value_0 | X3 | 63:0 | Bits64 | Doubleword 0 of the measurement value |
| value_1 | X4 | 63:0 | Bits64 | Doubleword 1 of the measurement value |
| value_2 | X5 | 63:0 | Bits64 | Doubleword 2 of the measurement value |
| value_3 | X6 | 63:0 | Bits64 | Doubleword 3 of the measurement value |
| value_4 | X7 | 63:0 | Bits64 | Doubleword 4 of the measurement value |
| value_5 | X8 | 63:0 | Bits64 | Doubleword 5 of the measurement value |
| value_6 | X9 | 63:0 | Bits64 | Doubleword 6 of the measurement value |
| value_7 | X10 | 63:0 | Bits64 | Doubleword 7 of the measurement value |
16.3.7.1.2 Context
The RSI_MEASUREMENT_EXTEND command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
| realm_pre | RmmRealm | CurrentRealm() |
true | Current Realm |
| meas_pre | RmmRealmMeasurement |
realm_pre.measurements[
index]
|
true | Previous measurement value |
16.3.7.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
16.3.7.2 Failure conditions
| ID | Condition |
|---|---|
| index_bound | pre: index < 1 || index > 4 post: result == RSI_ERROR_INPUT |
| size_bound | pre: size > 64 post: result == RSI_ERROR_INPUT |
16.3.7.2.1 Failure condition ordering
The RSI_MEASUREMENT_EXTEND command does not have any failure condition orderings.
16.3.7.3 Success conditions
| ID | Condition |
|---|---|
| realm_meas | realm.measurements[index] == RemExtend( realm.hash_algo, meas_pre, [value_0, value_1, value_2, value_3, value_4, value_5, value_6, value_7][ (RMM_REALM_MEASUREMENT_WIDTH-1):0], size * 8) |
16.3.7.4 Footprint
| ID | Value |
|---|---|
| realm_meas | realm.measurements[index] |
16.3.8 RSI_MEASUREMENT_READ command
Read measurement for the current Realm.
16.3.8.1 Interface
16.3.8.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000192 |
| index | X1 | 63:0 | UInt64 | Measurement index |
index 0 selects the RIM. An index of 1 or
greater selects the corresponding REM.
16.3.8.1.2 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
| value_0 | X1 | 63:0 | Bits64 | Doubleword 0 of the Realm measurement identified by “index” |
| value_1 | X2 | 63:0 | Bits64 | Doubleword 1 of the Realm measurement identified by “index” |
| value_2 | X3 | 63:0 | Bits64 | Doubleword 2 of the Realm measurement identified by “index” |
| value_3 | X4 | 63:0 | Bits64 | Doubleword 3 of the Realm measurement identified by “index” |
| value_4 | X5 | 63:0 | Bits64 | Doubleword 4 of the Realm measurement identified by “index” |
| value_5 | X6 | 63:0 | Bits64 | Doubleword 5 of the Realm measurement identified by “index” |
| value_6 | X7 | 63:0 | Bits64 | Doubleword 6 of the Realm measurement identified by “index” |
| value_7 | X8 | 63:0 | Bits64 | Doubleword 7 of the Realm measurement identified by “index” |
If the size of the measurement value is smaller than 512 bits, the output values are padded with zeroes.
16.3.8.2 Failure conditions
| ID | Condition |
|---|---|
| index_bound | pre: index > 4 post: result == RSI_ERROR_INPUT |
16.3.8.3 Success conditions
The RSI_MEASUREMENT_READ command does not have any success conditions.
16.3.8.4 Footprint
The RSI_MEASUREMENT_READ command does not have any footprint.
16.3.9 RSI_MEM_GET_PERM_VALUE command
Get overlay permission value for a specified (plane index, overlay permission index) tuple.
See also:
- Section 10.3.2
16.3.9.1 Interface
16.3.9.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001A0 |
| plane_index | X1 | 63:0 | UInt64 | Plane index |
| perm_index | X2 | 63:0 | UInt64 | Permission index |
16.3.9.1.2 Context
The RSI_MEM_GET_PERM_VALUE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
16.3.9.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
| value | X1 | 63:0 | Bits64 | Memory permission value |
16.3.9.2 Failure conditions
| ID | Condition |
|---|---|
| plane_bound | pre: plane_index > realm.num_aux_planes post: result == RSI_ERROR_INPUT |
| perm_bound |
pre: perm_index >=
RMM_NUM_PERM_OVERLAY_INDICES
post: result == RSI_ERROR_INPUT
|
16.3.9.2.1 Failure condition ordering
The RSI_MEM_GET_PERM_VALUE command does not have any failure condition orderings.
16.3.9.3 Success conditions
| ID | Condition |
|---|---|
| label | value == realm.overlay_perms[plane_index].values[perm_index] |
16.3.9.4 Footprint
The RSI_MEM_GET_PERM_VALUE command does not have any footprint.
16.3.10 RSI_MEM_SET_PERM_INDEX command
Set overlay permission index for a specified IPA range.
See also:
- Section 10.3.2
16.3.10.1 Interface
16.3.10.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001A1 |
| base | X1 | 63:0 | Address | Base of target IPA region |
| top | X2 | 63:0 | Address | Top of target IPA region |
| perm_index | X3 | 63:0 | UInt64 | Permission index |
| cookie | X4 | 63:0 | Bits64 | Cookie value |
16.3.10.1.2 Context
The RSI_MEM_SET_PERM_INDEX command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
| rec | RmmRec | CurrentRec() |
false | Current REC |
16.3.10.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
| new_base | X1 | 63:0 | Address | Base of IPA region which was not modified by the command |
| response | X2 | 0:0 | RsiResponse | Whether the Host accepted or rejected the request |
| new_cookie | X3 | 63:0 | Bits64 | New cookie value |
The following unused bits of RSI_MEM_SET_PERM_INDEX output values MBZ: X2[63:1].
16.3.10.2 Failure conditions
| ID | Condition |
|---|---|
| base_align | pre: !AddrIsGranuleAligned(base) post: result == RSI_ERROR_INPUT |
| top_align | pre: !AddrIsGranuleAligned(top) post: result == RSI_ERROR_INPUT |
| size_valid | pre: UInt(top) <= UInt(base) post: result == RSI_ERROR_INPUT |
| rgn_bound | pre: !AddrRangeIsProtected(base, top, realm) post: result == RSI_ERROR_INPUT |
| perm_bound |
pre: perm_index >=
RMM_NUM_PERM_OVERLAY_INDICES
post: result == RSI_ERROR_INPUT
|
| cookie | pre: Cookie is invalid post: result == RSI_ERROR_INPUT |
16.3.10.2.1 Failure condition ordering
The RSI_MEM_SET_PERM_INDEX command does not have any failure condition orderings.
16.3.10.3 Success conditions
| ID | Condition |
|---|---|
| locked | realm.overlay_locked[perm_index] == MEM_PERM_LOCKED |
| new_base | new_base == rec.s2ap_addr |
| response | response == RecS2APResponseToRsi(rec) |
16.3.10.4 Footprint
The RSI_MEM_SET_PERM_INDEX command does not have any footprint.
16.3.11 RSI_MEM_SET_PERM_VALUE command
Set overlay permission value for a specified (plane index, overlay permission index) tuple.
See also:
- Section 10.3.2
16.3.11.1 Interface
16.3.11.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001A2 |
| plane_index | X1 | 63:0 | UInt64 | Plane index |
| perm_index | X2 | 63:0 | UInt64 | Permission index |
| value | X3 | 63:0 | Bits64 | Memory permission value |
16.3.11.1.2 Context
The RSI_MEM_SET_PERM_VALUE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
16.3.11.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
16.3.11.2 Failure conditions
| ID | Condition |
|---|---|
| plane_bound |
pre: (plane_index == 0
|| plane_index > realm.num_aux_planes)
post: result == RSI_ERROR_INPUT
|
| perm_bound |
pre: perm_index >=
RMM_NUM_PERM_OVERLAY_INDICES
post: result == RSI_ERROR_INPUT
|
| locked | pre: realm.overlay_locked[perm_index] == MEM_PERM_LOCKED post: result == RSI_ERROR_INPUT |
| supported | pre: !MemPermLabelSupported(value) post: result == RSI_ERROR_INPUT |
16.3.11.2.1 Failure condition ordering
The RSI_MEM_SET_PERM_VALUE command does not have any failure condition orderings.
16.3.11.3 Success conditions
| ID | Condition |
|---|---|
| label | realm.overlay_perms[plane_index].values[perm_index] == value |
16.3.11.4 Footprint
The RSI_MEM_SET_PERM_VALUE command does not have any footprint.
16.3.12 RSI_PLANE_ENTER command
Enter a Plane.
16.3.12.1 Interface
16.3.12.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001A3 |
| plane_idx | X1 | 63:0 | UInt64 | Index of target Plane |
| run_ptr | X2 | 63:0 | Address | IPA of PlaneRun object |
16.3.12.1.2 Context
The RSI_PLANE_ENTER command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
| run | RsiPlaneRun | RsiPlaneRunAt( realm, run_ptr) |
false | PlaneRun object |
| walk | RmmRttWalkResult | RttWalk( realm, run_ptr, RMM_RTT_PAGE_LEVEL, RMM_RTT_TREE_PRIMARY) |
false | RTT walk result |
16.3.12.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
16.3.12.2 Failure conditions
| ID | Condition |
|---|---|
| idx_bound |
pre: (plane_idx == 0
|| plane_idx > realm.num_aux_planes)
post: result == RSI_ERROR_INPUT
|
| run_align | pre: !AddrIsGranuleAligned(run_ptr) post: result == RSI_ERROR_INPUT |
| run_bound | pre: !AddrIsProtected(run_ptr, realm) post: result == RSI_ERROR_INPUT |
| run_empty | pre: walk.rtte.ripas == EMPTY post: result == RSI_ERROR_INPUT |
16.3.12.2.1 Failure condition ordering
The RSI_PLANE_ENTER command does not have any failure condition orderings.
16.3.12.3 Success conditions
| ID | Condition |
|---|---|
| plane_exit | run.exit contains Plane exit syndrome information. |
16.3.12.4 Footprint
The RSI_PLANE_ENTER command does not have any footprint.
16.3.13 RSI_PLANE_REG_READ command
Read a Plane register.
See also:
- Section 10.2.6
16.3.13.1 Interface
16.3.13.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001AE |
| plane_idx | X1 | 63:0 | UInt64 | Index of target Plane |
| encoding | X2 | 63:0 | Bits64 | Encoding of target register |
The encoding value is an architecturally-defined system register encoding.
16.3.13.1.2 Context
The RSI_PLANE_REG_READ command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
16.3.13.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
| value | X1 | 63:0 | Bits64 | Value of target register |
16.3.13.2 Failure conditions
| ID | Condition |
|---|---|
| idx_bound | pre: plane_idx > realm.num_aux_planes post: result == RSI_ERROR_INPUT |
| reg_valid | pre: !PlaneRegIsValid(realm, encoding) post: result == RSI_ERROR_INPUT |
16.3.13.2.1 Failure condition ordering
The RSI_PLANE_REG_READ command does not have any failure condition orderings.
16.3.13.3 Success conditions
| ID | Condition |
|---|---|
| value | value == PlaneRegValue(realm, plane_idx, encoding) |
16.3.13.4 Footprint
The RSI_PLANE_REG_READ command does not have any footprint.
16.3.14 RSI_PLANE_REG_WRITE command
Write a Plane register.
See also:
- Section 10.2.6
16.3.14.1 Interface
16.3.14.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001AF |
| plane_idx | X1 | 63:0 | UInt64 | Index of target Plane |
| encoding | X2 | 63:0 | Bits64 | Encoding of target register |
| value | X3 | 63:0 | Bits64 | Value to write to target register |
The encoding value is an architecturally-defined system register encoding.
16.3.14.1.2 Context
The RSI_PLANE_REG_WRITE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
16.3.14.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
16.3.14.2 Failure conditions
| ID | Condition |
|---|---|
| idx_bound | pre: plane_idx > realm.num_aux_planes post: result == RSI_ERROR_INPUT |
| reg_valid | pre: !PlaneRegIsValid(realm, encoding) post: result == RSI_ERROR_INPUT |
16.3.14.2.1 Failure condition ordering
The RSI_PLANE_REG_WRITE command does not have any failure condition orderings.
16.3.14.3 Success conditions
| ID | Condition |
|---|---|
| value | PlaneRegValue(realm, plane_idx, encoding) == value |
16.3.14.4 Footprint
The RSI_PLANE_REG_WRITE command does not have any footprint.
16.3.15 RSI_RDEV_CONTINUE command
Continue an interruptible Realm device operation.
See also:
- Section 9.5.1
16.3.15.1 Interface
16.3.15.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001A4 |
| vdev_id | X1 | 63:0 | Bits64 | Realm device identifier |
| inst_id | X2 | 63:0 | UInt64 | Device instance identifier |
16.3.15.1.2 Context
The RSI_RDEV_CONTINUE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
| rdev | RmmRdev | RdevFromInstId( realm, inst_id) |
false | Realm device |
16.3.15.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
16.3.15.2 Failure conditions
| ID | Condition |
|---|---|
| da_en | pre: realm.feat_da != FEATURE_TRUE post: result == RSI_ERROR_STATE |
| vdev_id | pre: !RdevIdsAreValid(realm, vdev_id, inst_id) post: result == RSI_ERROR_INPUT |
| state | pre: (rdev.state != RDEV_UNLOCKED_BUSY && rdev.state != RDEV_LOCKED_BUSY && rdev.state != RDEV_STARTED_BUSY && rdev.state != RDEV_STOPPING) post: result == RSI_ERROR_INPUT |
16.3.15.2.1 Failure condition ordering
[da_en] < [vdev_id]
[vdev_id] < [state]
16.3.15.3 Success conditions
| ID | Condition |
|---|---|
| error | pre: (DeviceCommunicate(rdev) == DEV_COMM_ERROR && rdev.state != RDEV_STOPPING) post: rdev.state == RDEV_ERROR |
| new | pre: (DeviceCommunicate(rdev) == DEV_COMM_IDLE && rdev.state == RDEV_UNLOCKED_BUSY && rdev.operation != RDEV_OP_LOCK) post: rdev.state == RDEV_UNLOCKED |
| to_locked | pre: (DeviceCommunicate(rdev) == DEV_COMM_IDLE && rdev.state == RDEV_UNLOCKED_BUSY && rdev.operation == RDEV_OP_LOCK) post: rdev.state == RDEV_LOCKED |
| locked | pre: (DeviceCommunicate(rdev) == DEV_COMM_IDLE && rdev.state == RDEV_LOCKED_BUSY && rdev.operation != RDEV_OP_LOCK) post: rdev.state == RDEV_LOCKED |
| to_started | pre: (DeviceCommunicate(rdev) == DEV_COMM_IDLE && rdev.state == RDEV_LOCKED_BUSY && rdev.operation == RDEV_OP_START) post: rdev.state == RDEV_STARTED |
| started | pre: (DeviceCommunicate(rdev) == DEV_COMM_IDLE && rdev.state == RDEV_STARTED_BUSY) post: rdev.state == RDEV_STARTED |
| stopped | pre: (DeviceCommunicate(rdev) != DEV_COMM_ACTIVE && rdev.state == RDEV_STOPPING) post: rdev.state == RDEV_STOPPED |
16.3.15.4 Footprint
| ID | Value |
|---|---|
| state | rdev.state |
16.3.16 RSI_RDEV_GET_INFO command
Get information for a device.
16.3.16.1 Interface
16.3.16.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001A5 |
| vdev_id | X1 | 63:0 | Bits64 | Realm device identifier |
| inst_id | X2 | 63:0 | UInt64 | Device instance identifier |
| addr | X3 | 63:0 | Address | IPA of the Granule to which the configuration data will be written |
16.3.16.1.2 Context
The RSI_RDEV_GET_INFO command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
| rdev | RmmRdev | RdevFromInstId( realm, inst_id) |
false | Realm device |
| vdev | RmmVdev | VdevAt(rdev.vdev_ptr) |
false | Virtual device |
| pdev | RmmPdev | PdevAt(vdev.pdev) |
false | Physical device |
| cfg | RsiDeviceInfo | RsiDeviceInfoAt(addr) |
false | Device configuration |
| walk | RmmRttWalkResult | RttWalk( realm, addr, RMM_RTT_PAGE_LEVEL, RMM_RTT_TREE_PRIMARY) |
false | RTT walk result |
16.3.16.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
16.3.16.2 Failure conditions
| ID | Condition |
|---|---|
| da_en | pre: realm.feat_da != FEATURE_TRUE post: result == RSI_ERROR_STATE |
| vdev_id | pre: !RdevIdsAreValid(realm, vdev_id, inst_id) post: result == RSI_ERROR_INPUT |
| addr_align | pre: !AddrIsGranuleAligned(addr) post: result == RSI_ERROR_INPUT |
| addr_bound | pre: !AddrIsProtected(addr, realm) post: result == RSI_ERROR_INPUT |
| addr_empty | pre: walk.rtte.ripas == EMPTY post: result == RSI_ERROR_INPUT |
16.3.16.2.1 Failure condition ordering
[da_en] < [vdev_id, addr_align, addr_bound]
16.3.16.3 Success conditions
| ID | Condition |
|---|---|
| hash_algo | Equal(cfg.hash_algo, pdev.hash_algo) |
16.3.16.4 Footprint
The RSI_RDEV_GET_INFO command does not have any footprint.
16.3.17 RSI_RDEV_GET_INSTANCE_ID command
Get instance ID for a device.
See also:
- [@#sec:device-assignment:rmm-device-comm:vdev-request]Section 9.2.2
16.3.17.1 Interface
16.3.17.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400019C |
| vdev_id | X1 | 63:0 | Bits64 | Realm device identifier |
16.3.17.1.2 Context
The RSI_RDEV_GET_INSTANCE_ID command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
| rdev | RmmRdev | RdevFromVdevId(realm, vdev_id) |
false | Realm device |
| vdev | RmmVdev | VdevAt(rdev.vdev_ptr) |
false | Virtual device |
16.3.17.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
| inst_id | X1 | 63:0 | UInt64 | Instance ID |
16.3.17.2 Failure conditions
| ID | Condition |
|---|---|
| da_en | pre: realm.feat_da != FEATURE_TRUE post: result == RSI_ERROR_STATE |
| vdev_id | pre: !RdevIdIsValid(realm, vdev_id) post: result == RSI_ERROR_INPUT |
16.3.17.2.1 Failure condition ordering
[da_en] < [vdev_id]
16.3.17.3 Success conditions
| ID | Condition |
|---|---|
| inst_id | inst_id == vdev.inst_id |
16.3.17.4 Footprint
The RSI_RDEV_GET_INSTANCE_ID command does not have any footprint.
16.3.18 RSI_RDEV_GET_INTERFACE_REPORT command
Get Realm device interface report.
See also:
- Section 9.5.2
16.3.18.1 Interface
16.3.18.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001A6 |
| vdev_id | X1 | 63:0 | Bits64 | Realm device identifier |
| inst_id | X2 | 63:0 | UInt64 | Device instance identifier |
| version_max | X3 | 63:0 | UInt64 | Maximum TDISP version accepted by caller |
16.3.18.1.2 Context
The RSI_RDEV_GET_INTERFACE_REPORT command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
| rdev | RmmRdev | RdevFromInstId( realm, inst_id) |
false | Realm device |
16.3.18.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
| version | X1 | 63:0 | UInt64 | TDISP version |
16.3.18.2 Failure conditions
| ID | Condition |
|---|---|
| da_en | pre: realm.feat_da != FEATURE_TRUE post: result == RSI_ERROR_STATE |
| vdev_id | pre: !RdevIdsAreValid(realm, vdev_id, inst_id) post: result == RSI_ERROR_INPUT |
| version | pre: TDISP version is not supported. post: result == RSI_ERROR_INPUT |
| state | pre: (rdev.state != RDEV_LOCKED && rdev.state != RDEV_STARTED) post: result == RSI_ERROR_INPUT |
16.3.18.2.1 Failure condition ordering
[da_en] < [vdev_id, version]
[vdev_id] < [state]
16.3.18.3 Success conditions
| ID | Condition |
|---|---|
| locked | pre: rdev.state == RDEV_LOCKED post: rdev.state == RDEV_LOCKED_BUSY |
| started | pre: rdev.state == RDEV_STARTED post: rdev.state == RDEV_STARTED_BUSY |
| operation | rdev.operation == RDEV_OP_GET_INTERFACE_REPORT |
16.3.18.4 Footprint
| ID | Value |
|---|---|
| state | rdev.state |
| operation | rdev.operation |
16.3.19 RSI_RDEV_GET_MEASUREMENTS command
Get Realm device measurements.
16.3.19.1 Interface
16.3.19.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001A7 |
| vdev_id | X1 | 63:0 | Bits64 | Virtual device identifier |
| inst_id | X2 | 63:0 | UInt64 | Device instance identifier |
| op | X3 | 63:0 | Bits64 | Measurement operation as defined as Param2 in SPDM
GET_MEASURMENTS request |
| flags | X4 | 63:0 | Bits64 | If set to 0x1, request RawBitStream. Otherwise, request hash of the measurement as defined by request attributes in SPDM GET_MEASUREMENTS command. |
16.3.19.1.2 Context
The RSI_RDEV_GET_MEASUREMENTS command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
| rdev | RmmRdev | RdevFromInstId( realm, inst_id) |
false | Realm device |
16.3.19.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
16.3.19.2 Failure conditions
| ID | Condition |
|---|---|
| da_en | pre: realm.feat_da != FEATURE_TRUE post: result == RSI_ERROR_STATE |
| vdev_id | pre: !RdevIdsAreValid(realm, vdev_id, inst_id) post: result == RSI_ERROR_INPUT |
| state | pre: (rdev.state != RDEV_UNLOCKED && rdev.state != RDEV_LOCKED && rdev.state != RDEV_STARTED) post: result == RSI_ERROR_INPUT |
16.3.19.2.1 Failure condition ordering
[da_en] < [vdev_id]
[vdev_id] < [state]
16.3.19.3 Success conditions
| ID | Condition |
|---|---|
| new | pre: rdev.state == RDEV_UNLOCKED post: rdev.state == RDEV_UNLOCKED_BUSY |
| locked | pre: rdev.state == RDEV_LOCKED post: rdev.state == RDEV_LOCKED_BUSY |
| started | pre: rdev.state == RDEV_STARTED post: rdev.state == RDEV_STARTED_BUSY |
| operation | rdev.operation == RDEV_OP_GET_MEASUREMENTS |
16.3.19.4 Footprint
| ID | Value |
|---|---|
| state | rdev.state |
| operation | rdev.operation |
16.3.20 RSI_RDEV_GET_STATE command
Get state of a Realm device.
See also:
- Section 9.5.5
16.3.20.1 Interface
16.3.20.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001A8 |
| vdev_id | X1 | 63:0 | Bits64 | Realm device identifier |
| inst_id | X2 | 63:0 | UInt64 | Device instance identifier |
16.3.20.1.2 Context
The RSI_RDEV_GET_STATE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
| rdev | RmmRdev | RdevFromInstId( realm, inst_id) |
false | Realm device |
16.3.20.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
| state | X1 | 63:0 | RsiDeviceState | Realm device state |
16.3.20.2 Failure conditions
| ID | Condition |
|---|---|
| da_en | pre: realm.feat_da != FEATURE_TRUE post: result == RSI_ERROR_STATE |
| vdev_id | pre: !RdevIdsAreValid(realm, vdev_id, inst_id) post: result == RSI_ERROR_INPUT |
16.3.20.2.1 Failure condition ordering
[da_en] < [vdev_id]
16.3.20.3 Success conditions
| ID | Condition |
|---|---|
| state | Equal(state, rdev.state) |
16.3.20.4 Footprint
The RSI_RDEV_GET_STATE command does not have any footprint.
16.3.21 RSI_RDEV_LOCK command
Lock a Realm device.
See also:
- Section 9.5.5
16.3.21.1 Interface
16.3.21.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001A9 |
| vdev_id | X1 | 63:0 | Bits64 | Realm device identifier |
| inst_id | X2 | 63:0 | UInt64 | Device instance identifier |
16.3.21.1.2 Context
The RSI_RDEV_LOCK command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
| rdev | RmmRdev | RdevFromInstId( realm, inst_id) |
false | Realm device |
16.3.21.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
16.3.21.2 Failure conditions
| ID | Condition |
|---|---|
| da_en | pre: realm.feat_da != FEATURE_TRUE post: result == RSI_ERROR_STATE |
| vdev_id | pre: !RdevIdsAreValid(realm, vdev_id, inst_id) post: result == RSI_ERROR_INPUT |
| state | pre: rdev.state != RDEV_UNLOCKED post: result == RSI_ERROR_INPUT |
16.3.21.2.1 Failure condition ordering
[da_en] < [vdev_id]
[vdev_id] < [state]
16.3.21.3 Success conditions
| ID | Condition |
|---|---|
| state | rdev.state == RDEV_UNLOCKED_BUSY |
| operation | rdev.operation == RDEV_OP_LOCK |
16.3.21.4 Footprint
| ID | Value |
|---|---|
| state | rdev.state |
| operation | rdev.operation |
16.3.22 RSI_RDEV_START command
Start a Realm device.
See also:
- Section 9.5.5
16.3.22.1 Interface
16.3.22.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001AA |
| vdev_id | X1 | 63:0 | Bits64 | Realm device identifier |
| inst_id | X2 | 63:0 | UInt64 | Device instance identifier |
16.3.22.1.2 Context
The RSI_RDEV_START command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
| rdev | RmmRdev | RdevFromInstId( realm, inst_id) |
false | Realm device |
16.3.22.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
16.3.22.2 Failure conditions
| ID | Condition |
|---|---|
| da_en | pre: realm.feat_da != FEATURE_TRUE post: result == RSI_ERROR_STATE |
| vdev_id | pre: !RdevIdsAreValid(realm, vdev_id, inst_id) post: result == RSI_ERROR_INPUT |
| state | pre: rdev.state != RDEV_LOCKED post: result == RSI_ERROR_INPUT |
16.3.22.2.1 Failure condition ordering
[da_en] < [vdev_id]
[vdev_id] < [state]
16.3.22.3 Success conditions
| ID | Condition |
|---|---|
| state | rdev.state == RDEV_LOCKED_BUSY |
| operation | rdev.operation == RDEV_OP_START |
16.3.22.4 Footprint
| ID | Value |
|---|---|
| state | rdev.state |
| operation | rdev.operation |
16.3.23 RSI_RDEV_STOP command
Stop a Realm device.
See also:
- Section 9.5.5
16.3.23.1 Interface
16.3.23.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001AB |
| vdev_id | X1 | 63:0 | Bits64 | Realm device identifier |
| inst_id | X2 | 63:0 | UInt64 | Device instance identifier |
16.3.23.1.2 Context
The RSI_RDEV_STOP command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
| rdev | RmmRdev | RdevFromInstId( realm, inst_id) |
false | Realm device |
16.3.23.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
16.3.23.2 Failure conditions
| ID | Condition |
|---|---|
| da_en | pre: realm.feat_da != FEATURE_TRUE post: result == RSI_ERROR_STATE |
| vdev_id | pre: !RdevIdsAreValid(realm, vdev_id, inst_id) post: result == RSI_ERROR_INPUT |
| state | pre: (rdev.state != RDEV_UNLOCKED && rdev.state != RDEV_LOCKED && rdev.state != RDEV_STARTED && rdev.state != RDEV_ERROR) post: result == RSI_ERROR_INPUT |
16.3.23.2.1 Failure condition ordering
[da_en] < [vdev_id]
[vdev_id] < [state]
16.3.23.3 Success conditions
| ID | Condition |
|---|---|
| state | rdev.state == RDEV_STOPPING |
16.3.23.4 Footprint
| ID | Value |
|---|---|
| state | rdev.state |
16.3.24 RSI_RDEV_VALIDATE_MAPPING command
Validate Realm device memory mappings.
See also:
- Section 9.5.3
16.3.24.1 Interface
16.3.24.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC40001AC |
| vdev_id | X1 | 63:0 | Bits64 | Realm device identifier |
| inst_id | X2 | 63:0 | UInt64 | Device instance identifier |
| ipa_base | X3 | 63:0 | Address | Base of target IPA region |
| ipa_top | X4 | 63:0 | Address | Top of target IPA region |
| pa_base | X5 | 63:0 | Address | Base of target PA region |
| flags | X6 | 63:0 | RsiRdevValidateIoFlagsRsiDevMemFlags | Flags |
16.3.24.1.2 Context
The RSI_RDEV_VALIDATE_MAPPING command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
| rec | RmmRec | CurrentRec() |
false | Current REC |
| rdev | RmmRdev | RdevFromInstId( realm, inst_id) |
false | Realm device |
16.3.24.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
| new_ipa_base | X1 | 63:0 | Address | Base of IPA region which was not modified by the command |
| response | X2 | 0:0 | RsiResponse | Whether the Host accepted or rejected the request |
The following unused bits of RSI_RDEV_VALIDATE_MAPPING output values MBZ: X2[63:1].
16.3.24.2 Failure conditions
| ID | Condition |
|---|---|
| da_en | pre: realm.feat_da != FEATURE_TRUE post: result == RSI_ERROR_STATE |
| vdev_id | pre: !RdevIdsAreValid(realm, vdev_id, inst_id) post: result == RSI_ERROR_INPUT |
| state | pre: (rdev.state != RDEV_LOCKED && rdev.state != RDEV_STARTED) post: result == RSI_ERROR_INPUT |
| ipa_base_align | pre: !AddrIsGranuleAligned(ipa_base) post: result == RSI_ERROR_INPUT |
| ipa_top_align | pre: !AddrIsGranuleAligned(ipa_top) post: result == RSI_ERROR_INPUT |
| pa_align | pre: !AddrIsGranuleAligned(pa_base) post: result == RSI_ERROR_INPUT |
| size_valid | pre: UInt(ipa_top) <= UInt(ipa_base) post: result == RSI_ERROR_INPUT |
| rgn_bound | pre: !AddrRangeIsProtected(ipa_base, ipa_top, realm) post: result == RSI_ERROR_INPUT |
16.3.24.2.1 Failure condition ordering
[da_en] < [vdev_id]
[vdev_id] < [state, ipa_base_align, ipa_top_align, pa_align,
size_valid, rgn_bound]
16.3.24.3 Success conditions
| ID | Condition |
|---|---|
| new_ipa_base | new_ipa_base == rec.ripas_addrdev_mem_addr |
| response | response == RecRipasResponseToRsiRecDevMemResponseToRsi(rec) |
16.3.24.4 Footprint
The RSI_RDEV_VALIDATE_MAPPING command does not have any footprint.
16.3.25 RSI_REALM_CONFIG command
Read configuration for the current Realm.
See also:
- Section 5.2.4
16.3.25.1 Interface
16.3.25.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000196 |
| addr | X1 | 63:0 | Address | IPA of the Granule to which the configuration data will be written |
16.3.25.1.2 Context
The RSI_REALM_CONFIG command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
| cfg | RsiRealmConfig | RsiRealmConfigAt(addr) |
false | Realm configuration |
| walk | RmmRttWalkResult | RttWalk( realm, addr, RMM_RTT_PAGE_LEVEL, RMM_RTT_TREE_PRIMARY) |
false | RTT walk result |
16.3.25.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
16.3.25.2 Failure conditions
| ID | Condition |
|---|---|
| addr_align | pre: !AddrIsGranuleAligned(addr) post: result == RSI_ERROR_INPUT |
| addr_bound | pre: !AddrIsProtected(addr, realm) post: result == RSI_ERROR_INPUT |
| addr_empty | pre: walk.rtte.ripas == EMPTY post: result == RSI_ERROR_INPUT |
16.3.25.2.1 Failure condition ordering
The RSI_REALM_CONFIG command does not have any failure condition orderings.
16.3.25.3 Success conditions
| ID | Condition |
|---|---|
| ipa_width | cfg.ipa_width == realm.ipa_width |
| hash_algo | Equal(cfg.hash_algo, realm.hash_algo) |
| num_aux_planes | cfg.num_aux_planes == realm.num_aux_planes |
16.3.25.4 Footprint
The RSI_REALM_CONFIG command does not have any footprint.
16.3.26 RSI_VERSION command
Returns RSI version.
On calling this command, the Realm provides a requested RSI version.
The output values include a status code and two revisions which are supported by the RMM: a lower revision and a higher revision.
- The higher revision value is the highest interface revision which is supported by the RMM.
- The lower revision is less than or equal to the higher revision.
The status code and lower revision output values indicate which of the following is true, in order of precedence:
The RMM supports an interface revision which is compatible with the requested revision.
- The status code is RSI_SUCCESS.
- The lower revision is equal to the requested revision.
The RMM does not support an interface revision which is compatible with the requested revision. The RMM supports an interface revision which is incompatible with and less than the requested revision.
- The status code is RSI_ERROR_INPUT.
- The lower revision is the highest interface revision which is both less than the requested revision and supported by the RMM.
The RMM does not support an interface revision which is compatible with the requested revision. The RMM supports an interface revision which is incompatible with and greater than the requested revision.
- The status code is RSI_ERROR_INPUT.
- The lower revision is equal to the higher revision.
16.3.26.1 Interface
16.3.26.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000190 |
| req | X1 | 63:0 | RsiInterfaceVersion | Requested interface revision |
16.3.26.1.2 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
| lower | X1 | 63:0 | RsiInterfaceVersion | Lower implementedsupported interface revision |
| higher | X2 | 63:0 | RsiInterfaceVersion | Higher implementedsupported interface revision |
16.3.26.2 Failure conditions
| ID | Condition |
|---|---|
| incompat_lower | pre: (!RsiVersionIsSupported(req) && RsiVersionLowerIsSupported(req)) post: (result == RSI_ERROR_INPUT && VersionEqual(lower, RsiVersionHighestBelow(req)) && VersionEqual(higher, RsiVersionHighest())) |
| incompat_higher | pre: (!RsiVersionIsSupported(req) && !RsiVersionLowerIsSupported(req) && RsiVersionHigherIsSupported(req)) post: (result == RSI_ERROR_INPUT && VersionEqual(lower, higher) && VersionEqual(higher, RsiVersionHighest())) |
16.3.26.2.1 Failure condition ordering
The RSI_VERSION command does not have any failure condition orderings.
16.3.26.3 Success conditions
| ID | Condition |
|---|---|
| lower | VersionEqual(lower, req) |
| higher | VersionEqual(higher, RsiVersionHighest()) |
16.3.26.4 Footprint
The RSI_VERSION command does not have any footprint.
16.3.27 RSI_VSMMU_ACTIVATE command
Activate a VSMMU.
See also:
- Section 9.6.4
16.3.27.1 Interface
16.3.27.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400019B |
| base | X1 | 63:0 | Address | Base of target IPA region |
| top | X2 | 63:0 | Address | Top of target IPA region |
16.3.27.1.2 Context
The RSI_VSMMU_ACTIVATE command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
16.3.27.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
| new_base | X1 | 63:0 | Address | Base of IPA region which was not modified by the command |
16.3.27.2 Failure conditions
| ID | Condition |
|---|---|
| base_align | pre: !AddrIsGranuleAligned(base) post: result == RSI_ERROR_INPUT |
| top_align | pre: !AddrIsGranuleAligned(top) post: result == RSI_ERROR_INPUT |
| size_valid | pre: UInt(top) <= UInt(base) post: result == RSI_ERROR_INPUT |
| rgn_bound | pre: !AddrRangeIsProtected(base, top, realm) post: result == RSI_ERROR_INPUT |
16.3.27.2.1 Failure condition ordering
The RSI_VSMMU_ACTIVATE command does not have any failure condition orderings.
16.3.27.3 Success conditions
The RSI_VSMMU_ACTIVATE command does not have any success conditions.
16.3.27.4 Footprint
The RSI_VSMMU_ACTIVATE command does not have any footprint.
16.3.28 RSI_VSMMU_GET_INFO command
Get information of a VSMMU.
See also:
- Section 9.6.4
16.3.28.1 Interface
16.3.28.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC400019A |
| addr | X1 | 63:0 | Address | Base IPA of the VSMMU |
16.3.28.1.2 Context
The RSI_VSMMU_GET_INFO command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
| walk | RmmRttWalkResult | RttWalk( realm, addr, RMM_RTT_PAGE_LEVEL, RMM_RTT_TREE_PRIMARY) |
false | RTT walk result |
16.3.28.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | RsiCommandReturnCode | Command return status |
| top | X1 | 63:0 | Address | Top IPA of the VSMMU |
16.3.28.2 Failure conditions
| ID | Condition |
|---|---|
| addr_align | pre: !AddrIsGranuleAligned(addr) post: result == RSI_ERROR_INPUT |
| addr_bound | pre: !AddrIsProtected(addr, realm) post: result == RSI_ERROR_INPUT |
| rtte_state | pre: walk.rtte.state != ASSIGNED_VSMMU post: result == RSI_ERROR_INPUT |
| vsmmu_base | pre: addr != VsmmuAt(walk.rtte.addr).reg_base post: result == RSI_ERROR_INPUT |
16.3.28.2.1 Failure condition ordering
The RSI_VSMMU_GET_INFO command does not have any failure condition orderings.
16.3.28.3 Success conditions
| ID | Condition |
|---|---|
| vsmmu_base | top == VsmmuAt(walk.rtte.addr).reg_top |
16.3.28.4 Footprint
The RSI_VSMMU_GET_INFO command does not have any footprint.
16.4 RSI types
This section defines types which are used in the RSI interface.
16.4.1 RsiBoolean type
The RsiBoolean enumeration represents a boolean value.
The RsiBoolean enumeration is a concrete type.
The width of the RsiBoolean enumeration is 1 bits.
The values of the RsiBoolean enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RSI_FALSE | False |
| 1 | RSI_TRUE | True |
16.4.2 RsiCommandReturnCode type
The RsiCommandReturnCode enumeration represents a return code from an RSI command.
The RsiCommandReturnCode enumeration is a concrete type.
The width of the RsiCommandReturnCode enumeration is 64 bits.
See also:
- Section 12
The values of the RsiCommandReturnCode enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RSI_SUCCESS | Command completed successfully |
| 1 | RSI_ERROR_INPUT | The value of a command input value caused the command to fail |
| 2 | RSI_ERROR_STATE | The state of the current Realm or current REC does not match the state expected by the command |
| 3 | RSI_INCOMPLETE | The operation requested by the command is not complete |
| 4 | RSI_ERROR_UNKNOWN | The operation requested by the command failed for an unknown reason |
| 5 | RSI_ERROR_DEVICE | The state of a Realm device does not match the state expected by the command |
Unused encodings for the RsiCommandReturnCode enumeration are reserved for use by future versions of this specification.
16.4.3 RsiDeviceInfo RsiDeviceAttestationType type
The RsiDeviceInfo structure containsRsiDeviceAttestationType enumeration represents attestation type of a device configuration information.
The RsiDeviceInfo structureRsiDeviceAttestationType enumeration is a concrete type.
The width of the RsiDeviceAttestationType enumeration is 64 bits.
See also:
- Section 9.1.2
The values of the RsiDeviceAttestationType enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RSI_INDEPENDENTLY_ATTESTED | Device is independently-attested. |
| 1 | RSI_PLATFORM_ATTESTED | Device is platform-attested. |
Unused encodings for the RsiDeviceAttestationType enumeration are reserved for use by future versions of this specification.
The RsiDeviceAttestationType enumeration is used in the following types:
16.4.4 RsiDeviceInfo type
The RsiDeviceInfo structure contains device configuration information.
The RsiDeviceInfo structure is a concrete type.
The width of the RsiDeviceInfo structure is 512 (0x200)
bytes.
The members of the RsiDeviceInfo structure are shown in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| cert_idattest_type | 0x0 |
RsiDeviceAttestationType | Attestation type |
| cert_id | 0x8 |
UInt64 | Certificate identifier |
| hash_algo | 0x80x10 |
RsiHashAlgorithm | Algorithm used to generate device digests |
| cert_digest | 0x40 |
Bits512 | Certificate digest |
| meas_digest | 0x80 |
Bits512 | Measurement block digest |
| report_digest | 0xc0 |
Bits512 | Interface report digest |
Unused bits of the RsiDeviceInfo structure MBZ.
16.4.45 RsiDeviceState type
The RsiDeviceState enumeration represents state of an assigned Realm device.
The RsiDeviceState enumeration is a concrete type.
The width of the RsiDeviceState enumeration is 64 bits.
See also:
- Section 9.5
The values of the RsiDeviceState enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RSI_RDEV_UNLOCKED | Device interface is unlocked. |
| 1 | RSI_RDEV_UNLOCKED_BUSY | Device interface is unlocked and is handling an interruptible Realm device operation. |
| 2 | RSI_RDEV_LOCKED | Device interface is locked. |
| 3 | RSI_RDEV_LOCKED_BUSY | Device interface is locked and is handling an interruptible Realm device operation. |
| 4 | RSI_RDEV_STARTED | Device interface is started. |
| 5 | RSI_RDEV_STARTED_BUSY | Device interface is started and is handling an interruptible Realm device operation. |
| 6 | RSI_RDEV_STOPPING | Device interface is stopping. |
| 7 | RSI_RDEV_STOPPED | Device interface is stopped. |
| 8 | RSI_RDEV_ERROR | Device interface has reported a fatal error. |
Unused encodings for the RsiDeviceState enumeration are reserved for use by future versions of this specification.
16.4.5 RsiDevMemCoherent type The RsiDevMemCoherent enumeration represents whether a device memory location is within the system coherent memory space. The RsiDevMemCoherent enumeration is a concrete type. The width of the RsiDevMemCoherent enumeration is 1 bits. The values of the RsiDevMemCoherent enumeration are shown in the following table. Encoding Name Description 0 RSI_DEV_MEM_NON_COHERENT A device memory location is not within the system coherent memory space 1 RSI_DEV_MEM_COHERENT A device memory location is within the system coherent memory space The RsiDevMemCoherent enumeration is used in the following types: RsiRdevValidateIoFlags16.4.6 RsiFeatureRsiDevMemCoherent type
The RsiFeatureRsiDevMemCoherent enumeration represents whether a feature is enableddevice memory location is within the system coherent memory space.
The RsiFeatureRsiDevMemCoherent enumeration is a concrete type.
The width of the RsiFeatureRsiDevMemCoherent enumeration is 1 bits.
The values of the RsiFeatureRsiDevMemCoherent enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RSI_FEATURE_FALSERSI_DEV_MEM_NON_COHERENT | FeatureA device memory location is not enabled.within the system coherent memory space |
| 1 | RSI_FEATURE_TRUERSI_DEV_MEM_COHERENT | Feature is enabled.A device memory location is within the system coherent memory space |
The RsiFeatureRsiDevMemCoherent enumeration is used in the following types:
- RsiFeatureRegister0RsiDevMemFlags
16.4.7 RsiFeatureRegister0 RsiDevMemFlags type
The RsiFeatureRegister0RsiDevMemFlags fieldset contains RSI feature register 0flags which describe properties of a device memory mapping.
The RsiFeatureRegister0RsiDevMemFlags fieldset is a concrete type.
The width of the RsiFeatureRegister0RsiDevMemFlags fieldset is 64 bits.
The fields of the RsiFeatureRegister0RsiDevMemFlags fieldset are shown in the following diagram.
The fields of the RsiFeatureRegister0RsiDevMemFlags fieldset are shown in the following table.
| Name | Bits | Description | Value |
|---|---|---|---|
| DAcoh | 0 | Whether Realmthe output address of the device assignment is supportedmemory mapping is within the system coherent memory space. | RsiFeatureRsiDevMemCoherent |
| MROorder | 1 | Whether “mostly read-only” permissions are supportedOrdering properties of the device memory location. | RsiFeatureRsiDevMemOrdering |
| 63:2 | Reserved | MBZSBZ |
16.4.8 RsiGicOwnerRsiDevMemOrdering type
The RsiGicOwnerRsiDevMemOrdering enumeration represents which Plane is GIC ownerordering properties of a device memory location.
The RsiGicOwnerRsiDevMemOrdering enumeration is a concrete type.
The width of the RsiGicOwnerRsiDevMemOrdering enumeration is 1 bits.
The values of the RsiGicOwnerRsiDevMemOrdering enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RSI_GIC_OWNER_0RSI_DEV_MEM_NOT_LIMITED_ORDER | Plane 0 is GIC owner.A device memory location is not within a Limited Order Region (LOR) |
| 1 | RSI_GIC_OWNER_NRSI_DEV_MEM_LIMITED_ORDER | Plane N is GIC owner.A device memory location is within a Limited Order Region (LOR) |
The RsiGicOwnerRsiDevMemOrdering enumeration is used in the following types:
- RsiPlaneEnterFlagsRsiDevMemFlags
16.4.9 RsiHashAlgorithmRsiFeature type
The RsiHashAlgorithmRsiFeature enumeration represents hash algorithmwhether a feature is enabled.
The RsiHashAlgorithmRsiFeature enumeration is a concrete type.
The width of the RsiHashAlgorithmRsiFeature enumeration is 81 bits.
The values of the RsiFeature enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RSI_FEATURE_FALSE | Feature is not enabled. |
| 1 | RSI_FEATURE_TRUE | Feature is enabled. |
The RsiFeature enumeration is used in the following types:
16.4.10 RsiFeatureRegister0 type
The RsiFeatureRegister0 fieldset contains RSI feature register 0.
The RsiFeatureRegister0 fieldset is a concrete type.
The width of the RsiFeatureRegister0 fieldset is 64 bits.
The fields of the RsiFeatureRegister0 fieldset are shown in the following diagram.
The fields of the RsiFeatureRegister0 fieldset are shown in the following table.
| Name | Bits | Description | Value |
|---|---|---|---|
| DA | 0 | Whether Realm device assignment is supported | RsiFeature |
| MRO | 1 | Whether “mostly read-only” permissions are supported | RsiFeature |
| 63:2 | Reserved | MBZ |
16.4.11 RsiGicOwner type
The RsiGicOwner enumeration represents which Plane is GIC owner.
The RsiGicOwner enumeration is a concrete type.
The width of the RsiGicOwner enumeration is 1 bits.
The values of the RsiGicOwner enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RSI_GIC_OWNER_0 | Plane 0 is GIC owner. |
| 1 | RSI_GIC_OWNER_N | Plane N is GIC owner. |
The RsiGicOwner enumeration is used in the following types:
16.4.12 RsiHashAlgorithm type
The RsiHashAlgorithm enumeration represents hash algorithm.
The RsiHashAlgorithm enumeration is a concrete type.
The width of the RsiHashAlgorithm enumeration is 8 bits.
See also:
- Section 16.3.25
The values of the RsiHashAlgorithm enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RSI_HASH_SHA_256 | SHA-256 (Secure Hash Standard (SHS) [20]) |
| 1 | RSI_HASH_SHA_512 | SHA-512 (Secure Hash Standard (SHS) [20]) |
Unused encodings for the RsiHashAlgorithm enumeration are reserved for use by future versions of this specification.
The RsiHashAlgorithm enumeration is used in the following types:
- RsiDeviceInfo
- RsiRealmConfig RsiDeviceInfo
16.4.1013 RsiHostCall type
The RsiHostCall structure contains data structure used to pass Host call arguments and return values.
The RsiHostCall structure is a concrete type.
The width of the RsiHostCall structure is 256 (0x100)
bytes.
The members of the RsiHostCall structure are shown in the following table.
Unused bits of the RsiHostCall structure SBZ.
16.4.1114 RsiInterfaceVersion type
The RsiInterfaceVersion fieldset contains an RSI interface version.
The RsiInterfaceVersion fieldset is a concrete type.
The width of the RsiInterfaceVersion fieldset is 64 bits.
The fields of the RsiInterfaceVersion fieldset are shown in the following diagram.
The fields of the RsiInterfaceVersion fieldset are shown in the following table.
16.4.15 RsiPlaneExitReason RsiPlaneEnter type
The RsiPlaneExitReason enumeration represents the reason for aRsiPlaneEnter structure contains data passed from P0 to the RMM on Plane exit entry.
The RsiPlaneExitReason enumerationRsiPlaneEnter structure is a concrete type.
The width of the RsiPlaneExitReason enumeration is 8 bitsRsiPlaneEnter structure is 2048 (0x800)
bytes.
The values of the RsiPlaneExitReason enumerationmembers of the RsiPlaneEnter structure are shown in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| 0flags | RSI_EXIT_SYNC0x0 |
Plane exit due to synchronous exceptionRsiPlaneEnterFlags | Flags |
| pc | 0x8 |
Bits64 | Program counter |
| gprs[31] | 0x100 |
Bits64 | Registers |
| gicv3_hcr | 0x200 |
Bits64 | GICv3 Hypervisor Control Register value |
| gicv3_lrs[16] | 0x208 |
Bits64 | GICv3 List Register values |
Unused encodings for the RsiPlaneExitReason enumeration are reserved for use by future versions of this specificationbits of the RsiPlaneEnter structure SBZ.
The RsiPlaneExitReason enumerationRsiPlaneEnter structure is used in the following types:
- RsiPlaneExitRsiPlaneRun
16.4.16 RsiPlaneRun RsiPlaneEnterFlags type
The RsiPlaneRun structureRsiPlaneEnterFlags fieldset contains fields used to share information between RMM andflags provided by P0 during Plane entry and Plane exit.
The RsiPlaneRun structureRsiPlaneEnterFlags fieldset is a concrete type.
The width of the RsiPlaneRun structure is 4096 (0x1000) bytesRsiPlaneEnterFlags fieldset is 64 bits.
The members of the RsiPlaneRun structurefields of the RsiPlaneEnterFlags fieldset are shown in the following diagram.
The fields of the RsiPlaneEnterFlags fieldset are shown in the following table.
| Name | Byte offsetBits | TypeDescription | Value |
|---|---|---|---|
| entertrap_wfi | 0x00 | Whether to trap WFI execution by the Plane. | RsiTrap |
| trap_wfe | 1 | Whether to trap WFE execution by the Plane. | RsiTrap |
| trap_hc | 2 | Whether to trap RSI_HOST_CALL execution by the Plane. RSI_TRAP: execution of RSI_HOST_CALL causes Plane exit RSI_NO_TRAP: execution of RSI_HOST_CALL causes REC exit to Host |
RsiTrap |
| gic_owner | 3 | Whether to transfer GIC ownership to the target Plane. | RsiGicOwner |
| 63:4 | Reserved | SBZ |
The RsiPlaneEnterFlags fieldset is used in the following types:
- RsiPlaneEnter Entry information exit 0x800 RsiPlaneExit Exit information
16.4.17 RsiRdevValidateIoFlags RsiPlaneExit type
The RsiRdevValidateIoFlags fieldsetRsiPlaneExit structure contains flags provided when requesting validation of a device memory mappingdata passed from the RMM to P0 on Plane exit.
The RsiRdevValidateIoFlags fieldsetRsiPlaneExit structure is a concrete type.
The width of the RsiRdevValidateIoFlags fieldset is 64 bitsRsiPlaneExit structure is 2048 (0x800)
bytes.
The fields of the RsiRdevValidateIoFlags fieldsetmembers of the RsiPlaneExit structure are shown in the following diagram. The fields of the RsiRdevValidateIoFlags fieldset are shown in the following table.
| Name | BitsByte offset | Type | Description | Value
|---|---|---|---|
| cohreason | 00x0 |
Whether the output address of the device memory mapping is within the system coherent memory space. RsiDevMemCoherentRsiPlaneExitReason | Exit reason |
| elr_el2 | 63:10x100 |
ReservedBits64 | Exception Link Register |
| esr_el2 | 0x108 |
Bits64 | Exception Syndrome Register |
| far_el2 | 0x110 |
Bits64 | Fault Address Register |
| hpfar_el2 | 0x118 |
Bits64 | Hypervisor IPA Fault Address register |
| gprs[31] | 0x200 |
Bits64 | Registers |
| gicv3_hcr | 0x300 |
Bits64 | GICv3 Hypervisor Control Register value |
| gicv3_lrs[16] | 0x308 |
Bits64 | GICv3 List Register values |
| gicv3_misr | 0x388 |
Bits64 | GICv3 Maintenance Interrupt State Register value |
| gicv3_vmcr | 0x390 |
Bits64 | GICv3 Virtual Machine Control Register value |
| cntp_ctl | 0x400 |
Bits64 | Counter-timer Physical Timer Control Register value |
| cntp_cval | 0x408 |
Bits64 | Counter-timer Physical Timer CompareValue Register value |
| cntv_ctl | 0x410 |
Bits64 | Counter-timer Virtual Timer Control Register value |
| cntv_cval | 0x418 |
Bits64 | Counter-timer Virtual Timer CompareValue Register value |
Unused bits of the RsiPlaneExit structure SBZ .
The RsiPlaneExit structure is used in the following types:
16.4.18 RsiRealmConfig RsiPlaneExitReason type
The RsiRealmConfig structure contains realm configurationRsiPlaneExitReason enumeration represents the reason for a Plane exit.
The RsiRealmConfig structureRsiPlaneExitReason enumeration is a concrete type.
The width of the RsiRealmConfigRsiPlaneExitReason enumeration is 8 bits.
The values of the RsiPlaneExitReason enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RSI_EXIT_SYNC | Plane exit due to synchronous exception |
Unused encodings for the RsiPlaneExitReason enumeration are reserved for use by future versions of this specification.
The RsiPlaneExitReason enumeration is used in the following types:
16.4.19 RsiPlaneRun type
The RsiPlaneRun structure contains fields used to share information between RMM and P0 during Plane entry and Plane exit.
The RsiPlaneRun structure is a concrete type.
The width of the RsiPlaneRun structure is 4096 (0x1000)
bytes.
The members of the RsiPlaneRun structure are shown in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| enter | 0x0 |
RsiPlaneEnter | Entry information |
| exit | 0x800 |
RsiPlaneExit | Exit information |
16.4.20 RsiRealmConfig type
The RsiRealmConfig structure contains realm configuration.
The RsiRealmConfig structure is a concrete type.
The width of the RsiRealmConfig structure is 4096
(0x1000) bytes.
See also:
- Section 16.3.25
The members of the RsiRealmConfig structure are shown in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| ipa_width | 0x0 |
UInt64 | IPA width in bits |
| hash_algo | 0x8 |
RsiHashAlgorithm | Hash algorithm |
| num_aux_planes | 0x10 |
UInt64 | Number of auxiliary Planes |
| gicv3_vtr | 0x18 |
Bits64 | GICv3 VGIC Type Register value |
| rpv | 0x200 |
Bits512 | Realm Personalization Value |
Unused bits of the RsiRealmConfig structure MBZ.
16.4.1921 RsiResponse type
The RsiResponse enumeration represents whether the Host accepted or rejected a Realm request.
The RsiResponse enumeration is a concrete type.
The width of the RsiResponse enumeration is 1 bits.
The values of the RsiResponse enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RSI_ACCEPT | Host accepted the Realm request. |
| 1 | RSI_REJECT | Host rejected the Realm request. |
16.4.2022 RsiRipas type
The RsiRipas enumeration represents realm IPA state.
The RsiRipas enumeration is a concrete type.
The width of the RsiRipas enumeration is 8 bits.
The values of the RsiRipas enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RSI_EMPTY | Address where no Realm resources are mapped. |
| 1 | RSI_RAM | Address where private code or data owned by the Realm is mapped. |
| 2 | RSI_DESTROYED | Address which is inaccessible to the Realm due to an action taken by the Host. |
| 3 | RSI_DEV | Address where memory of an assigned Realm device is mapped. |
Unused encodings for the RsiRipas enumeration are reserved for use by future versions of this specification.
16.4.21 RsiRipasChangeDestroyed type The RsiRipasChangeDestroyed enumeration represents whether a RIPAS change from DESTROYED should be permitted. The RsiRipasChangeDestroyed enumeration is a concrete type. The width of the RsiRipasChangeDestroyed enumeration is 1 bits. The values of the RsiRipasChangeDestroyed enumeration are shown in the following table. Encoding Name Description 0 RSI_NO_CHANGE_DESTROYED A RIPAS change from DESTROYED should not be permitted. 1 RSI_CHANGE_DESTROYED A RIPAS change from DESTROYED should be permitted. The RsiRipasChangeDestroyed enumeration is used in the following types: RsiRipasChangeFlags 16.4.22 RsiRipasChangeFlags type The RsiRipasChangeFlags fieldset contains flags provided by the Realm when requesting a RIPAS change. The RsiRipasChangeFlags fieldset is a concrete type. The width of the RsiRipasChangeFlags fieldset is 64 bits. The fields of the RsiRipasChangeFlags fieldset are shown in the following diagram. The fields of the RsiRipasChangeFlags fieldset are shown in the following table. Name Bits Description Value destroyed 0 Whether a RIPAS change from DESTROYED should be permitted RsiRipasChangeDestroyed 63:1 Reserved SBZ16.4.23 RsiTrap RsiRipasChangeDestroyed type
The RsiTrapRsiRipasChangeDestroyed enumeration represents whether a trap is enabledRIPAS change from DESTROYED should be permitted.
The RsiTrapRsiRipasChangeDestroyed enumeration is a concrete type.
The width of the RsiTrapRsiRipasChangeDestroyed enumeration is 1 bits.
The values of the RsiTrapRsiRipasChangeDestroyed enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RSI_NO_CHANGE_DESTROYED | A RIPAS change from DESTROYED should not be permitted. |
| 1 | RSI_CHANGE_DESTROYED | A RIPAS change from DESTROYED should be permitted. |
The RsiRipasChangeDestroyed enumeration is used in the following types:
16.4.24 RsiRipasChangeFlags type
The RsiRipasChangeFlags fieldset contains flags provided by the Realm when requesting a RIPAS change.
The RsiRipasChangeFlags fieldset is a concrete type.
The width of the RsiRipasChangeFlags fieldset is 64 bits.
The fields of the RsiRipasChangeFlags fieldset are shown in the following diagram.
The fields of the RsiRipasChangeFlags fieldset are shown in the following table.
| Name | Bits | Description | Value |
|---|---|---|---|
| destroyed | 0 | Whether a RIPAS change from DESTROYED should be permitted | RsiRipasChangeDestroyed |
| 63:1 | Reserved | SBZ |
16.4.25 RsiTrap type
The RsiTrap enumeration represents whether a trap is enabled.
The RsiTrap enumeration is a concrete type.
The width of the RsiTrap enumeration is 1 bits.
The values of the RsiTrap enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | RSI_NO_TRAP | Trap is disabled. |
| 1 | RSI_TRAP | Trap is enabled. |
The RsiTrap enumeration is used in the following types:
17 Power State Control Interface
This section describes how Power State Control Interface (PSCI) function execution by a Realm execution of SMC instructions is handled.
17.1 PSCI overview
In this section,
recrefers to the currently executing RECexitrefer to the RmiRecExit object which was provided to the RMI_REC_ENTER commandtarget_recrefers to the REC object identified by an MPIDR value passed to a PSCI function.
The RMM provides a trusted implementation of parts of the PSCI ABI. This section describes the checks performed by the RMM when a Realm executes a PSCI command, and the internal RMM state changes which result from a successful PSCI command execution. Successful execution by the RMM of some PSCI commands results in a REC exit due to PSCI, which allows the Host to perform further processing of the command.
The HVC conduit for PSCI is not supported for Realms.
See also:
- Arm Power State Coordination Interface (PSCI) [23]
- Section 2.3.2
- Section 4.3.7
- Section 4.5
- Section 21.4
17.2 PSCI version
The RMM must support version >= 1.1 of the Power State Control Interface.
See also:
- Section 17.3.8
17.3 PSCI commands
The following table summarizes the FIDs of commands in the PSCI interface.
| FID | Command |
|---|---|
0x84000000 |
PSCI_VERSION |
| … | |
0x84000002 |
PSCI_CPU_OFF |
| … | |
0x84000008 |
PSCI_SYSTEM_OFF |
0x84000009 |
PSCI_SYSTEM_RESET |
0x8400000A |
PSCI_FEATURES |
| … | |
0xC4000001 |
PSCI_CPU_SUSPEND |
| … | |
0xC4000003 |
PSCI_CPU_ON |
0xC4000004 |
PSCI_AFFINITY_INFO |
17.3.1 PSCI_AFFINITY_INFO command
Query status of a VPE.
17.3.1.1 Interface
17.3.1.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000004 |
| target_affinity | X1 | 63:0 | Bits64 | This parameter contains a copy of the affinity fields of the MPIDR register |
| lowest_affinity_leve l | X2 | 31:0 | UInt32 | Denotes the lowest affinity level field that is valid in the target_affinity parameter |
The following unused bits of PSCI_AFFINITY_INFO input values SBZ: X2[63:32].
17.3.1.1.2 Context
The PSCI_AFFINITY_INFO command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| target_rec | RmmRec | RecFromMpidr( target_affinity) |
false | Target REC |
17.3.1.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | PsciReturnCode | Command return code |
17.3.1.2 Failure conditions
| ID | Condition |
|---|---|
| target_bound | pre: lowest_affinity_level != 0 post: result == PSCI_INVALID_PARAMETERS |
| target_match | pre: !MpidrIsUsed(target_affinity) post: result == PSCI_INVALID_PARAMETERS |
17.3.1.2.1 Failure condition ordering
The PSCI_AFFINITY_INFO command does not have any failure condition orderings.
17.3.1.3 Success conditions
| ID | Condition |
|---|---|
| runnable | pre: target_rec.flags.runnable == RUNNABLE post: result == PSCI_SUCCESS |
| not_runnable | pre: target_rec.flags.runnable == NOT_RUNNABLE post: result == PSCI_OFF |
17.3.1.4 Footprint
The PSCI_AFFINITY_INFO command does not have any footprint.
17.3.2 PSCI_CPU_OFF command
Power down the calling core.
17.3.2.1 Interface
17.3.2.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0x84000002 |
17.3.2.1.2 Context
The PSCI_CPU_OFF command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| rec | RmmRec | CurrentRec() |
false | Current REC |
17.3.2.1.3 Output values
The PSCI_CPU_OFF command does not have any output values.
Following execution of PSCI_CPU_OFF, control does not return to the caller.
17.3.2.2 Failure conditions
The PSCI_CPU_OFF command does not have any failure conditions.
17.3.2.3 Success conditions
The PSCI_CPU_OFF command does not have any success conditions.
Following execution of PSCI_CPU_OFF, control does not return to the caller.
17.3.2.4 Footprint
The PSCI_CPU_OFF command does not have any footprint.
17.3.3 PSCI_CPU_ON command
Power up a core.
17.3.3.1 Interface
17.3.3.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000003 |
| target_cpu | X1 | 63:0 | Bits64 | This parameter contains a copy of the affinity fields of the MPIDR register |
| entry_point_address | X2 | 63:0 | Address | Address at which the core must resume execution |
| context_id | X3 | 31:0 | UInt32 | This parameter is only meaningful to the caller (must be present in X0 of the target PE upon first entry to Non-Secure exception level) |
The following unused bits of PSCI_CPU_ON input values SBZ: X3[63:32].
17.3.3.1.2 Context
The PSCI_CPU_ON command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
| target_rec | RmmRec | RecFromMpidr(target_cpu) |
false | Target REC |
17.3.3.1.3 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | PsciReturnCode | Command return code |
17.3.3.2 Failure conditions
| ID | Condition |
|---|---|
| entry | pre: !AddrIsProtected(entry_point_address, realm) post: result == PSCI_INVALID_ADDRESS |
| mpidr | pre: !MpidrIsUsed(target_cpu) post: result == PSCI_INVALID_PARAMETERS |
| runnable | pre: target_rec.flags.runnable == RUNNABLE post: result == PSCI_ALREADY_ON |
17.3.3.2.1 Failure condition ordering
The PSCI_CPU_ON command does not have any failure condition orderings.
17.3.3.3 Success conditions
| ID | Condition |
|---|---|
| entry | target_rec.pc == ToBits64(UInt(entry_point_address)) |
| runnable | target_rec.flags.runnable == RUNNABLE |
17.3.3.4 Footprint
| ID | Value |
|---|---|
| runnable | target_rec.flags.runnable |
17.3.4 PSCI_CPU_SUSPEND command
Suspend execution on the calling VPE.
17.3.4.1 Interface
17.3.4.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0xC4000001 |
| power_state | X1 | 31:0 | UInt32 | Identifier for a specific local state |
| entry_point_address | X2 | 63:0 | Address | Address at which the core must resume execution |
| context_id | X3 | 63:0 | UInt64 | This parameter is only meaningful to the caller (must be present in X0 upon first entry to Non- Secure exception level) |
The following unused bits of PSCI_CPU_SUSPEND input values SBZ: X1[63:32].
The RMM treats all target power states as suspend requests, and
therefore the entry_point_address and
context_id arguments are ignored.
17.3.4.1.2 Output values
The PSCI_CPU_SUSPEND command does not have any output values.
Following execution of PSCI_CPU_SUSPEND, control does not return to the caller.
17.3.4.2 Failure conditions
The PSCI_CPU_SUSPEND command does not have any failure conditions.
17.3.4.3 Success conditions
The PSCI_CPU_SUSPEND command does not have any success conditions.
Following execution of PSCI_CPU_SUSPEND, control does not return to the caller.
17.3.4.4 Footprint
The PSCI_CPU_SUSPEND command does not have any footprint.
17.3.5 PSCI_FEATURES command
Query whether a specific PSCI feature is implemented.
17.3.5.1 Interface
17.3.5.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0x8400000A |
| psci_func_id | X1 | 31:0 | UInt32 | Function ID for a PSCI Function |
The following unused bits of PSCI_FEATURES input values SBZ: X1[63:32].
17.3.5.1.2 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | PsciReturnCode | Command return code |
17.3.5.2 Failure conditions
The PSCI_FEATURES command does not have any failure conditions.
17.3.5.3 Success conditions
| ID | Condition |
|---|---|
| func_ok | pre: psci_func_id is a supported PSCI function. post: result == PSCI_SUCCESS |
| func_not_ok | pre: psci_func_id is not a supported PSCI function. post: result == PSCI_NOT_SUPPORTED |
17.3.5.4 Footprint
The PSCI_FEATURES command does not have any footprint.
17.3.6 PSCI_SYSTEM_OFF command
Shut down the system.
17.3.6.1 Interface
17.3.6.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0x84000008 |
17.3.6.1.2 Context
The PSCI_SYSTEM_OFF command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
17.3.6.1.3 Output values
The PSCI_SYSTEM_OFF command does not have any output values.
Following execution of PSCI_SYSTEM_OFF, control does not return to the caller.
17.3.6.2 Failure conditions
The PSCI_SYSTEM_OFF command does not have any failure conditions.
17.3.6.3 Success conditions
| ID | Condition |
|---|---|
| state | realm.state == REALM_SYSTEM_OFF |
Following execution of PSCI_SYSTEM_OFF, control does not return to the caller.
17.3.6.4 Footprint
The PSCI_SYSTEM_OFF command does not have any footprint.
17.3.7 PSCI_SYSTEM_RESET command
Shut down the system.
17.3.7.1 Interface
17.3.7.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0x84000009 |
17.3.7.1.2 Context
The PSCI_SYSTEM_RESET command operates on the following context.
| Name | Type | Value | Before | Description |
|---|---|---|---|---|
| realm | RmmRealm | CurrentRealm() |
false | Current Realm |
17.3.7.1.3 Output values
The PSCI_SYSTEM_RESET command does not have any output values.
Following execution of PSCI_SYSTEM_RESET, control does not return to the caller.
17.3.7.2 Failure conditions
The PSCI_SYSTEM_RESET command does not have any failure conditions.
17.3.7.3 Success conditions
| ID | Condition |
|---|---|
| state | realm.state == REALM_SYSTEM_OFF |
Following execution of PSCI_SYSTEM_RESET, control does not return to the caller.
17.3.7.4 Footprint
The PSCI_SYSTEM_RESET command does not have any footprint.
17.3.8 PSCI_VERSION command
Query the version of PSCI implemented.
17.3.8.1 Interface
17.3.8.1.1 Input values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| fid | X0 | 63:0 | UInt64 | FID, value 0x84000000 |
17.3.8.1.2 Output values
| Name | Register | Bits | Type | Description |
|---|---|---|---|---|
| result | X0 | 63:0 | PsciInterfaceVersion | Interface version |
See also:
- Section 17.2
17.3.8.2 Failure conditions
The PSCI_VERSION command does not have any failure conditions.
17.3.8.3 Success conditions
The PSCI_VERSION command does not have any success conditions.
17.3.8.4 Footprint
The PSCI_VERSION command does not have any footprint.
17.4 PSCI types
This section defines types which are used in the PSCI interface.
17.4.1 PsciInterfaceVersion type
The PsciInterfaceVersion fieldset contains an PSCI interface version.
The PsciInterfaceVersion fieldset is a concrete type.
The width of the PsciInterfaceVersion fieldset is 64 bits.
The fields of the PsciInterfaceVersion fieldset are shown in the following diagram.
The fields of the PsciInterfaceVersion fieldset are shown in the following table.
17.4.2 PsciReturnCode type
The PsciReturnCode enumeration represents the return code of a PSCI command.
The PsciReturnCode enumeration is a concrete type.
The width of the PsciReturnCode enumeration is 64 bits.
The values of the PsciReturnCode enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| -9 | PSCI_INVALID_ADDRESS | Refer to PSCI specification |
| -8 | PSCI_DISABLED | Refer to PSCI specification |
| -7 | PSCI_NOT_PRESENT | Refer to PSCI specification |
| -6 | PSCI_INTERNAL_FAILURE | Refer to PSCI specification |
| -5 | PSCI_ON_PENDING | Refer to PSCI specification |
| -4 | PSCI_ALREADY_ON | Refer to PSCI specification |
| -3 | PSCI_DENIED | Refer to PSCI specification |
| -2 | PSCI_INVALID_PARAMETERS | Refer to PSCI specification |
| -1 | PSCI_NOT_SUPPORTED | Refer to PSCI specification |
| 0 | PSCI_SUCCESS | Refer to PSCI specification |
| 1 | PSCI_OFF | Refer to PSCI specification |
Unused encodings for the PsciReturnCode enumeration are reserved for use by future versions of this specification.
18 RMM constants
This section describes constants which are used in the definition of RMM commands or RMM abstract state.
18.1 RMM_GRANULE_SIZE
Size of a Granule in bytes.
The value of RMM_GRANULE_SIZE is 0x1000.
18.2 RMM_NUM_PERM_OVERLAY_INDICES
Number of permission overlay indices.
The value of RMM_NUM_PERM_OVERLAY_INDICES is 15.
18.3 RMM_RTT_BLOCK_LEVEL
RTT level of a block entry.
The value of RMM_RTT_BLOCK_LEVEL is 2.
18.4 RMM_RTT_PAGE_LEVEL
RTT level of a page entry.
The value of RMM_RTT_PAGE_LEVEL is 3.
18.5 RMM_RTT_TREE_PRIMARY
Index of primary RTT tree.
The value of RMM_RTT_TREE_PRIMARY is 0.
19 RMM types
This section describes types which are used to model the abstract state of the RMM.
19.1 RmmAddressRange type
The RmmAddressRange structure contains address range.
The RmmAddressRange structure is an abstract type.
The members of the RmmAddressRange structure are shown in the following table.
The RmmAddressRange structure is used in the following types:
19.2 RmmBoolean type
The RmmBoolean enumeration represents whether a feature is enabled.
The RmmBoolean enumeration is an abstract type.
The values of the RmmBoolean enumeration are shown in the following table.
| Name | Description |
|---|---|
| RMM_FALSE | False |
| RMM_TRUE | True |
The RmmBoolean enumeration is used in the following types:
19.3 RmmDataFlags type
The RmmDataFlags fieldset contains flags provided by the Host during DATA Granule creation.
The RmmDataFlags fieldset is a concrete type.
The width of the RmmDataFlags fieldset is 64 bits.
The fields of the RmmDataFlags fieldset are shown in the following diagram.
The fields of the RmmDataFlags fieldset are shown in the following table.
| Name | Bits | Description | Value |
|---|---|---|---|
| measure | 0 | Whether to measure DATA Granule contents | RmmDataMeasureContent |
| 63:1 | Reserved | SBZ |
The RmmDataFlags fieldset is used in the following types:
19.4 RmmDataMeasureContent type
The RmmDataMeasureContent enumeration represents whether to measure DATA Granule contents.
The RmmDataMeasureContent enumeration is a concrete type.
The width of the RmmDataMeasureContent enumeration is 1 bits.
The values of the RmmDataMeasureContent enumeration are shown in the following table.
| Encoding | Name | Description |
|---|---|---|
| 0 | NO_MEASURE_CONTENT | Do not measure DATA Granule contents. |
| 1 | MEASURE_CONTENT | Measure DATA Granule contents. |
The RmmDataMeasureContent enumeration is used in the following types:
19.5 RmmDevCommState type
The RmmDevCommState enumeration represents the state of communication between an RMM device object and a device.
The RmmDevCommState enumeration is an abstract type.
The values of the RmmDevCommState enumeration are shown in the following table.
| Name | Description |
|---|---|
| DEV_COMM_ACTIVE | The RMM has initiated a device transaction. One or more device requests associated with this device transaction have been sent from the RMM to the device. The RMM has not received all the expected device responses associated with this device transaction. |
| DEV_COMM_ERROR | The RMM encountered an error during communication with the device. |
| DEV_COMM_IDLE | The RMM is not communicating with the device. |
| DEV_COMM_PENDING | The RMM has a device request which is ready to be sent to the device. |
The RmmDevCommState enumeration is used in the following types:
19.6 RmmFeatureRmmDevMemCoherent type
The RmmFeatureRmmDevMemCoherent enumeration represents whether a feature is enableddevice memory location is within the system coherent memory space.
The RmmFeatureRmmDevMemCoherent enumeration is an abstract type.
The values of the RmmDevMemCoherent enumeration are shown in the following table.
| Name | Description |
|---|---|
| DEV_MEM_COHERENT | A device memory location is within the system coherent memory space |
| DEV_MEM_NON_COHERENT | A device memory location is not within the system coherent memory space |
The RmmDevMemCoherent enumeration is used in the following types:
19.7 RmmDevMemFlags type
The RmmDevMemFlags structure contains flags which describe properties of a device memory mapping.
The RmmDevMemFlags structure is an abstract type.
The members of the RmmDevMemFlags structure are shown in the following table.
| Name | Type | Description |
|---|---|---|
| coh | RmmDevMemCoherent | Whether the output address of the device memory mapping is within the system coherent memory space. |
| order | RmmDevMemOrdering | Ordering properties of the device memory location. |
The RmmDevMemFlags structure is used in the following types:
19.8 RmmDevMemOrdering type
The RmmDevMemOrdering enumeration represents ordering properties of a device memory location.
The RmmDevMemOrdering enumeration is an abstract type.
The values of the RmmDevMemOrdering enumeration are shown in the following table.
| Name | Description |
|---|---|
| DEV_MEM_LIMITED_ORDER | A device memory location is within a Limited Order Region (LOR) |
| DEV_MEM_NOT_LIMITED_ORDER | A device memory location is not within a Limited Order Region (LOR) |
The RmmDevMemOrdering enumeration is used in the following types:
19.9 RmmFeature type
The RmmFeature enumeration represents whether a feature is enabled.
The RmmFeature enumeration is an abstract type.
See also:
- Section 3
The values of the RmmFeature enumeration are shown in the following table.
| Name | Description |
|---|---|
| FEATURE_FALSE |
|
| FEATURE_TRUE |
|
The RmmFeature enumeration is used in the following types:
- RmmFeatures
- RmmRealm RmmFeatures
- RmmVdev
19.710 RmmFeatures type
The RmmFeatures structure contains features supported by RMM implementation.
The RmmFeatures structure is an abstract type.
See also:
- Section 3
The members of the RmmFeatures structure are shown in the following table.
| Name | Type | Description |
|---|---|---|
| max_ipa_width | UInt64 | Maximum IPA width |
| feat_lpa2 | RmmFeature | Whether LPA2 is supported |
| feat_sve | RmmFeature | Whether SVE is supported |
| max_sve_vl | UInt64 | Maximum SVE vector length |
| num_bps | UInt64 | Number of breakpoints available |
| num_wps | UInt64 | Number of watchpoints available |
| feat_pmu | RmmFeature | Number of watchpoints available |
| pmu_num_ctrs | UInt64 | Number of PMU counters available |
| feat_sha_256 | RmmFeature | Whether SHA-256 is supported |
| feat_sha_512 | RmmFeature | Whether SHA-512 is supported |
| feat_da | RmmFeature | Whether Realm device assignment is supported |
| max_num_aux_planes | UInt64 | Maximum number of auxiliary Planes |
| rtt_plane | RmmRttPlaneFeature | RTT usage models supported for multi-Plane Realms |
| rtt_s2ap_indirect | RmmFeature | Whether S2AP indirect encoding is supported for multi-Plane Realms |
| max_mecid | Bits64 | Maximum supported MECID |
| max_recs_order | UInt64 | Order of the maximum number of RECs which can be created per Realm |
| gicv3_num_lrs | UInt64 | Number of GICv3 List Registers which are available. |
19.811 RmmGptEntry type
The RmmGptEntry enumeration represents granule Protection Table entry.
The RmmGptEntry enumeration is an abstract type.
See also:
- Section 14.30
The values of the RmmGptEntry enumeration are shown in the following table.
| Name | Description |
|---|---|
| GPT_AAP | Access permitted via any PAS. |
| GPT_NS | Access permitted via Non-secure PAS only. |
| GPT_REALM | Access permitted via Realm PAS only. |
| GPT_ROOT | Access permitted via Root PAS only. |
| GPT_SECURE | Access permitted via Secure PAS only. |
The RmmGptEntry enumeration is used in the following types:
19.912 RmmGranule type
The RmmGranule structure contains attributes of a Granule.
The RmmGranule structure is an abstract type.
The members of the RmmGranule structure are shown in the following table.
| Name | Type | Description |
|---|---|---|
| gpt | RmmGptEntry | GPT entry |
| state | RmmGranuleState | Lifecycle state |
19.1013 RmmGranuleState type
The RmmGranuleState enumeration represents the state of a granule.
The RmmGranuleState enumeration is an abstract type.
The values of the RmmGranuleState enumeration are shown in the following table.
| Name | Description |
|---|---|
| DATA | Realm code or data. |
| DELEGATED | Delegated for use by the RMM. |
| DEV_DELEGATEDDEV_MAPPED | Device memory, mapped into a Realm. |
| PDEV | Physical device. |
| PDEV_AUX | Physical device auxiliary Granule. |
| RD | Realm Descriptor. |
| REC | Realm Execution Context. |
| REC_AUX | Realm Execution Context auxiliary Granule. |
| RTT | Realm Translation Table. |
| UNDELEGATED | Not delegated for use by the RMM. |
| DEV_MAPPEDVDEV | Device memory, mapped into a Realm. DEV_UNDELEGATED Device memory, not delegated for use by the RMM. PDEV PhysicalVirtual device. |
| PDEV_AUXVDEV_AUX | PhysicalVirtual device auxiliary Granule. |
| VSMMU | Virtual SMMU. |
The RmmGranuleState enumeration is used in the following types:
19.1114 RmmHashAlgorithm type
The RmmHashAlgorithm enumeration represents hash algorithm.
The RmmHashAlgorithm enumeration is an abstract type.
The values of the RmmHashAlgorithm enumeration are shown in the following table.
| Name | Description |
|---|---|
| HASH_SHA_256 | SHA-256 (Secure Hash Standard (SHS) [20]) |
| HASH_SHA_512 | SHA-512 (Secure Hash Standard (SHS) [20]) |
The RmmHashAlgorithm enumeration is used in the following types:
19.1215 RmmHipas type
The RmmHipas enumeration represents host IPA state.
The RmmHipas enumeration is an abstract type.
The values of the RmmHipas enumeration are shown in the following table.
| Name | Description |
|---|---|
| HIPAS_ASSIGNED | Protected IPA which is associated with a DATA Granule. |
| HIPAS_ASSIGNED_DEV | Protected IPA which is associated with a DEV_MAPPED Granule. |
| HIPAS_ASSIGNED_NS | Unprotected IPA which is associated with a physical Granule. |
| HIPAS_ASSIGNED_VSMMU | Protected IPA which is associated with a VSMMU Granule. |
| HIPAS_UNASSIGNED | Protected IPA which is not associated with any Granule. |
| HIPAS_UNASSIGNED_NS | Unprotected IPA which is not associated with any Granule. |
19.1316 RmmLfaPolicy type
The RmmLfaPolicy enumeration represents a Live Firmware Activation policy.
The RmmLfaPolicy enumeration is an abstract type.
The values of the RmmLfaPolicy enumeration are shown in the following table.
| Name | Description |
|---|---|
| LFA_ALLOW | LFA is permitted. |
| LFA_DISALLOW | LFA is not permitted. |
The RmmLfaPolicy enumeration is used in the following types:
19.1417 RmmMeasurementDescriptorData type
The RmmMeasurementDescriptorData structure contains data structure used to calculate the contribution to the RIM of a DATA Granule.
The RmmMeasurementDescriptorData structure is a concrete type.
The width of the RmmMeasurementDescriptorData structure is 256
(0x100) bytes.
See also:
- Section 15.3.1.4
The members of the RmmMeasurementDescriptorData structure are shown in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| desc_type | 0x0 |
Bits8 | Measurement descriptor type, value 0x0 |
| len | 0x8 |
UInt64 | Length of this data structure in bytes |
| rim | 0x10 |
RmmRealmMeasurement | Current RIM value |
| ipa | 0x50 |
Address | IPA at which the DATA Granule is mapped in the Realm |
| flags | 0x58 |
RmmDataFlags | Flags provided by Host |
| content | 0x60 |
RmmRealmMeasurement | Hash of contents of DATA Granule, or zero if flags indicate DATA Granule contents are unmeasured |
Unused bits of the RmmMeasurementDescriptorData structure MBZ.
19.1518 RmmMeasurementDescriptorRec type
The RmmMeasurementDescriptorRec structure contains data structure used to calculate the contribution to the RIM of a REC.
The RmmMeasurementDescriptorRec structure is a concrete type.
The width of the RmmMeasurementDescriptorRec structure is 256
(0x100) bytes.
See also:
- Section 15.3.3028.4
The members of the RmmMeasurementDescriptorRec structure are shown in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| desc_type | 0x0 |
Bits8 | Measurement descriptor type, value 0x1 |
| len | 0x8 |
UInt64 | Length of this data structure in bytes |
| rim | 0x10 |
RmmRealmMeasurement | Current RIM value |
| content | 0x50 |
RmmRealmMeasurement | Hash of 4KB page which contains REC parameters data structure |
Unused bits of the RmmMeasurementDescriptorRec structure MBZ.
19.1619 RmmMeasurementDescriptorRipas type
The RmmMeasurementDescriptorRipas structure contains data structure used to calculate the contribution to the RIM of a RIPAS change.
The RmmMeasurementDescriptorRipas structure is a concrete type.
The width of the RmmMeasurementDescriptorRipas structure is 256
(0x100) bytes.
See also:
- Section 15.3.4342.4
The members of the RmmMeasurementDescriptorRipas structure are shown in the following table.
| Name | Byte offset | Type | Description |
|---|---|---|---|
| desc_type | 0x0 |
Bits8 | Measurement descriptor type, value 0x2 |
| len | 0x8 |
UInt64 | Length of this data structure in bytes |
| rim | 0x10 |
RmmRealmMeasurement | Current RIM value |
| base | 0x50 |
Address | Base IPA of the RIPAS change |
| top | 0x58 |
Address | Top IPA of the RIPAS change |
Unused bits of the RmmMeasurementDescriptorRipas structure MBZ.
19.1720 RmmMecPolicy type
The RmmMecPolicy enumeration represents a MEC policy.
The RmmMecPolicy enumeration is an abstract type.
The values of the RmmMecPolicy enumeration are shown in the following table.
| Name | Description |
|---|---|
| MEC_POLICY_PRIVATE | The MEC protects memory owned by a single Realm. A MEC with this policy may be referred to as a Private MEC. |
| MEC_POLICY_SHARED | The MEC protects memory owned by multiple Realms. A MEC with this policy may be referred to as a Shared MEC. |
The RmmMecPolicy enumeration is used in the following types:
19.1821 RmmMecState type
The RmmMecState enumeration represents state of a MEC.
The RmmMecState enumeration is an abstract type.
The values of the RmmMecState enumeration are shown in the following table.
| Name | Description |
|---|---|
| MEC_STATE_PRIVATE_ASSIGNED | A Private MEC which is assigned to a Realm. |
| MEC_STATE_PRIVATE_UNASSIGNED | A Private MEC which is not assigned to a Realm. |
| MEC_STATE_SHARED | A Shared MEC. |
19.1922 RmmMemPermLocked type
The RmmMemPermLocked enumeration represents whether a memory permission value is locked.
The RmmMemPermLocked enumeration is an abstract type.
The values of the RmmMemPermLocked enumeration are shown in the following table.
| Name | Description |
|---|---|
| MEM_PERM_LOCKED | Memory permission value is locked |
| MEM_PERM_UNLOCKED | Memory permission value is unlocked |
The RmmMemPermLocked enumeration is used in the following types:
19.2023 RmmMemPerms type
The RmmMemPerms structure contains memory permissions.
The RmmMemPerms structure is an abstract type.
The members of the RmmMemPerms structure are shown in the following table.
| Name | Type | Description |
|---|---|---|
| values | Bits64[16] | Mapping from memory permission index to memory permission label Values use architectural encodings. |
The RmmMemPerms structure is used in the following types:
19.2124 RmmPdev type
The RmmPdev structure contains attributes of a PDEV.
The RmmPdev structure is an abstract type.
The members of the RmmPdev structure are shown in the following table.
| Name | Type | Description |
|---|---|---|
| pdev_id | Bits64 | Device identifier |
| prot_configprot | RmmPdevProtConfigRmmPdevProtection | Configuration of protection between system and device |
| segment_id | Bits8 | Segment identifier PCIe Segment identifier of the Root Port and endpoint. |
| ecam_addr | Address | ECAM base address of the PCIe configuration space. |
| root_id | Bits16 | Root Port identifier Physical PCIe routing identifier of the Root Port to which the endpoint is connected. |
| cert_id | UInt64 | Certificate identifier |
| rid_base | Bits16 | Base of requester ID range (inclusive). The value is in PCI BDF format. |
| rid_top | Bits16 | Top of requester ID range (exclusive). The value is in PCI BDF format. |
| hash_algo | RmmHashAlgorithm | Algorithm used to generate device digests |
| ide_sid | UInt64 | IDE stream ID |
| iocoh_num_addr_rangencoh_num_addr_range | UInt64 | Number of IOdevice non-coherent address ranges |
| iocoh_addr_rangencoh_addr_range | RmmAddressRange[16] | IODevice non-coherent address range |
| fcoh_num_addr_rangecoh_num_addr_range | UInt64 | Number of fully-device coherent address ranges |
| fcoh_addr_rangecoh_addr_range | RmmAddressRange[4] | Fully-Device coherent address range |
| aux | Address[32] | Addresses of auxiliary Granules |
| num_aux | UInt64 | Number of auxiliary Granules |
| state | RmmPdevState | Lifecycle state |
| comm_state | RmmDevCommState | Device communication state |
| num_vdevs | UInt64 | Number of VDEVs associated with this PDEV |
19.2225 RmmPdevProtConfigRmmPdevProtection type
The RmmPdevProtConfigRmmPdevProtection enumeration represents configuration of protection between system and device.
The RmmPdevProtConfigRmmPdevProtection enumeration is an abstract type.
See also:
- Section 9.1.1
The values of the RmmPdevProtConfigRmmPdevProtection enumeration are shown in the following table.
| Name | Description |
|---|---|
| PDEV_FCOH_E2E_IDE | Fully-coherent device with end-to-end protection provided by IDE. |
| PDEV_FCOH_E2E_SYS | Fully-coherent device with end-to-end protection provided by system construction. |
| PDEV_IOCOH_E2E_IDE | IO-coherent device with end-to-end protection provided by IDE. |
| PDEV_IOCOH_E2E_SYS | IO-coherent device with end-to-end protection provided by system construction. |
The RmmPdevProtConfigRmmPdevProtection enumeration is used in the following types:
19.2326 RmmPdevState type
The RmmPdevState enumeration represents the state of a PDEV.
The RmmPdevState enumeration is an abstract type.
The values of the RmmPdevState enumeration are shown in the following table.
| Name | Description |
|---|---|
| PDEV_COMMUNICATING | The RMM is communicating with the device. |
| PDEV_ERROR | Device has reported a fatal error. |
| PDEV_HAS_KEY | RMM has device public key. |
| PDEV_IDE_RESETTING | The PDEV’s IDE link is being reset. |
| PDEV_NEEDS_KEY | RMM needs device public key. |
| PDEV_NEW | Initial state of the device. |
| PDEV_READY | Secure connection between the RMM and the device has been established. Physical link between the device and memory is secured. Ready for creation of VDEV instances. |
| PDEV_STOPPED | Secure connection between the RMM and the device has been terminated. |
| PDEV_STOPPING | The RMM is communicating with the device to terminate the secure connection between the RMM and the device. |
The RmmPdevState enumeration is used in the following types:
19.2427 RmmPhysicalAddressSpace type
The RmmPhysicalAddressSpace enumeration represents the PAS of a Granule.
The RmmPhysicalAddressSpace enumeration is an abstract type.
See also:
- Section 14.30
The values of the RmmPhysicalAddressSpace enumeration are shown in the following table.
| Name | Description |
|---|---|
| PAS_NS | Non-secure PAS. |
| PAS_REALM | Realm PAS. |
| PAS_ROOT | Root PAS. |
| PAS_SECURE | Secure PAS. |
19.2528 RmmRdev type
The RmmRdev structure contains attributes of an RDEV.
The RmmRdev structure is an abstract type.
The members of the RmmRdev structure are shown in the following table.
| Name | Type | Description |
|---|---|---|
| state | RmmRdevState | Lifecycle state |
| operation | RmmRdevOperation | Operation being performed by the RDEV |
| vdev_ptr | Address | PA of VDEV associated with this RDEV |
19.2629 RmmRdevOperation type
The RmmRdevOperation enumeration represents operation being performed by an RDEV.
The RmmRdevOperation enumeration is an abstract type.
The values of the RmmRdevOperation enumeration are shown in the following table.
| Name | Description |
|---|---|
| RDEV_OP_GET_INTERFACE_REPORT | RDEV is handling an RSI_RDEV_GET_INTERFACE_REPORT request. |
| RDEV_OP_GET_MEASUREMENTS | RDEV is handling an RSI_RDEV_GET_MEASUREMENTS request. |
| RDEV_OP_LOCK | RDEV is handling an RSI_RDEV_LOCK request. |
| RDEV_OP_NONE | No operation is being performed. |
| RDEV_OP_START | RDEV is handling an RSI_RDEV_START request. |
The RmmRdevOperation enumeration is used in the following types:
19.2730 RmmRdevState type
The RmmRdevState enumeration represents the state of an RDEV.
The RmmRdevState enumeration is an abstract type.
The values of the RmmRdevState enumeration are shown in the following table.
| Name | Description |
|---|---|
| RDEV_ERROR | Device interface has reported a fatal error. |
| RDEV_LOCKED | Device interface is locked. |
| RDEV_LOCKED_BUSY | Device interface is locked and is handling an interruptible Realm device operation. |
| RDEV_STARTED | Device interface is started. |
| RDEV_STARTED_BUSY | Device interface is started and is handling an interruptible Realm device operation. |
| RDEV_STOPPED | Device interface is stopped. |
| RDEV_STOPPING | Device interface is stopping. |
| RDEV_UNLOCKED | Device interface is unlocked. |
| RDEV_UNLOCKED_BUSY | Device interface is unlocked and is handling an interruptible Realm device operation. |
The RmmRdevState enumeration is used in the following types:
19.2831 RmmRealm type
The RmmRealm structure contains attributes of a Realm.
The RmmRealm structure is an abstract type.
See also:
- Section 2.1
The members of the RmmRealm structure are shown in the following table.
| Name | Type | Description |
|---|---|---|
| feat_lpa2 | RmmFeature | Whether LPA2 is enabled for this Realm |
| ipa_width | UInt8 | IPA width in bits |
| measurements | RmmRealmMeasurement[5] | Realm measurements |
| hash_algo | RmmHashAlgorithm | Algorithm used to compute Realm measurements |
| rec_index | UInt64 | Index of next REC to be created |
| rtt_base | Address[4] | Realm Translation Table base addresses If rtt_tree_per_plane is FEATURE_FALSE then only the first entry is valid. If rtt_tree_per_plane is FEATURE_TRUE then only the first (num_aux_planes + 1) entries are valid. |
| rtt_level_start | Int64 | RTT starting level |
| rtt_num_start | UInt64 | Number of physically contiguous starting level RTTs |
| state | RmmRealmState | Lifecycle state |
| vmid | Bits16[4] | Virtual Machine Identifiers If rtt_tree_per_plane is FEATURE_FALSE then only the first entry is valid. If rtt_tree_per_plane is FEATURE_TRUE then only the first (num_aux_planes + 1) entries are valid. |
| rpv | Bits512 | Realm Personalization Value |
| feat_da | RmmFeature | Whether Realm device assignment is enabled for this Realm |
| rtt_tree_per_plane | RmmFeature | Whether this Realm has an RTT tree per Plane |
| num_aux_planes | UInt64 | Number of auxiliary Planes |
| rtt_s2ap_indirectrtt_s2ap_encoding | RmmFeatureRmmRttS2APEncoding | Whether the Realm uses S2AP indirect encoding |
| overlay_perms | RmmMemPerms[4] | Memory overlay permissions |
| overlay_locked | RmmMemPermLocked[16] | Whether memory overlay value is locked |
| lfa_policy | RmmLfaPolicy | Live Firmware Activation policy for components within the Realm’s TCB |
| mecid | Bits64 | Memory Encryption Context Identifier |
| mec_policy | RmmMecPolicy | MEC policy |
| num_recs | UInt64 | Number of RECs owned by this Realm |
| num_vdevs | UInt64 | Number of VDEVs owned by this Realm |
| vdev_count | UInt64 | Number of VDEVs which have been assigned to this Realm |
19.2932 RmmRealmMeasurement type
The RmmRealmMeasurement type is realm measurement.
The RmmRealmMeasurement type is a concrete type.
The width of the RmmRealmMeasurement type is 512 bits.
19.3033 RmmRealmState type
The RmmRealmState enumeration represents the state of a Realm.
The RmmRealmState enumeration is an abstract type.
The values of the RmmRealmState enumeration are shown in the following table.
| Name | Description |
|---|---|
| REALM_ACTIVE | Eligible for execution. |
| REALM_NEW | Under construction. Not eligible for execution. |
| REALM_SYSTEM_OFF | System has been turned off. Not eligible for execution. |
The RmmRealmState enumeration is used in the following types:
19.3134 RmmRec type
The RmmRec structure contains attributes of a REC.
The RmmRec structure is an abstract type.
See also:
- Section 2.3
The members of the RmmRec structure are shown in the following table.
| Name | Type | Description |
|---|---|---|
| attest_stateowner | RmmRecAttestStateAddress | Attestation token generation statePA of RD of Realm which owns this REC |
| aux | Address[16] | AddressesPAs of auxiliary Granules |
| flags | RmmRecFlags | Flags which control REC behavior |
| mpidr | Bits64 | MPIDR value |
| gic_owner | UInt64 | Index of Plane which is the GIC owner |
| state | RmmRecState | Lifecycle state |
| pending | RmmRecPending | Whether a REC operation is pending |
| emulatable_abort | RmmRecEmulatableAbort | Whether the most recent exit from this REC was due to an Emulatable Data Abort |
| gprs | Bits64[32] | General-purpose register values |
| mpidrpc | Bits64 | MPIDRProgram counter value |
| sysregs | RmmSystemRegisters | EL1 and EL0 system register values |
| ownerattest_state | RmmRecAttestState | Attestation token generation state |
| attest_challenge | Bits512 | Challenge for under-construction attestation token |
| ripas_addr | Address | Next IPA to be processed in RIPAS change |
| ripas_top | Address | Top IPA of pending RIPAS change |
| ripas_value | RmmRipas | RIPAS value of pending RIPAS change |
| ripas_destroyed | RmmRipasChangeDestroyed | Whether a RIPAS change from DESTROYED should be permitted |
| ripas_response | RmmRecResponse | Host response to RIPAS change request |
| dev_mem_addr | Address | Next IPA to be processed in device memory mapping validation |
| dev_mem_top | Address | Top IPA of pending device memory mapping validation |
| dev_mem_pa | Address | PA of RD of Realm which owns this RECdevice memory |
| dev_mem_flags | RmmDevMemFlags | Device memory mapping validation flags |
| pcdev_mem_response | RmmRecResponse | Host response to device memory mapping validation request |
| s2ap_addr | Address | Next IPA to be processed in S2AP change |
| s2ap_top | Address | Top IPA of pending S2AP change |
| s2ap_overlay_index | UInt4 | Overlay index of pending S2AP change |
| s2ap_response | RmmRecResponse | Host response to S2AP change request |
| vdev_id | Bits64 | Program counter value pending RmmRecPending Whether a REC operation is pending vdev_id Bits64Virtual device ID |
| inst_id | UInt64 | Device instance ID |
| inst_id_valid | RmmBoolean | Whether device instance ID is valid |
19.3235 RmmRecAttestState type
The RmmRecAttestState enumeration represents whether an attestation token generation operation is ongoing on this REC.
The RmmRecAttestState enumeration is an abstract type.
The values of the RmmRecAttestState enumeration are shown in the following table.
| Name | Description |
|---|---|
| ATTEST_IN_PROGRESS | An attestation token generation operation is in progress. |
| NO_ATTEST_IN_PROGRESS | No attestation token generation operation is in progress. |
The RmmRecAttestState enumeration is used in the following types:
19.3336 RmmRecEmulatableAbort type
The RmmRecEmulatableAbort enumeration represents whether the most recent exit from a REC was due to an Emulatable Data Abort.
The RmmRecEmulatableAbort enumeration is an abstract type.
The values of the RmmRecEmulatableAbort enumeration are shown in the following table.
| Name | Description |
|---|---|
| EMULATABLE_ABORT | The most recent exit from a REC was due to an Emulatable Data Abort. |
| NOT_EMULATABLE_ABORT | The most recent exit from a REC was not due to an Emulatable Data Abort. |
The RmmRecEmulatableAbort enumeration is used in the following types:
19.3437 RmmRecFlags type
The RmmRecFlags structure contains REC flags.
The RmmRecFlags structure is an abstract type.
The members of the RmmRecFlags structure are shown in the following table.
| Name | Type | Description |
|---|---|---|
| runnable | RmmRecRunnable | Whether the REC is elgible to run |
The RmmRecFlags structure is used in the following types:
19.3538 RmmRecPending type
The RmmRecPending enumeration represents whether a REC operation is pending.
The RmmRecPending enumeration is an abstract type.
The values of the RmmRecPending enumeration are shown in the following table.
| Name | Description |
|---|---|
| REC_PENDING_HOST_CALL | A Host call is pending. |
| REC_PENDING_NONE | No operation is pending. |
| REC_PENDING_PSCI | A PSCI operation is pending. |
| REC_PENDING_VDEV_REQUEST | A VDEV request is pending. |
The RmmRecPending enumeration is used in the following types:
19.3639 RmmRecResponse type
The RmmRecResponse enumeration represents whether the Host accepted or rejected a Realm request.
The RmmRecResponse enumeration is an abstract type.
The values of the RmmRecResponse enumeration are shown in the following table.
| Name | Description |
|---|---|
| ACCEPT | Host accepted the Realm request. |
| REJECT | Host rejected the Realm request. |
The RmmRecResponse enumeration is used in the following types:
19.3740 RmmRecRunnable type
The RmmRecRunnable enumeration represents whether a REC is eligible for execution.
The RmmRecRunnable enumeration is an abstract type.
The values of the RmmRecRunnable enumeration are shown in the following table.
| Name | Description |
|---|---|
| NOT_RUNNABLE | Not eligible for execution. |
| RUNNABLE | Eligible for execution. |
The RmmRecRunnable enumeration is used in the following types:
19.3841 RmmRecState type
The RmmRecState enumeration represents the state of a REC.
The RmmRecState enumeration is an abstract type.
The values of the RmmRecState enumeration are shown in the following table.
| Name | Description |
|---|---|
| REC_READY | REC is not currently running. |
| REC_RUNNING | REC is currently running. |
The RmmRecState enumeration is used in the following types:
19.3942 RmmRipas type
The RmmRipas enumeration represents realm IPA state.
The RmmRipas enumeration is an abstract type.
The values of the RmmRipas enumeration are shown in the following table.
| Name | Description |
|---|---|
| DESTROYED | Address which is inaccessible to the Realm due to an action taken by the Host. |
| DEV | Address where memory of an assigned Realm device is mapped. |
| EMPTY | Address where no Realm resources are mapped. |
| RAM | Address where private code or data owned by the Realm is mapped. |
The RmmRipas enumeration is used in the following types:
19.4043 RmmRipasChangeDestroyed type
The RmmRipasChangeDestroyed enumeration represents whether a RIPAS change from DESTROYED should be permitted.
The RmmRipasChangeDestroyed enumeration is an abstract type.
The values of the RmmRipasChangeDestroyed enumeration are shown in the following table.
| Name | Description |
|---|---|
| CHANGE_DESTROYED | A RIPAS change from DESTROYED should be permitted. |
| NO_CHANGE_DESTROYED | A RIPAS change from DESTROYED should not be permitted. |
The RmmRipasChangeDestroyed enumeration is used in the following types:
19.4144 RmmRtt type
The RmmRtt structure contains an RTT.
The RmmRtt structure is an abstract type.
The members of the RmmRtt structure are shown in the following table.
| Name | Type | Description |
|---|---|---|
| entries | RmmRttEntry[512] | Entries |
19.4245 RmmRttEntry type
The RmmRttEntry structure contains attributes of an RTT Entry.
The RmmRttEntry structure is an abstract type.
See also:
- Section 5.56
The members of the RmmRttEntry structure are shown in the following table.
| Name | Type | Description |
|---|---|---|
| addr | Address | Output address |
| ripas | RmmRipas | RIPAS |
| state | RmmRttEntryState | State |
| attr_prot | RmmRttMemAttr | Memory type and cacheability attributes for a Protected IPA This attribute and attr_unprot are aliased views of the underlying MemAttr field in the RTT descriptor. This view is valid if the RTT entry describes an address in Protected IPA space. The RMM uses stage 2 memory attributes to constrain the resultant memory type and cacheability attributes, based on the type of physical location identified by the output address. |
| attr_unprot | Bits3 | Memory type and cacheability attributes for an Unprotected IPA This attribute and attr_prot are aliased views of the underlying MemAttr field in the RTT descriptor. This view is valid if the RTT entry describes an address in Unprotected IPA space. The Host controls memory type and cacheability attributes by setting the value of the MemAttr[2:0] field in the RTT descriptor. |
| s2ap_basesh | UInt3RmmRttShareability | S2AP base permission indexShareability attributes. |
| s2ap_overlays2ap_direct | UInt3RmmRttS2APDirect | Directly-encoded S2AP overlay permission index This attribute is valid if the RTT entry describes an address in Unprotected IPA space and the Realm uses direct S2AP encoding. |
| s2ap_indirect | RmmRttS2APIndirect | Directly-encoded S2AP This attribute is valid if either of the following is true:
|
The RmmRttEntry structure is used in the following types:
19.4346 RmmRttEntryState type
The RmmRttEntryState enumeration represents the state of an RTTE.
The RmmRttEntryState enumeration is an abstract type.
The values of the RmmRttEntryState enumeration are shown in the following table.
| Name | Description |
|---|---|
| ASSIGNED | This RTTE is identified by a Protected IPA. The output address of this RTTE points to a DATA Granule. |
| ASSIGNED_DEV | This RTTE is identified by a Protected IPA. The output address of this RTTE points to a DEV_MAPPED Granule. |
| ASSIGNED_NS | This RTTE is identified by an Unprotected IPA. The output address of this RTTE points to a Granule-aligned address within NS PAS. |
| ASSIGNED_VSMMU | This RTTE is identified by a Protected IPA. The output address of this RTTE points to a VSMMU Granule. |
| AUX_DESTROYED | An auxiliary RTT was destroyed while a corresponding primary RTT entry was live. |
| TABLE | The output address of this RTTE points to the next-level RTT. |
| UNASSIGNED | This RTTE is identified by a Protected IPA. This RTTE is not associated with any Granule. |
| UNASSIGNED_NS | This RTTE is identified by an Unprotected IPA. This RTTE is not associated with any Granule. |
The RmmRttEntryState enumeration is used in the following types:
19.4447 RmmRttPlaneFeatureRmmRttMemAttr type
The RmmRttPlaneFeatureRmmRttMemAttr enumeration represents RTT usage models supported for multi-Plane Realmsmemory type and cacheability attributes.
The RmmRttPlaneFeatureRmmRttMemAttr enumeration is an abstract type.
The values of the RmmRttMemAttr enumeration are shown in the following table.
| Name | Description |
|---|---|
| MEMATTR_CACHEABLE | Memory type and cacheability attributes for a mapping to a cacheable location. |
| MEMATTR_NON_CACHEABLE | Memory type and cacheability attributes for a mapping to a non-cacheable location. |
| MEMATTR_PASSTHROUGH | Pass through memory type and cacheability attributes from stage 1 translation. |
The RmmRttMemAttr enumeration is used in the following types:
19.48 RmmRttPlaneFeature type
The RmmRttPlaneFeature enumeration represents RTT usage models supported for multi-Plane Realms.
The RmmRttPlaneFeature enumeration is an abstract type.
See also:
- Section 3.11
The values of the RmmRttPlaneFeature enumeration are shown in the following table.
| Name | Description |
|---|---|
| RTT_PLANE_AUX | A multi-Plane Realm uses auxiliary RTTs |
| RTT_PLANE_AUX_SINGLE | A multi-Plane Realm can be configured to either use auxiliary RTTs, or a single RTT |
| RTT_PLANE_SINGLE | A multi-Plane Realm uses a single RTT |
The RmmRttPlaneFeature enumeration is used in the following types:
19.4549 RmmRttWalkNotAligned RmmRttProtected type
The RmmRttWalkNotAligned structure contains result ofRmmRttProtected enumeration represents specifies whether an RTT walk which is not aligned to the requested level entry is in Protected IPA space or Unprotected IPA space.
The RmmRttWalkNotAligned structure is an RmmRttProtected enumeration is an abstract type.
The members of the RmmRttWalkNotAligned structurevalues of the RmmRttProtected enumeration are shown in the following table.
| Name | Description |
|---|---|
| RTT_PROTECTED | Protected IPA space. |
| RTT_UNPROTECTED | Unprotected IPA space. |
19.50 RmmRttS2APDirect type
The RmmRttS2APDirect structure contains directly-encoded S2AP.
The RmmRttS2APDirect structure is an abstract type.
The members of the RmmRttS2APDirect structure are shown in the following table.
| Name | Type | Description |
|---|---|---|
| validread | RmmBoolean | Read permission |
| write | RmmBoolean | Write permission |
The RmmRttS2APDirect structure is used in the following types:
19.51 RmmRttS2APEncoding type
The RmmRttS2APEncoding enumeration represents encoding used for S2AP.
The RmmRttS2APEncoding enumeration is an abstract type.
The values of the RmmRttS2APEncoding enumeration are shown in the following table.
| Name | Description |
|---|---|
| S2AP_DIRECT | Direct S2AP encoding. |
| S2AP_INDIRECT | Indirect S2AP encoding. |
The RmmRttS2APEncoding enumeration is used in the following types:
19.52 RmmRttS2APIndirect type
The RmmRttS2APIndirect structure contains indirectly-encoded S2AP.
The RmmRttS2APIndirect structure is an abstract type.
The members of the RmmRttS2APIndirect structure are shown in the following table.
The RmmRttS2APIndirect structure is used in the following types:
19.53 RmmRttShareability type
The RmmRttShareability enumeration represents shareability attributes.
The RmmRttShareability enumeration is an abstract type.
The values of the RmmRttShareability enumeration are shown in the following table.
The RmmRttShareability enumeration is used in the following types:
19.54 RmmRttWalkNotAligned type
The RmmRttWalkNotAligned structure contains result of an RTT walk which is not aligned to the requested level.
The RmmRttWalkNotAligned structure is an abstract type.
The members of the RmmRttWalkNotAligned structure are shown in the following table.
| Name | Type | Description |
|---|---|---|
| valid | RmmBoolean | TRUE if an RTT walk was performed whose result is not aligned to the requested level |
| index | UInt64 | RTT index |
| addr | Address | Address |
| walk | RmmRttWalkResult | Walk result |
19.4655 RmmRttWalkResult type
The RmmRttWalkResult structure contains result of an RTT walk.
The RmmRttWalkResult structure is an abstract type.
See also:
- Section 5.56.10
The members of the RmmRttWalkResult structure are shown in the following table.
| Name | Type | Description |
|---|---|---|
| level | Int8 | RTT level reached by the walk |
| rtt_addr | Address | Address of RTT reached by the walk |
| rtte | RmmRttEntry | RTTE reached by the walk |
The RmmRttWalkResult structure is used in the following types:
19.4756 RmmSystemRegisters type
The RmmSystemRegisters structure contains EL0 and EL1 system registers.
The RmmSystemRegisters structure is an abstract type.
The RmmSystemRegisters structure is used in the following types:
19.4857 RmmVdev type
The RmmVdev structure contains attributes of a VDEV.
The RmmVdev structure is an abstract type.
The members of the RmmVdev structure are shown in the following table.
| Name | Type | Description |
|---|---|---|
| vdev_id | Bits64 | Virtual device identifier |
| tdi_id | Bits64 | TDI identifier |
| inst_id | UInt64 | Instance identifier |
| pdev | Address | PA of parent PDEV |
| realm | Address | PA of RD of Realm which owns this VDEV |
| state | RmmVdevState | Lifecycle state |
| comm_state | RmmDevCommState | Device communication state |
| aux | Address[32] | Addresses of auxiliary Granules |
| num_aux | UInt64 | Number of auxiliary Granules |
| vsmmu | RmmFeature | Whether device uses a VSMMU |
| vsmmu_addr | Address | PA of VSMMU. This field is valid if vsmmu is FEATURE_TRUE. |
| vsid | Bits64 | Virtual Stream Identifier. This field is valid if vsmmu is FEATURE_TRUE. |
19.4958 RmmVdevState type
The RmmVdevState enumeration represents the state of a VDEV.
The RmmVdevState enumeration is an abstract type.
The values of the RmmVdevState enumeration are shown in the following table.
| Name | Description |
|---|---|
| VDEV_COMMUNICATING | The RMM is communicating with the VDEV. |
| VDEV_ERROR | Device interface has reported a fatal error. |
| VDEV_NEW | Initial state of the device. |
| VDEV_READY | No device transaction is associated with the VDEV. |
| VDEV_STOPPED | Device interface is stopped. |
| VDEV_STOPPING | The RMM is communicating with the VDEV to stop the device interface. |
The RmmVdevState enumeration is used in the following types:
19.5059 RmmVsmmu type
The RmmVsmmu structure contains attributes of a VSMMU.
The RmmVsmmu structure is an abstract type.
The members of the RmmVsmmu structure are shown in the following table.
20 Generic types
This section defines types which are shared between RMM interfaces and descriptions of RMM abstract state.
20.1 Address type
The Address type is an address.
The Address type is a concrete type.
The width of the Address type is 64 bits.
20.2 BitsN type
The BitsN type is an N-bit field.
The BitsN type is a concrete type.
The width of the BitsN type is N bits.
20.3 IntN type
The IntN type is an signed N-bit integer.
The IntN type is a concrete type.
The width of the IntN type is N bits.
20.4 UIntN type
The UIntN type is an unsigned N-bit integer.
The UIntN type is a concrete type.
The width of the UIntN type is N bits.
21 Flows
This section presents flows which explain how the RMM architecture can be used by the Host, and by Realm software.
Note that parts of the sequences below are for illustration only. For example, in the Realm creation flows, the RMI_GRANULE_DELEGATE and RMI_GRANULE_UNDELEGATE commands are called immediately before or after the RMI_X_CREATE and RMI_X_DESTROY commands respectively. An alternative flow would be for the Host to maintain a pool of Granules in the DELEGATED state, from which RMM data structures and Realm data can be allocated on demand.
21.1 Granule delegation flows
21.1.1 Granule delegation flow
The following diagram shows how the GPT entry of a Granule is changed to GPT_REALM.
See Arm Architecture Reference Manual Supplement, The Realm Management Extension (RME), for Armv9-A [2] for example software flows for the operations performed by the Monitor in this flow.
It is anticipated that the Monitor software will be required to use synchronization mechanisms to serialize access to the GPT.
21.1.2 Granule undelegation flow
The following diagram shows how the GPT entry of a Granule is changed from GPT_REALM.
See Arm Architecture Reference Manual Supplement, The Realm Management Extension (RME), for Armv9-A [2] for example software flows for the operations performed by the Monitor in this flow.
It is anticipated that the Monitor software will be required to use synchronization mechanisms to serialize access to the GPT.
21.2 Realm lifecycle flows
This section contains flows which relate to the Realm lifecycle.
See also:
- Section 2.1.5
21.2.1 Realm creation flow
The following diagram shows the flow for creating a Realm.
To create a Realm, the Host must allocate and delegate two Granules:
rdto store the Realm Descriptorrttwhich will be the starting level Realm Translation Table (RTT)
The Host also provides an NS Granule (params) containing
Realm creation parameters.
21.2.2 Realm Translation Table creation flow
The following diagram shows the flow for populating the Realm Translation Tables (RTTs).
The starting level Realm Translation Tables (RTTs) are provided at Realm creation time.
Subsequent levels of RTT are added using the RMI_RTT_CREATE command.
21.2.3 Initialize memory of New Realm flow
Immediately following Realm creation, every page in the Protected IPA space has its RIPAS set to EMPTY. There are two ways in which the Host can set the RIPAS of a given page of Protected IPA space to RAM:
Change the RIPAS by executing RMI_RTT_INIT_RIPAS, but do not populate the contents of the page. The RIM is extended to reflect the RIPAS change.
Both change the RIPAS and populate the page with contents provided by the Host, by executing RMI_DATA_CREATE. The RIM is extended to reflect the contents added by the Host.
Once the Host has performed either of these actions for a given page of Protected IPA space, that page cannot be further modified prior to Realm activation.
The following diagram shows the flow for initializing the RIPAS without providing contents.
The following diagram shows the flow for populating the page with contents provided by the Host.
To do this, the Host must:
- Delegate a destination Granule (
dst). - Provide an NS Granule (
src), whose contents will be copied into the destination Granule. - Specify the Protected IPA
ipaat which thedstGranule should be mapped in the Realm’s IPA space. - Ensure that the level 3 RTT which contains the RTTE identified by the Protected IPA has been created.
Once the Data Granule has been created, the src Granule
can be reallocated by the Host.
See also:
21.2.4 REC creation flow
The following diagram shows the flow for creating a REC during Realm creation.
To create a REC, the Host must:
- Delegate a destination Granule (
rec). - Query the number of auxiliary Granules required, by calling RMI_REC_AUX_COUNT
- Delegate the required number of auxiliary Granules
(
aux) - Provide auxiliary Granule addresses, register values and REC
activation status in an NS Granule (
params).
Once the REC has been created, the params Granule can be
reallocated by the Host.
21.2.5 Realm destruction flow
The following diagram shows the flow for destroying a Realm.
To destroy a Realm, the Host must first make the Realm non-live. This is done by destroying (in any order) the objects which are associated with the Realm:
- Data Granules
- RECs
- RTTs
Finally, the Realm itself can be destroyed.
Once each of these objects has been destroyed, the corresponding Granules can be undelegated and reallocated by the Host.
See also:
21.3 Realm exception model flows
This section contains flows which relate to the Realm exception model.
See also:
- Section 4
21.3.1 Realm entry and exit flow
The following diagram shows how a Realm is executed, and illustrates the different reasons for exiting the Realm and returning control to the Host.
A REC is entered using the RMI_REC_ENTER command. The parameters to this command include:
- an RmiRecEnter object, which is a data structure used to pass values from the Host to the RMM on REC entry
- an RmiRecExit object, which is a data structure used to pass values from the RMM to the Host on REC exit
21.3.2 Host call flow
The following diagram shows how software executing inside the Realm can voluntarily yield control back to the Host by making a Host call.
A REC is entered using the RMI_REC_ENTER command. The parameters to this command include:
- an RmiRecEnter object, which is a data structure used to pass values from the Host to the RMM on REC entry
- an RmiRecExit object, which is a data structure used to pass values from the RMM to the Host on REC exit
On execution of RSI_HOST_CALL, arguments are copied from the RsiHostCall object in Realm memory into the RmiRecExit object in NS memory. On the subsequent RMI_REC_ENTER, return values are copied from the RmiRecEnter object in NS memory into the RsiHostCall object in Realm memory.
See also:
- Section 4.5
21.3.3 REC exit due to Data Abort fault flow
The following diagram shows how a Data Abort due to a Realm access is taken to the Host.
A REC is entered using the RMI_REC_ENTER command. The parameters to this command include:
- an RmiRecEnter object, which is a data structure used to pass values from the Host to the RMM on REC entry
- an RmiRecExit object, which is a data structure used to pass values from the RMM to the Host on REC exit
See also:
- Section 4
21.3.4 MMIO emulation flow
The following diagram shows how an MMIO access by a Realm can be emulated by the Host.
See also:
- Section 4
21.4 PSCI flows
21.4.1 PSCI_CPU_ON flow
The following diagram shows how one Realm VPE can set the “runnable” flag in another Realm VPE by executing PSCI_CPU_ON.
21.5 Realm memory management flows
This section contains flows which relate to management of Realm memory.
See also:
- Section 5
21.5.1 Add memory to Active Realm flow
The following diagram shows the flow for adding memory to a Realm whose state is REALM_ACTIVE.
To add memory to a Realm whose state is REALM_ACTIVE, the Host must:
- Delegate a destination Granule (
dst). - Specify the Protected IPA at which the
dstGranule will be mapped in the Realm’s IPA space. - Ensure that the level 3 RTT which contains the RTTE identified by the Protected IPA has been created.
Once a given Protected IPA has been populated with unknown content, it cannot be repopulated.
21.5.2 NS memory flow
The following diagram describes how NS memory can be mapped into a Realm.
21.5.3 RIPAS change flow
The following diagram describes how a Realm requests a RIPAS change, and how that request is handled by the Host.
- The Realm calls RSI_IPA_STATE_SET to request a RIPAS change for IPA
range
[base, top). - This causes a REC exit due to RIPAS change pending.
On taking a REC exit due to RIPAS change pending, the Host does the following:
- Reads the region base and top addresses from the RmiRecExit object.
- Applies the requested RIPAS change to an IPA range starting from the base of the target region, and extending no further than the top of the target region.
- Calls RMI_REC_ENTER to re-enter the REC.
The Realm observes in X1 the top of the region for which the RIPAS change was applied.
21.5.4 S2AP change flow
The following diagram describes how a Realm requests a S2AP change, and how that request is handled by the Host.
- The Realm calls RSI_MEM_SET_PERM_INDEX to request an S2AP change for
IPA range
[base, top). - This causes a REC exit due to S2AP change pending.
On taking a REC exit due to S2AP change pending, the Host does the following:
- Reads the region base and top addresses from the RmiRecExit object.
- Applies the requested S2AP change to an IPA range starting from the base of the target region, and extending no further than the top of the target region.
- Calls RMI_REC_ENTER to re-enter the REC.
The Realm observes in X1 the top of the region for which the S2AP change was applied.
21.6 Realm interrupts and timers flows
21.6.1 Interrupt flow
The following diagram shows how a virtual interrupt is injected into a Realm by the Host.
See also:
- Section 6.1
21.6.2 Timer interrupt delivery flow
The following diagram shows how a timer interrupt is delivered to and handled by a Realm.
See also:
- Section 6.2
21.7 Realm attestation flows
21.7.1 Attestation token generation flow
The following diagram shows the flow for a Realm to obtain an attestation token.
The Realm first calls RSI_ATTESTATION_TOKEN_INIT, providing a challenge value. The output values include an upper bound on the attestation token size.
The Realm then calls RSI_ATTESTATION_TOKEN_CONTINUE, providing the address of a buffer where the next part of the attestation token will be written. This command is called in a loop, until the result is not RSI_INCOMPLETE.
21.7.2 Handling interrupts during attestation token generation flow
The following diagram shows how interrupts are handled during generation of an attestation token.
If the RMM detects that a physical interrupt is pending during execution of RSI_ATTESTATION_TOKEN_CONTINUE, it saves the execution context to the REC object, and performs a REC exit due to IRQ.
During handling of the IRQ, the Host may signal a virtual interrupt to the REC.
On the next entry to the REC, if a virtual interrupt is pending, it is taken to the REC’s exception vector.
Whether or not a virtual interrupt was taken, on return to the original thread, the REC determines that X0 is RSI_INCOMPLETE, and therefore calls RSI_ATTESTATION_TOKEN_CONTINUE again.
21.8 Realm device assignment flows
See Section 9.
22 Realm shared memory protocol
This section describes a protocol for management of memory which is shared between a Realm and the Host. This protocol makes use of the primitives described in this specification. However, the protocol itself is not part of the RMM architecture. Use of this protocol is subject to a contract between the Realm and Host software agents.
See also:
- Section 5
22.1 Realm shared memory protocol description
The Host agrees to provide the Realm with a certain amount of memory. This memory is referred to below as the Realm’s “memory footprint”.
The memory footprint is described to the Realm, for example via firmware tables. The Realm can choose, at any point during its execution, how much of its memory footprint is protected (accessible only to the Realm) and how much is shared with the Host.
Realm software treats the most significant IPA bit as a “protection
attribute” bit. This means that for every Protected IPA (in which the
most significant bit is '0'), there exists a corresponding
Unprotected IPA alias, which is generated by setting the most
significant bit to '1'.
The choice of whether a given page is protectedprivate or shared at a given time is expressed by setting the RIPAS of the Protected IPA:
- If the RIPAS of the Protected IPA is RAM, the page is protected and access to the Unprotected IPA alias causes a Synchronous External Abort taken to the Realmprivate.
- If the RIPAS of the Protected IPA is EMPTY, the page is shared and access to the Unprotected IPA alias does not cause a Synchronous External Abort taken to the Realm.
The initial RIPAS for every page in the Realm’s memory footprint is described to the Realm, for example via firmware tables. The Host agrees that during Realm execution, it will accept a RIPAS change request on any page within the Realm’s memory footprint.
Based on the private / shared status of the page, the Host agrees to the following behaviour regarding the Unprotected IPA alias:
If the page is private, the Host does not create a valid mapping at the Unprotected IPA alias. Realm access to the Unprotected IPA alias causes a REC exit due to Data Abort. In response, the Host sets the “inject_sea” flag on the next REC entry, which causes a Synchronous External Abort to be taken to the Realm.
If the page is shared, the Host creates (either eagerly, or in response to a REC exit due to Data Abort) a valid mapping at the Unprotected IPA alias. Realm access to the Unprotected IPA alias does not cause a Synchronous External Abort taken to the Realm.
22.2 Realm shared memory protocol flow
The following diagram illustrates how the protocol is used to set up and tear down a shared memory buffer.
See also:
- Section 21.5.3
Glossary
ASL
Language used to express pseudocode implementations. Formal language definition can be found in Arm Specification Language Reference Manual [18].
CBOR
CCA
CCA platform
CDDL
COSE
DOE
DSM
EAT
ECAM
FAL
FID
GIC
See Arm Generic Interrupt Controller (GIC) Architecture Specification version 3 and version 4 [6]
GPF
GPT
Table which determines the Physical Address Space of each Granule.
HIPAS
Host
IAK
IDE
See PCI Express 6.0 specification [14]
IPA
Address space visible to software executing at EL1 in the Realm.
IPI
IRI
A subset of the components which make up the GIC.
ITS
A service provided by the GIC.
LFA
LOR
MBZ
MEC
MECID
MMIO
MPIDR
NS
PAS
PDEV
Object which represents a communication channel between the RMM and a physical device, for example a PCIe device.
PE
PMU
PSCI
See Arm Power State Coordination Interface (PSCI) [23]
PSMMU
See Arm System Memory Management Unit Architecture Specification [16]
RAK
RD
Object which stores attributes of a Realm.
RDEV
Object which represents Realm view of an assigned device
Realm
REC
Object which stores PE state associated with a thread of execution within a Realm.
REM
RHA
RIM
RIPAS
RME
RMI
RMM
RNVS
RPV
RSI
RTT
Object which describes the IPA space of a Realm.
RTTE
SBZ
SEA
SGI
SMCCC
See Arm SMC Calling Convention [17]
SMMU
See Arm System Memory Management Unit Architecture Specification [16]
SPDM
See Security Protocol and Data Model (SPDM) [19] and Secured Messages using SPDM Specification version 1.1.0 [15]
SPM
TA
TOS
TSM
See Section 9
VDEV
Object which represents the binding between a device function and a Realm.
VMM
VMSA
VPE
VSMMU
See Arm System Memory Management Unit Architecture Specification [16]
Wiping