Merge changes from topic "za/feat_rme" into integration

* changes:
  refactor(gpt): productize and refactor GPT library
  feat(rme): disable Watchdog for Arm platforms if FEAT_RME enabled
  docs(rme): add build and run instructions for FEAT_RME
  fix(plat/fvp): bump BL2 stack size
  fix(plat/fvp): allow changing the kernel DTB load address
  refactor(plat/arm): rename ARM_DTB_DRAM_NS region macros
  refactor(plat/fvp): update FVP platform DTS for FEAT_RME
  feat(plat/arm): add GPT initialization code for Arm platforms
  feat(plat/fvp): add memory map for FVP platform for FEAT_RME
  refactor(plat/arm): modify memory region attributes to account for FEAT_RME
  feat(plat/fvp): add RMM image support for FVP platform
  feat(rme): add GPT Library
  feat(rme): add ENABLE_RME build option and support for RMM image
  refactor(makefile): remove BL prefixes in build macros
  feat(rme): add context management changes for FEAT_RME
  feat(rme): add Test Realm Payload (TRP)
  feat(rme): add RMM dispatcher (RMMD)
  feat(rme): run BL2 in root world when FEAT_RME is enabled
  feat(rme): add xlat table library changes for FEAT_RME
  feat(rme): add Realm security state definition
  feat(rme): add register definitions and helper functions for FEAT_RME
