feat(rmmd): add support to create a boot manifest

This patch also adds an initial RMM Boot Manifest (v0.1) for fvp
platform.

Signed-off-by: Javier Almansa Sobrino <javier.almansasobrino@arm.com>
Change-Id: I1374f8f9cb207028f1820953cd2a5cf6d6c3b948
This commit is contained in:
Javier Almansa Sobrino 2022-04-25 17:18:15 +01:00
parent dc65ae4643
commit 1d0ca40e90
14 changed files with 257 additions and 80 deletions

View file

@ -2081,6 +2081,19 @@ This function returns the size of the shared area between EL3 and RMM (or 0 on
failure). A pointer to the shared area (or a NULL pointer on failure) is stored
in the pointer passed as argument.
Function : plat_rmmd_load_manifest() [when ENABLE_RME == 1]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
Arguments : rmm_manifest_t *manifest
Return : int
When ENABLE_RME is enabled, this function populates a boot manifest for the
RMM image and stores it in the area specified by manifest.
When ENABLE_RME is disabled, this function is not used.
Function : bl31_plat_enable_mmu [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View file

@ -13,6 +13,9 @@
#if defined(SPD_spmd)
#include <services/spm_core_manifest.h>
#endif
#if ENABLE_RME
#include <services/rmm_core_manifest.h>
#endif
#if TRNG_SUPPORT
#include "plat_trng.h"
#endif
@ -305,11 +308,15 @@ plat_local_state_t plat_get_target_pwr_state(unsigned int lvl,
/*******************************************************************************
* Mandatory BL31 functions when ENABLE_RME=1
******************************************************************************/
#if ENABLE_RME
int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
uintptr_t hash, size_t hash_size);
int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
unsigned int type);
size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared);
int plat_rmmd_load_manifest(rmm_manifest_t *manifest);
#endif
/*******************************************************************************
* Optional BL31 functions (may be overridden)
******************************************************************************/

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef RMM_CORE_MANIFEST_H
#define RMM_CORE_MANIFEST_H
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <lib/cassert.h>
#define RMMD_MANIFEST_VERSION_MAJOR U(0)
#define RMMD_MANIFEST_VERSION_MINOR U(1)
/*
* Manifest version encoding:
* - Bit[31] RES0
* - Bits [30:16] Major version
* - Bits [15:0] Minor version
*/
#define _RMMD_MANIFEST_VERSION(_major, _minor) \
((((_major) & 0x7FFF) << 16) | ((_minor) & 0xFFFF))
#define RMMD_MANIFEST_VERSION _RMMD_MANIFEST_VERSION( \
RMMD_MANIFEST_VERSION_MAJOR, \
RMMD_MANIFEST_VERSION_MINOR)
#define RMMD_GET_MANIFEST_VERSION_MAJOR(_version) \
((_version >> 16) & 0x7FFF)
#define RMMD_GET_MANIFEST_VERSION_MINOR(_version) \
(_version & 0xFFFF)
/* Boot manifest core structure as per v0.1 */
typedef struct rmm_manifest {
uint32_t version; /* Manifest version */
uintptr_t plat_data; /* Manifest platform data */
} rmm_manifest_t;
CASSERT(offsetof(rmm_manifest_t, version) == 0,
rmm_manifest_t_version_unaligned);
CASSERT(offsetof(rmm_manifest_t, plat_data) == 8,
rmm_manifest_t_plat_data_unaligned);
#endif /* RMM_CORE_MANIFEST_H */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -7,9 +7,11 @@
#ifndef PLATFORM_TRP_H
#define PLATFORM_TRP_H
#include <services/rmm_core_manifest.h>
/*******************************************************************************
* Mandatory TRP functions (only if platform contains a TRP)
******************************************************************************/
void trp_early_platform_setup(void);
void trp_early_platform_setup(rmm_manifest_t *manifest);
#endif /* PLATFORM_TRP_H */

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef TRP_HELPERS_H
#define TRP_HELPERS_H
/* Definitions to help the assembler access the SMC/ERET args structure */
#define TRP_ARGS_SIZE TRP_ARGS_END
#define TRP_ARG0 0x0
#define TRP_ARG1 0x8
#define TRP_ARG2 0x10
#define TRP_ARG3 0x18
#define TRP_ARG4 0x20
#define TRP_ARG5 0x28
#define TRP_ARG6 0x30
#define TRP_ARG7 0x38
#define TRP_ARGS_END 0x40
#ifndef __ASSEMBLER__
#include <platform_def.h>
/* Data structure to hold SMC arguments */
typedef struct trp_args {
uint64_t regs[TRP_ARGS_END >> 3];
} __aligned(CACHE_WRITEBACK_GRANULE) trp_args_t;
trp_args_t *set_smc_args(uint64_t arg0,
uint64_t arg1,
uint64_t arg2,
uint64_t arg3,
uint64_t arg4,
uint64_t arg5,
uint64_t arg6,
uint64_t arg7);
__dead2 void trp_boot_abort(uint64_t err);
#endif /* __ASSEMBLER __ */
#endif /* TRP_HELPERS_H */

