fix(doc): document missing RMM-EL3 runtime services

This patch adds documentation for the missing RMM-EL3
runtime services:

* RMM_RMI_REQ_COMPLETE
* RMM_GTSI_DELEGATE
* RMM_GTSI_UNDELEGATE

This patch also fixes a couple of minor bugs on return codes
for delegate/undelegate internal APIs.

Signed-off-by: Javier Almansa Sobrino <javier.almansasobrino@arm.com>
Change-Id: Ic721005e7851e838eebaee7865ba78fadc3309e4
This commit is contained in:
Javier Almansa Sobrino 2022-07-04 17:06:36 +01:00
parent 6be1aa7e9d
commit e50fedbc86
5 changed files with 142 additions and 18 deletions

View file

@ -200,7 +200,7 @@ For the type specification of the RMM Boot Manifest v0.1, refer to
.. _runtime_services_and_interface:
RMMM-EL3 Runtime Interface
RMM-EL3 Runtime Interface
__________________________
This section defines the RMM-EL3 runtime interface which specifies the ABI for
@ -247,9 +247,133 @@ implemented by EL3 Firmware.
:header: "FID", "Command"
:widths: 2 5
0xC400018F,``RMM_RMI_REQ_COMPLETE``
0xC40001B0,``RMM_GTSI_DELEGATE``
0xC40001B1,``RMM_GTSI_UNDELEGATE``
0xC40001B2,``RMM_ATTEST_GET_REALM_KEY``
0xC40001B3,``RMM_ATTEST_GET_PLAT_TOKEN``
RMM_RMI_REQ_COMPLETE command
============================
Notifies the completion of an RMI call to the Non-Secure world.
This call is the only function currently in RMM-EL3 runtime interface which
results in a world switch to NS. This call is the reply to the original RMI
call and it is forwarded by EL3 to the NS world.
FID
---
``0xC400018F``
Input values
------------
.. csv-table::
:header: "Name", "Register", "Field", "Type", "Description"
:widths: 1 1 1 1 5
fid,x0,[63:0],UInt64,Command FID
err_code,x1,[63:0],RmiCommandReturnCode,Error code returned by the RMI service invoked by NS World. See Realm Management Monitor specification for more info
Output values
-------------
This call does not return.
Failure conditions
------------------
Since this call does not return to RMM, there is no failure condition which
can be notified back to RMM.
RMM_GTSI_DELEGATE command
=========================
Delegate a memory granule by changing its PAS from Non-Secure to Realm.
FID
---
``0xC40001B0``
Input values
------------
.. csv-table::
:header: "Name", "Register", "Field", "Type", "Description"
:widths: 1 1 1 1 5
fid,x0,[63:0],UInt64,Command FID
base_pa,x1,[63:0],Address,PA of the start of the granule to be delegated
Output values
-------------
.. csv-table::
:header: "Name", "Register", "Field", "Type", "Description"
:widths: 1 1 1 2 4
Result,x0,[63:0],Error Code,Command return status
Failure conditions
------------------
The table below shows all the possible error codes returned in ``Result`` upon
a failure. The errors are ordered by condition check.
.. csv-table::
:header: "ID", "Condition"
:widths: 1 5
``E_RMM_BAD_ADDR``,``PA`` does not correspond to a valid granule address
``E_RMM_BAD_PAS``,The granule pointed by ``PA`` does not belong to Non-Secure PAS
``E_RMM_OK``,No errors detected
RMM_GTSI_UNDELEGATE command
===========================
Undelegate a memory granule by changing its PAS from Realm to Non-Secure.
FID
---
``0xC40001B1``
Input values
------------
.. csv-table::
:header: "Name", "Register", "Field", "Type", "Description"
:widths: 1 1 1 1 5
fid,x0,[63:0],UInt64,Command FID
base_pa,x1,[63:0],Address,PA of the start of the granule to be undelegated
Output values
-------------
.. csv-table::
:header: "Name", "Register", "Field", "Type", "Description"
:widths: 1 1 1 2 4
Result,x0,[63:0],Error Code,Command return status
Failure conditions
------------------
The table below shows all the possible error codes returned in ``Result`` upon
a failure. The errors are ordered by condition check.
.. csv-table::
:header: "ID", "Condition"
:widths: 1 5
``E_RMM_BAD_ADDR``,``PA`` does not correspond to a valid granule address
``E_RMM_BAD_PAS``,The granule pointed by ``PA`` does not belong to Realm PAS
``E_RMM_OK``,No errors detected
RMM_ATTEST_GET_REALM_KEY command
================================

View file