This commit is contained in:
Soby Mathew 2021-10-06 19:44:28 +02:00 committed by TrustedFirmware Code Review
commit 1d65121174
85 changed files with 4303 additions and 332 deletions

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
# Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@ -129,6 +129,23 @@ else
$(error Unknown BRANCH_PROTECTION value ${BRANCH_PROTECTION})
endif
# FEAT_RME
ifeq (${ENABLE_RME},1)
# RME doesn't support PIE
ifneq (${ENABLE_PIE},0)
$(error ENABLE_RME does not support PIE)
endif
# RME requires AARCH64
ifneq (${ARCH},aarch64)
$(error ENABLE_RME requires AArch64)
endif
# RME requires el2 context to be saved for now.
CTX_INCLUDE_EL2_REGS := 1
CTX_INCLUDE_AARCH32_REGS := 0
ARM_ARCH_MAJOR := 8
ARM_ARCH_MINOR := 6
endif
# USE_SPINLOCK_CAS requires AArch64 build
ifeq (${USE_SPINLOCK_CAS},1)
ifneq (${ARCH},aarch64)
@ -558,6 +575,18 @@ ifneq (${SPD},none)
# over the sources.
endif
################################################################################
# Include rmmd Makefile if RME is enabled
################################################################################
ifneq (${ENABLE_RME},0)
ifneq (${ARCH},aarch64)
$(error ENABLE_RME requires AArch64)
endif
include services/std_svc/rmmd/rmmd.mk
$(warning "RME is an experimental feature")
endif
################################################################################
# Include the platform specific Makefile after the SPD Makefile (the platform
# makefile may use all previous definitions in this file)
@ -926,6 +955,7 @@ $(eval $(call assert_booleans,\
ENABLE_PIE \
ENABLE_PMF \
ENABLE_PSCI_STAT \
ENABLE_RME \
ENABLE_RUNTIME_INSTRUMENTATION \
ENABLE_SPE_FOR_LOWER_ELS \
ENABLE_SVE_FOR_NS \
@ -1028,6 +1058,7 @@ $(eval $(call add_defines,\
ENABLE_PIE \
ENABLE_PMF \
ENABLE_PSCI_STAT \
ENABLE_RME \
ENABLE_RUNTIME_INSTRUMENTATION \
ENABLE_SPE_FOR_LOWER_ELS \
ENABLE_SVE_FOR_NS \
@ -1148,7 +1179,7 @@ $(eval $(call MAKE_LIB,c))
# Expand build macros for the different images
ifeq (${NEED_BL1},yes)
$(eval $(call MAKE_BL,1))
$(eval $(call MAKE_BL,bl1))
endif
ifeq (${NEED_BL2},yes)
@ -1157,7 +1188,7 @@ FIP_BL2_ARGS := tb-fw
endif
$(if ${BL2}, $(eval $(call TOOL_ADD_IMG,bl2,--${FIP_BL2_ARGS})),\
$(eval $(call MAKE_BL,2,${FIP_BL2_ARGS})))
$(eval $(call MAKE_BL,bl2,${FIP_BL2_ARGS})))
endif
ifeq (${NEED_SCP_BL2},yes)
@ -1170,10 +1201,10 @@ BL31_SOURCES += ${SPD_SOURCES}
BL31_SOURCES := $(sort ${BL31_SOURCES})
ifneq (${DECRYPTION_SUPPORT},none)
$(if ${BL31}, $(eval $(call TOOL_ADD_IMG,bl31,--soc-fw,,$(ENCRYPT_BL31))),\
$(eval $(call MAKE_BL,31,soc-fw,,$(ENCRYPT_BL31))))
$(eval $(call MAKE_BL,bl31,soc-fw,,$(ENCRYPT_BL31))))
else
$(if ${BL31}, $(eval $(call TOOL_ADD_IMG,bl31,--soc-fw)),\
$(eval $(call MAKE_BL,31,soc-fw)))
$(eval $(call MAKE_BL,bl31,soc-fw)))
endif
endif
@ -1186,14 +1217,25 @@ BL32_SOURCES := $(sort ${BL32_SOURCES})
BUILD_BL32 := $(if $(BL32),,$(if $(BL32_SOURCES),1))
ifneq (${DECRYPTION_SUPPORT},none)
$(if ${BUILD_BL32}, $(eval $(call MAKE_BL,32,tos-fw,,$(ENCRYPT_BL32))),\
$(if ${BUILD_BL32}, $(eval $(call MAKE_BL,bl32,tos-fw,,$(ENCRYPT_BL32))),\
$(eval $(call TOOL_ADD_IMG,bl32,--tos-fw,,$(ENCRYPT_BL32))))
else
$(if ${BUILD_BL32}, $(eval $(call MAKE_BL,32,tos-fw)),\
$(if ${BUILD_BL32}, $(eval $(call MAKE_BL,bl32,tos-fw)),\
$(eval $(call TOOL_ADD_IMG,bl32,--tos-fw)))
endif
endif
# If RMM image is needed but RMM is not defined, Test Realm Payload (TRP)
# needs to be built from RMM_SOURCES.
ifeq (${NEED_RMM},yes)
# Sort RMM source files to remove duplicates
RMM_SOURCES := $(sort ${RMM_SOURCES})
BUILD_RMM := $(if $(RMM),,$(if $(RMM_SOURCES),1))
$(if ${BUILD_RMM}, $(eval $(call MAKE_BL,rmm,rmm-fw)),\
$(eval $(call TOOL_ADD_IMG,rmm,--rmm-fw)))
endif
# Add the BL33 image if required by the platform
ifeq (${NEED_BL33},yes)
$(eval $(call TOOL_ADD_IMG,bl33,--nt-fw))
@ -1201,7 +1243,7 @@ endif
ifeq (${NEED_BL2U},yes)
$(if ${BL2U}, $(eval $(call TOOL_ADD_IMG,bl2u,--ap-fwu-cfg,FWU_)),\
$(eval $(call MAKE_BL,2u,ap-fwu-cfg,FWU_)))
$(eval $(call MAKE_BL,bl2u,ap-fwu-cfg,FWU_)))
endif
# Expand build macros for the different images

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -16,6 +16,7 @@
/* Following contains the cpu context pointers. */
static void *bl1_cpu_context_ptr[2];
entry_point_info_t *bl2_ep_info;
void *cm_get_context(uint32_t security_state)
@ -30,6 +31,40 @@ void cm_set_context(void *context, uint32_t security_state)
bl1_cpu_context_ptr[security_state] = context;
}
#if ENABLE_RME
/*******************************************************************************
* This function prepares the entry point information to run BL2 in Root world,
* i.e. EL3, for the case when FEAT_RME is enabled.
******************************************************************************/
void bl1_prepare_next_image(unsigned int image_id)
{
image_desc_t *bl2_desc;
assert(image_id == BL2_IMAGE_ID);
/* Get the image descriptor. */
bl2_desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
assert(bl2_desc != NULL);
/* Get the entry point info. */
bl2_ep_info = &bl2_desc->ep_info;
bl2_ep_info->spsr = (uint32_t)SPSR_64(MODE_EL3, MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS);
/*
* Flush cache since bl2_ep_info is accessed after MMU is disabled
* before jumping to BL2.
*/
flush_dcache_range((uintptr_t)bl2_ep_info, sizeof(entry_point_info_t));
/* Indicate that image is in execution state. */
bl2_desc->state = IMAGE_STATE_EXECUTED;
/* Print debug info and flush the console before running BL2. */
print_entry_point_info(bl2_ep_info);
}
#else
/*******************************************************************************
* This function prepares the context for Secure/Normal world images.
* Normal world images are transitioned to EL2(if supported) else EL1.
@ -93,3 +128,4 @@ void bl1_prepare_next_image(unsigned int image_id)
print_entry_point_info(next_bl_ep);
}
#endif /* ENABLE_RME */

View File

@ -1,13 +1,15 @@
/*
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <common/bl_common.h>
#include <el3_common_macros.S>
.globl bl1_entrypoint
.globl bl1_run_bl2_in_root
/* -----------------------------------------------------
@ -66,5 +68,41 @@ func bl1_entrypoint
* Do the transition to next boot image.
* --------------------------------------------------
*/
#if ENABLE_RME
b bl1_run_bl2_in_root
#else
b el3_exit
#endif
endfunc bl1_entrypoint
/* -----------------------------------------------------
* void bl1_run_bl2_in_root();
* This function runs BL2 in root/EL3 when RME is enabled.
* -----------------------------------------------------
*/
func bl1_run_bl2_in_root
/* read bl2_ep_info */
adrp x20, bl2_ep_info
add x20, x20, :lo12:bl2_ep_info
ldr x20, [x20]
/* ---------------------------------------------
* MMU needs to be disabled because BL2 executes
* in EL3. It will initialize the address space
* according to its own requirements.
* ---------------------------------------------
*/
bl disable_mmu_icache_el3
tlbi alle3
ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET]
msr elr_el3, x0
msr spsr_el3, x1
ldp x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x30)]
ldp x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x20)]
ldp x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x10)]
ldp x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x0)]
exception_return
endfunc bl1_run_bl2_in_root

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -11,6 +11,8 @@
#include <common/bl_common.h>
extern entry_point_info_t *bl2_ep_info;
/******************************************
* Function prototypes
*****************************************/
@ -18,6 +20,7 @@ void bl1_arch_setup(void);
void bl1_arch_next_el_setup(void);
void bl1_prepare_next_image(unsigned int image_id);
void bl1_run_bl2_in_root(void);
u_register_t bl1_fwu_smc_handler(unsigned int smc_fid,
u_register_t x1,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -10,7 +10,6 @@
#include <el3_common_macros.S>
.globl bl2_entrypoint
.globl bl2_run_next_image
func bl2_entrypoint
@ -56,37 +55,3 @@ func bl2_entrypoint
no_ret plat_panic_handler
endfunc bl2_entrypoint
func bl2_run_next_image
mov r8,r0
/*
* MMU needs to be disabled because both BL2 and BL32 execute
* in PL1, and therefore share the same address space.
* BL32 will initialize the address space according to its
* own requirement.
*/
bl disable_mmu_icache_secure
stcopr r0, TLBIALL
dsb sy
isb
mov r0, r8
bl bl2_el3_plat_prepare_exit
/*
* Extract PC and SPSR based on struct `entry_point_info_t`
* and load it in LR and SPSR registers respectively.
*/
ldr lr, [r8, #ENTRY_POINT_INFO_PC_OFFSET]
ldr r1, [r8, #(ENTRY_POINT_INFO_PC_OFFSET + 4)]
msr spsr_xc, r1
/* Some BL32 stages expect lr_svc to provide the BL33 entry address */
cps #MODE32_svc
ldr lr, [r8, #ENTRY_POINT_INFO_LR_SVC_OFFSET]
cps #MODE32_mon
add r8, r8, #ENTRY_POINT_INFO_ARGS_OFFSET
ldm r8, {r0, r1, r2, r3}
exception_return
endfunc bl2_run_next_image

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <common/bl_common.h>
.globl bl2_run_next_image
func bl2_run_next_image
mov r8,r0
/*
* MMU needs to be disabled because both BL2 and BL32 execute
* in PL1, and therefore share the same address space.
* BL32 will initialize the address space according to its
* own requirement.
*/
bl disable_mmu_icache_secure
stcopr r0, TLBIALL
dsb sy
isb
mov r0, r8
bl bl2_el3_plat_prepare_exit
/*
* Extract PC and SPSR based on struct `entry_point_info_t`
* and load it in LR and SPSR registers respectively.
*/
ldr lr, [r8, #ENTRY_POINT_INFO_PC_OFFSET]
ldr r1, [r8, #(ENTRY_POINT_INFO_PC_OFFSET + 4)]
msr spsr_xc, r1
/* Some BL32 stages expect lr_svc to provide the BL33 entry address */
cps #MODE32_svc
ldr lr, [r8, #ENTRY_POINT_INFO_LR_SVC_OFFSET]
cps #MODE32_mon
add r8, r8, #ENTRY_POINT_INFO_ARGS_OFFSET
ldm r8, {r0, r1, r2, r3}
exception_return
endfunc bl2_run_next_image

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -12,8 +12,6 @@
#include <el3_common_macros.S>
.globl bl2_entrypoint
.globl bl2_el3_run_image
.globl bl2_run_next_image
#if BL2_IN_XIP_MEM
#define FIXUP_SIZE 0
@ -72,36 +70,3 @@ func bl2_entrypoint
*/
no_ret plat_panic_handler
endfunc bl2_entrypoint
func bl2_run_next_image
mov x20,x0
/* ---------------------------------------------
* MMU needs to be disabled because both BL2 and BL31 execute
* in EL3, and therefore share the same address space.
* BL31 will initialize the address space according to its
* own requirement.
* ---------------------------------------------
*/
bl disable_mmu_icache_el3
tlbi alle3
bl bl2_el3_plat_prepare_exit
#if ENABLE_PAUTH
/* ---------------------------------------------
* Disable pointer authentication before jumping
* to next boot image.
* ---------------------------------------------
*/
bl pauth_disable_el3
#endif /* ENABLE_PAUTH */
ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET]
msr elr_el3, x0
msr spsr_el3, x1
ldp x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x30)]
ldp x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x20)]
ldp x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x10)]
ldp x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x0)]
exception_return
endfunc bl2_run_next_image

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <platform_def.h>
#include <arch.h>
#include <asm_macros.S>
#include <common/bl_common.h>
#include <el3_common_macros.S>
.globl bl2_entrypoint
func bl2_entrypoint
/* Save arguments x0-x3 from previous Boot loader */
mov x20, x0
mov x21, x1
mov x22, x2
mov x23, x3
el3_entrypoint_common \
_init_sctlr=0 \
_warm_boot_mailbox=0 \
_secondary_cold_boot=0 \
_init_memory=0 \
_init_c_runtime=1 \
_exception_vectors=bl2_el3_exceptions \
_pie_fixup_size=0
/* ---------------------------------------------
* Restore parameters of boot rom
* ---------------------------------------------
*/
mov x0, x20
mov x1, x21
mov x2, x22
mov x3, x23
/* ---------------------------------------------
* Perform BL2 setup
* ---------------------------------------------
*/
bl bl2_setup
#if ENABLE_PAUTH
/* ---------------------------------------------
* Program APIAKey_EL1 and enable pointer authentication.
* ---------------------------------------------
*/
bl pauth_init_enable_el3
#endif /* ENABLE_PAUTH */
/* ---------------------------------------------
* Jump to main function.
* ---------------------------------------------
*/
bl bl2_main
/* ---------------------------------------------
* Should never reach this point.
* ---------------------------------------------
*/
no_ret plat_panic_handler
endfunc bl2_entrypoint

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <common/bl_common.h>
.globl bl2_run_next_image
func bl2_run_next_image
mov x20,x0
/* ---------------------------------------------
* MMU needs to be disabled because both BL2 and BL31 execute
* in EL3, and therefore share the same address space.
* BL31 will initialize the address space according to its
* own requirement.
* ---------------------------------------------
*/
bl disable_mmu_icache_el3
tlbi alle3
bl bl2_el3_plat_prepare_exit
#if ENABLE_PAUTH
/* ---------------------------------------------
* Disable pointer authentication before jumping
* to next boot image.
* ---------------------------------------------
*/
bl pauth_disable_el3
#endif /* ENABLE_PAUTH */
ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET]
msr elr_el3, x0
msr spsr_el3, x1
ldp x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x30)]
ldp x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x20)]
ldp x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x10)]
ldp x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x0)]
exception_return
endfunc bl2_run_next_image

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -25,7 +25,11 @@ SECTIONS
#if SEPARATE_CODE_AND_RODATA
.text . : {
__TEXT_START__ = .;
#if ENABLE_RME
*bl2_rme_entrypoint.o(.text*)
#else /* ENABLE_RME */
*bl2_entrypoint.o(.text*)
#endif /* ENABLE_RME */
*(SORT_BY_ALIGNMENT(.text*))
*(.vectors)
. = ALIGN(PAGE_SIZE);

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
# Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@ -15,13 +15,26 @@ ifeq (${ARCH},aarch64)
BL2_SOURCES += common/aarch64/early_exceptions.S
endif
ifeq (${BL2_AT_EL3},0)
ifeq (${ENABLE_RME},1)
# Using RME, run BL2 at EL3
include lib/gpt_rme/gpt_rme.mk
BL2_SOURCES += bl2/${ARCH}/bl2_rme_entrypoint.S \
bl2/${ARCH}/bl2_el3_exceptions.S \
bl2/${ARCH}/bl2_run_next_image.S \
${GPT_LIB_SRCS}
BL2_LINKERFILE := bl2/bl2.ld.S
else ifeq (${BL2_AT_EL3},0)
# Normal operation, no RME, no BL2 at EL3
BL2_SOURCES += bl2/${ARCH}/bl2_entrypoint.S
BL2_LINKERFILE := bl2/bl2.ld.S
else
# BL2 at EL3, no RME
BL2_SOURCES += bl2/${ARCH}/bl2_el3_entrypoint.S \
bl2/${ARCH}/bl2_el3_exceptions.S \
bl2/${ARCH}/bl2_run_next_image.S \
lib/cpus/${ARCH}/cpu_helpers.S \
lib/cpus/errata_report.c

View File

@ -29,31 +29,9 @@
#define NEXT_IMAGE "BL32"
#endif
#if !BL2_AT_EL3
#if BL2_AT_EL3
/*******************************************************************************
* Setup function for BL2.
******************************************************************************/
void bl2_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
u_register_t arg3)
{
/* Perform early platform-specific setup */
bl2_early_platform_setup2(arg0, arg1, arg2, arg3);
/* Perform late platform-specific setup */
bl2_plat_arch_setup();
#if CTX_INCLUDE_PAUTH_REGS
/*
* Assert that the ARMv8.3-PAuth registers are present or an access
* fault will be triggered when they are being saved or restored.
*/
assert(is_armv8_3_pauth_present());
#endif /* CTX_INCLUDE_PAUTH_REGS */
}
#else /* if BL2_AT_EL3 */
/*******************************************************************************
* Setup function for BL2 when BL2_AT_EL3=1.
* Setup function for BL2 when BL2_AT_EL3=1
******************************************************************************/
void bl2_el3_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
u_register_t arg3)
@ -64,6 +42,27 @@ void bl2_el3_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
/* Perform late platform-specific setup */
bl2_el3_plat_arch_setup();
#if CTX_INCLUDE_PAUTH_REGS
/*
* Assert that the ARMv8.3-PAuth registers are present or an access
* fault will be triggered when they are being saved or restored.
*/
assert(is_armv8_3_pauth_present());
#endif /* CTX_INCLUDE_PAUTH_REGS */
}
#else /* BL2_AT_EL3 */
/*******************************************************************************
* Setup function for BL2 when BL2_AT_EL3=0
******************************************************************************/
void bl2_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
u_register_t arg3)
{
/* Perform early platform-specific setup */
bl2_early_platform_setup2(arg0, arg1, arg2, arg3);
/* Perform late platform-specific setup */
bl2_plat_arch_setup();
#if CTX_INCLUDE_PAUTH_REGS
/*
* Assert that the ARMv8.3-PAuth registers are present or an access
@ -115,7 +114,7 @@ void bl2_main(void)
measured_boot_finish();
#endif /* MEASURED_BOOT */
#if !BL2_AT_EL3
#if !BL2_AT_EL3 && !ENABLE_RME
#ifndef __aarch64__
/*
* For AArch32 state BL1 and BL2 share the MMU setup.
@ -140,7 +139,7 @@ void bl2_main(void)
* be passed to next BL image as an argument.
*/
smc(BL1_SMC_RUN_IMAGE, (unsigned long)next_bl_ep_info, 0, 0, 0, 0, 0, 0);
#else /* if BL2_AT_EL3 */
#else /* if BL2_AT_EL3 || ENABLE_RME */
NOTICE("BL2: Booting " NEXT_IMAGE "\n");
print_entry_point_info(next_bl_ep_info);
console_flush();
@ -153,5 +152,5 @@ void bl2_main(void)
#endif /* ENABLE_PAUTH */
bl2_run_next_image(next_bl_ep_info);
#endif /* BL2_AT_EL3 */
#endif /* BL2_AT_EL3 && ENABLE_RME */
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -195,6 +195,19 @@ func bl31_warm_entrypoint
#endif
bl bl31_plat_enable_mmu
#if ENABLE_RME
/*
* At warm boot GPT data structures have already been initialized in RAM
* but the sysregs for this CPU need to be initialized. Note that the GPT
* accesses are controlled attributes in GPCCR and do not depend on the
* SCR_EL3.C bit.
*/
bl gpt_enable
cbz x0, 1f
no_ret plat_panic_handler
1:
#endif
#if ENABLE_PAUTH
/* --------------------------------------------------------------------
* Program APIAKey_EL1 and enable pointer authentication

View File

@ -500,6 +500,21 @@ smc_handler64:
stp x16, x17, [x6, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
str x18, [x6, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
/* Clear flag register */
mov x7, xzr
#if ENABLE_RME
/* Copy SCR_EL3.NSE bit to the flag to indicate caller's security */
ubfx x7, x18, #SCR_NSE_SHIFT, 1
/*
* Shift copied SCR_EL3.NSE bit by 5 to create space for
* SCR_EL3.NS bit. Bit 5 of the flag correspondes to
* the SCR_EL3.NSE bit.
*/
lsl x7, x7, #5
#endif /* ENABLE_RME */
/* Copy SCR_EL3.NS bit to the flag to indicate caller's security */
bfi x7, x18, #0, #1

View File

@ -111,6 +111,13 @@ ifeq ($(SMC_PCI_SUPPORT),1)
BL31_SOURCES += services/std_svc/pci_svc.c
endif
ifeq (${ENABLE_RME},1)
include lib/gpt_rme/gpt_rme.mk
BL31_SOURCES += ${GPT_LIB_SRCS} \
${RMMD_SOURCES}
endif
BL31_LINKERFILE := bl31/bl31.ld.S
# Flag used to indicate if Crash reporting via console should be included

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -19,9 +19,9 @@
******************************************************************************/
void *cm_get_context(uint32_t security_state)
{
assert(security_state <= NON_SECURE);
assert(sec_state_is_valid(security_state));
return get_cpu_data(cpu_context[security_state]);
return get_cpu_data(cpu_context[get_cpu_context_index(security_state)]);
}
/*******************************************************************************
@ -30,9 +30,10 @@ void *cm_get_context(uint32_t security_state)
******************************************************************************/
void cm_set_context(void *context, uint32_t security_state)
{
assert(security_state <= NON_SECURE);
assert(sec_state_is_valid(security_state));
set_cpu_data(cpu_context[security_state], context);
set_cpu_data(cpu_context[get_cpu_context_index(security_state)],
context);
}
/*******************************************************************************
@ -46,7 +47,8 @@ void *cm_get_context_by_index(unsigned int cpu_idx,
{
assert(sec_state_is_valid(security_state));
return get_cpu_data_by_index(cpu_idx, cpu_context[security_state]);
return get_cpu_data_by_index(cpu_idx,
cpu_context[get_cpu_context_index(security_state)]);
}
/*******************************************************************************
@ -58,5 +60,7 @@ void cm_set_context_by_index(unsigned int cpu_idx, void *context,
{
assert(sec_state_is_valid(security_state));
set_cpu_data_by_index(cpu_idx, cpu_context[security_state], context);
set_cpu_data_by_index(cpu_idx,
cpu_context[get_cpu_context_index(security_state)],
context);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -35,6 +35,13 @@ PMF_REGISTER_SERVICE_SMC(rt_instr_svc, PMF_RT_INSTR_SVC_ID,
******************************************************************************/
static int32_t (*bl32_init)(void);
/*****************************************************************************
* Function used to initialise RMM if RME is enabled
*****************************************************************************/
#if ENABLE_RME
static int32_t (*rmm_init)(void);
#endif
/*******************************************************************************
* Variable to indicate whether next image to execute after BL31 is BL33
* (non-secure & default) or BL32 (secure).
@ -139,12 +146,15 @@ void bl31_main(void)
/*
* All the cold boot actions on the primary cpu are done. We now need to
* decide which is the next image (BL32 or BL33) and how to execute it.
* decide which is the next image and how to execute it.
* If the SPD runtime service is present, it would want to pass control
* to BL32 first in S-EL1. In that case, SPD would have registered a
* function to initialize bl32 where it takes responsibility of entering
* S-EL1 and returning control back to bl31_main. Once this is done we
* can prepare entry into BL33 as normal.
* S-EL1 and returning control back to bl31_main. Similarly, if RME is
* enabled and a function is registered to initialize RMM, control is
* transferred to RMM in R-EL2. After RMM initialization, control is
* returned back to bl31_main. Once this is done we can prepare entry
* into BL33 as normal.
*/
/*
@ -155,9 +165,27 @@ void bl31_main(void)
int32_t rc = (*bl32_init)();
if (rc == 0)
if (rc == 0) {
WARN("BL31: BL32 initialization failed\n");
}
}
/*
* If RME is enabled and init hook is registered, initialize RMM
* in R-EL2.
*/
#if ENABLE_RME
if (rmm_init != NULL) {
INFO("BL31: Initializing RMM\n");
int32_t rc = (*rmm_init)();
if (rc == 0) {
WARN("BL31: RMM initialization failed\n");
}
}
#endif
/*
* We are ready to enter the next EL. Prepare entry into the image
* corresponding to the desired security state after the next ERET.
@ -236,3 +264,14 @@ void bl31_register_bl32_init(int32_t (*func)(void))
{
bl32_init = func;
}
#if ENABLE_RME
/*******************************************************************************
* This function initializes the pointer to RMM init function. This is expected
* to be called by the RMMD after it finishes all its initialization
******************************************************************************/
void bl31_register_rmm_init(int32_t (*func)(void))
{
rmm_init = func;
}
#endif

View File

@ -109,6 +109,16 @@ Exception Handling Framework (EHF)
:|G|: `john-powell-arm`_
:|F|: bl31/ehf.c
Realm Management Extension (RME)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:|M|: Bipin Ravi <bipin.ravi@arm.com>
:|G|: `bipinravi-arm`_
:|M|: Mark Dykes <mark.dykes@arm.com>
:|G|: `mardyk01`_
:|M|: John Powell <John.Powell@arm.com>
:|G|: `john-powell-arm`_
:|M|: Zelalem Aweke <Zelalem.Aweke@arm.com>
:|G|: `zelalem-aweke`_
Drivers, Libraries and Framework Code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -22,3 +22,4 @@ Components
ffa-manifest-binding
xlat-tables-lib-v2-design
cot-binding
realm-management-extension

View File

@ -0,0 +1,194 @@
Realm Management Extension (RME)
====================================
FEAT_RME (or RME for short) is an Armv9-A extension and is one component of the
`Arm Confidential Compute Architecture (Arm CCA)`_. TF-A supports RME starting
from version 2.6. This document provides instructions on how to build and run
TF-A with RME.
Building and running TF-A with RME
------------------------------------
This section describes how you can build and run TF-A with RME enabled.
We assume you have all the :ref:`Prerequisites` to build TF-A.
To enable RME, you need to set the ENABLE_RME build flag when building
TF-A. Currently, this feature is only supported for the FVP platform.
The following instructions show you how to build and run TF-A with RME
for two scenarios: TF-A with TF-A Tests, and four-world execution with
Hafnium and TF-A Tests. The instructions assume you have already obtained
TF-A. You can use the following command to clone TF-A.
.. code:: shell
git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
To run the tests, you need an FVP model. You can download a model that supports
RME from the `Arm Architecture Models website`_. Please select the
*Base RevC AEM FVP* model. After extracting the downloaded file, you should be able to
find the *FVP_Base_RevC-2xAEMvA* binary. The instructions below have been tested
with model version 11.15 revision 18.
.. note::
ENABLE_RME build option is currently experimental.
Building TF-A with TF-A Tests
********************************************
Use the following instructions to build TF-A with `TF-A Tests`_ as the
non-secure payload (BL33).
**1. Obtain and build TF-A Tests**
.. code:: shell
git clone https://git.trustedfirmware.org/TF-A/tf-a-tests.git
cd tf-a-tests
make CROSS_COMPILE=aarch64-none-elf- PLAT=fvp DEBUG=1
This produces a TF-A Tests binary (*tftf.bin*) in the *build/fvp/debug* directory.
**2. Build TF-A**
.. code:: shell
cd trusted-firmware-a
make CROSS_COMPILE=aarch64-none-elf- \
PLAT=fvp \
ENABLE_RME=1 \
FVP_HW_CONFIG_DTS=fdts/fvp-base-gicv3-psci-1t.dts \
DEBUG=1 \
BL33=<path/to/tftf.bin> \
all fip
This produces *bl1.bin* and *fip.bin* binaries in the *build/fvp/debug* directory.
The above command also builds a Test Realm Payload (TRP), which is a small test
payload that implements Realm Monitor Management (RMM) functionalities and runs
in the realm world (R-EL2). The TRP binary is packaged in *fip.bin*.
Four-world execution with Hafnium and TF-A Tests
****************************************************
Four-world execution involves software components at each security state: root,
secure, realm and non-secure. This section describes how to build TF-A
with four-world support. We use TF-A as the root firmware, `Hafnium`_ as the
secure component, TRP as the realm-world firmware and TF-A Tests as the
non-secure payload.
Before building TF-A, you first need to build the other software components.
You can find instructions on how to get and build TF-A Tests above.
**1. Obtain and build Hafnium**
.. code:: shell
git clone --recurse-submodules https://git.trustedfirmware.org/hafnium/hafnium.git
cd hafnium
make PROJECT=reference
The Hafnium binary should be located at
*out/reference/secure_aem_v8a_fvp_clang/hafnium.bin*
**2. Build TF-A**
Build TF-A with RME as well as SPM enabled.
.. code:: shell
make CROSS_COMPILE=aarch64-none-elf- \
PLAT=fvp \
ENABLE_RME=1 \
FVP_HW_CONFIG_DTS=fdts/fvp-base-gicv3-psci-1t.dts \
SPD=spmd \
SPMD_SPM_AT_SEL2=1 \
BRANCH_PROTECTION=1 \
CTX_INCLUDE_PAUTH_REGS=1 \
DEBUG=1 \
SP_LAYOUT_FILE=<path/to/tf-a-tests>/build/fvp/debug/sp_layout.json> \
BL32=<path/to/hafnium.bin> \
BL33=<path/to/tftf.bin> \
all fip
Running the tests
*********************
Use the following command to run the tests on FVP. TF-A Tests should boot
and run the default tests including RME tests.
.. code:: shell
FVP_Base_RevC-2xAEMvA \
-C bp.flashloader0.fname=<path/to/fip.bin> \
-C bp.secureflashloader.fname=<path/to/bl1.bin> \
-C bp.refcounter.non_arch_start_at_default=1 \
-C bp.refcounter.use_real_time=0 \
-C bp.ve_sysregs.exit_on_shutdown=1 \
-C cache_state_modelled=1 \
-C cluster0.NUM_CORES=4 \
-C cluster0.PA_SIZE=48 \
-C cluster0.ecv_support_level=2 \
-C cluster0.gicv3.cpuintf-mmap-access-level=2 \
-C cluster0.gicv3.without-DS-support=1 \
-C cluster0.gicv4.mask-virtual-interrupt=1 \
-C cluster0.has_arm_v8-6=1 \
-C cluster0.has_branch_target_exception=1 \
-C cluster0.has_rme=1 \
-C cluster0.has_rndr=1 \
-C cluster0.has_amu=1 \
-C cluster0.has_v8_7_pmu_extension=2 \
-C cluster0.max_32bit_el=-1 \
-C cluster0.restriction_on_speculative_execution=2 \
-C cluster0.restriction_on_speculative_execution_aarch32=2 \
-C cluster1.NUM_CORES=4 \
-C cluster1.PA_SIZE=48 \
-C cluster1.ecv_support_level=2 \
-C cluster1.gicv3.cpuintf-mmap-access-level=2 \
-C cluster1.gicv3.without-DS-support=1 \
-C cluster1.gicv4.mask-virtual-interrupt=1 \
-C cluster1.has_arm_v8-6=1 \
-C cluster1.has_branch_target_exception=1 \
-C cluster1.has_rme=1 \
-C cluster1.has_rndr=1 \
-C cluster1.has_amu=1 \
-C cluster1.has_v8_7_pmu_extension=2 \
-C cluster1.max_32bit_el=-1 \
-C cluster1.restriction_on_speculative_execution=2 \
-C cluster1.restriction_on_speculative_execution_aarch32=2 \
-C pci.pci_smmuv3.mmu.SMMU_AIDR=2 \
-C pci.pci_smmuv3.mmu.SMMU_IDR0=0x0046123B \
-C pci.pci_smmuv3.mmu.SMMU_IDR1=0x00600002 \
-C pci.pci_smmuv3.mmu.SMMU_IDR3=0x1714 \
-C pci.pci_smmuv3.mmu.SMMU_IDR5=0xFFFF0475 \
-C pci.pci_smmuv3.mmu.SMMU_S_IDR1=0xA0000002 \
-C pci.pci_smmuv3.mmu.SMMU_S_IDR2=0 \
-C pci.pci_smmuv3.mmu.SMMU_S_IDR3=0 \
-C bp.pl011_uart0.out_file=uart0.log \
-C bp.pl011_uart1.out_file=uart1.log \
-C bp.pl011_uart2.out_file=uart2.log \
-C pctl.startup=0.0.0.0 \
-Q 1000 \
"$@"
The bottom of the output from *uart0* should look something like the following.
.. code-block:: shell
...
> Test suite 'FF-A Interrupt'
Passed
> Test suite 'SMMUv3 tests'
Passed
> Test suite 'PMU Leakage'
Passed
> Test suite 'DebugFS'
Passed
> Test suite 'Realm payload tests'
Passed
...
.. _Arm Confidential Compute Architecture (Arm CCA): https://www.arm.com/why-arm/architecture/security-features/arm-confidential-compute-architecture
.. _Arm Architecture Models website: https://developer.arm.com/tools-and-software/simulation-models/fixed-virtual-platforms/arm-ecosystem-models
.. _TF-A Tests: https://trustedfirmware-a-tests.readthedocs.io/en/latest
.. _Hafnium: https://www.trustedfirmware.org/projects/hafnium

View File

@ -271,6 +271,10 @@ Common build options
be enabled. If ``ENABLE_PMF`` is set, the residency statistics are tracked in
software.
- ``ENABLE_RME``: Boolean option to enable support for the ARMv9 Realm
Management Extension. Default value is 0. This is currently an experimental
feature.
- ``ENABLE_RUNTIME_INSTRUMENTATION``: Boolean option to enable runtime
instrumentation which injects timestamp collection points into TF-A to
allow runtime performance to be measured. Currently, only PSCI is

View File

@ -24,7 +24,11 @@
#address-cells = <2>;
#size-cells = <2>;
chosen { };
#if (ENABLE_RME == 1)
chosen { bootargs = "mem=1G console=ttyAMA0 earlycon=pl011,0x1c090000 root=/dev/vda ip=on";};
#else
chosen {};
#endif
aliases {
serial0 = &v2m_serial0;
@ -135,8 +139,13 @@
memory@80000000 {
device_type = "memory";
#if (ENABLE_RME == 1)
reg = <0x00000000 0x80000000 0 0x7C000000>,
<0x00000008 0x80000000 0 0x80000000>;
#else
reg = <0x00000000 0x80000000 0 0x7F000000>,
<0x00000008 0x80000000 0 0x80000000>;
#endif
};
gic: interrupt-controller@2f000000 {

View File

@ -182,6 +182,11 @@
#define ID_AA64PFR0_CSV2_SHIFT U(56)
#define ID_AA64PFR0_CSV2_MASK ULL(0xf)
#define ID_AA64PFR0_CSV2_LENGTH U(4)
#define ID_AA64PFR0_FEAT_RME_SHIFT U(52)
#define ID_AA64PFR0_FEAT_RME_MASK ULL(0xf)
#define ID_AA64PFR0_FEAT_RME_LENGTH U(4)
#define ID_AA64PFR0_FEAT_RME_NOT_SUPPORTED U(0)
#define ID_AA64PFR0_FEAT_RME_V1 U(1)
/* Exception level handling */
#define EL_IMPL_NONE ULL(0)
@ -432,6 +437,9 @@
/* SCR definitions */
#define SCR_RES1_BITS ((U(1) << 4) | (U(1) << 5))
#define SCR_NSE_SHIFT U(62)
#define SCR_NSE_BIT (ULL(1) << SCR_NSE_SHIFT)
#define SCR_GPF_BIT (UL(1) << 48)
#define SCR_TWEDEL_SHIFT U(30)
#define SCR_TWEDEL_MASK ULL(0xf)
#define SCR_HXEn_BIT (UL(1) << 38)
@ -440,6 +448,7 @@
#define SCR_ECVEN_BIT (UL(1) << 28)
#define SCR_FGTEN_BIT (UL(1) << 27)
#define SCR_ATA_BIT (UL(1) << 26)
#define SCR_EnSCXT_BIT (UL(1) << 25)
#define SCR_FIEN_BIT (UL(1) << 21)
#define SCR_EEL2_BIT (UL(1) << 18)
#define SCR_API_BIT (UL(1) << 17)
@ -601,6 +610,7 @@
#define SPSR_M_MASK U(0x1)
#define SPSR_M_AARCH64 U(0x0)
#define SPSR_M_AARCH32 U(0x1)
#define SPSR_M_EL2H U(0x9)
#define SPSR_EL_SHIFT U(2)
#define SPSR_EL_WIDTH U(2)
@ -1092,6 +1102,12 @@
#define AMEVCNTVOFF1E_EL2 S3_4_C13_C11_6
#define AMEVCNTVOFF1F_EL2 S3_4_C13_C11_7
/*******************************************************************************
* Realm management extension register definitions
******************************************************************************/
#define GPCCR_EL3 S3_6_C2_C1_6
#define GPTBR_EL3 S3_6_C2_C1_4
/*******************************************************************************
* RAS system registers
******************************************************************************/

View File

@ -123,4 +123,15 @@ static inline bool is_feat_hcx_present(void)
ID_AA64MMFR1_EL1_HCX_MASK) == ID_AA64MMFR1_EL1_HCX_SUPPORTED);
}
static inline unsigned int get_armv9_2_feat_rme_support(void)
{
/*
* Return the RME version, zero if not supported. This function can be
* used as both an integer value for the RME version or compared to zero
* to detect RME presence.
*/
return (unsigned int)(read_id_aa64pfr0_el1() >>
ID_AA64PFR0_FEAT_RME_SHIFT) & ID_AA64PFR0_FEAT_RME_MASK;
}
#endif /* ARCH_FEATURES_H */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -540,6 +540,10 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(hcrx_el2, HCRX_EL2)
/* DynamIQ Shared Unit power management */
DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1)
/* Armv9.2 RME Registers */
DEFINE_RENAME_SYSREG_RW_FUNCS(gptbr_el3, GPTBR_EL3)
DEFINE_RENAME_SYSREG_RW_FUNCS(gpccr_el3, GPCCR_EL3)
#define IS_IN_EL(x) \
(GET_EL(read_CurrentEl()) == MODE_EL##x)
@ -583,7 +587,28 @@ static inline uint64_t el_implemented(unsigned int el)
}
}
/* Previously defined accesor functions with incomplete register names */
/*
* TLBIPAALLOS instruction
* (TLB Inivalidate GPT Information by PA,
* All Entries, Outer Shareable)
*/
static inline void tlbipaallos(void)
{
__asm__("SYS #6,c8,c1,#4");
}
/*
* Invalidate cached copies of GPT entries
* from TLBs by physical address
*
* @pa: the starting address for the range
* of invalidation
* @size: size of the range of invalidation
*/
void gpt_tlbi_by_pa(uint64_t pa, size_t size);
/* Previously defined accessor functions with incomplete register names */
#define read_current_el() read_CurrentEl()

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -87,6 +87,13 @@
* do so.
*/
orr x0, x0, #(SCR_API_BIT | SCR_APK_BIT)
#endif
#if ENABLE_RME
/*
* TODO: Settting the EEL2 bit to allow EL3 access to secure only registers
* in context management. This will need to be refactored.
*/
orr x0, x0, #SCR_EEL2_BIT
#endif
msr scr_el3, x0
@ -365,6 +372,7 @@
msr vbar_el3, x0
isb
#if !(defined(IMAGE_BL2) && ENABLE_RME)
/* ---------------------------------------------------------------------
* It is a cold boot.
* Perform any processor specific actions upon reset e.g. cache, TLB
@ -372,6 +380,7 @@
* ---------------------------------------------------------------------
*/
bl reset_handler
#endif
el3_arch_init_common
@ -414,7 +423,8 @@
* ---------------------------------------------------------------------
*/
.if \_init_c_runtime
#if defined(IMAGE_BL31) || (defined(IMAGE_BL2) && BL2_AT_EL3 && BL2_INV_DCACHE)
#if defined(IMAGE_BL31) || (defined(IMAGE_BL2) && \
((BL2_AT_EL3 && BL2_INV_DCACHE) || ENABLE_RME))
/* -------------------------------------------------------------
* Invalidate the RW memory used by the BL31 image. This
* includes the data and NOBITS sections. This is done to

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -19,6 +19,7 @@ void bl31_set_next_image_type(uint32_t security_state);
uint32_t bl31_get_next_image_type(void);
void bl31_prepare_next_image_entry(void);
void bl31_register_bl32_init(int32_t (*func)(void));
void bl31_register_rmm_init(int32_t (*func)(void));
void bl31_warm_entrypoint(void);
void bl31_main(void);
void bl31_lib_init(void);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -126,6 +126,8 @@ IMPORT_SYM(uintptr_t, __BL31_START__, BL31_START);
IMPORT_SYM(uintptr_t, __BL31_END__, BL31_END);
#elif defined(IMAGE_BL32)
IMPORT_SYM(uintptr_t, __BL32_END__, BL32_END);
#elif defined(IMAGE_RMM)
IMPORT_SYM(uintptr_t, __RMM_END__, RMM_END);
#endif /* IMAGE_BLX */
/* The following symbols are only exported from the BL2 at EL3 linker script. */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -18,14 +18,21 @@
#define SECURE EP_SECURE
#define NON_SECURE EP_NON_SECURE
#define REALM EP_REALM
#if ENABLE_RME
#define sec_state_is_valid(s) (((s) == SECURE) || \
((s) == NON_SECURE) || \
((s) == REALM))
#else
#define sec_state_is_valid(s) (((s) == SECURE) || ((s) == NON_SECURE))
#endif
#define PARAM_EP_SECURITY_MASK EP_SECURITY_MASK
#define NON_EXECUTABLE EP_NON_EXECUTABLE
#define EXECUTABLE EP_EXECUTABLE
/* Secure or Non-secure image */
/* Get/set security state of an image */
#define GET_SECURITY_STATE(x) ((x) & EP_SECURITY_MASK)
#define SET_SECURITY_STATE(x, security) \
((x) = ((x) & ~EP_SECURITY_MASK) | (security))

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -24,11 +24,23 @@
#define ENTRY_POINT_INFO_ARGS_OFFSET U(0x14)
#endif
/* Security state of the image. */
#define EP_SECURITY_MASK UL(0x1)
/*
* Security state of the image. Bit 0 and
* bit 5 are used to determine the security
* state of the image as follows:
*
* ---------------------------------
* Bit 5 | Bit 0 | Security state
* ---------------------------------
* 0 0 EP_SECURE
* 0 1 EP_NON_SECURE
* 1 1 EP_REALM
*/
#define EP_SECURITY_MASK UL(0x21)
#define EP_SECURITY_SHIFT UL(0)
#define EP_SECURE UL(0x0)
#define EP_NON_SECURE UL(0x1)
#define EP_REALM UL(0x21)
/* Endianness of the image. */
#define EP_EE_MASK U(0x2)