View file

@ -17,6 +17,9 @@
#include <lib/xlat_tables/xlat_tables_compat.h>
#include <platform_def.h>
#include <services/arm_arch_svc.h>
#if ENABLE_RME
#include <services/rmm_core_manifest.h>
#endif
#if SPM_MM
#include <services/spm_mm_partition.h>
#endif
@ -527,4 +530,15 @@ size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared)
return (size_t)RMM_SHARED_SIZE;
}
int plat_rmmd_load_manifest(rmm_manifest_t *manifest)
{
assert(manifest != NULL);
manifest->version = RMMD_MANIFEST_VERSION;
manifest->plat_data = (uintptr_t)NULL;
return 0;
}
#endif

View file

@ -1,5 +1,5 @@
#
# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
# Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@ -8,3 +8,5 @@
RMM_SOURCES += plat/arm/common/trp/arm_trp_setup.c \
plat/arm/common/arm_topology.c \
plat/common/aarch64/platform_mp_stack.S
INCLUDES += -Iinclude/services/trp

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Arm Limited. All rights reserved.
* Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -8,33 +8,65 @@
#include <common/debug.h>
#include <drivers/arm/pl011.h>
#include <drivers/console.h>
#include <services/rmm_core_manifest.h>
#include <services/rmmd_svc.h>
#include <services/trp/platform_trp.h>
#include <trp_helpers.h>
#include <plat/arm/common/plat_arm.h>
#include <platform_def.h>
/*******************************************************************************
* Received from boot manifest and populated here
******************************************************************************/
extern uint32_t trp_boot_manifest_version;
/*******************************************************************************
* Initialize the UART
******************************************************************************/
static console_t arm_trp_runtime_console;
void arm_trp_early_platform_setup(void)
static int arm_trp_process_manifest(rmm_manifest_t *manifest)
{
/* Verify the Boot Manifest Version. Only the Major is considered */
if (RMMD_MANIFEST_VERSION_MAJOR !=
RMMD_GET_MANIFEST_VERSION_MAJOR(manifest->version)) {
return E_RMM_BOOT_MANIFEST_VERSION_NOT_SUPPORTED;
}
trp_boot_manifest_version = manifest->version;
flush_dcache_range((uintptr_t)manifest, sizeof(rmm_manifest_t));
return 0;
}
void arm_trp_early_platform_setup(rmm_manifest_t *manifest)
{
int rc;
rc = arm_trp_process_manifest(manifest);
if (rc != 0) {
trp_boot_abort(rc);
}
/*
* Initialize a different console than already in use to display
* messages from trp
*/
int rc = console_pl011_register(PLAT_ARM_TRP_UART_BASE,
PLAT_ARM_TRP_UART_CLK_IN_HZ,
ARM_CONSOLE_BAUDRATE,
&arm_trp_runtime_console);
rc = console_pl011_register(PLAT_ARM_TRP_UART_BASE,
PLAT_ARM_TRP_UART_CLK_IN_HZ,
ARM_CONSOLE_BAUDRATE,
&arm_trp_runtime_console);
if (rc == 0) {
panic();
}
console_set_scope(&arm_trp_runtime_console,
CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
}
void trp_early_platform_setup(void)
void trp_early_platform_setup(rmm_manifest_t *manifest)
{
arm_trp_early_platform_setup();
arm_trp_early_platform_setup(manifest);
}

View file

@ -5,6 +5,7 @@
*/
#include <stdint.h>
#include <string.h>
#include <common/debug.h>
#include <lib/spinlock.h>
#include <lib/xlat_tables/xlat_tables_v2.h>

View file

@ -171,6 +171,8 @@ int rmmd_setup(void)
uint32_t ep_attr;
unsigned int linear_id = plat_my_core_pos();
rmmd_rmm_context_t *rmm_ctx = &rmm_context[linear_id];
rmm_manifest_t *manifest;
int rc;
/* Make sure RME is supported. */
assert(get_armv9_2_feat_rme_support() != 0U);
@ -203,6 +205,15 @@ int rmmd_setup(void)
assert((shared_buf_size == SZ_4K) &&
((void *)shared_buf_base != NULL));
/* Load the boot manifest at the beginning of the shared area */
manifest = (rmm_manifest_t *)shared_buf_base;
rc = plat_rmmd_load_manifest(manifest);
if (rc != 0) {
ERROR("Error loading RMM Boot Manifest (%i)\n", rc);
return rc;
}
flush_dcache_range((uintptr_t)shared_buf_base, shared_buf_size);
/*
* Prepare coldboot arguments for RMM:
* arg0: This CPUID (primary processor).

View file

@ -1,11 +1,12 @@
#
# Copyright (c) 2021 Arm Limited and Contributors. All rights reserved.
# Copyright (c) 2021-2022 Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
RMM_SOURCES += services/std_svc/rmmd/trp/trp_entry.S \
services/std_svc/rmmd/trp/trp_main.c
RMM_SOURCES += services/std_svc/rmmd/trp/trp_entry.S \
services/std_svc/rmmd/trp/trp_main.c \
services/std_svc/rmmd/trp/trp_helpers.c
RMM_LINKERFILE := services/std_svc/rmmd/trp/linker.lds

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <plat/common/platform.h>
#include <services/rmmd_svc.h>
#include "trp_private.h"
/*
* Per cpu data structure to populate parameters for an SMC in C code and use
* a pointer to this structure in assembler code to populate x0-x7
*/
static trp_args_t trp_smc_args[PLATFORM_CORE_COUNT];
/*
* Set the arguments for SMC call
*/
trp_args_t *set_smc_args(uint64_t arg0,
uint64_t arg1,
uint64_t arg2,
uint64_t arg3,
uint64_t arg4,
uint64_t arg5,
uint64_t arg6,
uint64_t arg7)
{
uint32_t linear_id;
trp_args_t *pcpu_smc_args;
/*
* Return to Secure Monitor by raising an SMC. The results of the
* service are passed as an arguments to the SMC
*/
linear_id = plat_my_core_pos();
pcpu_smc_args = &trp_smc_args[linear_id];
write_trp_arg(pcpu_smc_args, TRP_ARG0, arg0);
write_trp_arg(pcpu_smc_args, TRP_ARG1, arg1);
write_trp_arg(pcpu_smc_args, TRP_ARG2, arg2);
write_trp_arg(pcpu_smc_args, TRP_ARG3, arg3);
write_trp_arg(pcpu_smc_args, TRP_ARG4, arg4);
write_trp_arg(pcpu_smc_args, TRP_ARG5, arg5);
write_trp_arg(pcpu_smc_args, TRP_ARG6, arg6);
write_trp_arg(pcpu_smc_args, TRP_ARG7, arg7);
return pcpu_smc_args;
}
/*
* Abort the boot process with the reason given in err.
*/
__dead2 void trp_boot_abort(uint64_t err)
{
(void)trp_smc(set_smc_args(RMM_BOOT_COMPLETE, err, 0, 0, 0, 0, 0, 0));
panic();
}

View file

@ -7,63 +7,20 @@
#include <common/debug.h>
#include <plat/common/platform.h>
#include <services/rmm_core_manifest.h>
#include <services/rmmd_svc.h>
#include <services/trp/platform_trp.h>
#include <trp_helpers.h>
#include "trp_private.h"
#include <platform_def.h>
#include "trp_private.h"
/* Parameters received from the previous image */
static unsigned int trp_boot_abi_version;
static uintptr_t trp_shared_region_start;
/*******************************************************************************
* Per cpu data structure to populate parameters for an SMC in C code and use
* a pointer to this structure in assembler code to populate x0-x7
******************************************************************************/
static trp_args_t trp_smc_args[PLATFORM_CORE_COUNT];
/*******************************************************************************
* Set the arguments for SMC call
******************************************************************************/
static trp_args_t *set_smc_args(uint64_t arg0,
uint64_t arg1,
uint64_t arg2,
uint64_t arg3,
uint64_t arg4,
uint64_t arg5,
uint64_t arg6,
uint64_t arg7)
{
uint32_t linear_id;
trp_args_t *pcpu_smc_args;
/*
* Return to Secure Monitor by raising an SMC. The results of the
* service are passed as an arguments to the SMC
*/
linear_id = plat_my_core_pos();
pcpu_smc_args = &trp_smc_args[linear_id];
write_trp_arg(pcpu_smc_args, TRP_ARG0, arg0);
write_trp_arg(pcpu_smc_args, TRP_ARG1, arg1);
write_trp_arg(pcpu_smc_args, TRP_ARG2, arg2);
write_trp_arg(pcpu_smc_args, TRP_ARG3, arg3);
write_trp_arg(pcpu_smc_args, TRP_ARG4, arg4);
write_trp_arg(pcpu_smc_args, TRP_ARG5, arg5);
write_trp_arg(pcpu_smc_args, TRP_ARG6, arg6);
write_trp_arg(pcpu_smc_args, TRP_ARG7, arg7);
return pcpu_smc_args;
}
/*
* Abort the boot process with the reason given in err.
*/
__dead2 static void trp_boot_abort(uint64_t err)
{
(void)trp_smc(set_smc_args(RMM_BOOT_COMPLETE, err, 0, 0, 0, 0, 0, 0));
panic();
}
/* Parameters received from boot manifest */
uint32_t trp_boot_manifest_version;
/*******************************************************************************
* Setup function for TRP.
@ -106,7 +63,7 @@ void trp_setup(uint64_t x0,
sizeof(trp_shared_region_start));
/* Perform early platform-specific setup */
trp_early_platform_setup();
trp_early_platform_setup((rmm_manifest_t *)trp_shared_region_start);
}
/* Main function for TRP */
@ -116,6 +73,9 @@ void trp_main(void)
NOTICE("TRP: %s\n", build_message);
NOTICE("TRP: Supported RMM-EL3 Interface ABI: v.%u.%u\n",
TRP_RMM_EL3_ABI_VERS_MAJOR, TRP_RMM_EL3_ABI_VERS_MINOR);
NOTICE("TRP: Boot Manifest Version : v.%u.%u\n",
RMMD_GET_MANIFEST_VERSION_MAJOR(trp_boot_manifest_version),
RMMD_GET_MANIFEST_VERSION_MINOR(trp_boot_manifest_version));
INFO("TRP: Memory base : 0x%lx\n", (unsigned long)RMM_BASE);
INFO("TRP: Base address for the shared region : 0x%lx\n",
(unsigned long)trp_shared_region_start);

View file

@ -8,18 +8,7 @@
#define TRP_PRIVATE_H
#include <services/rmmd_svc.h>
/* Definitions to help the assembler access the SMC/ERET args structure */
#define TRP_ARGS_SIZE TRP_ARGS_END
#define TRP_ARG0 0x0
#define TRP_ARG1 0x8
#define TRP_ARG2 0x10
#define TRP_ARG3 0x18
#define TRP_ARG4 0x20
#define TRP_ARG5 0x28
#define TRP_ARG6 0x30
#define TRP_ARG7 0x38
#define TRP_ARGS_END 0x40
#include <trp_helpers.h>
/* Definitions for RMM-EL3 Interface ABI VERSION */
#define TRP_RMM_EL3_ABI_VERS_MAJOR RMM_EL3_IFC_VERSION_MAJOR
@ -33,11 +22,6 @@
#include <stdint.h>
/* Data structure to hold SMC arguments */
typedef struct trp_args {
uint64_t regs[TRP_ARGS_END >> 3];
} __aligned(CACHE_WRITEBACK_GRANULE) trp_args_t;
#define write_trp_arg(args, offset, val) (((args)->regs[offset >> 3]) \
= val)
/* RMI SMC64 FIDs handled by the TRP */