diff --git a/docs/plat/qemu-sbsa.rst b/docs/plat/qemu-sbsa.rst index 51fe414..bc82ae5 100644 --- a/docs/plat/qemu-sbsa.rst +++ b/docs/plat/qemu-sbsa.rst @@ -19,7 +19,6 @@ Current limitations: - Only cold boot is supported -- No instructions for how to load a BL32 (Secure Payload) To build TF-A: @@ -27,9 +26,18 @@ git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git tfa cd tfa - export CROSS_COMPILE=aarch64-linux-gnu- + export CROSS_COMPILE=aarch64-none-elf- make PLAT=qemu_sbsa all fip +To build TF-A with BL32 and SPM enabled(StandaloneMM as a Secure Payload): + +:: + + git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git tfa + cd tfa + export CROSS_COMPILE=aarch64-none-elf- + make PLAT=qemu_sbsa BL32=../STANDALONE_MM.fd SPM_MM=1 EL3_EXCEPTION_HANDLING=1 all fip + Images will be placed at build/qemu_sbsa/release (bl1.bin and fip.bin). Need to copy them into top directory for EDK2 compilation. diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c index 365cfb7..7f8e4c4 100644 --- a/plat/qemu/common/qemu_common.c +++ b/plat/qemu/common/qemu_common.c @@ -1,5 +1,6 @@ + /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -77,7 +78,11 @@ MAP_DEVICE2, #endif MAP_NS_DRAM0, +#if SPM_MM + QEMU_SP_IMAGE_MMAP, +#else MAP_BL32_MEM, +#endif {0} }; #endif @@ -88,7 +93,11 @@ #ifdef MAP_DEVICE1 MAP_DEVICE1, #endif +#if SPM_MM + QEMU_SPM_BUF_EL3_MMAP, +#else MAP_BL32_MEM, +#endif {0} }; #endif diff --git a/plat/qemu/common/qemu_spm.c b/plat/qemu/common/qemu_spm.c new file mode 100644 index 0000000..e9ab1a5 --- /dev/null +++ b/plat/qemu/common/qemu_spm.c @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2020, Linaro Limited and Contributors. All rights reserved. + */ + +#include +#include +#include + +#include + +/* Region equivalent to MAP_DEVICE1 suitable for mapping at EL0 */ +#define MAP_DEVICE1_EL0 MAP_REGION_FLAT(DEVICE1_BASE, \ + DEVICE1_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE | MT_USER) + +const mmap_region_t plat_qemu_secure_partition_mmap[] = { + MAP_DEVICE1_EL0, /* for the UART */ + QEMU_SP_IMAGE_MMAP, + QEMU_SPM_BUF_EL0_MMAP, + QEMU_SP_IMAGE_NS_BUF_MMAP, + QEMU_SP_IMAGE_RW_MMAP, + {0} +}; + +/* + * Boot information passed to a secure partition during initialisation. + * Linear indices in MP information will be filled at runtime. + */ +static spm_mm_mp_info_t sp_mp_info[] = { + [0] = {0x80000000, 0}, + [1] = {0x80000001, 0}, + [2] = {0x80000002, 0}, + [3] = {0x80000003, 0}, + [4] = {0x80000004, 0}, + [5] = {0x80000005, 0}, + [6] = {0x80000006, 0}, + [7] = {0x80000007, 0} +}; + +const spm_mm_boot_info_t plat_qemu_secure_partition_boot_info = { + .h.type = PARAM_SP_IMAGE_BOOT_INFO, + .h.version = VERSION_1, + .h.size = sizeof(spm_mm_boot_info_t), + .h.attr = 0, + .sp_mem_base = PLAT_QEMU_SP_IMAGE_BASE, + .sp_mem_limit = BL32_LIMIT, + .sp_image_base = PLAT_QEMU_SP_IMAGE_BASE, + .sp_stack_base = PLAT_SP_IMAGE_STACK_BASE, + .sp_heap_base = PLAT_QEMU_SP_IMAGE_HEAP_BASE, + .sp_ns_comm_buf_base = PLAT_QEMU_SP_IMAGE_NS_BUF_BASE, + .sp_shared_buf_base = PLAT_SPM_BUF_BASE, + .sp_image_size = PLAT_QEMU_SP_IMAGE_SIZE, + .sp_pcpu_stack_size = PLAT_SP_IMAGE_STACK_PCPU_SIZE, + .sp_heap_size = PLAT_QEMU_SP_IMAGE_HEAP_SIZE, + .sp_ns_comm_buf_size = PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE, + .sp_shared_buf_size = PLAT_SPM_BUF_SIZE, + .num_sp_mem_regions = PLAT_QEMU_SP_IMAGE_NUM_MEM_REGIONS, + .num_cpus = PLATFORM_CORE_COUNT, + .mp_info = sp_mp_info +}; + +/* Enumeration of priority levels on QEMU platforms. */ +ehf_pri_desc_t qemu_exceptions[] = { + EHF_PRI_DESC(QEMU_PRI_BITS, PLAT_SP_PRI) +}; + +/* Plug in QEMU exceptions to Exception Handling Framework. */ +EHF_REGISTER_PRIORITIES(qemu_exceptions, ARRAY_SIZE(qemu_exceptions), + QEMU_PRI_BITS); + +const mmap_region_t *plat_get_secure_partition_mmap(void *cookie) +{ + return plat_qemu_secure_partition_mmap; +} + +const spm_mm_boot_info_t * +plat_get_secure_partition_boot_info(void *cookie) +{ + return &plat_qemu_secure_partition_boot_info; +} diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h index d0a56cf..7634005 100644 --- a/plat/qemu/qemu_sbsa/include/platform_def.h +++ b/plat/qemu/qemu_sbsa/include/platform_def.h @@ -1,10 +1,11 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright (c) 2019, Linaro Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, Linaro Limited and Contributors. + * All rights reserved. */ -#ifndef __PLATFORM_DEF_H__ -#define __PLATFORM_DEF_H__ +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H #include #include @@ -107,9 +108,10 @@ * Put BL1 RW at the top of the Secure SRAM. BL1_RW_BASE is calculated using * the current BL1 RW debug size plus a little space for growth. */ +#define BL1_SIZE 0x12000 #define BL1_RO_BASE SEC_ROM_BASE #define BL1_RO_LIMIT (SEC_ROM_BASE + SEC_ROM_SIZE) -#define BL1_RW_BASE (BL1_RW_LIMIT - 0x12000) +#define BL1_RW_BASE (BL1_RW_LIMIT - BL1_SIZE) #define BL1_RW_LIMIT (BL_RAM_BASE + BL_RAM_SIZE) /* @@ -118,7 +120,8 @@ * Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug * size plus a little space for growth. */ -#define BL2_BASE (BL31_BASE - 0x1D000) +#define BL2_SIZE 0x1D000 +#define BL2_BASE (BL31_BASE - BL2_SIZE) #define BL2_LIMIT BL31_BASE /* @@ -127,8 +130,9 @@ * Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the * current BL3-1 debug size plus a little space for growth. */ -#define BL31_BASE (BL31_LIMIT - 0x20000) -#define BL31_LIMIT (BL_RAM_BASE + BL_RAM_SIZE) +#define BL31_SIZE 0x50000 +#define BL31_BASE (BL31_LIMIT - BL31_SIZE) +#define BL31_LIMIT (BL1_RW_BASE) #define BL31_PROGBITS_LIMIT BL1_RW_BASE @@ -138,12 +142,11 @@ * BL3-2 can execute from Secure SRAM, or Secure DRAM. */ #define BL32_SRAM_BASE BL_RAM_BASE -#define BL32_SRAM_LIMIT BL31_BASE -#define BL32_DRAM_BASE SEC_DRAM_BASE -#define BL32_DRAM_LIMIT (SEC_DRAM_BASE + SEC_DRAM_SIZE) +#define BL32_SRAM_LIMIT BL2_BASE #define BL32_MEM_BASE BL_RAM_BASE -#define BL32_MEM_SIZE BL_RAM_SIZE +#define BL32_MEM_SIZE (BL_RAM_SIZE - BL1_SIZE - \ + BL2_SIZE - BL31_SIZE) #define BL32_BASE BL32_SRAM_BASE #define BL32_LIMIT BL32_SRAM_LIMIT @@ -152,11 +155,21 @@ #define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 42) #define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 42) +#if SPM_MM +#define MAX_MMAP_REGIONS 12 +#define MAX_XLAT_TABLES 11 +#else #define MAX_MMAP_REGIONS 11 #define MAX_XLAT_TABLES 10 +#endif #define MAX_IO_DEVICES 3 #define MAX_IO_HANDLES 4 +#if SPM_MM && defined(IMAGE_BL31) +# define PLAT_SP_IMAGE_MMAP_REGIONS 30 +# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 20 +#endif + /* * PL011 related constants */ @@ -165,6 +178,10 @@ #define UART0_CLK_IN_HZ 1 #define UART1_CLK_IN_HZ 1 +/* Secure UART */ +#define UART2_BASE 0x60040000 +#define UART2_CLK_IN_HZ 1 + #define PLAT_QEMU_BOOT_UART_BASE UART0_BASE #define PLAT_QEMU_BOOT_UART_CLK_IN_HZ UART0_CLK_IN_HZ @@ -179,7 +196,7 @@ #define QEMU_FLASH1_SIZE 0x10000000 #define PLAT_QEMU_FIP_BASE 0x00008000 -#define PLAT_QEMU_FIP_MAX_SIZE 0x00020000 +#define PLAT_QEMU_FIP_MAX_SIZE 0x00400000 /* This is map from GIC_DIST up to last CPU (255) GIC_REDISTR */ #define DEVICE0_BASE 0x40000000 @@ -240,4 +257,99 @@ */ #define SYS_COUNTER_FREQ_IN_TICKS ((1000 * 1000 * 1000) / 16) -#endif /* __PLATFORM_DEF_H__ */ +#if SPM_MM +#define PLAT_QEMU_SP_IMAGE_BASE BL_RAM_BASE +#define PLAT_QEMU_SP_IMAGE_SIZE ULL(0x300000) + +#ifdef IMAGE_BL2 +/* In BL2 all memory allocated to the SPM Payload image is marked as RW. */ +# define QEMU_SP_IMAGE_MMAP MAP_REGION_FLAT( \ + PLAT_QEMU_SP_IMAGE_BASE, \ + PLAT_QEMU_SP_IMAGE_SIZE, \ + MT_MEMORY | MT_RW | \ + MT_SECURE) +#elif IMAGE_BL31 +/* All SPM Payload memory is marked as code in S-EL0 */ +# define QEMU_SP_IMAGE_MMAP MAP_REGION2(PLAT_QEMU_SP_IMAGE_BASE, \ + PLAT_QEMU_SP_IMAGE_BASE, \ + PLAT_QEMU_SP_IMAGE_SIZE, \ + MT_CODE | MT_SECURE | \ + MT_USER, \ + PAGE_SIZE) +#endif + +/* + * EL3 -> S-EL0 secure shared memory + */ +#define PLAT_SPM_BUF_PCPU_SIZE ULL(0x10000) +#define PLAT_SPM_BUF_SIZE (PLATFORM_CORE_COUNT * \ + PLAT_SPM_BUF_PCPU_SIZE) +#define PLAT_SPM_BUF_BASE (BL32_LIMIT - PLAT_SPM_BUF_SIZE) + +#define QEMU_SPM_BUF_EL3_MMAP MAP_REGION_FLAT(PLAT_SPM_BUF_BASE, \ + PLAT_SPM_BUF_SIZE, \ + MT_RW_DATA | MT_SECURE) + +#define QEMU_SPM_BUF_EL0_MMAP MAP_REGION2(PLAT_SPM_BUF_BASE, \ + PLAT_SPM_BUF_BASE, \ + PLAT_SPM_BUF_SIZE, \ + MT_RO_DATA | MT_SECURE | \ + MT_USER, \ + PAGE_SIZE) + +/* + * Shared memory between Normal world and S-EL0 for + * passing data during service requests. It will be marked as RW and NS. + */ +#define PLAT_QEMU_SP_IMAGE_NS_BUF_BASE (PLAT_QEMU_DT_BASE + \ + PLAT_QEMU_DT_MAX_SIZE) +#define PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE ULL(0x10000) +#define QEMU_SP_IMAGE_NS_BUF_MMAP MAP_REGION2( \ + PLAT_QEMU_SP_IMAGE_NS_BUF_BASE, \ + PLAT_QEMU_SP_IMAGE_NS_BUF_BASE, \ + PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE, \ + MT_RW_DATA | MT_NS | \ + MT_USER, \ + PAGE_SIZE) + +#define PLAT_SP_IMAGE_NS_BUF_BASE PLAT_QEMU_SP_IMAGE_NS_BUF_BASE +#define PLAT_SP_IMAGE_NS_BUF_SIZE PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE + +#define PLAT_QEMU_SP_IMAGE_HEAP_BASE (PLAT_QEMU_SP_IMAGE_BASE + \ + PLAT_QEMU_SP_IMAGE_SIZE) +#define PLAT_QEMU_SP_IMAGE_HEAP_SIZE ULL(0x800000) + +#define PLAT_SP_IMAGE_STACK_BASE (PLAT_QEMU_SP_IMAGE_HEAP_BASE + \ + PLAT_QEMU_SP_IMAGE_HEAP_SIZE) +#define PLAT_SP_IMAGE_STACK_PCPU_SIZE ULL(0x10000) +#define QEMU_SP_IMAGE_STACK_TOTAL_SIZE (PLATFORM_CORE_COUNT * \ + PLAT_SP_IMAGE_STACK_PCPU_SIZE) + +#define QEMU_SP_IMAGE_RW_MMAP MAP_REGION2( \ + PLAT_QEMU_SP_IMAGE_HEAP_BASE, \ + PLAT_QEMU_SP_IMAGE_HEAP_BASE, \ + (QEMU_SP_IMAGE_STACK_TOTAL_SIZE + \ + PLAT_QEMU_SP_IMAGE_HEAP_SIZE), \ + MT_RW_DATA | MT_SECURE | \ + MT_USER, \ + PAGE_SIZE) + +/* Total number of memory regions with distinct properties */ +#define PLAT_QEMU_SP_IMAGE_NUM_MEM_REGIONS 6 + +/* + * Name of the section to put the translation tables used by the S-EL1/S-EL0 + * context of a Secure Partition. + */ +#define PLAT_SP_IMAGE_XLAT_SECTION_NAME "qemu_sp_xlat_table" +#define PLAT_SP_IMAGE_BASE_XLAT_SECTION_NAME "qemu_sp_xlat_table" + +/* Cookies passed to the Secure Partition at boot. Not used by QEMU platforms.*/ +#define PLAT_SPM_COOKIE_0 ULL(0) +#define PLAT_SPM_COOKIE_1 ULL(0) +#endif + +#define QEMU_PRI_BITS 2 +#define PLAT_SP_PRI 0x20 + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk index 09856d6..3aa7cbe 100644 --- a/plat/qemu/qemu_sbsa/platform.mk +++ b/plat/qemu/qemu_sbsa/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2019, Linaro Limited and Contributors. All rights reserved. +# Copyright (c) 2019-2020, Linaro Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -8,6 +8,12 @@ include lib/libfdt/libfdt.mk +ifeq (${SPM_MM},1) +NEED_BL32 := yes +EL3_EXCEPTION_HANDLING := 1 +GICV2_G0_FOR_EL3 := 1 +endif + # Enable new version of image loading on QEMU platforms LOAD_IMAGE_V2 := 1 @@ -80,6 +86,9 @@ ${PLAT_QEMU_COMMON_PATH}/aarch64/plat_helpers.S \ ${PLAT_QEMU_COMMON_PATH}/qemu_bl31_setup.c \ ${QEMU_GIC_SOURCES} +ifeq (${SPM_MM},1) + BL31_SOURCES += ${PLAT_QEMU_COMMON_PATH}/qemu_spm.c +endif SEPARATE_CODE_AND_RODATA := 1 ENABLE_STACK_PROTECTOR := 0