View File

@ -101,7 +101,10 @@
*/
#define BKUP_FWU_METADATA_IMAGE_ID U(33)
/* Realm Monitor Manager (RMM) */
#define RMM_IMAGE_ID U(34)
/* Max Images */
#define MAX_IMAGE_IDS U(34)
#define MAX_IMAGE_IDS U(35)
#endif /* ARM_TRUSTED_FIRMWARE_EXPORT_COMMON_TBBR_TBBR_IMG_DEF_EXP_H */

View File

@ -405,13 +405,12 @@ DEFINE_REG_STRUCT(pauth, CTX_PAUTH_REGS_ALL);
= (uint64_t) (val))
/*
* Top-level context structure which is used by EL3 firmware to
* preserve the state of a core at EL1 in one of the two security
* states and save enough EL3 meta data to be able to return to that
* EL and security state. The context management library will be used
* to ensure that SP_EL3 always points to an instance of this
* structure at exception entry and exit. Each instance will
* correspond to either the secure or the non-secure state.
* Top-level context structure which is used by EL3 firmware to preserve
* the state of a core at the next lower EL in a given security state and
* save enough EL3 meta data to be able to return to that EL and security
* state. The context management library will be used to ensure that
* SP_EL3 always points to an instance of this structure at exception
* entry and exit.
*/
typedef struct cpu_context {
gp_regs_t gpregs_ctx;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2014-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -19,16 +19,25 @@
/* 8-bytes aligned size of psci_cpu_data structure */
#define PSCI_CPU_DATA_SIZE_ALIGNED ((PSCI_CPU_DATA_SIZE + 7) & ~7)
#if ENABLE_RME
/* Size of cpu_context array */
#define CPU_DATA_CONTEXT_NUM 3
/* Offset of cpu_ops_ptr, size 8 bytes */
#define CPU_DATA_CPU_OPS_PTR 0x18
#else /* ENABLE_RME */
#define CPU_DATA_CONTEXT_NUM 2
#define CPU_DATA_CPU_OPS_PTR 0x10
#endif /* ENABLE_RME */
#if ENABLE_PAUTH
/* 8-bytes aligned offset of apiakey[2], size 16 bytes */
#define CPU_DATA_APIAKEY_OFFSET (0x18 + PSCI_CPU_DATA_SIZE_ALIGNED)
#define CPU_DATA_CRASH_BUF_OFFSET (CPU_DATA_APIAKEY_OFFSET + 0x10)
#else
#define CPU_DATA_CRASH_BUF_OFFSET (0x18 + PSCI_CPU_DATA_SIZE_ALIGNED)
#endif /* ENABLE_PAUTH */
#define CPU_DATA_APIAKEY_OFFSET (0x8 + PSCI_CPU_DATA_SIZE_ALIGNED \
+ CPU_DATA_CPU_OPS_PTR)
#define CPU_DATA_CRASH_BUF_OFFSET (0x10 + CPU_DATA_APIAKEY_OFFSET)
#else /* ENABLE_PAUTH */
#define CPU_DATA_CRASH_BUF_OFFSET (0x8 + PSCI_CPU_DATA_SIZE_ALIGNED \
+ CPU_DATA_CPU_OPS_PTR)
#endif /* ENABLE_PAUTH */
/* need enough space in crash buffer to save 8 registers */
#define CPU_DATA_CRASH_BUF_SIZE 64
@ -65,11 +74,14 @@
#ifndef __ASSEMBLER__
#include <assert.h>
#include <stdint.h>
#include <arch_helpers.h>
#include <lib/cassert.h>
#include <lib/psci/psci.h>
#include <platform_def.h>
#include <stdint.h>
/* Offsets for the cpu_data structure */
#define CPU_DATA_PSCI_LOCK_OFFSET __builtin_offsetof\
@ -80,27 +92,34 @@
(cpu_data_t, platform_cpu_data)
#endif
typedef enum context_pas {
CPU_CONTEXT_SECURE = 0,
CPU_CONTEXT_NS,
#if ENABLE_RME
CPU_CONTEXT_REALM,
#endif
CPU_CONTEXT_NUM
} context_pas_t;
/*******************************************************************************
* Function & variable prototypes
******************************************************************************/
/*******************************************************************************
* Cache of frequently used per-cpu data:
* Pointers to non-secure and secure security state contexts
* Pointers to non-secure, realm, and secure security state contexts
* Address of the crash stack
* It is aligned to the cache line boundary to allow efficient concurrent
* manipulation of these pointers on different cpus
*
* TODO: Add other commonly used variables to this (tf_issues#90)
*
* The data structure and the _cpu_data accessors should not be used directly
* by components that have per-cpu members. The member access macros should be
* used for this.
******************************************************************************/
typedef struct cpu_data {
#ifdef __aarch64__
void *cpu_context[2];
#endif
void *cpu_context[CPU_DATA_CONTEXT_NUM];
#endif /* __aarch64__ */
uintptr_t cpu_ops_ptr;
struct psci_cpu_data psci_svc_cpu_data;
#if ENABLE_PAUTH
@ -122,6 +141,11 @@ typedef struct cpu_data {
extern cpu_data_t percpu_data[PLATFORM_CORE_COUNT];
#ifdef __aarch64__
CASSERT(CPU_DATA_CONTEXT_NUM == CPU_CONTEXT_NUM,
assert_cpu_data_context_num_mismatch);
#endif
#if ENABLE_PAUTH
CASSERT(CPU_DATA_APIAKEY_OFFSET == __builtin_offsetof
(cpu_data_t, apiakey),
@ -160,6 +184,31 @@ static inline struct cpu_data *_cpu_data(void)
struct cpu_data *_cpu_data(void);
#endif
/*
* Returns the index of the cpu_context array for the given security state.
* All accesses to cpu_context should be through this helper to make sure
* an access is not out-of-bounds. The function assumes security_state is
* valid.
*/
static inline context_pas_t get_cpu_context_index(uint32_t security_state)
{
if (security_state == SECURE) {
return CPU_CONTEXT_SECURE;
} else {
#if ENABLE_RME
if (security_state == NON_SECURE) {
return CPU_CONTEXT_NS;
} else {
assert(security_state == REALM);
return CPU_CONTEXT_REALM;
}
#else
assert(security_state == NON_SECURE);
return CPU_CONTEXT_NS;
#endif
}
}
/**************************************************************************
* APIs for initialising and accessing per-cpu data
*************************************************************************/

View File

@ -0,0 +1,276 @@
/*
* Copyright (c) 2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef GPT_RME_H
#define GPT_RME_H
#include <stdint.h>
#include <arch.h>
/******************************************************************************/
/* GPT helper macros and definitions */
/******************************************************************************/
/*
* Structure for specifying a mapping range and it's properties. This should not
* be manually initialized, using the MAP_GPT_REGION_x macros is recommended as
* to avoid potential incompatibilities in the future.
*/
typedef struct pas_region {
uintptr_t base_pa; /* Base address for PAS. */
size_t size; /* Size of the PAS. */
unsigned int attrs; /* PAS GPI and entry type. */
} pas_region_t;
/* GPT GPI definitions */
#define GPT_GPI_NO_ACCESS U(0x0)
#define GPT_GPI_SECURE U(0x8)
#define GPT_GPI_NS U(0x9)
#define GPT_GPI_ROOT U(0xA)
#define GPT_GPI_REALM U(0xB)
#define GPT_GPI_ANY U(0xF)
#define GPT_GPI_VAL_MASK UL(0xF)
/* PAS attribute GPI definitions. */
#define GPT_PAS_ATTR_GPI_SHIFT U(0)
#define GPT_PAS_ATTR_GPI_MASK U(0xF)
#define GPT_PAS_ATTR_GPI(_attrs) (((_attrs) \
>> GPT_PAS_ATTR_GPI_SHIFT) \
& GPT_PAS_ATTR_GPI_MASK)
/* PAS attribute mapping type definitions */
#define GPT_PAS_ATTR_MAP_TYPE_BLOCK U(0x0)
#define GPT_PAS_ATTR_MAP_TYPE_GRANULE U(0x1)
#define GPT_PAS_ATTR_MAP_TYPE_SHIFT U(4)
#define GPT_PAS_ATTR_MAP_TYPE_MASK U(0x1)
#define GPT_PAS_ATTR_MAP_TYPE(_attrs) (((_attrs) \
>> GPT_PAS_ATTR_MAP_TYPE_SHIFT) \
& GPT_PAS_ATTR_MAP_TYPE_MASK)
/*
* Macro to initialize the attributes field in the pas_region_t structure.
* [31:5] Reserved
* [4] Mapping type (GPT_PAS_ATTR_MAP_TYPE_x definitions)
* [3:0] PAS GPI type (GPT_GPI_x definitions)
*/
#define GPT_PAS_ATTR(_type, _gpi) \
((((_type) & GPT_PAS_ATTR_MAP_TYPE_MASK) \
<< GPT_PAS_ATTR_MAP_TYPE_SHIFT) | \
(((_gpi) & GPT_PAS_ATTR_GPI_MASK) \
<< GPT_PAS_ATTR_GPI_SHIFT))
/*
* Macro to create a GPT entry for this PAS range as a block descriptor. If this
* region does not fit the requirements for a block descriptor then GPT
* initialization will fail.
*/
#define GPT_MAP_REGION_BLOCK(_pa, _sz, _gpi) \
{ \
.base_pa = (_pa), \
.size = (_sz), \
.attrs = GPT_PAS_ATTR(GPT_PAS_ATTR_MAP_TYPE_BLOCK, (_gpi)), \
}
/*
* Macro to create a GPT entry for this PAS range as a table descriptor. If this
* region does not fit the requirements for a table descriptor then GPT
* initialization will fail.
*/
#define GPT_MAP_REGION_GRANULE(_pa, _sz, _gpi) \
{ \
.base_pa = (_pa), \
.size = (_sz), \
.attrs = GPT_PAS_ATTR(GPT_PAS_ATTR_MAP_TYPE_GRANULE, (_gpi)), \
}
/******************************************************************************/
/* GPT register field definitions */
/******************************************************************************/
/*
* Least significant address bits protected by each entry in level 0 GPT. This
* field is read-only.
*/
#define GPCCR_L0GPTSZ_SHIFT U(20)
#define GPCCR_L0GPTSZ_MASK U(0xF)
typedef enum {
GPCCR_L0GPTSZ_30BITS = U(0x0),
GPCCR_L0GPTSZ_34BITS = U(0x4),
GPCCR_L0GPTSZ_36BITS = U(0x6),
GPCCR_L0GPTSZ_39BITS = U(0x9)
} gpccr_l0gptsz_e;
/* Granule protection check priority bit definitions */
#define GPCCR_GPCP_SHIFT U(17)
#define GPCCR_GPCP_BIT (ULL(1) << GPCCR_EL3_GPCP_SHIFT)
/* Granule protection check bit definitions */
#define GPCCR_GPC_SHIFT U(16)
#define GPCCR_GPC_BIT (ULL(1) << GPCCR_GPC_SHIFT)
/* Physical granule size bit definitions */
#define GPCCR_PGS_SHIFT U(14)
#define GPCCR_PGS_MASK U(0x3)
#define SET_GPCCR_PGS(x) (((x) & GPCCR_PGS_MASK) << GPCCR_PGS_SHIFT)
typedef enum {
GPCCR_PGS_4K = U(0x0),
GPCCR_PGS_64K = U(0x1),
GPCCR_PGS_16K = U(0x2)
} gpccr_pgs_e;
/* GPT fetch shareability attribute bit definitions */
#define GPCCR_SH_SHIFT U(12)
#define GPCCR_SH_MASK U(0x3)
#define SET_GPCCR_SH(x) (((x) & GPCCR_SH_MASK) << GPCCR_SH_SHIFT)
typedef enum {
GPCCR_SH_NS = U(0x0),
GPCCR_SH_OS = U(0x2),
GPCCR_SH_IS = U(0x3)
} gpccr_sh_e;
/* GPT fetch outer cacheability attribute bit definitions */
#define GPCCR_ORGN_SHIFT U(10)
#define GPCCR_ORGN_MASK U(0x3)
#define SET_GPCCR_ORGN(x) (((x) & GPCCR_ORGN_MASK) << GPCCR_ORGN_SHIFT)
typedef enum {
GPCCR_ORGN_NC = U(0x0),
GPCCR_ORGN_WB_RA_WA = U(0x1),
GPCCR_ORGN_WT_RA_NWA = U(0x2),
GPCCR_ORGN_WB_RA_NWA = U(0x3)
} gpccr_orgn_e;
/* GPT fetch inner cacheability attribute bit definitions */
#define GPCCR_IRGN_SHIFT U(8)
#define GPCCR_IRGN_MASK U(0x3)
#define SET_GPCCR_IRGN(x) (((x) & GPCCR_IRGN_MASK) << GPCCR_IRGN_SHIFT)
typedef enum {
GPCCR_IRGN_NC = U(0x0),
GPCCR_IRGN_WB_RA_WA = U(0x1),
GPCCR_IRGN_WT_RA_NWA = U(0x2),
GPCCR_IRGN_WB_RA_NWA = U(0x3)
} gpccr_irgn_e;
/* Protected physical address size bit definitions */
#define GPCCR_PPS_SHIFT U(0)
#define GPCCR_PPS_MASK U(0x7)
#define SET_GPCCR_PPS(x) (((x) & GPCCR_PPS_MASK) << GPCCR_PPS_SHIFT)
typedef enum {
GPCCR_PPS_4GB = U(0x0),
GPCCR_PPS_64GB = U(0x1),
GPCCR_PPS_1TB = U(0x2),
GPCCR_PPS_4TB = U(0x3),
GPCCR_PPS_16TB = U(0x4),
GPCCR_PPS_256TB = U(0x5),
GPCCR_PPS_4PB = U(0x6)
} gpccr_pps_e;
/* Base Address for the GPT bit definitions */
#define GPTBR_BADDR_SHIFT U(0)
#define GPTBR_BADDR_VAL_SHIFT U(12)
#define GPTBR_BADDR_MASK ULL(0xffffffffff)
/******************************************************************************/
/* GPT public APIs */
/******************************************************************************/
/*
* Public API that initializes the entire protected space to GPT_GPI_ANY using
* the L0 tables (block descriptors). Ideally, this function is invoked prior
* to DDR discovery and initialization. The MMU must be initialized before
* calling this function.
*
* Parameters
* pps PPS value to use for table generation
* l0_mem_base Base address of L0 tables in memory.
* l0_mem_size Total size of memory available for L0 tables.
*
* Return
* Negative Linux error code in the event of a failure, 0 for success.
*/
int gpt_init_l0_tables(gpccr_pps_e pps,
uintptr_t l0_mem_base,
size_t l0_mem_size);
/*
* Public API that carves out PAS regions from the L0 tables and builds any L1
* tables that are needed. This function ideally is run after DDR discovery and
* initialization. The L0 tables must have already been initialized to GPI_ANY
* when this function is called.
*
* Parameters
* pgs PGS value to use for table generation.
* l1_mem_base Base address of memory used for L1 tables.
* l1_mem_size Total size of memory available for L1 tables.
* *pas_regions Pointer to PAS regions structure array.
* pas_count Total number of PAS regions.
*
* Return
* Negative Linux error code in the event of a failure, 0 for success.
*/
int gpt_init_pas_l1_tables(gpccr_pgs_e pgs,
uintptr_t l1_mem_base,
size_t l1_mem_size,
pas_region_t *pas_regions,
unsigned int pas_count);
/*
* Public API to initialize the runtime gpt_config structure based on the values
* present in the GPTBR_EL3 and GPCCR_EL3 registers. GPT initialization
* typically happens in a bootloader stage prior to setting up the EL3 runtime
* environment for the granule transition service so this function detects the
* initialization from a previous stage. Granule protection checks must be
* enabled already or this function will return an error.
*
* Return
* Negative Linux error code in the event of a failure, 0 for success.
*/
int gpt_runtime_init(void);
/*
* Public API to enable granule protection checks once the tables have all been
* initialized. This function is called at first initialization and then again
* later during warm boots of CPU cores.
*
* Return
* Negative Linux error code in the event of a failure, 0 for success.
*/
int gpt_enable(void);
/*
* Public API to disable granule protection checks.
*/
void gpt_disable(void);
/*
* This function is the core of the granule transition service. When a granule
* transition request occurs it is routed to this function where the request is
* validated then fulfilled if possible.
*
* TODO: implement support for transitioning multiple granules at once.
*
* Parameters
* base: Base address of the region to transition, must be aligned to granule
* size.
* size: Size of region to transition, must be aligned to granule size.
* src_sec_state: Security state of the caller.
* target_pas: Target PAS of the specified memory region.
*
* Return
* Negative Linux error code in the event of a failure, 0 for success.
*/
int gpt_transition_pas(uint64_t base,
size_t size,
unsigned int src_sec_state,
unsigned int target_pas);
#endif /* GPT_RME_H */

View File