@ -38,7 +38,7 @@
* RMM.
*/
/* 0x18F */
#define RMMD_RMI_REQ_COMPLETE SMC64_RMI_FID(U(0x3F))
#define RMM_RMI_REQ_COMPLETE SMC64_RMI_FID(U(0x3F))
/* RMM_BOOT_COMPLETE arg0 error codes */
#define E_RMM_BOOT_SUCCESS (0)
@ -80,8 +80,8 @@
((_fid & 0x00FE0000) == 0U)); })
/* 0x1B0 - 0x1B1 */
#define RMMD_GTSI_DELEGATE SMC64_RMMD_EL3_FID(U(0))
#define RMMD_GTSI_UNDELEGATE SMC64_RMMD_EL3_FID(U(1))
#define RMM_GTSI_DELEGATE SMC64_RMMD_EL3_FID(U(0))
#define RMM_GTSI_UNDELEGATE SMC64_RMMD_EL3_FID(U(1))
/* Return error codes from RMM-EL3 SMCs */
#define E_RMM_OK 0
@ -110,7 +110,7 @@
* ret1 - Size of the realm attestation key if successful.
*/
/* 0x1B2 */
#define RMMD_ATTEST_GET_REALM_KEY SMC64_RMMD_EL3_FID(U(2))
#define RMM_ATTEST_GET_REALM_KEY SMC64_RMMD_EL3_FID(U(2))
/*
* Retrieve Platform token from EL3.
@ -126,7 +126,7 @@
* ret1 - Size of the platform token if successful.
*/
/* 0x1B3 */
#define RMMD_ATTEST_GET_PLAT_TOKEN SMC64_RMMD_EL3_FID(U(3))
#define RMM_ATTEST_GET_PLAT_TOKEN SMC64_RMMD_EL3_FID(U(3))
/* ECC Curve types for attest key generation */
#define ATTEST_KEY_CURVE_ECC_SECP384R1 0

View file

@ -1076,7 +1076,7 @@ int gpt_delegate_pas(uint64_t base, size_t size, unsigned int src_sec_state)
VERBOSE(" Caller: %u, Current GPI: %u\n", src_sec_state,
gpi_info.gpi);
spin_unlock(&gpt_lock);
return -EINVAL;
return -EPERM;
}
if (src_sec_state == SMC_FROM_SECURE) {
@ -1197,7 +1197,7 @@ int gpt_undelegate_pas(uint64_t base, size_t size, unsigned int src_sec_state)
VERBOSE(" Caller: %u, Current GPI: %u\n", src_sec_state,
gpi_info.gpi);
spin_unlock(&gpt_lock);
return -EINVAL;
return -EPERM;
}

View file

@ -311,7 +311,7 @@ uint64_t rmmd_rmi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
}
switch (smc_fid) {
case RMMD_RMI_REQ_COMPLETE:
case RMM_RMI_REQ_COMPLETE:
return rmmd_smc_forward(REALM, NON_SECURE, x1,
x2, x3, x4, 0, handle);
@ -419,16 +419,16 @@ uint64_t rmmd_rmm_el3_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
}
switch (smc_fid) {
case RMMD_GTSI_DELEGATE:
case RMM_GTSI_DELEGATE:
ret = gpt_delegate_pas(x1, PAGE_SIZE_4KB, SMC_FROM_REALM);
SMC_RET1(handle, gpt_to_gts_error(ret, smc_fid, x1));
case RMMD_GTSI_UNDELEGATE:
case RMM_GTSI_UNDELEGATE:
ret = gpt_undelegate_pas(x1, PAGE_SIZE_4KB, SMC_FROM_REALM);
SMC_RET1(handle, gpt_to_gts_error(ret, smc_fid, x1));
case RMMD_ATTEST_GET_PLAT_TOKEN:
case RMM_ATTEST_GET_PLAT_TOKEN:
ret = rmmd_attest_get_platform_token(x1, &x2, x3);
SMC_RET2(handle, ret, x2);
case RMMD_ATTEST_GET_REALM_KEY:
case RMM_ATTEST_GET_REALM_KEY:
ret = rmmd_attest_get_signing_key(x1, &x2, x3);
SMC_RET2(handle, ret, x2);

View file

@ -93,7 +93,7 @@ static trp_args_t *trp_ret_rmi_version(void)
{
VERBOSE("RMM version is %u.%u\n", RMI_ABI_VERSION_MAJOR,
RMI_ABI_VERSION_MINOR);
return set_smc_args(RMMD_RMI_REQ_COMPLETE, RMI_ABI_VERSION,
return set_smc_args(RMM_RMI_REQ_COMPLETE, RMI_ABI_VERSION,
0, 0, 0, 0, 0, 0);
}
@ -105,13 +105,13 @@ static trp_args_t *trp_asc_mark_realm(unsigned long long x1)
unsigned long long ret;
VERBOSE("Delegating granule 0x%llx\n", x1);
ret = trp_smc(set_smc_args(RMMD_GTSI_DELEGATE, x1, 0, 0, 0, 0, 0, 0));
ret = trp_smc(set_smc_args(RMM_GTSI_DELEGATE, x1, 0, 0, 0, 0, 0, 0));
if (ret != 0ULL) {
ERROR("Granule transition from NON-SECURE type to REALM type "
"failed 0x%llx\n", ret);
}
return set_smc_args(RMMD_RMI_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0);
return set_smc_args(RMM_RMI_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0);
}
/*******************************************************************************
@ -122,13 +122,13 @@ static trp_args_t *trp_asc_mark_nonsecure(unsigned long long x1)
unsigned long long ret;
VERBOSE("Undelegating granule 0x%llx\n", x1);
ret = trp_smc(set_smc_args(RMMD_GTSI_UNDELEGATE, x1, 0, 0, 0, 0, 0, 0));
ret = trp_smc(set_smc_args(RMM_GTSI_UNDELEGATE, x1, 0, 0, 0, 0, 0, 0));
if (ret != 0ULL) {
ERROR("Granule transition from REALM type to NON-SECURE type "
"failed 0x%llx\n", ret);
}
return set_smc_args(RMMD_RMI_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0);
return set_smc_args(RMM_RMI_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0);
}
/*******************************************************************************