Browse Source
TRP is a small test payload that implements Realm Monitor Management (RMM) functionalities. RMM runs in the Realm world (R-EL2) and manages the execution of Realm VMs and their interaction with the hypervisor in Normal world. TRP is used to test the interface between RMM and Normal world software, known as Realm Management Interface (RMI). Current functions includes returning RMM version and transitioning granules from Non-secure to Realm world and vice versa. More information about RMM can be found at: https://developer.arm.com/documentation/den0125/latest Signed-off-by: Zelalem Aweke <zelalem.aweke@arm.com> Change-Id: Ic7b9a1e1f3142ef6458d40150d0b4ba6bd723ea2pull/1981/head
Zelalem Aweke
3 years ago
11 changed files with 434 additions and 0 deletions
@ -0,0 +1,15 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. |
||||
|
* |
||||
|
* SPDX-License-Identifier: BSD-3-Clause |
||||
|
*/ |
||||
|
|
||||
|
#ifndef PLATFORM_TRP_H |
||||
|
#define PLATFORM_TRP_H |
||||
|
|
||||
|
/*******************************************************************************
|
||||
|
* Mandatory TRP functions (only if platform contains a TRP) |
||||
|
******************************************************************************/ |
||||
|
void trp_early_platform_setup(void); |
||||
|
|
||||
|
#endif /* PLATFORM_TRP_H */ |
@ -0,0 +1,12 @@ |
|||||
|
#
|
||||
|
# Copyright (c) 2021, Arm Limited. All rights reserved.
|
||||
|
#
|
||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
#
|
||||
|
|
||||
|
# TRP source files specific to FVP platform
|
||||
|
|
||||
|
RMM_SOURCES += plat/arm/board/fvp/aarch64/fvp_helpers.S |
||||
|
|
||||
|
include plat/arm/common/trp/arm_trp.mk |
||||
|
|
@ -0,0 +1,10 @@ |
|||||
|
#
|
||||
|
# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
|
||||
|
#
|
||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
#
|
||||
|
|
||||
|
# TRP source files common to ARM standard platforms
|
||||
|
RMM_SOURCES += plat/arm/common/trp/arm_trp_setup.c \
|
||||
|
plat/arm/common/arm_topology.c \
|
||||
|
plat/common/aarch64/platform_mp_stack.S |
@ -0,0 +1,40 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2021, Arm Limited. All rights reserved. |
||||
|
* |
||||
|
* SPDX-License-Identifier: BSD-3-Clause |
||||
|
*/ |
||||
|
|
||||
|
#include <common/bl_common.h> |
||||
|
#include <common/debug.h> |
||||
|
#include <drivers/arm/pl011.h> |
||||
|
#include <drivers/console.h> |
||||
|
#include <plat/arm/common/plat_arm.h> |
||||
|
#include <platform_def.h> |
||||
|
|
||||
|
/*******************************************************************************
|
||||
|
* Initialize the UART |
||||
|
******************************************************************************/ |
||||
|
static console_t arm_trp_runtime_console; |
||||
|
|
||||
|
void arm_trp_early_platform_setup(void) |
||||
|
{ |
||||
|
/*
|
||||
|
* 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); |
||||
|
if (rc == 0) { |
||||
|
panic(); |
||||
|
} |
||||
|
|
||||
|
console_set_scope(&arm_trp_runtime_console, |
||||
|
CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME); |
||||
|
} |
||||
|
|
||||
|
void trp_early_platform_setup(void) |
||||
|
{ |
||||
|
arm_trp_early_platform_setup(); |
||||
|
} |
@ -0,0 +1,71 @@ |
|||||
|
/* |
||||
|
* (C) COPYRIGHT 2021 Arm Limited or its affiliates. |
||||
|
* ALL RIGHTS RESERVED |
||||
|
*/ |
||||
|
|
||||
|
#include <common/bl_common.ld.h> |
||||
|
#include <lib/xlat_tables/xlat_tables_defs.h> |
||||
|
|
||||
|
/* Mapped using 4K pages, requires us to align different sections with |
||||
|
* different property at the same granularity. */ |
||||
|
PAGE_SIZE_4K = 4096; |
||||
|
|
||||
|
OUTPUT_FORMAT("elf64-littleaarch64") |
||||
|
OUTPUT_ARCH(aarch64) |
||||
|
ENTRY(trp_head) |
||||
|
|
||||
|
MEMORY { |
||||
|
RAM (rwx): ORIGIN = RMM_BASE, LENGTH = RMM_LIMIT - RMM_BASE |
||||
|
} |
||||
|
|
||||
|
|
||||
|
SECTIONS |
||||
|
{ |
||||
|
. = RMM_BASE; |
||||
|
|
||||
|
.text : { |
||||
|
*(.head.text) |
||||
|
. = ALIGN(8); |
||||
|
*(.text*) |
||||
|
} >RAM |
||||
|
|
||||
|
. = ALIGN(PAGE_SIZE_4K); |
||||
|
|
||||
|
.rodata : { |
||||
|
*(.rodata*) |
||||
|
} >RAM |
||||
|
|
||||
|
. = ALIGN(PAGE_SIZE_4K); |
||||
|
|
||||
|
__RW_START__ = . ; |
||||
|
|
||||
|
.data : { |
||||
|
*(.data*) |
||||
|
} >RAM |
||||
|
|
||||
|
.bss (NOLOAD) : { |
||||
|
__BSS_START__ = .; |
||||
|
*(.bss*) |
||||
|
__BSS_END__ = .; |
||||
|
} >RAM |
||||
|
__BSS_SIZE__ = SIZEOF(.bss); |
||||
|
|
||||
|
|
||||
|
STACK_SECTION >RAM |
||||
|
|
||||
|
|
||||
|
/* |
||||
|
* Define a linker symbol to mark the end of the RW memory area for this |
||||
|
* image. |
||||
|
*/ |
||||
|
__RW_END__ = .; |
||||
|
__RMM_END__ = .; |
||||
|
|
||||
|
|
||||
|
/DISCARD/ : { *(.dynstr*) } |
||||
|
/DISCARD/ : { *(.dynamic*) } |
||||
|
/DISCARD/ : { *(.plt*) } |
||||
|
/DISCARD/ : { *(.interp*) } |
||||
|
/DISCARD/ : { *(.gnu*) } |
||||
|
/DISCARD/ : { *(.note*) } |
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
#
|
||||
|
# Copyright (c) 2021 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_LINKERFILE := services/std_svc/rmmd/trp/linker.lds |
||||
|
|
||||
|
# Include the platform-specific TRP Makefile
|
||||
|
# If no platform-specific TRP Makefile exists, it means TRP is not supported
|
||||
|
# on this platform.
|
||||
|
TRP_PLAT_MAKEFILE := $(wildcard ${PLAT_DIR}/trp/trp-${PLAT}.mk) |
||||
|
ifeq (,${TRP_PLAT_MAKEFILE}) |
||||
|
$(error TRP is not supported on platform ${PLAT}) |
||||
|
else |
||||
|
include ${TRP_PLAT_MAKEFILE} |
||||
|
endif |
@ -0,0 +1,74 @@ |
|||||
|
/* |
||||
|
* Copyright (c) 2021, Arm Limited. All rights reserved. |
||||
|
* |
||||
|
* SPDX-License-Identifier: BSD-3-Clause |
||||
|
*/ |
||||
|
|
||||
|
#include <asm_macros.S> |
||||
|
#include <services/gtsi_svc.h> |
||||
|
#include <services/rmi_svc.h> |
||||
|
#include "trp_private.h" |
||||
|
|
||||
|
.global trp_head |
||||
|
.global trp_smc |
||||
|
|
||||
|
.section ".head.text", "ax" |
||||
|
|
||||
|
/* --------------------------------------------- |
||||
|
* Populate the params in x0-x7 from the pointer |
||||
|
* to the smc args structure in x0. |
||||
|
* --------------------------------------------- |
||||
|
*/ |
||||
|
.macro restore_args_call_smc |
||||
|
ldp x6, x7, [x0, #TRP_ARG6] |
||||
|
ldp x4, x5, [x0, #TRP_ARG4] |
||||
|
ldp x2, x3, [x0, #TRP_ARG2] |
||||
|
ldp x0, x1, [x0, #TRP_ARG0] |
||||
|
smc #0 |
||||
|
.endm |
||||
|
|
||||
|
/* --------------------------------------------- |
||||
|
* Entry point for TRP |
||||
|
* --------------------------------------------- |
||||
|
*/ |
||||
|
trp_head: |
||||
|
bl plat_set_my_stack |
||||
|
bl plat_is_my_cpu_primary |
||||
|
cbz x0, trp_secondary_cpu_entry |
||||
|
|
||||
|
/* --------------------------------------------- |
||||
|
* Zero out BSS section |
||||
|
* --------------------------------------------- |
||||
|
*/ |
||||
|
ldr x0, =__BSS_START__ |
||||
|
ldr x1, =__BSS_SIZE__ |
||||
|
bl zeromem |
||||
|
|
||||
|
bl trp_setup |
||||
|
|
||||
|
bl trp_main |
||||
|
trp_secondary_cpu_entry: |
||||
|
mov_imm x0, RMI_RMM_REQ_COMPLETE |
||||
|
mov x1, xzr |
||||
|
smc #0 |
||||
|
b trp_handler |
||||
|
|
||||
|
/* --------------------------------------------- |
||||
|
* Direct SMC call to BL31 service provided by |
||||
|
* RMM Dispatcher |
||||
|
* --------------------------------------------- |
||||
|
*/ |
||||
|
func trp_smc |
||||
|
restore_args_call_smc |
||||
|
ret |
||||
|
endfunc trp_smc |
||||
|
|
||||
|
/* --------------------------------------------- |
||||
|
* RMI call handler |
||||
|
* --------------------------------------------- |
||||
|
*/ |
||||
|
func trp_handler |
||||
|
bl trp_rmi_handler |
||||
|
restore_args_call_smc |
||||
|
b trp_handler |
||||
|
endfunc trp_handler |
@ -0,0 +1,136 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. |
||||
|
* |
||||
|
* SPDX-License-Identifier: BSD-3-Clause |
||||
|
*/ |
||||
|
|
||||
|
|
||||
|
#include <common/debug.h> |
||||
|
#include <plat/common/platform.h> |
||||
|
#include <services/gtsi_svc.h> |
||||
|
#include <services/rmi_svc.h> |
||||
|
#include <services/trp/platform_trp.h> |
||||
|
|
||||
|
#include <platform_def.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 |
||||
|
******************************************************************************/ |
||||
|
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; |
||||
|
} |
||||
|
|
||||
|
/*******************************************************************************
|
||||
|
* Setup function for TRP. |
||||
|
******************************************************************************/ |
||||
|
void trp_setup(void) |
||||
|
{ |
||||
|
/* Perform early platform-specific setup */ |
||||
|
trp_early_platform_setup(); |
||||
|
} |
||||
|
|
||||
|
/* Main function for TRP */ |
||||
|
void trp_main(void) |
||||
|
{ |
||||
|
NOTICE("TRP: %s\n", version_string); |
||||
|
NOTICE("TRP: %s\n", build_message); |
||||
|
INFO("TRP: Memory base : 0x%lx\n", (unsigned long)RMM_BASE); |
||||
|
INFO("TRP: Total size : 0x%lx bytes\n", (unsigned long)(RMM_END |
||||
|
- RMM_BASE)); |
||||
|
} |
||||
|
|
||||
|
/*******************************************************************************
|
||||
|
* Returning RMI version back to Normal World |
||||
|
******************************************************************************/ |
||||
|
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(RMI_RMM_REQ_COMPLETE, RMI_ABI_VERSION, |
||||
|
0, 0, 0, 0, 0, 0); |
||||
|
} |
||||
|
|
||||
|
/*******************************************************************************
|
||||
|
* Transitioning granule of NON-SECURE type to REALM type |
||||
|
******************************************************************************/ |
||||
|
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(SMC_ASC_MARK_REALM, 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(RMI_RMM_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0); |
||||
|
} |
||||
|
|
||||
|
/*******************************************************************************
|
||||
|
* Transitioning granule of REALM type to NON-SECURE type |
||||
|
******************************************************************************/ |
||||
|
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(SMC_ASC_MARK_NONSECURE, 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(RMI_RMM_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0); |
||||
|
} |
||||
|
|
||||
|
/*******************************************************************************
|
||||
|
* Main RMI SMC handler function |
||||
|
******************************************************************************/ |
||||
|
trp_args_t *trp_rmi_handler(unsigned long fid, unsigned long long x1) |
||||
|
{ |
||||
|
switch (fid) { |
||||
|
case RMI_RMM_REQ_VERSION: |
||||
|
return trp_ret_rmi_version(); |
||||
|
case RMI_RMM_GRANULE_DELEGATE: |
||||
|
return trp_asc_mark_realm(x1); |
||||
|
case RMI_RMM_GRANULE_UNDELEGATE: |
||||
|
return trp_asc_mark_nonsecure(x1); |
||||
|
default: |
||||
|
ERROR("Invalid SMC code to %s, FID %lu\n", __func__, fid); |
||||
|
} |
||||
|
return set_smc_args(SMC_UNK, 0, 0, 0, 0, 0, 0, 0); |
||||
|
} |
@ -0,0 +1,50 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. |
||||
|
* |
||||
|
* SPDX-License-Identifier: BSD-3-Clause |
||||
|
*/ |
||||
|
|
||||
|
#ifndef TRP_PRIVATE_H |
||||
|
#define TRP_PRIVATE_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 <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) |
||||
|
|
||||
|
/* Definitions for RMI VERSION */ |
||||
|
#define RMI_ABI_VERSION_MAJOR U(0x0) |
||||
|
#define RMI_ABI_VERSION_MINOR U(0x0) |
||||
|
#define RMI_ABI_VERSION ((RMI_ABI_VERSION_MAJOR << 16) | \ |
||||
|
RMI_ABI_VERSION_MINOR) |
||||
|
|
||||
|
/* Helper to issue SMC calls to BL31 */ |
||||
|
uint64_t trp_smc(trp_args_t *); |
||||
|
|
||||
|
/* The main function to executed only by Primary CPU */ |
||||
|
void trp_main(void); |
||||
|
|
||||
|
/* Setup TRP. Executed only by Primary CPU */ |
||||
|
void trp_setup(void); |
||||
|
|
||||
|
#endif /* __ASSEMBLER__ */ |
||||
|
#endif /* TRP_PRIVATE_H */ |
Loading…
Reference in new issue