@ -108,9 +108,24 @@
#define SMC_ARCH_CALL_NOT_REQUIRED -2
#define SMC_ARCH_CALL_INVAL_PARAM -3
/* Various flags passed to SMC handlers */
/*
* Various flags passed to SMC handlers
*
* Bit 5 and bit 0 of the flag are used to
* determine the source security state as
* follows:
* ---------------------------------
* Bit 5 | Bit 0 | Security state
* ---------------------------------
* 0 0 SMC_FROM_SECURE
* 0 1 SMC_FROM_NON_SECURE
* 1 1 SMC_FROM_REALM
*/
#define SMC_FROM_SECURE (U(0) << 0)
#define SMC_FROM_NON_SECURE (U(1) << 0)
#define SMC_FROM_REALM U(0x21)
#define SMC_FROM_MASK U(0x21)
#ifndef __ASSEMBLER__
@ -118,8 +133,18 @@
#include <lib/cassert.h>
#if ENABLE_RME
#define is_caller_non_secure(_f) (((_f) & SMC_FROM_MASK) \
== SMC_FROM_NON_SECURE)
#define is_caller_secure(_f) (((_f) & SMC_FROM_MASK) \
== SMC_FROM_SECURE)
#define is_caller_realm(_f) (((_f) & SMC_FROM_MASK) \
== SMC_FROM_REALM)
#define caller_sec_state(_f) ((_f) & SMC_FROM_MASK)
#else /* ENABLE_RME */
#define is_caller_non_secure(_f) (((_f) & SMC_FROM_NON_SECURE) != U(0))
#define is_caller_secure(_f) (!is_caller_non_secure(_f))
#endif /* ENABLE_RME */
/* The macro below is used to identify a Standard Service SMC call */
#define is_std_svc_call(_fid) (GET_SMC_OEN(_fid) == OEN_STD_START)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -72,6 +72,13 @@
#define MT_CODE (MT_MEMORY | MT_RO | MT_EXECUTE)
#define MT_RO_DATA (MT_MEMORY | MT_RO | MT_EXECUTE_NEVER)
/* Memory type for EL3 regions */
#if ENABLE_RME
#error FEAT_RME requires version 2 of the Translation Tables Library
#else
#define EL3_PAS MT_SECURE
#endif
/*
* Structure for specifying a single region of memory.
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -142,6 +142,7 @@
#define AP_NO_ACCESS_UNPRIVILEGED (AP1_NO_ACCESS_UNPRIVILEGED << 4)
#define AP_ONE_VA_RANGE_RES1 (AP1_RES1 << 4)
#define NS (U(0x1) << 3)
#define EL3_S1_NSE (U(0x1) << 9)
#define ATTR_NON_CACHEABLE_INDEX ULL(0x2)
#define ATTR_DEVICE_INDEX ULL(0x1)
#define ATTR_IWBWA_OWBWA_NTR_INDEX ULL(0x0)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -60,17 +60,22 @@
#define MT_TYPE(_attr) ((_attr) & MT_TYPE_MASK)
/* Access permissions (RO/RW) */
#define MT_PERM_SHIFT U(3)
/* Security state (SECURE/NS) */
#define MT_SEC_SHIFT U(4)
/* Physical address space (SECURE/NS/Root/Realm) */
#define MT_PAS_SHIFT U(4)
#define MT_PAS_MASK (U(3) << MT_PAS_SHIFT)
#define MT_PAS(_attr) ((_attr) & MT_PAS_MASK)
/* Access permissions for instruction execution (EXECUTE/EXECUTE_NEVER) */
#define MT_EXECUTE_SHIFT U(5)
#define MT_EXECUTE_SHIFT U(6)
/* In the EL1&0 translation regime, User (EL0) or Privileged (EL1). */
#define MT_USER_SHIFT U(6)
#define MT_USER_SHIFT U(7)
/* Shareability attribute for the memory region */
#define MT_SHAREABILITY_SHIFT U(7)
#define MT_SHAREABILITY_SHIFT U(8)
#define MT_SHAREABILITY_MASK (U(3) << MT_SHAREABILITY_SHIFT)
#define MT_SHAREABILITY(_attr) ((_attr) & MT_SHAREABILITY_MASK)
/* All other bits are reserved */
/*
@ -91,8 +96,10 @@
#define MT_RO (U(0) << MT_PERM_SHIFT)
#define MT_RW (U(1) << MT_PERM_SHIFT)
#define MT_SECURE (U(0) << MT_SEC_SHIFT)
#define MT_NS (U(1) << MT_SEC_SHIFT)
#define MT_SECURE (U(0) << MT_PAS_SHIFT)
#define MT_NS (U(1) << MT_PAS_SHIFT)
#define MT_ROOT (U(2) << MT_PAS_SHIFT)
#define MT_REALM (U(3) << MT_PAS_SHIFT)
/*
* Access permissions for instruction execution are only relevant for normal
@ -149,6 +156,13 @@ typedef struct mmap_region {
#define EL3_REGIME 3
#define EL_REGIME_INVALID -1
/* Memory type for EL3 regions. With RME, EL3 is in ROOT PAS */
#if ENABLE_RME
#define EL3_PAS MT_ROOT
#else
#define EL3_PAS MT_SECURE
#endif /* ENABLE_RME */
/*
* Declare the translation context type.
* Its definition is private.

View File

@ -74,38 +74,84 @@
ARM_SHARED_RAM_SIZE)
/*
* The top 16MB of DRAM1 is configured as secure access only using the TZC
* The top 16MB (or 64MB if RME is enabled) of DRAM1 is configured as
* follows:
* - SCP TZC DRAM: If present, DRAM reserved for SCP use
* - L1 GPT DRAM: Reserved for L1 GPT if RME is enabled
* - REALM DRAM: Reserved for Realm world if RME is enabled
* - AP TZC DRAM: The remaining TZC secured DRAM reserved for AP use
*
* RME enabled(64MB) RME not enabled(16MB)
* -------------------- -------------------
* | | | |
* | AP TZC (~28MB) | | AP TZC (~14MB) |
* -------------------- -------------------
* | | | |
* | REALM (32MB) | | EL3 TZC (2MB) |
* -------------------- -------------------
* | | | |
* | EL3 TZC (3MB) | | SCP TZC |
* -------------------- 0xFFFF_FFFF-------------------
* | L1 GPT + SCP TZC |
* | (~1MB) |
* 0xFFFF_FFFF --------------------
*/
#define ARM_TZC_DRAM1_SIZE UL(0x01000000)
#define ARM_SCP_TZC_DRAM1_BASE (ARM_DRAM1_BASE + \
ARM_DRAM1_SIZE - \
ARM_SCP_TZC_DRAM1_SIZE)
#define ARM_SCP_TZC_DRAM1_SIZE PLAT_ARM_SCP_TZC_DRAM1_SIZE
#define ARM_SCP_TZC_DRAM1_END (ARM_SCP_TZC_DRAM1_BASE + \
ARM_SCP_TZC_DRAM1_SIZE - 1U)
#if ENABLE_RME
#define ARM_TZC_DRAM1_SIZE UL(0x04000000) /* 64MB */
/*
* Define a 2MB region within the TZC secured DRAM for use by EL3 runtime
* Define a region within the TZC secured DRAM for use by EL3 runtime
* firmware. This region is meant to be NOLOAD and will not be zero
* initialized. Data sections with the attribute `arm_el3_tzc_dram` will be
* placed here.
* placed here. 3MB region is reserved if RME is enabled, 2MB otherwise.
*/
#define ARM_EL3_TZC_DRAM1_BASE (ARM_SCP_TZC_DRAM1_BASE - ARM_EL3_TZC_DRAM1_SIZE)
#define ARM_EL3_TZC_DRAM1_SIZE UL(0x00200000) /* 2 MB */
#define ARM_EL3_TZC_DRAM1_SIZE UL(0x00300000) /* 3MB */
#define ARM_L1_GPT_SIZE UL(0x00100000) /* 1MB */
#define ARM_REALM_SIZE UL(0x02000000) /* 32MB */
#else
#define ARM_TZC_DRAM1_SIZE UL(0x01000000) /* 16MB */
#define ARM_EL3_TZC_DRAM1_SIZE UL(0x00200000) /* 2MB */
#define ARM_L1_GPT_SIZE UL(0)
#define ARM_REALM_SIZE UL(0)
#endif /* ENABLE_RME */
#define ARM_SCP_TZC_DRAM1_BASE (ARM_DRAM1_BASE + \
ARM_DRAM1_SIZE - \
(ARM_SCP_TZC_DRAM1_SIZE + \
ARM_L1_GPT_SIZE))
#define ARM_SCP_TZC_DRAM1_SIZE PLAT_ARM_SCP_TZC_DRAM1_SIZE
#define ARM_SCP_TZC_DRAM1_END (ARM_SCP_TZC_DRAM1_BASE + \
ARM_SCP_TZC_DRAM1_SIZE - 1U)
#if ENABLE_RME
#define ARM_L1_GPT_ADDR_BASE (ARM_DRAM1_BASE + \
ARM_DRAM1_SIZE - \
ARM_L1_GPT_SIZE)
#define ARM_L1_GPT_END (ARM_L1_GPT_ADDR_BASE + \
ARM_L1_GPT_SIZE - 1U)
#define ARM_REALM_BASE (ARM_DRAM1_BASE + \
ARM_DRAM1_SIZE - \
(ARM_SCP_TZC_DRAM1_SIZE + \
ARM_EL3_TZC_DRAM1_SIZE + \
ARM_REALM_SIZE + \
ARM_L1_GPT_SIZE))
#define ARM_REALM_END (ARM_REALM_BASE + ARM_REALM_SIZE - 1U)
#endif /* ENABLE_RME */
#define ARM_EL3_TZC_DRAM1_BASE (ARM_SCP_TZC_DRAM1_BASE - \
ARM_EL3_TZC_DRAM1_SIZE)
#define ARM_EL3_TZC_DRAM1_END (ARM_EL3_TZC_DRAM1_BASE + \
ARM_EL3_TZC_DRAM1_SIZE - 1U)
#define ARM_AP_TZC_DRAM1_BASE (ARM_DRAM1_BASE + \
ARM_DRAM1_SIZE - \
ARM_TZC_DRAM1_SIZE)
ARM_DRAM1_SIZE - \
ARM_TZC_DRAM1_SIZE)
#define ARM_AP_TZC_DRAM1_SIZE (ARM_TZC_DRAM1_SIZE - \
(ARM_SCP_TZC_DRAM1_SIZE + \
ARM_EL3_TZC_DRAM1_SIZE))
(ARM_SCP_TZC_DRAM1_SIZE + \
ARM_EL3_TZC_DRAM1_SIZE + \
ARM_REALM_SIZE + \
ARM_L1_GPT_SIZE))
#define ARM_AP_TZC_DRAM1_END (ARM_AP_TZC_DRAM1_BASE + \
ARM_AP_TZC_DRAM1_SIZE - 1U)
ARM_AP_TZC_DRAM1_SIZE - 1U)
/* Define the Access permissions for Secure peripherals to NS_DRAM */
#if ARM_CRYPTOCELL_INTEG
@ -206,45 +252,58 @@
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, (grp), \
GIC_INTR_CFG_EDGE)
#define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \
ARM_SHARED_RAM_BASE, \
ARM_SHARED_RAM_SIZE, \
MT_DEVICE | MT_RW | MT_SECURE)
#define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \
ARM_SHARED_RAM_BASE, \
ARM_SHARED_RAM_SIZE, \
MT_DEVICE | MT_RW | EL3_PAS)
#define ARM_MAP_NS_DRAM1 MAP_REGION_FLAT( \
ARM_NS_DRAM1_BASE, \
ARM_NS_DRAM1_SIZE, \
MT_MEMORY | MT_RW | MT_NS)
#define ARM_MAP_NS_DRAM1 MAP_REGION_FLAT( \
ARM_NS_DRAM1_BASE, \
ARM_NS_DRAM1_SIZE, \
MT_MEMORY | MT_RW | MT_NS)
#define ARM_MAP_DRAM2 MAP_REGION_FLAT( \
ARM_DRAM2_BASE, \
ARM_DRAM2_SIZE, \
MT_MEMORY | MT_RW | MT_NS)
#define ARM_MAP_DRAM2 MAP_REGION_FLAT( \
ARM_DRAM2_BASE, \
ARM_DRAM2_SIZE, \
MT_MEMORY | MT_RW | MT_NS)
#define ARM_MAP_TSP_SEC_MEM MAP_REGION_FLAT( \
TSP_SEC_MEM_BASE, \
TSP_SEC_MEM_SIZE, \
MT_MEMORY | MT_RW | MT_SECURE)
#define ARM_MAP_TSP_SEC_MEM MAP_REGION_FLAT( \
TSP_SEC_MEM_BASE, \
TSP_SEC_MEM_SIZE, \
MT_MEMORY | MT_RW | MT_SECURE)
#if ARM_BL31_IN_DRAM
#define ARM_MAP_BL31_SEC_DRAM MAP_REGION_FLAT( \
BL31_BASE, \
PLAT_ARM_MAX_BL31_SIZE, \
MT_MEMORY | MT_RW | MT_SECURE)
#define ARM_MAP_BL31_SEC_DRAM MAP_REGION_FLAT( \
BL31_BASE, \
PLAT_ARM_MAX_BL31_SIZE, \
MT_MEMORY | MT_RW | MT_SECURE)
#endif
#define ARM_MAP_EL3_TZC_DRAM MAP_REGION_FLAT( \
ARM_EL3_TZC_DRAM1_BASE, \
ARM_EL3_TZC_DRAM1_SIZE, \
MT_MEMORY | MT_RW | MT_SECURE)
#define ARM_MAP_EL3_TZC_DRAM MAP_REGION_FLAT( \
ARM_EL3_TZC_DRAM1_BASE, \
ARM_EL3_TZC_DRAM1_SIZE, \
MT_MEMORY | MT_RW | EL3_PAS)
#if defined(SPD_spmd)
#define ARM_MAP_TRUSTED_DRAM MAP_REGION_FLAT( \
PLAT_ARM_TRUSTED_DRAM_BASE, \
PLAT_ARM_TRUSTED_DRAM_SIZE, \
MT_MEMORY | MT_RW | MT_SECURE)
#define ARM_MAP_TRUSTED_DRAM MAP_REGION_FLAT( \
PLAT_ARM_TRUSTED_DRAM_BASE, \
PLAT_ARM_TRUSTED_DRAM_SIZE, \
MT_MEMORY | MT_RW | MT_SECURE)
#endif
#if ENABLE_RME
#define ARM_MAP_RMM_DRAM MAP_REGION_FLAT( \
PLAT_ARM_RMM_BASE, \
PLAT_ARM_RMM_SIZE, \
MT_MEMORY | MT_RW | MT_REALM)
#define ARM_MAP_GPT_L1_DRAM MAP_REGION_FLAT( \
ARM_L1_GPT_ADDR_BASE, \
ARM_L1_GPT_SIZE, \
MT_MEMORY | MT_RW | EL3_PAS)
#endif /* ENABLE_RME */
/*
* Mapping for the BL1 RW region. This mapping is needed by BL2 in order to
@ -255,7 +314,7 @@
#define ARM_MAP_BL1_RW MAP_REGION_FLAT( \
BL1_RW_BASE, \
BL1_RW_LIMIT - BL1_RW_BASE, \
MT_MEMORY | MT_RW | MT_SECURE)
MT_MEMORY | MT_RW | EL3_PAS)
/*
* If SEPARATE_CODE_AND_RODATA=1 we define a region for each section
@ -265,35 +324,35 @@
#define ARM_MAP_BL_RO MAP_REGION_FLAT( \
BL_CODE_BASE, \
BL_CODE_END - BL_CODE_BASE, \
MT_CODE | MT_SECURE), \
MT_CODE | EL3_PAS), \
MAP_REGION_FLAT( \
BL_RO_DATA_BASE, \
BL_RO_DATA_END \
- BL_RO_DATA_BASE, \
MT_RO_DATA | MT_SECURE)
MT_RO_DATA | EL3_PAS)
#else
#define ARM_MAP_BL_RO MAP_REGION_FLAT( \
BL_CODE_BASE, \
BL_CODE_END - BL_CODE_BASE, \
MT_CODE | MT_SECURE)
MT_CODE | EL3_PAS)
#endif
#if USE_COHERENT_MEM
#define ARM_MAP_BL_COHERENT_RAM MAP_REGION_FLAT( \
BL_COHERENT_RAM_BASE, \
BL_COHERENT_RAM_END \
- BL_COHERENT_RAM_BASE, \
MT_DEVICE | MT_RW | MT_SECURE)
MT_DEVICE | MT_RW | EL3_PAS)
#endif
#if USE_ROMLIB
#define ARM_MAP_ROMLIB_CODE MAP_REGION_FLAT( \
ROMLIB_RO_BASE, \
ROMLIB_RO_LIMIT - ROMLIB_RO_BASE,\
MT_CODE | MT_SECURE)
MT_CODE | EL3_PAS)
#define ARM_MAP_ROMLIB_DATA MAP_REGION_FLAT( \
ROMLIB_RW_BASE, \
ROMLIB_RW_END - ROMLIB_RW_BASE,\
MT_MEMORY | MT_RW | MT_SECURE)
MT_MEMORY | MT_RW | EL3_PAS)
#endif
/*
@ -308,7 +367,15 @@
#define ARM_MAP_BL_CONFIG_REGION MAP_REGION_FLAT(ARM_BL_RAM_BASE, \
(ARM_FW_CONFIGS_LIMIT \
- ARM_BL_RAM_BASE), \
MT_MEMORY | MT_RW | MT_SECURE)
MT_MEMORY | MT_RW | EL3_PAS)
/*
* Map L0_GPT with read and write permissions
*/
#if ENABLE_RME
#define ARM_MAP_L0_GPT_REGION MAP_REGION_FLAT(ARM_L0_GPT_ADDR_BASE, \
ARM_L0_GPT_SIZE, \
MT_MEMORY | MT_RW | MT_ROOT)
#endif
/*
* The max number of regions like RO(code), coherent and data required by
@ -409,6 +476,18 @@
*/
#define ARM_FW_CONFIGS_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE * 2))
#if ENABLE_RME
/*
* Store the L0 GPT on Trusted SRAM next to firmware
* configuration memory, 4KB aligned.
*/
#define ARM_L0_GPT_SIZE (PAGE_SIZE)
#define ARM_L0_GPT_ADDR_BASE (ARM_FW_CONFIGS_LIMIT)
#define ARM_L0_GPT_LIMIT (ARM_L0_GPT_ADDR_BASE + ARM_L0_GPT_SIZE)
#else
#define ARM_L0_GPT_SIZE U(0)
#endif
/*******************************************************************************
* BL1 specific defines.
* BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of
@ -501,6 +580,14 @@
#endif
#endif
/******************************************************************************
* RMM specific defines
*****************************************************************************/
#if ENABLE_RME
#define RMM_BASE (ARM_REALM_BASE)
#define RMM_LIMIT (RMM_BASE + ARM_REALM_SIZE)
#endif
#if !defined(__aarch64__) || JUNO_AARCH32_EL3_RUNTIME
/*******************************************************************************
* BL32 specific defines for EL3 runtime in AArch32 mode

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef ARM_PAS_DEF_H
#define ARM_PAS_DEF_H
#include <lib/gpt_rme/gpt_rme.h>
#include <plat/arm/common/arm_def.h>
/*****************************************************************************
* PAS regions used to initialize the Granule Protection Table (GPT)
****************************************************************************/
/*
* The PA space is initially mapped in the GPT as follows:
*
* ============================================================================
* Base Addr| Size |L? GPT|PAS |Content |Comment
* ============================================================================
* 0GB | 1GB |L0 GPT|ANY |TBROM (EL3 code) |Fixed mapping
* | | | |TSRAM (EL3 data) |
* | | | |IO (incl.UARTs & GIC) |
* ----------------------------------------------------------------------------
* 1GB | 1GB |L0 GPT|ANY |IO |Fixed mapping
* ----------------------------------------------------------------------------
* 2GB | 1GB |L1 GPT|NS |DRAM (NS Kernel) |Use T.Descrip
* ----------------------------------------------------------------------------
* 3GB |1GB-64MB |L1 GPT|NS |DRAM (NS Kernel) |Use T.Descrip
* ----------------------------------------------------------------------------
* 4GB-64MB |64MB-32MB | | | |
* | -4MB |L1 GPT|SECURE|DRAM TZC |Use T.Descrip
* ----------------------------------------------------------------------------
* 4GB-32MB | | | | |
* -3MB-1MB |32MB |L1 GPT|REALM |RMM |Use T.Descrip
* ----------------------------------------------------------------------------
* 4GB-3MB | | | | |
* -1MB |3MB |L1 GPT|ROOT |EL3 DRAM data |Use T.Descrip
* ----------------------------------------------------------------------------
* 4GB-1MB |1MB |L1 GPT|ROOT |DRAM (L1 GPTs, SCP TZC) |Fixed mapping
* ============================================================================
*
* - 4KB of L0 GPT reside in TSRAM, on top of the CONFIG section.
* - ~1MB of L1 GPTs reside at the top of DRAM1 (TZC area).
* - The first 1GB region has GPT_GPI_ANY and, therefore, is not protected by
* the GPT.
* - The DRAM TZC area is split into three regions: the L1 GPT region and
* 3MB of region below that are defined as GPT_GPI_ROOT, 32MB Realm region
* below that is defined as GPT_GPI_REALM and the rest of it is defined as
* GPT_GPI_SECURE.
*/
/* TODO: This might not be the best way to map the PAS */
/* Device memory 0 to 2GB */
#define ARM_PAS_1_BASE (U(0))
#define ARM_PAS_1_SIZE ((ULL(1)<<31)) /* 2GB */
/* NS memory 2GB to (end - 64MB) */
#define ARM_PAS_2_BASE (ARM_PAS_1_BASE + ARM_PAS_1_SIZE)
#define ARM_PAS_2_SIZE (ARM_NS_DRAM1_SIZE)
/* Secure TZC region */
#define ARM_PAS_3_BASE (ARM_AP_TZC_DRAM1_BASE)
#define ARM_PAS_3_SIZE (ARM_AP_TZC_DRAM1_SIZE)
#define ARM_PAS_GPI_ANY MAP_GPT_REGION(ARM_PAS_1_BASE, \
ARM_PAS_1_SIZE, \
GPT_GPI_ANY)
#define ARM_PAS_KERNEL GPT_MAP_REGION_GRANULE(ARM_PAS_2_BASE, \
ARM_PAS_2_SIZE, \
GPT_GPI_NS)
#define ARM_PAS_SECURE GPT_MAP_REGION_GRANULE(ARM_PAS_3_BASE, \
ARM_PAS_3_SIZE, \
GPT_GPI_SECURE)
#define ARM_PAS_REALM GPT_MAP_REGION_GRANULE(ARM_REALM_BASE, \
ARM_REALM_SIZE, \
GPT_GPI_REALM)
#define ARM_PAS_EL3_DRAM GPT_MAP_REGION_GRANULE(ARM_EL3_TZC_DRAM1_BASE, \
ARM_EL3_TZC_DRAM1_SIZE, \
GPT_GPI_ROOT)
#define ARM_PAS_GPTS GPT_MAP_REGION_GRANULE(ARM_L1_GPT_ADDR_BASE, \
ARM_L1_GPT_SIZE, \
GPT_GPI_ROOT)
/* GPT Configuration options */
#define PLATFORM_L0GPTSZ GPCCR_L0GPTSZ_30BITS
#endif /* ARM_PAS_DEF_H */

View File

@ -41,7 +41,7 @@ typedef struct arm_tzc_regions_info {
******************************************************************************/
#if SPM_MM
#define ARM_TZC_REGIONS_DEF \
{ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END, \
{ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END + ARM_L1_GPT_SIZE,\
TZC_REGION_S_RDWR, 0}, \
{ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \
PLAT_ARM_TZC_NS_DEV_ACCESS}, \
@ -51,9 +51,20 @@ typedef struct arm_tzc_regions_info {
PLAT_SP_IMAGE_NS_BUF_SIZE) - 1, TZC_REGION_S_NONE, \
PLAT_ARM_TZC_NS_DEV_ACCESS}
#elif ENABLE_RME
#define ARM_TZC_REGIONS_DEF \
{ARM_AP_TZC_DRAM1_BASE, ARM_AP_TZC_DRAM1_END, TZC_REGION_S_RDWR, 0},\
{ARM_EL3_TZC_DRAM1_BASE, ARM_L1_GPT_END, TZC_REGION_S_RDWR, 0}, \
{ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \
PLAT_ARM_TZC_NS_DEV_ACCESS}, \
{ARM_REALM_BASE, ARM_REALM_END, ARM_TZC_NS_DRAM_S_ACCESS, \
PLAT_ARM_TZC_NS_DEV_ACCESS}, \
{ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS, \
PLAT_ARM_TZC_NS_DEV_ACCESS}
#else
#define ARM_TZC_REGIONS_DEF \
{ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END, \
{ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END + ARM_L1_GPT_SIZE,\
TZC_REGION_S_RDWR, 0}, \
{ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \
PLAT_ARM_TZC_NS_DEV_ACCESS}, \

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef GTSI_SVC_H
#define GTSI_SVC_H
/* GTSI error codes. */
#define GTSI_SUCCESS 0
#define GTSI_ERROR_NOT_SUPPORTED -1
#define GTSI_ERROR_INVALID_ADDRESS -2
#define GTSI_ERROR_INVALID_PAS -3
/* The macros below are used to identify GTSI calls from the SMC function ID */
#define GTSI_FNUM_MIN_VALUE U(0x100)
#define GTSI_FNUM_MAX_VALUE U(0x101)
#define is_gtsi_fid(fid) __extension__ ({ \
__typeof__(fid) _fid = (fid); \
((GET_SMC_NUM(_fid) >= GTSI_FNUM_MIN_VALUE) && \
(GET_SMC_NUM(_fid) <= GTSI_FNUM_MAX_VALUE)); })
/* Get GTSI fastcall std FID from function number */
#define GTSI_FID(smc_cc, func_num) \
((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
((smc_cc) << FUNCID_CC_SHIFT) | \
(OEN_STD_START << FUNCID_OEN_SHIFT) | \
((func_num) << FUNCID_NUM_SHIFT))
#define GRAN_TRANS_TO_REALM_FNUM U(0x100)
#define GRAN_TRANS_TO_NS_FNUM U(0x101)
#define SMC_ASC_MARK_REALM GTSI_FID(SMC_64, GRAN_TRANS_TO_REALM_FNUM)
#define SMC_ASC_MARK_NONSECURE GTSI_FID(SMC_64, GRAN_TRANS_TO_NS_FNUM)
#define GRAN_TRANS_RET_BAD_ADDR -2
#define GRAN_TRANS_RET_BAD_PAS -3
#endif /* GTSI_SVC_H */

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef RMI_SVC_H
#define RMI_SVC_H
#include <lib/smccc.h>
#include <lib/utils_def.h>
/* RMI error codes. */
#define RMI_SUCCESS 0
#define RMI_ERROR_NOT_SUPPORTED -1
#define RMI_ERROR_INVALID_ADDRESS -2
#define RMI_ERROR_INVALID_PAS -3
/* The macros below are used to identify RMI calls from the SMC function ID */
#define RMI_FNUM_MIN_VALUE U(0x00)
#define RMI_FNUM_MAX_VALUE U(0x20)
#define is_rmi_fid(fid) __extension__ ({ \
__typeof__(fid) _fid = (fid); \
((GET_SMC_NUM(_fid) >= RMI_FNUM_MIN_VALUE) && \
(GET_SMC_NUM(_fid) <= RMI_FNUM_MAX_VALUE) && \
(GET_SMC_TYPE(_fid) == SMC_TYPE_FAST) && \
(GET_SMC_CC(_fid) == SMC_64) && \
(GET_SMC_OEN(_fid) == OEN_ARM_START) && \
((_fid & 0x00FE0000) == 0U)); })
/* Get RMI fastcall std FID from function number */
#define RMI_FID(smc_cc, func_num) \
((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
((smc_cc) << FUNCID_CC_SHIFT) | \
(OEN_ARM_START << FUNCID_OEN_SHIFT) | \
((func_num) << FUNCID_NUM_SHIFT))
/*
* SMC_RMM_INIT_COMPLETE is the only function in the RMI that originates from
* the Realm world and is handled by the RMMD. The remaining functions are
* always invoked by the Normal world, forwarded by RMMD and handled by the
* RMM
*/
#define RMI_FNUM_REQ_COMPLETE U(0x10)
#define RMI_FNUM_VERSION_REQ U(0x00)
#define RMI_FNUM_GRAN_NS_REALM U(0x01)
#define RMI_FNUM_GRAN_REALM_NS U(0x10)
/* RMI SMC64 FIDs handled by the RMMD */
#define RMI_RMM_REQ_COMPLETE RMI_FID(SMC_64, RMI_FNUM_REQ_COMPLETE)
#define RMI_RMM_REQ_VERSION RMI_FID(SMC_64, RMI_FNUM_VERSION_REQ)
#define RMI_RMM_GRANULE_DELEGATE RMI_FID(SMC_64, RMI_FNUM_GRAN_NS_REALM)
#define RMI_RMM_GRANULE_UNDELEGATE RMI_FID(SMC_64, RMI_FNUM_GRAN_REALM_NS)
#define RMI_ABI_VERSION_GET_MAJOR(_version) ((_version) >> 16)
#define RMI_ABI_VERSION_GET_MINOR(_version) ((_version) & 0xFFFF)
/* Reserve a special value for MBZ parameters. */
#define RMI_PARAM_MBZ U(0x0)
#endif /* RMI_SVC_H */

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef RMMD_SVC_H
#define RMMD_SVC_H
#ifndef __ASSEMBLER__
#include <stdint.h>
int rmmd_setup(void);
uint64_t rmmd_rmi_handler(uint32_t smc_fid,
uint64_t x1,
uint64_t x2,
uint64_t x3,
uint64_t x4,
void *cookie,
void *handle,
uint64_t flags);
uint64_t rmmd_gtsi_handler(uint32_t smc_fid,
uint64_t x1,
uint64_t x2,
uint64_t x3,
uint64_t x4,
void *cookie,
void *handle,
uint64_t flags);
#endif /* __ASSEMBLER__ */
#endif /* RMMD_SVC_H */

View File

@ -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 */

View File

@ -38,6 +38,8 @@
{{0x8e, 0xa8, 0x7b, 0xb1}, {0xcf, 0xa2}, {0x3f, 0x4d}, 0x85, 0xfd, {0xe7, 0xbb, 0xa5, 0x02, 0x20, 0xd9} }
#define UUID_NON_TRUSTED_FIRMWARE_BL33 \
{{0xd6, 0xd0, 0xee, 0xa7}, {0xfc, 0xea}, {0xd5, 0x4b}, 0x97, 0x82, {0x99, 0x34, 0xf2, 0x34, 0xb6, 0xe4} }
#define UUID_REALM_MONITOR_MGMT_FIRMWARE \
{{0x6c, 0x07, 0x62, 0xa6}, {0x12, 0xf2}, {0x4b, 0x56}, 0x92, 0xcb, {0xba, 0x8f, 0x63, 0x36, 0x06, 0xd9} }
/* Key certificates */
#define UUID_ROT_KEY_CERT \
{{0x86, 0x2d, 0x1d, 0x72}, {0xf8, 0x60}, {0xe4, 0x11}, 0x92, 0x0b, {0x8b, 0xe7, 0x62, 0x16, 0x0f, 0x24} }

View File

@ -15,6 +15,7 @@
.globl zero_normalmem
.globl zeromem
.globl memcpy16
.globl gpt_tlbi_by_pa
.globl disable_mmu_el1
.globl disable_mmu_el3
@ -162,7 +163,8 @@ func zeromem_dczva
* Check for M bit (MMU enabled) of the current SCTLR_EL(1|3)
* register value and panic if the MMU is disabled.
*/
#if defined(IMAGE_BL1) || defined(IMAGE_BL31) || (defined(IMAGE_BL2) && BL2_AT_EL3)
#if defined(IMAGE_BL1) || defined(IMAGE_BL31) || (defined(IMAGE_BL2) && \
(BL2_AT_EL3 || ENABLE_RME))
mrs tmp1, sctlr_el3
#else
mrs tmp1, sctlr_el1
@ -592,3 +594,20 @@ func fixup_gdt_reloc
b.lo 1b
ret
endfunc fixup_gdt_reloc
/*
* TODO: Currently only supports size of 4KB,
* support other sizes as well.
*/
func gpt_tlbi_by_pa
#if ENABLE_ASSERTIONS
cmp x1, #PAGE_SIZE_4KB
ASM_ASSERT(eq)
tst x0, #(PAGE_SIZE_MASK)
ASM_ASSERT(eq)
#endif
lsr x0, x0, #FOUR_KB_SHIFT /* 4KB size encoding is zero */
sys #6, c8, c4, #3, x0 /* TLBI RPAOS, <Xt> */
dsb sy
ret
endfunc gpt_tlbi_by_pa

View File

@ -93,24 +93,41 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
scr_el3 = read_scr();
scr_el3 &= ~(SCR_NS_BIT | SCR_RW_BIT | SCR_FIQ_BIT | SCR_IRQ_BIT |
SCR_ST_BIT | SCR_HCE_BIT);
#if ENABLE_RME
/* When RME support is enabled, clear the NSE bit as well. */
scr_el3 &= ~SCR_NSE_BIT;
#endif /* ENABLE_RME */
/*
* SCR_NS: Set the security state of the next EL.
*/
if (security_state != SECURE)
if (security_state == NON_SECURE) {
scr_el3 |= SCR_NS_BIT;
}
#if ENABLE_RME
/* Check for realm state if RME support enabled. */
if (security_state == REALM) {
scr_el3 |= SCR_NS_BIT | SCR_NSE_BIT | SCR_EnSCXT_BIT;
}
#endif /* ENABLE_RME */
/*
* SCR_EL3.RW: Set the execution state, AArch32 or AArch64, for next
* Exception level as specified by SPSR.
*/
if (GET_RW(ep->spsr) == MODE_RW_64)
if (GET_RW(ep->spsr) == MODE_RW_64) {
scr_el3 |= SCR_RW_BIT;
}
/*
* SCR_EL3.ST: Traps Secure EL1 accesses to the Counter-timer Physical
* Secure timer registers to EL3, from AArch64 state only, if specified
* by the entrypoint attributes.
*/
if (EP_GET_ST(ep->h.attr) != 0U)
if (EP_GET_ST(ep->h.attr) != 0U) {
scr_el3 |= SCR_ST_BIT;
}
/*
* If FEAT_HCX is enabled, enable access to HCRX_EL2 by setting
@ -152,8 +169,9 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
* If the Secure world wants to use pointer authentication,
* CTX_INCLUDE_PAUTH_REGS must be set to 1.
*/
if (security_state == NON_SECURE)
if (security_state == NON_SECURE) {
scr_el3 |= SCR_API_BIT | SCR_APK_BIT;
}
#endif /* !CTX_INCLUDE_PAUTH_REGS */
#if !CTX_INCLUDE_MTE_REGS || ENABLE_ASSERTIONS
@ -188,8 +206,14 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
/*
* SCR_EL3.IRQ, SCR_EL3.FIQ: Enable the physical FIQ and IRQ routing as
* indicated by the interrupt routing model for BL31.
*
* TODO: The interrupt routing model code is not updated for REALM
* state. Use the default values of IRQ = FIQ = 0 for REALM security
* state for now.
*/
scr_el3 |= get_scr_el3_from_routing_model(security_state);
if (security_state != REALM) {
scr_el3 |= get_scr_el3_from_routing_model(security_state);
}
#endif
/* Save the initialized value of CPTR_EL3 register */
@ -256,9 +280,9 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
* required by PSCI specification)
*/
sctlr_elx = (EP_GET_EE(ep->h.attr) != 0U) ? SCTLR_EE_BIT : 0U;
if (GET_RW(ep->spsr) == MODE_RW_64)
if (GET_RW(ep->spsr) == MODE_RW_64) {
sctlr_elx |= SCTLR_EL1_RES1;
else {
} else {
/*
* If the target execution state is AArch32 then the following
* fields need to be set.
@ -413,7 +437,8 @@ void cm_init_my_context(const entry_point_info_t *ep)
}
/*******************************************************************************
* Prepare the CPU system registers for first entry into secure or normal world
* Prepare the CPU system registers for first entry into realm, secure, or
* normal world.
*
* If execution is requested to EL2 or hyp mode, SCTLR_EL2 is initialized
* If execution is requested to non-secure EL1 or svc mode, and the CPU supports
@ -497,7 +522,7 @@ void cm_prepare_el3_exit(uint32_t security_state)
* architecturally UNKNOWN on reset and are set to zero
* except for field(s) listed below.
*
* CNTHCTL_EL2.EL1PCEN: Set to one to disable traps to
* CNTHCTL_EL2.EL1PTEN: Set to one to disable traps to
* Hyp mode of Non-secure EL0 and EL1 accesses to the
* physical timer registers.
*
@ -645,10 +670,10 @@ void cm_el2_sysregs_context_save(uint32_t security_state)
u_register_t scr_el3 = read_scr();
/*
* Always save the non-secure EL2 context, only save the
* Always save the non-secure and realm EL2 context, only save the
* S-EL2 context if S-EL2 is enabled.
*/
if ((security_state == NON_SECURE) ||
if ((security_state != SECURE) ||
((security_state == SECURE) && ((scr_el3 & SCR_EEL2_BIT) != 0U))) {
cpu_context_t *ctx;
@ -667,10 +692,10 @@ void cm_el2_sysregs_context_restore(uint32_t security_state)
u_register_t scr_el3 = read_scr();
/*
* Always restore the non-secure EL2 context, only restore the
* Always restore the non-secure and realm EL2 context, only restore the
* S-EL2 context if S-EL2 is enabled.
*/
if ((security_state == NON_SECURE) ||
if ((security_state != SECURE) ||
((security_state == SECURE) && ((scr_el3 & SCR_EEL2_BIT) != 0U))) {
cpu_context_t *ctx;

1112
lib/gpt_rme/gpt_rme.c Normal file

File diff suppressed because it is too large Load Diff

8
lib/gpt_rme/gpt_rme.mk Normal file
View File

@ -0,0 +1,8 @@
#
# Copyright (c) 2021, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
GPT_LIB_SRCS := $(addprefix lib/gpt_rme/, \
gpt_rme.c)

View File

@ -0,0 +1,228 @@
/*
* Copyright (c) 2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef GPT_RME_PRIVATE_H
#define GPT_RME_PRIVATE_H
#include <arch.h>
#include <lib/gpt_rme/gpt_rme.h>
#include <lib/utils_def.h>
/******************************************************************************/
/* GPT descriptor definitions */
/******************************************************************************/
/* GPT level 0 descriptor bit definitions. */
#define GPT_L0_TYPE_MASK UL(0xF)
#define GPT_L0_TYPE_SHIFT U(0)
/* For now, we don't support contiguous descriptors, only table and block. */
#define GPT_L0_TYPE_TBL_DESC UL(0x3)
#define GPT_L0_TYPE_BLK_DESC UL(0x1)
#define GPT_L0_TBL_DESC_L1ADDR_MASK UL(0xFFFFFFFFFF)
#define GPT_L0_TBL_DESC_L1ADDR_SHIFT U(12)
#define GPT_L0_BLK_DESC_GPI_MASK UL(0xF)
#define GPT_L0_BLK_DESC_GPI_SHIFT U(4)
/* GPT level 1 descriptor bit definitions */
#define GPT_L1_GRAN_DESC_GPI_MASK UL(0xF)
/*
* This macro fills out every GPI entry in a granules descriptor to the same
* value.
*/
#define GPT_BUILD_L1_DESC(_gpi) (((uint64_t)(_gpi) << 4*0) | \
((uint64_t)(_gpi) << 4*1) | \
((uint64_t)(_gpi) << 4*2) | \
((uint64_t)(_gpi) << 4*3) | \
((uint64_t)(_gpi) << 4*4) | \
((uint64_t)(_gpi) << 4*5) | \
((uint64_t)(_gpi) << 4*6) | \
((uint64_t)(_gpi) << 4*7) | \
((uint64_t)(_gpi) << 4*8) | \
((uint64_t)(_gpi) << 4*9) | \
((uint64_t)(_gpi) << 4*10) | \
((uint64_t)(_gpi) << 4*11) | \
((uint64_t)(_gpi) << 4*12) | \
((uint64_t)(_gpi) << 4*13) | \
((uint64_t)(_gpi) << 4*14) | \
((uint64_t)(_gpi) << 4*15))
/******************************************************************************/
/* GPT platform configuration */
/******************************************************************************/
/* This value comes from GPCCR_EL3 so no externally supplied definition. */
#define GPT_L0GPTSZ ((unsigned int)((read_gpccr_el3() >> \
GPCCR_L0GPTSZ_SHIFT) & GPCCR_L0GPTSZ_MASK))
/* The "S" value is directly related to L0GPTSZ */
#define GPT_S_VAL (GPT_L0GPTSZ + 30U)
/*
* Map PPS values to T values.
*
* PPS Size T
* 0b000 4GB 32
* 0b001 64GB 36
* 0b010 1TB 40
* 0b011 4TB 42
* 0b100 16TB 44
* 0b101 256TB 48
* 0b110 4PB 52
*
* See section 15.1.27 of the RME specification.
*/
typedef enum {
PPS_4GB_T = 32U,
PPS_64GB_T = 36U,
PPS_1TB_T = 40U,
PPS_4TB_T = 42U,
PPS_16TB_T = 44U,
PPS_256TB_T = 48U,
PPS_4PB_T = 52U
} gpt_t_val_e;
/*
* Map PGS values to P values.
*
* PGS Size P
* 0b00 4KB 12
* 0b10 16KB 14
* 0b01 64KB 16
*
* Note that pgs=0b10 is 16KB and pgs=0b01 is 64KB, this is not a typo.
*
* See section 15.1.27 of the RME specification.
*/
typedef enum {
PGS_4KB_P = 12U,
PGS_16KB_P = 14U,
PGS_64KB_P = 16U
} gpt_p_val_e;
/* Max valid value for PGS. */
#define GPT_PGS_MAX (2U)
/* Max valid value for PPS. */
#define GPT_PPS_MAX (6U)
/******************************************************************************/
/* L0 address attribute macros */
/******************************************************************************/
/*
* If S is greater than or equal to T then there is a single L0 region covering
* the entire protected space so there is no L0 index, so the width (and the
* derivative mask value) are both zero. If we don't specifically handle this
* special case we'll get a negative width value which does not make sense and
* could cause a lot of problems.
*/
#define GPT_L0_IDX_WIDTH(_t) (((_t) > GPT_S_VAL) ? \
((_t) - GPT_S_VAL) : (0U))
/* Bit shift for the L0 index field in a PA. */
#define GPT_L0_IDX_SHIFT (GPT_S_VAL)
/* Mask for the L0 index field, must be shifted. */
#define GPT_L0_IDX_MASK(_t) (0xFFFFFFFFFFFFFFFFUL >> \
(64U - (GPT_L0_IDX_WIDTH(_t))))
/* Total number of L0 regions. */
#define GPT_L0_REGION_COUNT(_t) ((GPT_L0_IDX_MASK(_t)) + 1U)
/* Total size of each GPT L0 region in bytes. */
#define GPT_L0_REGION_SIZE (1UL << (GPT_L0_IDX_SHIFT))
/* Total size in bytes of the whole L0 table. */
#define GPT_L0_TABLE_SIZE(_t) ((GPT_L0_REGION_COUNT(_t)) << 3U)
/******************************************************************************/
/* L1 address attribute macros */
/******************************************************************************/
/* Width of the L1 index field. */
#define GPT_L1_IDX_WIDTH(_p) ((GPT_S_VAL - 1U) - ((_p) + 3U))
/* Bit shift for the L1 index field. */
#define GPT_L1_IDX_SHIFT(_p) ((_p) + 4U)
/* Mask for the L1 index field, must be shifted. */
#define GPT_L1_IDX_MASK(_p) (0xFFFFFFFFFFFFFFFFUL >> \
(64U - (GPT_L1_IDX_WIDTH(_p))))
/* Bit shift for the index of the L1 GPI in a PA. */
#define GPT_L1_GPI_IDX_SHIFT(_p) (_p)
/* Mask for the index of the L1 GPI in a PA. */
#define GPT_L1_GPI_IDX_MASK (0xF)
/* Total number of entries in each L1 table. */
#define GPT_L1_ENTRY_COUNT(_p) ((GPT_L1_IDX_MASK(_p)) + 1U)
/* Total size in bytes of each L1 table. */
#define GPT_L1_TABLE_SIZE(_p) ((GPT_L1_ENTRY_COUNT(_p)) << 3U)
/******************************************************************************/
/* General helper macros */
/******************************************************************************/
/* Protected space actual size in bytes. */
#define GPT_PPS_ACTUAL_SIZE(_t) (1UL << (_t))
/* Granule actual size in bytes. */
#define GPT_PGS_ACTUAL_SIZE(_p) (1UL << (_p))
/* L0 GPT region size in bytes. */
#define GPT_L0GPTSZ_ACTUAL_SIZE (1UL << GPT_S_VAL)
/* Get the index of the L0 entry from a physical address. */
#define GPT_L0_IDX(_pa) ((_pa) >> GPT_L0_IDX_SHIFT)
/*
* This definition is used to determine if a physical address lies on an L0
* region boundary.
*/
#define GPT_IS_L0_ALIGNED(_pa) (((_pa) & (GPT_L0_REGION_SIZE - U(1))) == U(0))
/* Get the type field from an L0 descriptor. */
#define GPT_L0_TYPE(_desc) (((_desc) >> GPT_L0_TYPE_SHIFT) & \
GPT_L0_TYPE_MASK)
/* Create an L0 block descriptor. */
#define GPT_L0_BLK_DESC(_gpi) (GPT_L0_TYPE_BLK_DESC | \
(((_gpi) & GPT_L0_BLK_DESC_GPI_MASK) << \
GPT_L0_BLK_DESC_GPI_SHIFT))
/* Create an L0 table descriptor with an L1 table address. */
#define GPT_L0_TBL_DESC(_pa) (GPT_L0_TYPE_TBL_DESC | ((uint64_t)(_pa) & \
(GPT_L0_TBL_DESC_L1ADDR_MASK << \
GPT_L0_TBL_DESC_L1ADDR_SHIFT)))
/* Get the GPI from an L0 block descriptor. */
#define GPT_L0_BLKD_GPI(_desc) (((_desc) >> GPT_L0_BLK_DESC_GPI_SHIFT) & \
GPT_L0_BLK_DESC_GPI_MASK)
/* Get the L1 address from an L0 table descriptor. */
#define GPT_L0_TBLD_ADDR(_desc) ((uint64_t *)(((_desc) & \
(GPT_L0_TBL_DESC_L1ADDR_MASK << \
GPT_L0_TBL_DESC_L1ADDR_SHIFT))))
/* Get the index into the L1 table from a physical address. */
#define GPT_L1_IDX(_p, _pa) (((_pa) >> GPT_L1_IDX_SHIFT(_p)) & \
GPT_L1_IDX_MASK(_p))
/* Get the index of the GPI within an L1 table entry from a physical address. */
#define GPT_L1_GPI_IDX(_p, _pa) (((_pa) >> GPT_L1_GPI_IDX_SHIFT(_p)) & \
GPT_L1_GPI_IDX_MASK)
/* Determine if an address is granule-aligned. */
#define GPT_IS_L1_ALIGNED(_p, _pa) (((_pa) & (GPT_PGS_ACTUAL_SIZE(_p) - U(1))) \
== U(0))
#endif /* GPT_RME_PRIVATE_H */

View File

@ -39,6 +39,23 @@ size_t xlat_arch_get_max_supported_granule_size(void)
return PAGE_SIZE_4KB;
}
/*
* Determine the physical address space encoded in the 'attr' parameter.
*
* The physical address will fall into one of two spaces; secure or
* nonsecure.
*/
uint32_t xlat_arch_get_pas(uint32_t attr)
{
uint32_t pas = MT_PAS(attr);
if (pas == MT_NS) {
return LOWER_ATTRS(NS);
} else { /* MT_SECURE */
return 0U;
}
}
#if ENABLE_ASSERTIONS
unsigned long long xlat_arch_get_max_supported_pa(void)
{

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -53,6 +53,33 @@ size_t xlat_arch_get_max_supported_granule_size(void)
}
}
/*
* Determine the physical address space encoded in the 'attr' parameter.
*
* The physical address will fall into one of four spaces; secure,
* nonsecure, root, or realm if RME is enabled, or one of two spaces;
* secure and nonsecure otherwise.
*/
uint32_t xlat_arch_get_pas(uint32_t attr)
{
uint32_t pas = MT_PAS(attr);
switch (pas) {
#if ENABLE_RME
/* TTD.NSE = 1 and TTD.NS = 1 for Realm PAS */
case MT_REALM:
return LOWER_ATTRS(EL3_S1_NSE | NS);
/* TTD.NSE = 1 and TTD.NS = 0 for Root PAS */
case MT_ROOT:
return LOWER_ATTRS(EL3_S1_NSE);
#endif
case MT_NS:
return LOWER_ATTRS(NS);
default: /* MT_SECURE */
return 0U;
}
}
unsigned long long tcr_physical_addr_size_bits(unsigned long long max_addr)
{
/* Physical address can't exceed 48 bits */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -125,11 +125,14 @@ uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr,
* faults aren't managed.
*/
desc |= LOWER_ATTRS(ACCESS_FLAG);
/* Determine the physical address space this region belongs to. */
desc |= xlat_arch_get_pas(attr);
/*
* Deduce other fields of the descriptor based on the MT_NS and MT_RW
* memory region attributes.
* Deduce other fields of the descriptor based on the MT_RW memory
* region attributes.
*/
desc |= ((attr & MT_NS) != 0U) ? LOWER_ATTRS(NS) : 0U;
desc |= ((attr & MT_RW) != 0U) ? LOWER_ATTRS(AP_RW) : LOWER_ATTRS(AP_RO);
/*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -40,6 +40,9 @@
extern uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
/* Determine the physical address space encoded in the 'attr' parameter. */
uint32_t xlat_arch_get_pas(uint32_t attr);
/*
* Return the execute-never mask that will prevent instruction fetch at the
* given translation regime.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -95,7 +95,23 @@ static void xlat_desc_print(const xlat_ctx_t *ctx, uint64_t desc)
? "-USER" : "-PRIV");
}
#if ENABLE_RME
switch (desc & LOWER_ATTRS(EL3_S1_NSE | NS)) {
case 0ULL:
printf("-S");
break;
case LOWER_ATTRS(NS):
printf("-NS");
break;
case LOWER_ATTRS(EL3_S1_NSE):
printf("-RT");
break;
default: /* LOWER_ATTRS(EL3_S1_NSE | NS) */
printf("-RL");
}
#else
printf(((LOWER_ATTRS(NS) & desc) != 0ULL) ? "-NS" : "-S");
#endif
#ifdef __aarch64__
/* Check Guarded Page bit */

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
# Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@ -98,41 +98,41 @@ $(if $(word $(2), $($(1))),\
endef
# IMG_LINKERFILE defines the linker script corresponding to a BL stage
# $(1) = BL stage (1, 2, 2u, 31, 32)
# $(1) = BL stage
define IMG_LINKERFILE
${BUILD_DIR}/bl$(1).ld
${BUILD_DIR}/$(1).ld
endef
# IMG_MAPFILE defines the output file describing the memory map corresponding
# to a BL stage
# $(1) = BL stage (1, 2, 2u, 31, 32)
# $(1) = BL stage
define IMG_MAPFILE
${BUILD_DIR}/bl$(1).map
${BUILD_DIR}/$(1).map
endef
# IMG_ELF defines the elf file corresponding to a BL stage
# $(1) = BL stage (1, 2, 2u, 31, 32)
# $(1) = BL stage
define IMG_ELF
${BUILD_DIR}/bl$(1).elf
${BUILD_DIR}/$(1).elf
endef
# IMG_DUMP defines the symbols dump file corresponding to a BL stage
# $(1) = BL stage (1, 2, 2u, 31, 32)
# $(1) = BL stage
define IMG_DUMP
${BUILD_DIR}/bl$(1).dump
${BUILD_DIR}/$(1).dump
endef
# IMG_BIN defines the default image file corresponding to a BL stage
# $(1) = BL stage (1, 2, 2u, 31, 32)
# $(1) = BL stage
define IMG_BIN
${BUILD_PLAT}/bl$(1).bin
${BUILD_PLAT}/$(1).bin
endef
# IMG_ENC_BIN defines the default encrypted image file corresponding to a
# BL stage
# $(1) = BL stage (2, 30, 31, 32, 33)
# $(1) = BL stage
define IMG_ENC_BIN
${BUILD_PLAT}/bl$(1)_enc.bin
${BUILD_PLAT}/$(1)_enc.bin
endef
# ENCRYPT_FW invokes enctool to encrypt firmware binary
@ -294,15 +294,15 @@ endef
# MAKE_C builds a C source file and generates the dependency file
# $(1) = output directory
# $(2) = source file (%.c)
# $(3) = BL stage (1, 2, 2u, 31, 32)
# $(3) = BL stage
define MAKE_C
$(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
$(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
$(eval BL_CPPFLAGS := $(BL$(call uppercase,$(3))_CPPFLAGS) -DIMAGE_BL$(call uppercase,$(3)))
$(eval BL_CFLAGS := $(BL$(call uppercase,$(3))_CFLAGS))
$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3)))
$(eval BL_CFLAGS := $($(call uppercase,$(3))_CFLAGS))
$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | bl$(3)_dirs
$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
$$(ECHO) " CC $$<"
$$(Q)$$(CC) $$(LTO_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CPPFLAGS) $(BL_CFLAGS) $(MAKE_DEP) -c $$< -o $$@
@ -314,15 +314,15 @@ endef
# MAKE_S builds an assembly source file and generates the dependency file
# $(1) = output directory
# $(2) = assembly file (%.S)
# $(3) = BL stage (1, 2, 2u, 31, 32)
# $(3) = BL stage
define MAKE_S
$(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
$(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
$(eval BL_CPPFLAGS := $(BL$(call uppercase,$(3))_CPPFLAGS) -DIMAGE_BL$(call uppercase,$(3)))
$(eval BL_ASFLAGS := $(BL$(call uppercase,$(3))_ASFLAGS))
$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3)))
$(eval BL_ASFLAGS := $($(call uppercase,$(3))_ASFLAGS))
$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | bl$(3)_dirs
$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
$$(ECHO) " AS $$<"
$$(Q)$$(AS) $$(ASFLAGS) $(BL_CPPFLAGS) $(BL_ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
@ -334,13 +334,13 @@ endef
# MAKE_LD generate the linker script using the C preprocessor
# $(1) = output linker script
# $(2) = input template
# $(3) = BL stage (1, 2, 2u, 31, 32)
# $(3) = BL stage
define MAKE_LD
$(eval DEP := $(1).d)
$(eval BL_CPPFLAGS := $(BL$(call uppercase,$(3))_CPPFLAGS) -DIMAGE_BL$(call uppercase,$(3)))
$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3)))
$(1): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | bl$(3)_dirs
$(1): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs
$$(ECHO) " PP $$<"
$$(Q)$$(CPP) $$(CPPFLAGS) $(BL_CPPFLAGS) $(TF_CFLAGS_$(ARCH)) -P -x assembler-with-cpp -D__LINKER__ $(MAKE_DEP) -o $$@ $$<
@ -368,7 +368,7 @@ endef
# MAKE_OBJS builds both C and assembly source files
# $(1) = output directory
# $(2) = list of source files (both C and assembly)
# $(3) = BL stage (1, 2, 2u, 31, 32)
# $(3) = BL stage
define MAKE_OBJS
$(eval C_OBJS := $(filter %.c,$(2)))
$(eval REMAIN := $(filter-out %.c,$(2)))
@ -445,13 +445,13 @@ endef
# MAKE_BL macro defines the targets and options to build each BL image.
# Arguments:
# $(1) = BL stage (1, 2, 2u, 31, 32)
# $(1) = BL stage
# $(2) = FIP command line option (if empty, image will not be included in the FIP)
# $(3) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip)
# $(4) = BL encryption flag (optional) (0, 1)
define MAKE_BL
$(eval BUILD_DIR := ${BUILD_PLAT}/bl$(1))
$(eval BL_SOURCES := $(BL$(call uppercase,$(1))_SOURCES))
$(eval BUILD_DIR := ${BUILD_PLAT}/$(1))
$(eval BL_SOURCES := $($(call uppercase,$(1))_SOURCES))
$(eval SOURCES := $(BL_SOURCES) $(BL_COMMON_SOURCES) $(PLAT_BL_COMMON_SOURCES))
$(eval OBJS := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
$(eval LINKERFILE := $(call IMG_LINKERFILE,$(1)))
@ -460,8 +460,8 @@ define MAKE_BL
$(eval DUMP := $(call IMG_DUMP,$(1)))
$(eval BIN := $(call IMG_BIN,$(1)))
$(eval ENC_BIN := $(call IMG_ENC_BIN,$(1)))
$(eval BL_LINKERFILE := $(BL$(call uppercase,$(1))_LINKERFILE))
$(eval BL_LIBS := $(BL$(call uppercase,$(1))_LIBS))
$(eval BL_LINKERFILE := $($(call uppercase,$(1))_LINKERFILE))
$(eval BL_LIBS := $($(call uppercase,$(1))_LIBS))
# We use sort only to get a list of unique object directory names.
# ordering is not relevant but sort removes duplicates.
$(eval TEMP_OBJ_DIRS := $(sort $(dir ${OBJS} ${LINKERFILE})))
@ -475,21 +475,21 @@ $(eval $(call MAKE_PREREQ_DIR,${BUILD_DIR},${BUILD_PLAT}))
$(eval $(foreach objd,${OBJ_DIRS},$(call MAKE_PREREQ_DIR,${objd},${BUILD_DIR})))
.PHONY : bl${1}_dirs
.PHONY : ${1}_dirs
# We use order-only prerequisites to ensure that directories are created,
# but do not cause re-builds every time a file is written.
bl${1}_dirs: | ${OBJ_DIRS}
${1}_dirs: | ${OBJ_DIRS}
$(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
$(eval $(call MAKE_LD,$(LINKERFILE),$(BL_LINKERFILE),$(1)))
$(eval BL_LDFLAGS := $(BL$(call uppercase,$(1))_LDFLAGS))
$(eval BL_LDFLAGS := $($(call uppercase,$(1))_LDFLAGS))
ifeq ($(USE_ROMLIB),1)
$(ELF): romlib.bin
endif
$(ELF): $(OBJS) $(LINKERFILE) | bl$(1)_dirs libraries $(BL_LIBS)
$(ELF): $(OBJS) $(LINKERFILE) | $(1)_dirs libraries $(BL_LIBS)
$$(ECHO) " LD $$@"
ifdef MAKE_BUILD_STRINGS
$(call MAKE_BUILD_STRINGS, $(BUILD_DIR)/build_message.o)
@ -499,10 +499,10 @@ else
$$(CC) $$(TF_CFLAGS) $$(CFLAGS) -xc -c - -o $(BUILD_DIR)/build_message.o
endif
ifneq ($(findstring armlink,$(notdir $(LD))),)
$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) --entry=bl${1}_entrypoint \
$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) --entry=${1}_entrypoint \
--predefine="-D__LINKER__=$(__LINKER__)" \
--predefine="-DTF_CFLAGS=$(TF_CFLAGS)" \
--map --list="$(MAPFILE)" --scatter=${PLAT_DIR}/scat/bl${1}.scat \
--map --list="$(MAPFILE)" --scatter=${PLAT_DIR}/scat/${1}.scat \
$(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) \
$(BUILD_DIR)/build_message.o $(OBJS)
else ifneq ($(findstring gcc,$(notdir $(LD))),)
@ -531,21 +531,21 @@ $(BIN): $(ELF)
@echo "Built $$@ successfully"
@${ECHO_BLANK_LINE}
.PHONY: bl$(1)
.PHONY: $(1)
ifeq ($(DISABLE_BIN_GENERATION),1)
bl$(1): $(ELF) $(DUMP)
$(1): $(ELF) $(DUMP)
else
bl$(1): $(BIN) $(DUMP)
$(1): $(BIN) $(DUMP)
endif
all: bl$(1)
all: $(1)
ifeq ($(4),1)
$(call ENCRYPT_FW,$(BIN),$(ENC_BIN))
$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,bl$(1),$(BIN),--$(2),$(ENC_BIN),$(3), \
$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,$(1),$(BIN),--$(2),$(ENC_BIN),$(3), \
$(ENC_BIN)))
else
$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,bl$(1),$(BIN),--$(2),$(BIN),$(3)))
$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,$(1),$(BIN),--$(2),$(BIN),$(3)))
endif
endef

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2016-2021, ARM Limited. All rights reserved.
# Copyright (c) 2016-2021, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@ -105,6 +105,9 @@ ENABLE_PMF := 0
# Flag to enable PSCI STATs functionality
ENABLE_PSCI_STAT := 0
# Flag to enable Realm Management Extension (FEAT_RME)
ENABLE_RME := 0
# Flag to enable runtime instrumentation using PMF
ENABLE_RUNTIME_INSTRUMENTATION := 0

View File

@ -107,6 +107,10 @@ const mmap_region_t plat_arm_mmap[] = {
#if defined(SPD_spmd)
ARM_MAP_TRUSTED_DRAM,
#endif
#if ENABLE_RME
ARM_MAP_RMM_DRAM,
ARM_MAP_GPT_L1_DRAM,
#endif /* ENABLE_RME */
#ifdef SPD_tspd
ARM_MAP_TSP_SEC_MEM,
#endif
@ -159,6 +163,9 @@ const mmap_region_t plat_arm_mmap[] = {
#endif
/* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */
ARM_DTB_DRAM_NS,
#if ENABLE_RME
ARM_MAP_GPT_L1_DRAM,
#endif
{0}
};
@ -191,6 +198,15 @@ const mmap_region_t plat_arm_mmap[] = {
};
#endif
#ifdef IMAGE_RMM
const mmap_region_t plat_arm_mmap[] = {
V2M_MAP_IOFPGA,
MAP_DEVICE0,
MAP_DEVICE1,
{0}
};
#endif
ARM_CASSERT_MMAP
#if FVP_INTERCONNECT_DRIVER != FVP_CCN

View File

@ -43,6 +43,11 @@
#define PLAT_ARM_TRUSTED_DRAM_BASE UL(0x06000000)
#define PLAT_ARM_TRUSTED_DRAM_SIZE UL(0x02000000) /* 32 MB */
#if ENABLE_RME
#define PLAT_ARM_RMM_BASE (RMM_BASE)
#define PLAT_ARM_RMM_SIZE (RMM_LIMIT - RMM_BASE)
#endif
/*
* Max size of SPMC is 2MB for fvp. With SPMD enabled this value corresponds to
* max size of BL32 image.
@ -61,12 +66,13 @@
#define PLAT_ARM_DRAM2_BASE ULL(0x880000000)
#define PLAT_ARM_DRAM2_SIZE UL(0x80000000)
#define PLAT_HW_CONFIG_DTB_BASE ULL(0x82000000)
#define PLAT_HW_CONFIG_DTB_SIZE ULL(0x8000)
/* Range of kernel DTB load address */
#define FVP_DTB_DRAM_MAP_START ULL(0x82000000)
#define FVP_DTB_DRAM_MAP_SIZE ULL(0x02000000) /* 32 MB */
#define ARM_DTB_DRAM_NS MAP_REGION_FLAT( \
PLAT_HW_CONFIG_DTB_BASE, \
PLAT_HW_CONFIG_DTB_SIZE, \
FVP_DTB_DRAM_MAP_START, \
FVP_DTB_DRAM_MAP_SIZE, \
MT_MEMORY | MT_RO | MT_NS)
/*
* Load address of BL33 for this platform port
@ -80,15 +86,27 @@
#if defined(IMAGE_BL31)
# if SPM_MM
# define PLAT_ARM_MMAP_ENTRIES 10
# define MAX_XLAT_TABLES 9
# if ENABLE_RME
# define MAX_XLAT_TABLES 10
# else
# define MAX_XLAT_TABLES 9
# endif
# define PLAT_SP_IMAGE_MMAP_REGIONS 30
# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
# else
# define PLAT_ARM_MMAP_ENTRIES 9
# if USE_DEBUGFS
# define MAX_XLAT_TABLES 8
# if ENABLE_RME
# define MAX_XLAT_TABLES 9
# else
# define MAX_XLAT_TABLES 8
# endif
# else
# define MAX_XLAT_TABLES 7
# if ENABLE_RME
# define MAX_XLAT_TABLES 8
# else
# define MAX_XLAT_TABLES 7
# endif
# endif
# endif
#elif defined(IMAGE_BL32)
@ -137,16 +155,17 @@
#endif
#if RESET_TO_BL31
/* Size of Trusted SRAM - the first 4KB of shared memory */
/* Size of Trusted SRAM - the first 4KB of shared memory - GPT L0 Tables */
#define PLAT_ARM_MAX_BL31_SIZE (PLAT_ARM_TRUSTED_SRAM_SIZE - \
ARM_SHARED_RAM_SIZE)
ARM_SHARED_RAM_SIZE - \
ARM_L0_GPT_SIZE)
#else
/*
* Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is
* calculated using the current BL31 PROGBITS debug size plus the sizes of
* BL2 and BL1-RW
*/
#define PLAT_ARM_MAX_BL31_SIZE UL(0x3D000)
#define PLAT_ARM_MAX_BL31_SIZE (UL(0x3D000) - ARM_L0_GPT_SIZE)
#endif /* RESET_TO_BL31 */
#ifndef __aarch64__
@ -177,7 +196,7 @@
# if TRUSTED_BOARD_BOOT
# define PLATFORM_STACK_SIZE UL(0x1000)
# else
# define PLATFORM_STACK_SIZE UL(0x440)
# define PLATFORM_STACK_SIZE UL(0x600)
# endif
#elif defined(IMAGE_BL2U)
# define PLATFORM_STACK_SIZE UL(0x400)
@ -185,6 +204,8 @@
# define PLATFORM_STACK_SIZE UL(0x800)
#elif defined(IMAGE_BL32)
# define PLATFORM_STACK_SIZE UL(0x440)
#elif defined(IMAGE_RMM)
# define PLATFORM_STACK_SIZE UL(0x440)
#endif
#define MAX_IO_DEVICES 3
@ -222,6 +243,9 @@
#define PLAT_ARM_TSP_UART_BASE V2M_IOFPGA_UART2_BASE
#define PLAT_ARM_TSP_UART_CLK_IN_HZ V2M_IOFPGA_UART2_CLK_IN_HZ
#define PLAT_ARM_TRP_UART_BASE V2M_IOFPGA_UART3_BASE
#define PLAT_ARM_TRP_UART_CLK_IN_HZ V2M_IOFPGA_UART3_CLK_IN_HZ
#define PLAT_FVP_SMMUV3_BASE UL(0x2b400000)
/* CCI related constants */

View File

@ -186,6 +186,10 @@ ifeq (${COT_DESC_IN_DTB},1)
BL2_SOURCES += plat/arm/common/fconf/fconf_nv_cntr_getter.c
endif
ifeq (${ENABLE_RME},1)
BL2_SOURCES += plat/arm/board/fvp/aarch64/fvp_helpers.S
endif
ifeq (${BL2_AT_EL3},1)
BL2_SOURCES += plat/arm/board/fvp/${ARCH}/fvp_helpers.S \
plat/arm/board/fvp/fvp_bl2_el3_setup.c \

View File

@ -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

View File

@ -53,12 +53,13 @@
#define PLAT_ARM_DRAM2_BASE ULL(0x880000000)
#define PLAT_ARM_DRAM2_SIZE ULL(0x180000000)
#define PLAT_HW_CONFIG_DTB_BASE ULL(0x82000000)
#define PLAT_HW_CONFIG_DTB_SIZE ULL(0x00008000) /* 32KB */
/* Range of kernel DTB load address */
#define JUNO_DTB_DRAM_MAP_START ULL(0x82000000)
#define JUNO_DTB_DRAM_MAP_SIZE ULL(0x00008000) /* 32KB */
#define ARM_DTB_DRAM_NS MAP_REGION_FLAT( \
PLAT_HW_CONFIG_DTB_BASE, \
PLAT_HW_CONFIG_DTB_SIZE, \
JUNO_DTB_DRAM_MAP_START, \
JUNO_DTB_DRAM_MAP_SIZE, \
MT_MEMORY | MT_RO | MT_NS)
/* virtual address used by dynamic mem_protect for chunk_base */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -75,8 +75,10 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
.image_info.image_base = BL31_BASE,
.image_info.image_max_size = BL31_LIMIT - BL31_BASE,
# ifdef BL32_BASE
# if defined(BL32_BASE)
.next_handoff_image_id = BL32_IMAGE_ID,
# elif ENABLE_RME
.next_handoff_image_id = RMM_IMAGE_ID,
# else
.next_handoff_image_id = BL33_IMAGE_ID,
# endif
@ -99,6 +101,22 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
.next_handoff_image_id = INVALID_IMAGE_ID,
},
# if ENABLE_RME
/* Fill RMM related information */
{
.image_id = RMM_IMAGE_ID,
SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
VERSION_2, entry_point_info_t, EP_REALM | EXECUTABLE),
.ep_info.pc = RMM_BASE,
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
VERSION_2, image_info_t, 0),
.image_info.image_base = RMM_BASE,
.image_info.image_max_size = RMM_LIMIT - RMM_BASE,
.next_handoff_image_id = BL33_IMAGE_ID,
},
# endif
# ifdef BL32_BASE
/* Fill BL32 related information */
{
@ -113,7 +131,11 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
.image_info.image_base = BL32_BASE,
.image_info.image_max_size = BL32_LIMIT - BL32_BASE,
# if ENABLE_RME
.next_handoff_image_id = RMM_IMAGE_ID,
# else
.next_handoff_image_id = BL33_IMAGE_ID,
# endif
},
/*

View File

@ -32,7 +32,7 @@
#define MAP_BL1_TOTAL MAP_REGION_FLAT( \
bl1_tzram_layout.total_base, \
bl1_tzram_layout.total_size, \
MT_MEMORY | MT_RW | MT_SECURE)
MT_MEMORY | MT_RW | EL3_PAS)
/*
* If SEPARATE_CODE_AND_RODATA=1 we define a region for each section
* otherwise one region is defined containing both
@ -41,17 +41,17 @@
#define MAP_BL1_RO MAP_REGION_FLAT( \
BL_CODE_BASE, \
BL1_CODE_END - BL_CODE_BASE, \
MT_CODE | MT_SECURE), \
MT_CODE | EL3_PAS), \
MAP_REGION_FLAT( \
BL1_RO_DATA_BASE, \
BL1_RO_DATA_END \
- BL_RO_DATA_BASE, \
MT_RO_DATA | MT_SECURE)
MT_RO_DATA | EL3_PAS)
#else
#define MAP_BL1_RO MAP_REGION_FLAT( \
BL_CODE_BASE, \
BL1_CODE_END - BL_CODE_BASE, \
MT_CODE | MT_SECURE)
MT_CODE | EL3_PAS)
#endif
/* Data structure which holds the extents of the trusted SRAM for BL1*/

View File

@ -9,6 +9,7 @@
#include <platform_def.h>
#include <arch_features.h>
#include <arch_helpers.h>
#include <common/bl_common.h>
#include <common/debug.h>
@ -17,10 +18,16 @@
#include <drivers/partition/partition.h>
#include <lib/fconf/fconf.h>
#include <lib/fconf/fconf_dyn_cfg_getter.h>
#if ENABLE_RME
#include <lib/gpt_rme/gpt_rme.h>
#endif /* ENABLE_RME */
#ifdef SPD_opteed
#include <lib/optee_utils.h>
#endif
#include <lib/utils.h>
#if ENABLE_RME
#include <plat/arm/common/arm_pas_def.h>
#endif /* ENABLE_RME */
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
@ -45,11 +52,17 @@ CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows);
#pragma weak bl2_plat_get_hash
#endif
#if ENABLE_RME
#define MAP_BL2_TOTAL MAP_REGION_FLAT( \
bl2_tzram_layout.total_base, \
bl2_tzram_layout.total_size, \
MT_MEMORY | MT_RW | MT_ROOT)
#else
#define MAP_BL2_TOTAL MAP_REGION_FLAT( \
bl2_tzram_layout.total_base, \
bl2_tzram_layout.total_size, \
MT_MEMORY | MT_RW | MT_SECURE)
#endif /* ENABLE_RME */
#pragma weak arm_bl2_plat_handle_post_image_load
@ -105,8 +118,10 @@ void bl2_plat_preload_setup(void)
*/
void arm_bl2_platform_setup(void)
{
#if !ENABLE_RME
/* Initialize the secure environment */
plat_arm_security_setup();
#endif
#if defined(PLAT_ARM_MEM_PROT_ADDR)
arm_nor_psci_do_static_mem_protect();
@ -118,9 +133,54 @@ void bl2_platform_setup(void)
arm_bl2_platform_setup();
}
#if ENABLE_RME
static void arm_bl2_plat_gpt_setup(void)
{
/*
* The GPT library might modify the gpt regions structure to optimize
* the layout, so the array cannot be constant.
*/
pas_region_t pas_regions[] = {
ARM_PAS_KERNEL,
ARM_PAS_SECURE,
ARM_PAS_REALM,
ARM_PAS_EL3_DRAM,
ARM_PAS_GPTS
};
/* Initialize entire protected space to GPT_GPI_ANY. */
if (gpt_init_l0_tables(GPCCR_PPS_4GB, ARM_L0_GPT_ADDR_BASE,
ARM_L0_GPT_SIZE) < 0) {
ERROR("gpt_init_l0_tables() failed!\n");
panic();
}
/* Carve out defined PAS ranges. */
if (gpt_init_pas_l1_tables(GPCCR_PGS_4K,
ARM_L1_GPT_ADDR_BASE,
ARM_L1_GPT_SIZE,
pas_regions,
(unsigned int)(sizeof(pas_regions) /
sizeof(pas_region_t))) < 0) {
ERROR("gpt_init_pas_l1_tables() failed!\n");
panic();
}
INFO("Enabling Granule Protection Checks\n");
if (gpt_enable() < 0) {
ERROR("gpt_enable() failed!\n");
panic();
}
}
#endif /* ENABLE_RME */
/*******************************************************************************
* Perform the very early platform specific architectural setup here. At the
* moment this is only initializes the mmu in a quick and dirty way.
* Perform the very early platform specific architectural setup here.
* When RME is enabled the secure environment is initialised before
* initialising and enabling Granule Protection.
* This function initialises the MMU in a quick and dirty way.
******************************************************************************/
void arm_bl2_plat_arch_setup(void)
{
@ -143,13 +203,29 @@ void arm_bl2_plat_arch_setup(void)
ARM_MAP_BL_COHERENT_RAM,
#endif
ARM_MAP_BL_CONFIG_REGION,
#if ENABLE_RME
ARM_MAP_L0_GPT_REGION,
#endif
{0}
};
#if ENABLE_RME
/* Initialise the secure environment */
plat_arm_security_setup();
#endif
setup_page_tables(bl_regions, plat_arm_get_mmap());
#ifdef __aarch64__
#if ENABLE_RME
/* BL2 runs in EL3 when RME enabled. */
assert(get_armv9_2_feat_rme_support() != 0U);
enable_mmu_el3(0);
/* Initialise and enable granule protection after MMU. */
arm_bl2_plat_gpt_setup();
#else
enable_mmu_el1(0);
#endif
#else
enable_mmu_svc_mon(0);
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -13,6 +13,9 @@
#include <drivers/console.h>
#include <lib/debugfs.h>
#include <lib/extensions/ras.h>
#if ENABLE_RME
#include <lib/gpt_rme/gpt_rme.h>
#endif
#include <lib/mmio.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
#include <plat/arm/common/plat_arm.h>
@ -25,6 +28,9 @@
*/
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
#if ENABLE_RME
static entry_point_info_t rmm_image_ep_info;
#endif
#if !RESET_TO_BL31
/*
@ -43,7 +49,7 @@ CASSERT(BL31_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl31_base_overflows);
#define MAP_BL31_TOTAL MAP_REGION_FLAT( \
BL31_START, \
BL31_END - BL31_START, \
MT_MEMORY | MT_RW | MT_SECURE)
MT_MEMORY | MT_RW | EL3_PAS)
#if RECLAIM_INIT_CODE
IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE);
IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_CODE_END_UNALIGNED);
@ -58,7 +64,7 @@ IMPORT_SYM(unsigned long, __STACKS_END__, BL_STACKS_END_UNALIGNED);
BL_INIT_CODE_BASE, \
BL_INIT_CODE_END \
- BL_INIT_CODE_BASE, \
MT_CODE | MT_SECURE)
MT_CODE | EL3_PAS)
#endif
#if SEPARATE_NOBITS_REGION
@ -66,7 +72,7 @@ IMPORT_SYM(unsigned long, __STACKS_END__, BL_STACKS_END_UNALIGNED);
BL31_NOBITS_BASE, \
BL31_NOBITS_LIMIT \
- BL31_NOBITS_BASE, \
MT_MEMORY | MT_RW | MT_SECURE)
MT_MEMORY | MT_RW | EL3_PAS)
#endif
/*******************************************************************************
@ -80,8 +86,18 @@ struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type)
entry_point_info_t *next_image_info;
assert(sec_state_is_valid(type));
next_image_info = (type == NON_SECURE)
? &bl33_image_ep_info : &bl32_image_ep_info;
if (type == NON_SECURE) {
next_image_info = &bl33_image_ep_info;
}
#if ENABLE_RME
else if (type == REALM) {
next_image_info = &rmm_image_ep_info;
}
#endif
else {
next_image_info = &bl32_image_ep_info;
}
/*
* None of the images on the ARM development platforms can have 0x0
* as the entrypoint
@ -169,21 +185,31 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi
bl_params_node_t *bl_params = params_from_bl2->head;
/*
* Copy BL33 and BL32 (if present), entry point information.
* Copy BL33, BL32 and RMM (if present), entry point information.
* They are stored in Secure RAM, in BL2's address space.
*/
while (bl_params != NULL) {
if (bl_params->image_id == BL32_IMAGE_ID)
if (bl_params->image_id == BL32_IMAGE_ID) {
bl32_image_ep_info = *bl_params->ep_info;
if (bl_params->image_id == BL33_IMAGE_ID)
}
#if ENABLE_RME
else if (bl_params->image_id == RMM_IMAGE_ID) {
rmm_image_ep_info = *bl_params->ep_info;
}
#endif
else if (bl_params->image_id == BL33_IMAGE_ID) {
bl33_image_ep_info = *bl_params->ep_info;
}
bl_params = bl_params->next_params_info;
}
if (bl33_image_ep_info.pc == 0U)
panic();
#if ENABLE_RME
if (rmm_image_ep_info.pc == 0U)
panic();
#endif
#endif /* RESET_TO_BL31 */
# if ARM_LINUX_KERNEL_AS_BL33
@ -193,7 +219,11 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi
* tree blob (DTB) in x0, while x1-x3 are reserved for future use and
* must be 0.
*/
#if RESET_TO_BL31
bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE;
#else
bl33_image_ep_info.args.arg0 = (u_register_t)hw_config;
#endif
bl33_image_ep_info.args.arg1 = 0U;
bl33_image_ep_info.args.arg2 = 0U;
bl33_image_ep_info.args.arg3 = 0U;
@ -355,6 +385,9 @@ void __init arm_bl31_plat_arch_setup(void)
{
const mmap_region_t bl_regions[] = {
MAP_BL31_TOTAL,
#if ENABLE_RME
ARM_MAP_L0_GPT_REGION,
#endif
#if RECLAIM_INIT_CODE
MAP_BL_INIT_CODE,
#endif
@ -376,6 +409,19 @@ void __init arm_bl31_plat_arch_setup(void)
enable_mmu_el3(0);
#if ENABLE_RME
/*
* Initialise Granule Protection library and enable GPC for the primary
* processor. The tables have already been initialized by a previous BL
* stage, so there is no need to provide any PAS here. This function
* sets up pointers to those tables.
*/
if (gpt_runtime_init() < 0) {
ERROR("gpt_runtime_init() failed!\n");
panic();
}
#endif /* ENABLE_RME */
arm_setup_romlib();
}

View File

@ -52,9 +52,10 @@ $(eval $(call assert_boolean,ARM_RECOM_STATE_ID_ENC))
$(eval $(call add_define,ARM_RECOM_STATE_ID_ENC))
# Process ARM_DISABLE_TRUSTED_WDOG flag
# By default, Trusted Watchdog is always enabled unless SPIN_ON_BL1_EXIT is set
# By default, Trusted Watchdog is always enabled unless
# SPIN_ON_BL1_EXIT or ENABLE_RME is set
ARM_DISABLE_TRUSTED_WDOG := 0
ifeq (${SPIN_ON_BL1_EXIT}, 1)
ifneq ($(filter 1,${SPIN_ON_BL1_EXIT} ${ENABLE_RME}),)
ARM_DISABLE_TRUSTED_WDOG := 1
endif
$(eval $(call assert_boolean,ARM_DISABLE_TRUSTED_WDOG))
@ -94,10 +95,13 @@ ifeq (${ARM_LINUX_KERNEL_AS_BL33},1)
ifndef PRELOADED_BL33_BASE
$(error "PRELOADED_BL33_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used.")
endif
ifndef ARM_PRELOADED_DTB_BASE
$(error "ARM_PRELOADED_DTB_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used.")
ifeq (${RESET_TO_BL31},1)
ifndef ARM_PRELOADED_DTB_BASE
$(error "ARM_PRELOADED_DTB_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is
used with RESET_TO_BL31.")
endif
$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
endif
$(eval $(call add_define,ARM_PRELOADED_DTB_BASE))
endif
# Arm Ethos-N NPU SiP service

View File

@ -67,6 +67,7 @@ const io_uuid_spec_t arm_uuid_spec[MAX_NUMBER_IDS] = {
[SOC_FW_CONFIG_ID] = {UUID_SOC_FW_CONFIG},
[TOS_FW_CONFIG_ID] = {UUID_TOS_FW_CONFIG},
[NT_FW_CONFIG_ID] = {UUID_NT_FW_CONFIG},
[RMM_IMAGE_ID] = {UUID_REALM_MONITOR_MGMT_FIRMWARE},
#endif /* ARM_IO_IN_DTB */
#if TRUSTED_BOARD_BOOT
[TRUSTED_BOOT_FW_CERT_ID] = {UUID_TRUSTED_BOOT_FW_CERT},
@ -162,6 +163,11 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = {
(uintptr_t)&arm_uuid_spec[BL33_IMAGE_ID],
open_fip
},
[RMM_IMAGE_ID] = {
&fip_dev_handle,
(uintptr_t)&arm_uuid_spec[RMM_IMAGE_ID],
open_fip
},
[HW_CONFIG_ID] = {
&fip_dev_handle,
(uintptr_t)&arm_uuid_spec[HW_CONFIG_ID],

View File

@ -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

View File

@ -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();
}

View File

@ -166,7 +166,7 @@ endif
BLE_PATH ?= $(PLAT_COMMON_BASE)/ble
include ${BLE_PATH}/ble.mk
$(eval $(call MAKE_BL,e))
$(eval $(call MAKE_BL,ble))
clean realclean distclean: mrvl_clean

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -11,9 +11,19 @@
#include <lib/cpus/wa_cve_2018_3639.h>
#include <lib/smccc.h>
#include <services/arm_arch_svc.h>
#include <services/rmi_svc.h>
#include <services/rmmd_svc.h>
#include <smccc_helpers.h>
#include <plat/common/platform.h>
#if ENABLE_RME
/* Setup Arm architecture Services */
static int32_t arm_arch_svc_setup(void)
{
return rmmd_setup();
}
#endif
static int32_t smccc_version(void)
{
return MAKE_SMCCC_VERSION(SMCCC_MAJOR_VERSION, SMCCC_MINOR_VERSION);
@ -133,6 +143,16 @@ static uintptr_t arm_arch_svc_smc_handler(uint32_t smc_fid,
SMC_RET0(handle);
#endif
default:
#if ENABLE_RME
/*
* RMI functions are allocated from the Arch service range. Call
* the RMM dispatcher to handle RMI calls.
*/
if (is_rmi_fid(smc_fid)) {
return rmmd_rmi_handler(smc_fid, x1, x2, x3, x4, cookie,
handle, flags);
}
#endif
WARN("Unimplemented Arm Architecture Service Call: 0x%x \n",
smc_fid);
SMC_RET1(handle, SMC_UNK);
@ -145,6 +165,10 @@ DECLARE_RT_SVC(
OEN_ARM_START,
OEN_ARM_END,
SMC_TYPE_FAST,
#if ENABLE_RME
arm_arch_svc_setup,
#else
NULL,
#endif
arm_arch_svc_smc_handler
);

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "../rmmd_private.h"
#include <asm_macros.S>
.global rmmd_rmm_enter
.global rmmd_rmm_exit
/* ---------------------------------------------------------------------
* This function is called with SP_EL0 as stack. Here we stash our EL3
* callee-saved registers on to the stack as a part of saving the C
* runtime and enter the secure payload.
* 'x0' contains a pointer to the memory where the address of the C
* runtime context is to be saved.
* ---------------------------------------------------------------------
*/
func rmmd_rmm_enter
/* Make space for the registers that we're going to save */
mov x3, sp
str x3, [x0, #0]
sub sp, sp, #RMMD_C_RT_CTX_SIZE
/* Save callee-saved registers on to the stack */
stp x19, x20, [sp, #RMMD_C_RT_CTX_X19]
stp x21, x22, [sp, #RMMD_C_RT_CTX_X21]
stp x23, x24, [sp, #RMMD_C_RT_CTX_X23]
stp x25, x26, [sp, #RMMD_C_RT_CTX_X25]
stp x27, x28, [sp, #RMMD_C_RT_CTX_X27]
stp x29, x30, [sp, #RMMD_C_RT_CTX_X29]
/* ---------------------------------------------------------------------
* Everything is setup now. el3_exit() will use the secure context to
* restore to the general purpose and EL3 system registers to ERET
* into the secure payload.
* ---------------------------------------------------------------------
*/
b el3_exit
endfunc rmmd_rmm_enter
/* ---------------------------------------------------------------------
* This function is called with 'x0' pointing to a C runtime context.
* It restores the saved registers and jumps to that runtime with 'x0'
* as the new SP register. This destroys the C runtime context that had
* been built on the stack below the saved context by the caller. Later
* the second parameter 'x1' is passed as a return value to the caller.
* ---------------------------------------------------------------------
*/
func rmmd_rmm_exit
/* Restore the previous stack */
mov sp, x0
/* Restore callee-saved registers on to the stack */
ldp x19, x20, [x0, #(RMMD_C_RT_CTX_X19 - RMMD_C_RT_CTX_SIZE)]
ldp x21, x22, [x0, #(RMMD_C_RT_CTX_X21 - RMMD_C_RT_CTX_SIZE)]
ldp x23, x24, [x0, #(RMMD_C_RT_CTX_X23 - RMMD_C_RT_CTX_SIZE)]
ldp x25, x26, [x0, #(RMMD_C_RT_CTX_X25 - RMMD_C_RT_CTX_SIZE)]
ldp x27, x28, [x0, #(RMMD_C_RT_CTX_X27 - RMMD_C_RT_CTX_SIZE)]
ldp x29, x30, [x0, #(RMMD_C_RT_CTX_X29 - RMMD_C_RT_CTX_SIZE)]
/* ---------------------------------------------------------------------
* This should take us back to the instruction after the call to the
* last rmmd_rmm_enter().* Place the second parameter to x0
* so that the caller will see it as a return value from the original
* entry call.
* ---------------------------------------------------------------------
*/
mov x0, x1
ret
endfunc rmmd_rmm_exit

View File

@ -0,0 +1,18 @@
#
# Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
ifneq (${ARCH},aarch64)
$(error "Error: RMMD is only supported on aarch64.")
endif
include services/std_svc/rmmd/trp/trp.mk
RMMD_SOURCES += $(addprefix services/std_svc/rmmd/, \
${ARCH}/rmmd_helpers.S \
rmmd_main.c)
# Let the top-level Makefile know that we intend to include RMM image
NEED_RMM := yes

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef RMMD_INITIAL_CONTEXT_H
#define RMMD_INITIAL_CONTEXT_H
#include <arch.h>
/*
* SPSR_EL2
* M=0x9 (0b1001 EL2h)
* M[4]=0
* DAIF=0xF Exceptions masked on entry.
* BTYPE=0 BTI not yet supported.
* SSBS=0 Not yet supported.
* IL=0 Not an illegal exception return.
* SS=0 Not single stepping.
* PAN=1 RMM shouldn't access realm memory.
* UAO=0
* DIT=0
* TCO=0
* NZCV=0
*/
#define REALM_SPSR_EL2 ( \
SPSR_M_EL2H | \
(0xF << SPSR_DAIF_SHIFT) | \
SPSR_PAN_BIT \
)
#endif /* RMMD_INITIAL_CONTEXT_H */

View File

@ -0,0 +1,345 @@
/*
* Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <arch_helpers.h>
#include <arch_features.h>
#include <bl31/bl31.h>
#include <common/debug.h>
#include <common/runtime_svc.h>
#include <context.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/el3_runtime/pubsub.h>
#include <lib/gpt_rme/gpt_rme.h>
#include <lib/spinlock.h>
#include <lib/utils.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/common_def.h>
#include <plat/common/platform.h>
#include <platform_def.h>
#include <services/gtsi_svc.h>
#include <services/rmi_svc.h>
#include <services/rmmd_svc.h>
#include <smccc_helpers.h>
#include "rmmd_initial_context.h"
#include "rmmd_private.h"
/*******************************************************************************
* RMM context information.
******************************************************************************/
rmmd_rmm_context_t rmm_context[PLATFORM_CORE_COUNT];
/*******************************************************************************
* RMM entry point information. Discovered on the primary core and reused
* on secondary cores.
******************************************************************************/
static entry_point_info_t *rmm_ep_info;
/*******************************************************************************
* Static function declaration.
******************************************************************************/
static int32_t rmm_init(void);
static uint64_t rmmd_smc_forward(uint32_t smc_fid, uint32_t src_sec_state,
uint32_t dst_sec_state, uint64_t x1,
uint64_t x2, uint64_t x3, uint64_t x4,
void *handle);
/*******************************************************************************
* This function takes an RMM context pointer and performs a synchronous entry
* into it.
******************************************************************************/
uint64_t rmmd_rmm_sync_entry(rmmd_rmm_context_t *rmm_ctx)
{
uint64_t rc;
assert(rmm_ctx != NULL);
cm_set_context(&(rmm_ctx->cpu_ctx), REALM);
/* Save the current el1/el2 context before loading realm context. */
cm_el1_sysregs_context_save(NON_SECURE);
cm_el2_sysregs_context_save(NON_SECURE);
/* Restore the realm context assigned above */
cm_el1_sysregs_context_restore(REALM);
cm_el2_sysregs_context_restore(REALM);
cm_set_next_eret_context(REALM);
/* Enter RMM */
rc = rmmd_rmm_enter(&rmm_ctx->c_rt_ctx);
/* Save realm context */
cm_el1_sysregs_context_save(REALM);
cm_el2_sysregs_context_save(REALM);
/* Restore the el1/el2 context again. */
cm_el1_sysregs_context_restore(NON_SECURE);
cm_el2_sysregs_context_restore(NON_SECURE);
return rc;
}
/*******************************************************************************
* This function returns to the place where rmmd_rmm_sync_entry() was
* called originally.
******************************************************************************/
__dead2 void rmmd_rmm_sync_exit(uint64_t rc)
{
rmmd_rmm_context_t *ctx = &rmm_context[plat_my_core_pos()];
/* Get context of the RMM in use by this CPU. */
assert(cm_get_context(REALM) == &(ctx->cpu_ctx));
/*
* The RMMD must have initiated the original request through a
* synchronous entry into RMM. Jump back to the original C runtime
* context with the value of rc in x0;
*/
rmmd_rmm_exit(ctx->c_rt_ctx, rc);
panic();
}
static void rmm_el2_context_init(el2_sysregs_t *regs)
{
regs->ctx_regs[CTX_SPSR_EL2 >> 3] = REALM_SPSR_EL2;
regs->ctx_regs[CTX_SCTLR_EL2 >> 3] = SCTLR_EL2_RES1;
}
/*******************************************************************************
* Jump to the RMM for the first time.
******************************************************************************/
static int32_t rmm_init(void)
{
uint64_t rc;
rmmd_rmm_context_t *ctx = &rmm_context[plat_my_core_pos()];
INFO("RMM init start.\n");
ctx->state = RMM_STATE_RESET;
/* Initialize RMM EL2 context. */
rmm_el2_context_init(&ctx->cpu_ctx.el2_sysregs_ctx);
rc = rmmd_rmm_sync_entry(ctx);
if (rc != 0ULL) {
ERROR("RMM initialisation failed 0x%llx\n", rc);
panic();
}
ctx->state = RMM_STATE_IDLE;
INFO("RMM init end.\n");
return 1;
}
/*******************************************************************************
* Load and read RMM manifest, setup RMM.
******************************************************************************/
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];
/* Make sure RME is supported. */
assert(get_armv9_2_feat_rme_support() != 0U);
rmm_ep_info = bl31_plat_get_next_image_ep_info(REALM);
if (rmm_ep_info == NULL) {
WARN("No RMM image provided by BL2 boot loader, Booting "
"device without RMM initialization. SMCs destined for "
"RMM will return SMC_UNK\n");
return -ENOENT;
}
/* Under no circumstances will this parameter be 0 */
assert(rmm_ep_info->pc == RMM_BASE);
/* Initialise an entrypoint to set up the CPU context */
ep_attr = EP_REALM;
if ((read_sctlr_el3() & SCTLR_EE_BIT) != 0U) {
ep_attr |= EP_EE_BIG;
}
SET_PARAM_HEAD(rmm_ep_info, PARAM_EP, VERSION_1, ep_attr);
rmm_ep_info->spsr = SPSR_64(MODE_EL2,
MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS);
/* Initialise RMM context with this entry point information */
cm_setup_context(&rmm_ctx->cpu_ctx, rmm_ep_info);
INFO("RMM setup done.\n");
/* Register init function for deferred init. */
bl31_register_rmm_init(&rmm_init);
return 0;
}
/*******************************************************************************
* Forward SMC to the other security state
******************************************************************************/
static uint64_t rmmd_smc_forward(uint32_t smc_fid, uint32_t src_sec_state,
uint32_t dst_sec_state, uint64_t x1,
uint64_t x2, uint64_t x3, uint64_t x4,
void *handle)
{
/* Save incoming security state */
cm_el1_sysregs_context_save(src_sec_state);
cm_el2_sysregs_context_save(src_sec_state);
/* Restore outgoing security state */
cm_el1_sysregs_context_restore(dst_sec_state);
cm_el2_sysregs_context_restore(dst_sec_state);
cm_set_next_eret_context(dst_sec_state);
SMC_RET8(cm_get_context(dst_sec_state), smc_fid, x1, x2, x3, x4,
SMC_GET_GP(handle, CTX_GPREG_X5),
SMC_GET_GP(handle, CTX_GPREG_X6),
SMC_GET_GP(handle, CTX_GPREG_X7));
}
/*******************************************************************************
* This function handles all SMCs in the range reserved for RMI. Each call is
* either forwarded to the other security state or handled by the RMM dispatcher
******************************************************************************/
uint64_t rmmd_rmi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
uint64_t x3, uint64_t x4, void *cookie,
void *handle, uint64_t flags)
{
rmmd_rmm_context_t *ctx = &rmm_context[plat_my_core_pos()];
uint32_t src_sec_state;
/* Determine which security state this SMC originated from */
src_sec_state = caller_sec_state(flags);
/* RMI must not be invoked by the Secure world */
if (src_sec_state == SMC_FROM_SECURE) {
WARN("RMM: RMI invoked by secure world.\n");
SMC_RET1(handle, SMC_UNK);
}
/*
* Forward an RMI call from the Normal world to the Realm world as it
* is.
*/
if (src_sec_state == SMC_FROM_NON_SECURE) {
VERBOSE("RMM: RMI call from non-secure world.\n");
return rmmd_smc_forward(smc_fid, NON_SECURE, REALM,
x1, x2, x3, x4, handle);
}
assert(src_sec_state == SMC_FROM_REALM);
switch (smc_fid) {
case RMI_RMM_REQ_COMPLETE:
if (ctx->state == RMM_STATE_RESET) {
VERBOSE("RMM: running rmmd_rmm_sync_exit\n");
rmmd_rmm_sync_exit(x1);
}
return rmmd_smc_forward(x1, REALM, NON_SECURE,
x2, x3, x4, 0, handle);
default:
WARN("RMM: Unsupported RMM call 0x%08x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);
}
}
/*******************************************************************************
* This cpu has been turned on. Enter RMM to initialise R-EL2. Entry into RMM
* is done after initialising minimal architectural state that guarantees safe
* execution.
******************************************************************************/
static void *rmmd_cpu_on_finish_handler(const void *arg)
{
int32_t rc;
uint32_t linear_id = plat_my_core_pos();
rmmd_rmm_context_t *ctx = &rmm_context[linear_id];
ctx->state = RMM_STATE_RESET;
/* Initialise RMM context with this entry point information */
cm_setup_context(&ctx->cpu_ctx, rmm_ep_info);
/* Initialize RMM EL2 context. */
rmm_el2_context_init(&ctx->cpu_ctx.el2_sysregs_ctx);
rc = rmmd_rmm_sync_entry(ctx);
if (rc != 0) {
ERROR("RMM initialisation failed (%d) on CPU%d\n", rc,
linear_id);
panic();
}
ctx->state = RMM_STATE_IDLE;
return NULL;
}
/* Subscribe to PSCI CPU on to initialize RMM on secondary */
SUBSCRIBE_TO_EVENT(psci_cpu_on_finish, rmmd_cpu_on_finish_handler);
static int gtsi_transition_granule(uint64_t pa,
unsigned int src_sec_state,
unsigned int target_pas)
{
int ret;
ret = gpt_transition_pas(pa, PAGE_SIZE_4KB, src_sec_state, target_pas);
/* Convert TF-A error codes into GTSI error codes */
if (ret == -EINVAL) {
ERROR("[GTSI] Transition failed: invalid %s\n", "address");
ERROR(" PA: 0x%llx, SRC: %d, PAS: %d\n", pa,
src_sec_state, target_pas);
ret = GRAN_TRANS_RET_BAD_ADDR;
} else if (ret == -EPERM) {
ERROR("[GTSI] Transition failed: invalid %s\n", "caller/PAS");
ERROR(" PA: 0x%llx, SRC: %d, PAS: %d\n", pa,
src_sec_state, target_pas);
ret = GRAN_TRANS_RET_BAD_PAS;
}
return ret;
}
/*******************************************************************************
* This function handles all SMCs in the range reserved for GTF.
******************************************************************************/
uint64_t rmmd_gtsi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
uint64_t x3, uint64_t x4, void *cookie,
void *handle, uint64_t flags)
{
uint32_t src_sec_state;
/* Determine which security state this SMC originated from */
src_sec_state = caller_sec_state(flags);
if (src_sec_state != SMC_FROM_REALM) {
WARN("RMM: GTF call originated from secure or normal world\n");
SMC_RET1(handle, SMC_UNK);
}
switch (smc_fid) {
case SMC_ASC_MARK_REALM:
SMC_RET1(handle, gtsi_transition_granule(x1, SMC_FROM_REALM,
GPT_GPI_REALM));
case SMC_ASC_MARK_NONSECURE:
SMC_RET1(handle, gtsi_transition_granule(x1, SMC_FROM_REALM,
GPT_GPI_NS));
default:
WARN("RMM: Unsupported GTF call 0x%08x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);
}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef RMMD_PRIVATE_H
#define RMMD_PRIVATE_H
#include <context.h>
/*******************************************************************************
* Constants that allow assembler code to preserve callee-saved registers of the
* C runtime context while performing a security state switch.
******************************************************************************/
#define RMMD_C_RT_CTX_X19 0x0
#define RMMD_C_RT_CTX_X20 0x8
#define RMMD_C_RT_CTX_X21 0x10
#define RMMD_C_RT_CTX_X22 0x18
#define RMMD_C_RT_CTX_X23 0x20
#define RMMD_C_RT_CTX_X24 0x28
#define RMMD_C_RT_CTX_X25 0x30
#define RMMD_C_RT_CTX_X26 0x38
#define RMMD_C_RT_CTX_X27 0x40
#define RMMD_C_RT_CTX_X28 0x48
#define RMMD_C_RT_CTX_X29 0x50
#define RMMD_C_RT_CTX_X30 0x58
#define RMMD_C_RT_CTX_SIZE 0x60
#define RMMD_C_RT_CTX_ENTRIES (RMMD_C_RT_CTX_SIZE >> DWORD_SHIFT)
#ifndef __ASSEMBLER__
#include <stdint.h>
#include <services/rmi_svc.h>
typedef enum rmm_state {
RMM_STATE_RESET = 0,
RMM_STATE_IDLE
} rmm_state_t;
/*
* Data structure used by the RMM dispatcher (RMMD) in EL3 to track context of
* the RMM at R-EL2.
*/
typedef struct rmmd_rmm_context {
uint64_t c_rt_ctx;
cpu_context_t cpu_ctx;
rmm_state_t state;
} rmmd_rmm_context_t;
/* Functions used to enter/exit the RMM synchronously */
uint64_t rmmd_rmm_sync_entry(rmmd_rmm_context_t *ctx);
__dead2 void rmmd_rmm_sync_exit(uint64_t rc);
/* Assembly helpers */
uint64_t rmmd_rmm_enter(uint64_t *c_rt_ctx);
void __dead2 rmmd_rmm_exit(uint64_t c_rt_ctx, uint64_t ret);
/* Reference to PM ops for the RMMD */
extern const spd_pm_ops_t rmmd_pm;
#endif /* __ASSEMBLER__ */
#endif /* RMMD_PRIVATE_H */

View File

@ -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*) }
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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 */

View File

@ -13,7 +13,9 @@
#include <lib/pmf/pmf.h>
#include <lib/psci/psci.h>
#include <lib/runtime_instr.h>
#include <services/gtsi_svc.h>
#include <services/pci_svc.h>
#include <services/rmmd_svc.h>
#include <services/sdei.h>
#include <services/spm_mm_svc.h>
#include <services/spmd_svc.h>
@ -158,6 +160,16 @@ static uintptr_t std_svc_smc_handler(uint32_t smc_fid,
flags);
}
#endif
#if ENABLE_RME
/*
* Granule transition service interface functions (GTSI) are allocated
* from the Std service range. Call the RMM dispatcher to handle calls.
*/
if (is_gtsi_fid(smc_fid)) {
return rmmd_gtsi_handler(smc_fid, x1, x2, x3, x4, cookie,
handle, flags);
}
#endif
#if SMC_PCI_SUPPORT
if (is_pci_fid(smc_fid)) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -67,6 +67,11 @@ toc_entry_t toc_entries[] = {
.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
.cmdline_name = "nt-fw"
},
{
.name = "Realm Monitor Management Firmware",
.uuid = UUID_REALM_MONITOR_MGMT_FIRMWARE,
.cmdline_name = "rmm-fw"
},
/* Dynamic Configs */
{
.name = "FW_CONFIG",