diff --git a/plat/qemu/aarch32/plat_helpers.S b/plat/qemu/aarch32/plat_helpers.S deleted file mode 100644 index aebcfa7..0000000 --- a/plat/qemu/aarch32/plat_helpers.S +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include - - .globl plat_my_core_pos - .globl plat_get_my_entrypoint - .globl platform_mem_init - .globl plat_qemu_calc_core_pos - .globl plat_crash_console_init - .globl plat_crash_console_putc - .globl plat_crash_console_flush - .globl plat_secondary_cold_boot_setup - .globl plat_get_my_entrypoint - .globl plat_is_my_cpu_primary - - -func plat_my_core_pos - ldcopr r0, MPIDR - b plat_qemu_calc_core_pos -endfunc plat_my_core_pos - -/* - * unsigned int plat_qemu_calc_core_pos(u_register_t mpidr); - * With this function: CorePos = (ClusterId * 4) + CoreId - */ -func plat_qemu_calc_core_pos - and r1, r0, #MPIDR_CPU_MASK - and r0, r0, #MPIDR_CLUSTER_MASK - add r0, r1, r0, LSR #6 - bx lr -endfunc plat_qemu_calc_core_pos - - /* ----------------------------------------------------- - * unsigned int plat_is_my_cpu_primary (void); - * - * Find out whether the current cpu is the primary - * cpu. - * ----------------------------------------------------- - */ -func plat_is_my_cpu_primary - ldcopr r0, MPIDR - ldr r1, =(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) - and r0, r1 - cmp r0, #QEMU_PRIMARY_CPU - moveq r0, #1 - movne r0, #0 - bx lr -endfunc plat_is_my_cpu_primary - - /* ----------------------------------------------------- - * void plat_secondary_cold_boot_setup (void); - * - * This function performs any platform specific actions - * needed for a secondary cpu after a cold reset e.g - * mark the cpu's presence, mechanism to place it in a - * holding pen etc. - * ----------------------------------------------------- - */ -func plat_secondary_cold_boot_setup - /* Calculate address of our hold entry */ - bl plat_my_core_pos - lsl r0, r0, #PLAT_QEMU_HOLD_ENTRY_SHIFT - mov_imm r2, PLAT_QEMU_HOLD_BASE - - /* Wait until we have a go */ -poll_mailbox: - ldr r1, [r2, r0] - cmp r1, #0 - beq 1f - mov_imm r0, PLAT_QEMU_TRUSTED_MAILBOX_BASE - ldr r1, [r0] - bx r1 -1: - wfe - b poll_mailbox -endfunc plat_secondary_cold_boot_setup - -func plat_get_my_entrypoint - /* TODO support warm boot */ - mov r0, #0 - bx lr -endfunc plat_get_my_entrypoint - -func platform_mem_init - bx lr -endfunc platform_mem_init - - /* --------------------------------------------- - * int plat_crash_console_init(void) - * Function to initialize the crash console - * without a C Runtime to print crash report. - * Clobber list : x0, x1, x2 - * --------------------------------------------- - */ -func plat_crash_console_init - mov_imm r0, PLAT_QEMU_CRASH_UART_BASE - mov_imm r1, PLAT_QEMU_CRASH_UART_CLK_IN_HZ - mov_imm r2, PLAT_QEMU_CONSOLE_BAUDRATE - b console_pl011_core_init -endfunc plat_crash_console_init - - /* --------------------------------------------- - * int plat_crash_console_putc(int c) - * Function to print a character on the crash - * console without a C Runtime. - * Clobber list : x1, x2 - * --------------------------------------------- - */ -func plat_crash_console_putc - mov_imm r1, PLAT_QEMU_CRASH_UART_BASE - b console_pl011_core_putc -endfunc plat_crash_console_putc - - /* --------------------------------------------- - * int plat_crash_console_flush(int c) - * Function to force a write of all buffered - * data that hasn't been output. - * Out : return -1 on error else return 0. - * Clobber list : x0, x1 - * --------------------------------------------- - */ -func plat_crash_console_flush - mov_imm r0, PLAT_QEMU_CRASH_UART_BASE - b console_pl011_core_flush -endfunc plat_crash_console_flush - diff --git a/plat/qemu/aarch64/plat_helpers.S b/plat/qemu/aarch64/plat_helpers.S deleted file mode 100644 index 13a5ee4..0000000 --- a/plat/qemu/aarch64/plat_helpers.S +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include - - .globl plat_my_core_pos - .globl plat_get_my_entrypoint - .globl platform_mem_init - .globl plat_qemu_calc_core_pos - .globl plat_crash_console_init - .globl plat_crash_console_putc - .globl plat_crash_console_flush - .globl plat_secondary_cold_boot_setup - .globl plat_get_my_entrypoint - .globl plat_is_my_cpu_primary - -func plat_my_core_pos - mrs x0, mpidr_el1 - b plat_qemu_calc_core_pos -endfunc plat_my_core_pos - -/* - * unsigned int plat_qemu_calc_core_pos(u_register_t mpidr); - * With this function: CorePos = (ClusterId * 4) + CoreId - */ -func plat_qemu_calc_core_pos - and x1, x0, #MPIDR_CPU_MASK - and x0, x0, #MPIDR_CLUSTER_MASK - add x0, x1, x0, LSR #6 - ret -endfunc plat_qemu_calc_core_pos - - /* ----------------------------------------------------- - * unsigned int plat_is_my_cpu_primary (void); - * - * Find out whether the current cpu is the primary - * cpu. - * ----------------------------------------------------- - */ -func plat_is_my_cpu_primary - mrs x0, mpidr_el1 - and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) - cmp x0, #QEMU_PRIMARY_CPU - cset w0, eq - ret -endfunc plat_is_my_cpu_primary - - /* ----------------------------------------------------- - * void plat_secondary_cold_boot_setup (void); - * - * This function performs any platform specific actions - * needed for a secondary cpu after a cold reset e.g - * mark the cpu's presence, mechanism to place it in a - * holding pen etc. - * ----------------------------------------------------- - */ -func plat_secondary_cold_boot_setup - /* Calculate address of our hold entry */ - bl plat_my_core_pos - lsl x0, x0, #PLAT_QEMU_HOLD_ENTRY_SHIFT - mov_imm x2, PLAT_QEMU_HOLD_BASE - - /* Wait until we have a go */ -poll_mailbox: - ldr x1, [x2, x0] - cbz x1, 1f - mov_imm x0, PLAT_QEMU_TRUSTED_MAILBOX_BASE - ldr x1, [x0] - br x1 -1: - wfe - b poll_mailbox -endfunc plat_secondary_cold_boot_setup - -func plat_get_my_entrypoint - /* TODO support warm boot */ - mov x0, #0 - ret -endfunc plat_get_my_entrypoint - -func platform_mem_init - ret -endfunc platform_mem_init - - /* --------------------------------------------- - * int plat_crash_console_init(void) - * Function to initialize the crash console - * without a C Runtime to print crash report. - * Clobber list : x0, x1, x2 - * --------------------------------------------- - */ -func plat_crash_console_init - mov_imm x0, PLAT_QEMU_CRASH_UART_BASE - mov_imm x1, PLAT_QEMU_CRASH_UART_CLK_IN_HZ - mov_imm x2, PLAT_QEMU_CONSOLE_BAUDRATE - b console_pl011_core_init -endfunc plat_crash_console_init - - /* --------------------------------------------- - * int plat_crash_console_putc(int c) - * Function to print a character on the crash - * console without a C Runtime. - * Clobber list : x1, x2 - * --------------------------------------------- - */ -func plat_crash_console_putc - mov_imm x1, PLAT_QEMU_CRASH_UART_BASE - b console_pl011_core_putc -endfunc plat_crash_console_putc - - /* --------------------------------------------- - * int plat_crash_console_flush(int c) - * Function to force a write of all buffered - * data that hasn't been output. - * Out : return -1 on error else return 0. - * Clobber list : x0, x1 - * --------------------------------------------- - */ -func plat_crash_console_flush - mov_imm x0, PLAT_QEMU_CRASH_UART_BASE - b console_pl011_core_flush -endfunc plat_crash_console_flush - diff --git a/plat/qemu/common/aarch32/plat_helpers.S b/plat/qemu/common/aarch32/plat_helpers.S new file mode 100644 index 0000000..aebcfa7 --- /dev/null +++ b/plat/qemu/common/aarch32/plat_helpers.S @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + + .globl plat_my_core_pos + .globl plat_get_my_entrypoint + .globl platform_mem_init + .globl plat_qemu_calc_core_pos + .globl plat_crash_console_init + .globl plat_crash_console_putc + .globl plat_crash_console_flush + .globl plat_secondary_cold_boot_setup + .globl plat_get_my_entrypoint + .globl plat_is_my_cpu_primary + + +func plat_my_core_pos + ldcopr r0, MPIDR + b plat_qemu_calc_core_pos +endfunc plat_my_core_pos + +/* + * unsigned int plat_qemu_calc_core_pos(u_register_t mpidr); + * With this function: CorePos = (ClusterId * 4) + CoreId + */ +func plat_qemu_calc_core_pos + and r1, r0, #MPIDR_CPU_MASK + and r0, r0, #MPIDR_CLUSTER_MASK + add r0, r1, r0, LSR #6 + bx lr +endfunc plat_qemu_calc_core_pos + + /* ----------------------------------------------------- + * unsigned int plat_is_my_cpu_primary (void); + * + * Find out whether the current cpu is the primary + * cpu. + * ----------------------------------------------------- + */ +func plat_is_my_cpu_primary + ldcopr r0, MPIDR + ldr r1, =(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) + and r0, r1 + cmp r0, #QEMU_PRIMARY_CPU + moveq r0, #1 + movne r0, #0 + bx lr +endfunc plat_is_my_cpu_primary + + /* ----------------------------------------------------- + * void plat_secondary_cold_boot_setup (void); + * + * This function performs any platform specific actions + * needed for a secondary cpu after a cold reset e.g + * mark the cpu's presence, mechanism to place it in a + * holding pen etc. + * ----------------------------------------------------- + */ +func plat_secondary_cold_boot_setup + /* Calculate address of our hold entry */ + bl plat_my_core_pos + lsl r0, r0, #PLAT_QEMU_HOLD_ENTRY_SHIFT + mov_imm r2, PLAT_QEMU_HOLD_BASE + + /* Wait until we have a go */ +poll_mailbox: + ldr r1, [r2, r0] + cmp r1, #0 + beq 1f + mov_imm r0, PLAT_QEMU_TRUSTED_MAILBOX_BASE + ldr r1, [r0] + bx r1 +1: + wfe + b poll_mailbox +endfunc plat_secondary_cold_boot_setup + +func plat_get_my_entrypoint + /* TODO support warm boot */ + mov r0, #0 + bx lr +endfunc plat_get_my_entrypoint + +func platform_mem_init + bx lr +endfunc platform_mem_init + + /* --------------------------------------------- + * int plat_crash_console_init(void) + * Function to initialize the crash console + * without a C Runtime to print crash report. + * Clobber list : x0, x1, x2 + * --------------------------------------------- + */ +func plat_crash_console_init + mov_imm r0, PLAT_QEMU_CRASH_UART_BASE + mov_imm r1, PLAT_QEMU_CRASH_UART_CLK_IN_HZ + mov_imm r2, PLAT_QEMU_CONSOLE_BAUDRATE + b console_pl011_core_init +endfunc plat_crash_console_init + + /* --------------------------------------------- + * int plat_crash_console_putc(int c) + * Function to print a character on the crash + * console without a C Runtime. + * Clobber list : x1, x2 + * --------------------------------------------- + */ +func plat_crash_console_putc + mov_imm r1, PLAT_QEMU_CRASH_UART_BASE + b console_pl011_core_putc +endfunc plat_crash_console_putc + + /* --------------------------------------------- + * int plat_crash_console_flush(int c) + * Function to force a write of all buffered + * data that hasn't been output. + * Out : return -1 on error else return 0. + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func plat_crash_console_flush + mov_imm r0, PLAT_QEMU_CRASH_UART_BASE + b console_pl011_core_flush +endfunc plat_crash_console_flush + diff --git a/plat/qemu/common/aarch64/plat_helpers.S b/plat/qemu/common/aarch64/plat_helpers.S new file mode 100644 index 0000000..13a5ee4 --- /dev/null +++ b/plat/qemu/common/aarch64/plat_helpers.S @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + + .globl plat_my_core_pos + .globl plat_get_my_entrypoint + .globl platform_mem_init + .globl plat_qemu_calc_core_pos + .globl plat_crash_console_init + .globl plat_crash_console_putc + .globl plat_crash_console_flush + .globl plat_secondary_cold_boot_setup + .globl plat_get_my_entrypoint + .globl plat_is_my_cpu_primary + +func plat_my_core_pos + mrs x0, mpidr_el1 + b plat_qemu_calc_core_pos +endfunc plat_my_core_pos + +/* + * unsigned int plat_qemu_calc_core_pos(u_register_t mpidr); + * With this function: CorePos = (ClusterId * 4) + CoreId + */ +func plat_qemu_calc_core_pos + and x1, x0, #MPIDR_CPU_MASK + and x0, x0, #MPIDR_CLUSTER_MASK + add x0, x1, x0, LSR #6 + ret +endfunc plat_qemu_calc_core_pos + + /* ----------------------------------------------------- + * unsigned int plat_is_my_cpu_primary (void); + * + * Find out whether the current cpu is the primary + * cpu. + * ----------------------------------------------------- + */ +func plat_is_my_cpu_primary + mrs x0, mpidr_el1 + and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) + cmp x0, #QEMU_PRIMARY_CPU + cset w0, eq + ret +endfunc plat_is_my_cpu_primary + + /* ----------------------------------------------------- + * void plat_secondary_cold_boot_setup (void); + * + * This function performs any platform specific actions + * needed for a secondary cpu after a cold reset e.g + * mark the cpu's presence, mechanism to place it in a + * holding pen etc. + * ----------------------------------------------------- + */ +func plat_secondary_cold_boot_setup + /* Calculate address of our hold entry */ + bl plat_my_core_pos + lsl x0, x0, #PLAT_QEMU_HOLD_ENTRY_SHIFT + mov_imm x2, PLAT_QEMU_HOLD_BASE + + /* Wait until we have a go */ +poll_mailbox: + ldr x1, [x2, x0] + cbz x1, 1f + mov_imm x0, PLAT_QEMU_TRUSTED_MAILBOX_BASE + ldr x1, [x0] + br x1 +1: + wfe + b poll_mailbox +endfunc plat_secondary_cold_boot_setup + +func plat_get_my_entrypoint + /* TODO support warm boot */ + mov x0, #0 + ret +endfunc plat_get_my_entrypoint + +func platform_mem_init + ret +endfunc platform_mem_init + + /* --------------------------------------------- + * int plat_crash_console_init(void) + * Function to initialize the crash console + * without a C Runtime to print crash report. + * Clobber list : x0, x1, x2 + * --------------------------------------------- + */ +func plat_crash_console_init + mov_imm x0, PLAT_QEMU_CRASH_UART_BASE + mov_imm x1, PLAT_QEMU_CRASH_UART_CLK_IN_HZ + mov_imm x2, PLAT_QEMU_CONSOLE_BAUDRATE + b console_pl011_core_init +endfunc plat_crash_console_init + + /* --------------------------------------------- + * int plat_crash_console_putc(int c) + * Function to print a character on the crash + * console without a C Runtime. + * Clobber list : x1, x2 + * --------------------------------------------- + */ +func plat_crash_console_putc + mov_imm x1, PLAT_QEMU_CRASH_UART_BASE + b console_pl011_core_putc +endfunc plat_crash_console_putc + + /* --------------------------------------------- + * int plat_crash_console_flush(int c) + * Function to force a write of all buffered + * data that hasn't been output. + * Out : return -1 on error else return 0. + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func plat_crash_console_flush + mov_imm x0, PLAT_QEMU_CRASH_UART_BASE + b console_pl011_core_flush +endfunc plat_crash_console_flush + diff --git a/plat/qemu/common/include/plat_macros.S b/plat/qemu/common/include/plat_macros.S new file mode 100644 index 0000000..b6cdb07 --- /dev/null +++ b/plat/qemu/common/include/plat_macros.S @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef PLAT_MACROS_S +#define PLAT_MACROS_S + +#include +#include + + /* --------------------------------------------- + * The below required platform porting macro + * prints out relevant GIC and CCI registers + * whenever an unhandled exception is taken in + * BL31. + * Clobbers: x0 - x10, x16, x17, sp + * --------------------------------------------- + */ + .macro plat_crash_print_regs + mov_imm x17, GICC_BASE + mov_imm x16, GICD_BASE + arm_print_gic_regs + .endm + +#endif /* PLAT_MACROS_S */ diff --git a/plat/qemu/common/qemu_bl1_setup.c b/plat/qemu/common/qemu_bl1_setup.c new file mode 100644 index 0000000..67f3327 --- /dev/null +++ b/plat/qemu/common/qemu_bl1_setup.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include +#include +#include + +#include "qemu_private.h" + +/* Data structure which holds the extents of the trusted SRAM for BL1*/ +static meminfo_t bl1_tzram_layout; + + +meminfo_t *bl1_plat_sec_mem_layout(void) +{ + return &bl1_tzram_layout; +} + +/******************************************************************************* + * Perform any BL1 specific platform actions. + ******************************************************************************/ +void bl1_early_platform_setup(void) +{ + /* Initialize the console to provide early debug support */ + qemu_console_init(); + + /* Allow BL1 to see the whole Trusted RAM */ + bl1_tzram_layout.total_base = BL_RAM_BASE; + bl1_tzram_layout.total_size = BL_RAM_SIZE; +} + +/****************************************************************************** + * Perform the very early platform specific architecture setup. This only + * does basic initialization. Later architectural setup (bl1_arch_setup()) + * does not do anything platform specific. + *****************************************************************************/ +#ifdef __aarch64__ +#define QEMU_CONFIGURE_BL1_MMU(...) qemu_configure_mmu_el3(__VA_ARGS__) +#else +#define QEMU_CONFIGURE_BL1_MMU(...) qemu_configure_mmu_svc_mon(__VA_ARGS__) +#endif + +void bl1_plat_arch_setup(void) +{ + QEMU_CONFIGURE_BL1_MMU(bl1_tzram_layout.total_base, + bl1_tzram_layout.total_size, + BL_CODE_BASE, BL1_CODE_END, + BL1_RO_DATA_BASE, BL1_RO_DATA_END, + BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END); +} + +void bl1_platform_setup(void) +{ + plat_qemu_io_setup(); +} diff --git a/plat/qemu/common/qemu_bl2_mem_params_desc.c b/plat/qemu/common/qemu_bl2_mem_params_desc.c new file mode 100644 index 0000000..a01f2dc --- /dev/null +++ b/plat/qemu/common/qemu_bl2_mem_params_desc.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +/******************************************************************************* + * Following descriptor provides BL image/ep information that gets used + * by BL2 to load the images and also subset of this information is + * passed to next BL image. The image loading sequence is managed by + * populating the images in required loading order. The image execution + * sequence is managed by populating the `next_handoff_image_id` with + * the next executable image id. + ******************************************************************************/ +static bl_mem_params_node_t bl2_mem_params_descs[] = { +#ifdef EL3_PAYLOAD_BASE + /* Fill EL3 payload related information (BL31 is EL3 payload) */ + { .image_id = BL31_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, + entry_point_info_t, + SECURE | EXECUTABLE | EP_FIRST_EXE), + .ep_info.pc = EL3_PAYLOAD_BASE, + .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, image_info_t, + IMAGE_ATTRIB_PLAT_SETUP | IMAGE_ATTRIB_SKIP_LOADING), + + .next_handoff_image_id = INVALID_IMAGE_ID, + }, +#else /* EL3_PAYLOAD_BASE */ +#ifdef __aarch64__ + /* Fill BL31 related information */ + { .image_id = BL31_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, + entry_point_info_t, + SECURE | EXECUTABLE | EP_FIRST_EXE), + .ep_info.pc = BL31_BASE, + .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS), +# if DEBUG + .ep_info.args.arg1 = QEMU_BL31_PLAT_PARAM_VAL, +# endif + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, image_info_t, + IMAGE_ATTRIB_PLAT_SETUP), + .image_info.image_base = BL31_BASE, + .image_info.image_max_size = BL31_LIMIT - BL31_BASE, + +# ifdef QEMU_LOAD_BL32 + .next_handoff_image_id = BL32_IMAGE_ID, +# else + .next_handoff_image_id = BL33_IMAGE_ID, +# endif + }, +#endif /* __aarch64__ */ +# ifdef QEMU_LOAD_BL32 + +#ifdef __aarch64__ +#define BL32_EP_ATTRIBS (SECURE | EXECUTABLE) +#define BL32_IMG_ATTRIBS 0 +#else +#define BL32_EP_ATTRIBS (SECURE | EXECUTABLE | EP_FIRST_EXE) +#define BL32_IMG_ATTRIBS IMAGE_ATTRIB_PLAT_SETUP +#endif + + /* Fill BL32 related information */ + { .image_id = BL32_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, + entry_point_info_t, BL32_EP_ATTRIBS), + .ep_info.pc = BL32_BASE, + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, + image_info_t, BL32_IMG_ATTRIBS), + + .image_info.image_base = BL32_BASE, + .image_info.image_max_size = BL32_LIMIT - BL32_BASE, + + .next_handoff_image_id = BL33_IMAGE_ID, + }, + + /* + * Fill BL32 external 1 related information. + * A typical use for extra1 image is with OP-TEE where it is the + * pager image. + */ + { .image_id = BL32_EXTRA1_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, + entry_point_info_t, SECURE | NON_EXECUTABLE), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, + image_info_t, IMAGE_ATTRIB_SKIP_LOADING), + .image_info.image_base = BL32_BASE, + .image_info.image_max_size = BL32_LIMIT - BL32_BASE, + + .next_handoff_image_id = INVALID_IMAGE_ID, + }, + + /* + * Fill BL32 external 2 related information. + * A typical use for extra2 image is with OP-TEE where it is the + * paged image. + */ + { .image_id = BL32_EXTRA2_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, + entry_point_info_t, SECURE | NON_EXECUTABLE), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, + image_info_t, IMAGE_ATTRIB_SKIP_LOADING), +#if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE) + .image_info.image_base = QEMU_OPTEE_PAGEABLE_LOAD_BASE, + .image_info.image_max_size = QEMU_OPTEE_PAGEABLE_LOAD_SIZE, +#endif + .next_handoff_image_id = INVALID_IMAGE_ID, + }, +# endif /* QEMU_LOAD_BL32 */ + + /* Fill BL33 related information */ + { .image_id = BL33_IMAGE_ID, + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, + entry_point_info_t, NON_SECURE | EXECUTABLE), +# ifdef PRELOADED_BL33_BASE + .ep_info.pc = PRELOADED_BL33_BASE, + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, image_info_t, + IMAGE_ATTRIB_SKIP_LOADING), +# else /* PRELOADED_BL33_BASE */ + .ep_info.pc = NS_IMAGE_OFFSET, + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, image_info_t, + 0), + .image_info.image_base = NS_IMAGE_OFFSET, + .image_info.image_max_size = NS_DRAM0_BASE + NS_DRAM0_SIZE - + NS_IMAGE_OFFSET, +# endif /* !PRELOADED_BL33_BASE */ + + .next_handoff_image_id = INVALID_IMAGE_ID, + } +#endif /* !EL3_PAYLOAD_BASE */ +}; + +REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs) diff --git a/plat/qemu/common/qemu_bl2_setup.c b/plat/qemu/common/qemu_bl2_setup.c new file mode 100644 index 0000000..166d245 --- /dev/null +++ b/plat/qemu/common/qemu_bl2_setup.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qemu_private.h" + + +/* Data structure which holds the extents of the trusted SRAM for BL2 */ +static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); + +void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + meminfo_t *mem_layout = (void *)arg1; + + /* Initialize the console to provide early debug support */ + qemu_console_init(); + + /* Setup the BL2 memory layout */ + bl2_tzram_layout = *mem_layout; + + plat_qemu_io_setup(); +} + +static void security_setup(void) +{ + /* + * This is where a TrustZone address space controller and other + * security related peripherals, would be configured. + */ +} + +static void update_dt(void) +{ + int ret; + void *fdt = (void *)(uintptr_t)PLAT_QEMU_DT_BASE; + + ret = fdt_open_into(fdt, fdt, PLAT_QEMU_DT_MAX_SIZE); + if (ret < 0) { + ERROR("Invalid Device Tree at %p: error %d\n", fdt, ret); + return; + } + + if (dt_add_psci_node(fdt)) { + ERROR("Failed to add PSCI Device Tree node\n"); + return; + } + + if (dt_add_psci_cpu_enable_methods(fdt)) { + ERROR("Failed to add PSCI cpu enable methods in Device Tree\n"); + return; + } + + ret = fdt_pack(fdt); + if (ret < 0) + ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, ret); +} + +void bl2_platform_setup(void) +{ + security_setup(); + update_dt(); + + /* TODO Initialize timer */ +} + +#ifdef __aarch64__ +#define QEMU_CONFIGURE_BL2_MMU(...) qemu_configure_mmu_el1(__VA_ARGS__) +#else +#define QEMU_CONFIGURE_BL2_MMU(...) qemu_configure_mmu_svc_mon(__VA_ARGS__) +#endif + +void bl2_plat_arch_setup(void) +{ + QEMU_CONFIGURE_BL2_MMU(bl2_tzram_layout.total_base, + bl2_tzram_layout.total_size, + BL_CODE_BASE, BL_CODE_END, + BL_RO_DATA_BASE, BL_RO_DATA_END, + BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END); +} + +/******************************************************************************* + * Gets SPSR for BL32 entry + ******************************************************************************/ +static uint32_t qemu_get_spsr_for_bl32_entry(void) +{ +#ifdef __aarch64__ + /* + * The Secure Payload Dispatcher service is responsible for + * setting the SPSR prior to entry into the BL3-2 image. + */ + return 0; +#else + return SPSR_MODE32(MODE32_svc, SPSR_T_ARM, SPSR_E_LITTLE, + DISABLE_ALL_EXCEPTIONS); +#endif +} + +/******************************************************************************* + * Gets SPSR for BL33 entry + ******************************************************************************/ +static uint32_t qemu_get_spsr_for_bl33_entry(void) +{ + uint32_t spsr; +#ifdef __aarch64__ + unsigned int mode; + + /* Figure out what mode we enter the non-secure world in */ + mode = (el_implemented(2) != EL_IMPL_NONE) ? MODE_EL2 : MODE_EL1; + + /* + * TODO: Consider the possibility of specifying the SPSR in + * the FIP ToC and allowing the platform to have a say as + * well. + */ + spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); +#else + spsr = SPSR_MODE32(MODE32_svc, + plat_get_ns_image_entrypoint() & 0x1, + SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS); +#endif + return spsr; +} + +static int qemu_bl2_handle_post_image_load(unsigned int image_id) +{ + int err = 0; + bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); +#if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE) + bl_mem_params_node_t *pager_mem_params = NULL; + bl_mem_params_node_t *paged_mem_params = NULL; +#endif + + assert(bl_mem_params); + + switch (image_id) { + case BL32_IMAGE_ID: +#if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE) + pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID); + assert(pager_mem_params); + + paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID); + assert(paged_mem_params); + + err = parse_optee_header(&bl_mem_params->ep_info, + &pager_mem_params->image_info, + &paged_mem_params->image_info); + if (err != 0) { + WARN("OPTEE header parse error.\n"); + } + +#if defined(SPD_opteed) + /* + * OP-TEE expect to receive DTB address in x2. + * This will be copied into x2 by dispatcher. + */ + bl_mem_params->ep_info.args.arg3 = PLAT_QEMU_DT_BASE; +#else /* case AARCH32_SP_OPTEE */ + bl_mem_params->ep_info.args.arg0 = + bl_mem_params->ep_info.args.arg1; + bl_mem_params->ep_info.args.arg1 = 0; + bl_mem_params->ep_info.args.arg2 = PLAT_QEMU_DT_BASE; + bl_mem_params->ep_info.args.arg3 = 0; +#endif +#endif + bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl32_entry(); + break; + + case BL33_IMAGE_ID: +#ifdef AARCH32_SP_OPTEE + /* AArch32 only core: OP-TEE expects NSec EP in register LR */ + pager_mem_params = get_bl_mem_params_node(BL32_IMAGE_ID); + assert(pager_mem_params); + pager_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc; +#endif + + /* BL33 expects to receive the primary CPU MPID (through r0) */ + bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); + bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl33_entry(); + break; + default: + /* Do nothing in default case */ + break; + } + + return err; +} + +/******************************************************************************* + * This function can be used by the platforms to update/use image + * information for given `image_id`. + ******************************************************************************/ +int bl2_plat_handle_post_image_load(unsigned int image_id) +{ + return qemu_bl2_handle_post_image_load(image_id); +} + +uintptr_t plat_get_ns_image_entrypoint(void) +{ + return NS_IMAGE_OFFSET; +} diff --git a/plat/qemu/common/qemu_bl31_setup.c b/plat/qemu/common/qemu_bl31_setup.c new file mode 100644 index 0000000..4d36b03 --- /dev/null +++ b/plat/qemu/common/qemu_bl31_setup.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#include "qemu_private.h" + +/* + * Placeholder variables for copying the arguments that have been passed to + * BL3-1 from BL2. + */ +static entry_point_info_t bl32_image_ep_info; +static entry_point_info_t bl33_image_ep_info; + +/******************************************************************************* + * Perform any BL3-1 early platform setup. Here is an opportunity to copy + * parameters passed by the calling EL (S-EL1 in BL2 & EL3 in BL1) before + * they are lost (potentially). This needs to be done before the MMU is + * initialized so that the memory layout can be used while creating page + * tables. BL2 has flushed this information to memory, so we are guaranteed + * to pick up good data. + ******************************************************************************/ +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + /* Initialize the console to provide early debug support */ + qemu_console_init(); + + /* + * Check params passed from BL2 + */ + bl_params_t *params_from_bl2 = (bl_params_t *)arg0; + + assert(params_from_bl2); + assert(params_from_bl2->h.type == PARAM_BL_PARAMS); + assert(params_from_bl2->h.version >= VERSION_2); + + bl_params_node_t *bl_params = params_from_bl2->head; + + /* + * Copy BL33 and BL32 (if present), entry point information. + * They are stored in Secure RAM, in BL2's address space. + */ + while (bl_params) { + if (bl_params->image_id == BL32_IMAGE_ID) + bl32_image_ep_info = *bl_params->ep_info; + + 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) + panic(); +} + +void bl31_plat_arch_setup(void) +{ + qemu_configure_mmu_el3(BL31_BASE, (BL31_END - BL31_BASE), + BL_CODE_BASE, BL_CODE_END, + BL_RO_DATA_BASE, BL_RO_DATA_END, + BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END); +} + +void bl31_platform_setup(void) +{ + plat_qemu_gic_init(); +} + +unsigned int plat_get_syscnt_freq2(void) +{ + return SYS_COUNTER_FREQ_IN_TICKS; +} + +/******************************************************************************* + * Return a pointer to the 'entry_point_info' structure of the next image + * for the security state specified. BL3-3 corresponds to the non-secure + * image type while BL3-2 corresponds to the secure image type. A NULL + * pointer is returned if the image does not exist. + ******************************************************************************/ +entry_point_info_t *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; + /* + * None of the images on the ARM development platforms can have 0x0 + * as the entrypoint + */ + if (next_image_info->pc) + return next_image_info; + else + return NULL; +} diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c new file mode 100644 index 0000000..56bf953 --- /dev/null +++ b/plat/qemu/common/qemu_common.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +#include "qemu_private.h" + +#define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \ + DEVICE0_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#ifdef DEVICE1_BASE +#define MAP_DEVICE1 MAP_REGION_FLAT(DEVICE1_BASE, \ + DEVICE1_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) +#endif + +#ifdef DEVICE2_BASE +#define MAP_DEVICE2 MAP_REGION_FLAT(DEVICE2_BASE, \ + DEVICE2_SIZE, \ + MT_DEVICE | MT_RO | MT_SECURE) +#endif + +#define MAP_SHARED_RAM MAP_REGION_FLAT(SHARED_RAM_BASE, \ + SHARED_RAM_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_BL32_MEM MAP_REGION_FLAT(BL32_MEM_BASE, BL32_MEM_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#define MAP_NS_DRAM0 MAP_REGION_FLAT(NS_DRAM0_BASE, NS_DRAM0_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + +#define MAP_FLASH0 MAP_REGION_FLAT(QEMU_FLASH0_BASE, QEMU_FLASH0_SIZE, \ + MT_MEMORY | MT_RO | MT_SECURE) + +/* + * Table of regions for various BL stages to map using the MMU. + * This doesn't include TZRAM as the 'mem_layout' argument passed to + * arm_configure_mmu_elx() will give the available subset of that, + */ +#ifdef IMAGE_BL1 +static const mmap_region_t plat_qemu_mmap[] = { + MAP_FLASH0, + MAP_SHARED_RAM, + MAP_DEVICE0, +#ifdef MAP_DEVICE1 + MAP_DEVICE1, +#endif +#ifdef MAP_DEVICE2 + MAP_DEVICE2, +#endif + {0} +}; +#endif +#ifdef IMAGE_BL2 +static const mmap_region_t plat_qemu_mmap[] = { + MAP_FLASH0, + MAP_SHARED_RAM, + MAP_DEVICE0, +#ifdef MAP_DEVICE1 + MAP_DEVICE1, +#endif +#ifdef MAP_DEVICE2 + MAP_DEVICE2, +#endif + MAP_NS_DRAM0, + MAP_BL32_MEM, + {0} +}; +#endif +#ifdef IMAGE_BL31 +static const mmap_region_t plat_qemu_mmap[] = { + MAP_SHARED_RAM, + MAP_DEVICE0, +#ifdef MAP_DEVICE1 + MAP_DEVICE1, +#endif + MAP_BL32_MEM, + {0} +}; +#endif +#ifdef IMAGE_BL32 +static const mmap_region_t plat_qemu_mmap[] = { + MAP_SHARED_RAM, + MAP_DEVICE0, +#ifdef MAP_DEVICE1 + MAP_DEVICE1, +#endif + {0} +}; +#endif + +/******************************************************************************* + * Macro generating the code for the function setting up the pagetables as per + * the platform memory map & initialize the mmu, for the given exception level + ******************************************************************************/ + +#define DEFINE_CONFIGURE_MMU_EL(_el) \ + void qemu_configure_mmu_##_el(unsigned long total_base, \ + unsigned long total_size, \ + unsigned long code_start, \ + unsigned long code_limit, \ + unsigned long ro_start, \ + unsigned long ro_limit, \ + unsigned long coh_start, \ + unsigned long coh_limit) \ + { \ + mmap_add_region(total_base, total_base, \ + total_size, \ + MT_MEMORY | MT_RW | MT_SECURE); \ + mmap_add_region(code_start, code_start, \ + code_limit - code_start, \ + MT_CODE | MT_SECURE); \ + mmap_add_region(ro_start, ro_start, \ + ro_limit - ro_start, \ + MT_RO_DATA | MT_SECURE); \ + mmap_add_region(coh_start, coh_start, \ + coh_limit - coh_start, \ + MT_DEVICE | MT_RW | MT_SECURE); \ + mmap_add(plat_qemu_mmap); \ + init_xlat_tables(); \ + \ + enable_mmu_##_el(0); \ + } + +/* Define EL1 and EL3 variants of the function initialising the MMU */ +#ifdef __aarch64__ +DEFINE_CONFIGURE_MMU_EL(el1) +DEFINE_CONFIGURE_MMU_EL(el3) +#else +DEFINE_CONFIGURE_MMU_EL(svc_mon) +#endif + + diff --git a/plat/qemu/common/qemu_console.c b/plat/qemu/common/qemu_console.c new file mode 100644 index 0000000..fec1828 --- /dev/null +++ b/plat/qemu/common/qemu_console.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +static console_pl011_t console; + +void qemu_console_init(void) +{ + (void)console_pl011_register(PLAT_QEMU_BOOT_UART_BASE, + PLAT_QEMU_BOOT_UART_CLK_IN_HZ, + PLAT_QEMU_CONSOLE_BAUDRATE, &console); + + console_set_scope(&console.console, CONSOLE_FLAG_BOOT | + CONSOLE_FLAG_RUNTIME); +} + diff --git a/plat/qemu/common/qemu_gicv2.c b/plat/qemu/common/qemu_gicv2.c new file mode 100644 index 0000000..fb56622 --- /dev/null +++ b/plat/qemu/common/qemu_gicv2.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +static const interrupt_prop_t qemu_interrupt_props[] = { + PLATFORM_G1S_PROPS(GICV2_INTR_GROUP0), + PLATFORM_G0_PROPS(GICV2_INTR_GROUP0) +}; + +static const struct gicv2_driver_data plat_gicv2_driver_data = { + .gicd_base = GICD_BASE, + .gicc_base = GICC_BASE, + .interrupt_props = qemu_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(qemu_interrupt_props), +}; + +void plat_qemu_gic_init(void) +{ + /* Initialize the gic cpu and distributor interfaces */ + gicv2_driver_init(&plat_gicv2_driver_data); + gicv2_distif_init(); + gicv2_pcpu_distif_init(); + gicv2_cpuif_enable(); +} + +void qemu_pwr_gic_on_finish(void) +{ + /* TODO: This setup is needed only after a cold boot */ + gicv2_pcpu_distif_init(); + + /* Enable the gic cpu interface */ + gicv2_cpuif_enable(); +} diff --git a/plat/qemu/common/qemu_gicv3.c b/plat/qemu/common/qemu_gicv3.c new file mode 100644 index 0000000..28572c5 --- /dev/null +++ b/plat/qemu/common/qemu_gicv3.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019, Linaro Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +static const interrupt_prop_t qemu_interrupt_props[] = { + PLATFORM_G1S_PROPS(INTR_GROUP1S), + PLATFORM_G0_PROPS(INTR_GROUP0) +}; + +static uintptr_t qemu_rdistif_base_addrs[PLATFORM_CORE_COUNT]; + +static unsigned int qemu_mpidr_to_core_pos(unsigned long mpidr) +{ + return (unsigned int)plat_core_pos_by_mpidr(mpidr); +} + +static const gicv3_driver_data_t qemu_gicv3_driver_data = { + .gicd_base = GICD_BASE, + .gicr_base = GICR_BASE, + .interrupt_props = qemu_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(qemu_interrupt_props), + .rdistif_num = PLATFORM_CORE_COUNT, + .rdistif_base_addrs = qemu_rdistif_base_addrs, + .mpidr_to_core_pos = qemu_mpidr_to_core_pos +}; + +void plat_qemu_gic_init(void) +{ + gicv3_driver_init(&qemu_gicv3_driver_data); + gicv3_distif_init(); + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); +} + +void qemu_pwr_gic_on_finish(void) +{ + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); +} diff --git a/plat/qemu/common/qemu_image_load.c b/plat/qemu/common/qemu_image_load.c new file mode 100644 index 0000000..9970d1d --- /dev/null +++ b/plat/qemu/common/qemu_image_load.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +/******************************************************************************* + * This function is a wrapper of a common function which flushes the data + * structures so that they are visible in memory for the next BL image. + ******************************************************************************/ +void plat_flush_next_bl_params(void) +{ + flush_bl_params_desc(); +} + +/******************************************************************************* + * This function is a wrapper of a common function which returns the list of + * loadable images. + ******************************************************************************/ +bl_load_info_t *plat_get_bl_image_load_info(void) +{ + return get_bl_load_info_from_mem_params_desc(); +} + +/******************************************************************************* + * This function is a wrapper of a common function which returns the data + * structures of the next BL image. + ******************************************************************************/ +bl_params_t *plat_get_next_bl_params(void) +{ + return get_next_bl_params_from_mem_params_desc(); +} diff --git a/plat/qemu/common/qemu_io_storage.c b/plat/qemu/common/qemu_io_storage.c new file mode 100644 index 0000000..0e81cd1 --- /dev/null +++ b/plat/qemu/common/qemu_io_storage.c @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Semihosting filenames */ +#define BL2_IMAGE_NAME "bl2.bin" +#define BL31_IMAGE_NAME "bl31.bin" +#define BL32_IMAGE_NAME "bl32.bin" +#define BL32_EXTRA1_IMAGE_NAME "bl32_extra1.bin" +#define BL32_EXTRA2_IMAGE_NAME "bl32_extra2.bin" +#define BL33_IMAGE_NAME "bl33.bin" + +#if TRUSTED_BOARD_BOOT +#define TRUSTED_BOOT_FW_CERT_NAME "tb_fw.crt" +#define TRUSTED_KEY_CERT_NAME "trusted_key.crt" +#define SOC_FW_KEY_CERT_NAME "soc_fw_key.crt" +#define TOS_FW_KEY_CERT_NAME "tos_fw_key.crt" +#define NT_FW_KEY_CERT_NAME "nt_fw_key.crt" +#define SOC_FW_CONTENT_CERT_NAME "soc_fw_content.crt" +#define TOS_FW_CONTENT_CERT_NAME "tos_fw_content.crt" +#define NT_FW_CONTENT_CERT_NAME "nt_fw_content.crt" +#endif /* TRUSTED_BOARD_BOOT */ + + + +/* IO devices */ +static const io_dev_connector_t *fip_dev_con; +static uintptr_t fip_dev_handle; +static const io_dev_connector_t *memmap_dev_con; +static uintptr_t memmap_dev_handle; +static const io_dev_connector_t *sh_dev_con; +static uintptr_t sh_dev_handle; + +static const io_block_spec_t fip_block_spec = { + .offset = PLAT_QEMU_FIP_BASE, + .length = PLAT_QEMU_FIP_MAX_SIZE +}; + +static const io_uuid_spec_t bl2_uuid_spec = { + .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, +}; + +static const io_uuid_spec_t bl31_uuid_spec = { + .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, +}; + +static const io_uuid_spec_t bl32_uuid_spec = { + .uuid = UUID_SECURE_PAYLOAD_BL32, +}; + +static const io_uuid_spec_t bl32_extra1_uuid_spec = { + .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, +}; + +static const io_uuid_spec_t bl32_extra2_uuid_spec = { + .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, +}; + +static const io_uuid_spec_t bl33_uuid_spec = { + .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, +}; + +#if TRUSTED_BOARD_BOOT +static const io_uuid_spec_t tb_fw_cert_uuid_spec = { + .uuid = UUID_TRUSTED_BOOT_FW_CERT, +}; + +static const io_uuid_spec_t trusted_key_cert_uuid_spec = { + .uuid = UUID_TRUSTED_KEY_CERT, +}; + +static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { + .uuid = UUID_SOC_FW_KEY_CERT, +}; + +static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { + .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, +}; + +static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { + .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, +}; + +static const io_uuid_spec_t soc_fw_cert_uuid_spec = { + .uuid = UUID_SOC_FW_CONTENT_CERT, +}; + +static const io_uuid_spec_t tos_fw_cert_uuid_spec = { + .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, +}; + +static const io_uuid_spec_t nt_fw_cert_uuid_spec = { + .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, +}; +#endif /* TRUSTED_BOARD_BOOT */ + +static const io_file_spec_t sh_file_spec[] = { + [BL2_IMAGE_ID] = { + .path = BL2_IMAGE_NAME, + .mode = FOPEN_MODE_RB + }, + [BL31_IMAGE_ID] = { + .path = BL31_IMAGE_NAME, + .mode = FOPEN_MODE_RB + }, + [BL32_IMAGE_ID] = { + .path = BL32_IMAGE_NAME, + .mode = FOPEN_MODE_RB + }, + [BL32_EXTRA1_IMAGE_ID] = { + .path = BL32_EXTRA1_IMAGE_NAME, + .mode = FOPEN_MODE_RB + }, + [BL32_EXTRA2_IMAGE_ID] = { + .path = BL32_EXTRA2_IMAGE_NAME, + .mode = FOPEN_MODE_RB + }, + [BL33_IMAGE_ID] = { + .path = BL33_IMAGE_NAME, + .mode = FOPEN_MODE_RB + }, +#if TRUSTED_BOARD_BOOT + [TRUSTED_BOOT_FW_CERT_ID] = { + .path = TRUSTED_BOOT_FW_CERT_NAME, + .mode = FOPEN_MODE_RB + }, + [TRUSTED_KEY_CERT_ID] = { + .path = TRUSTED_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB + }, + [SOC_FW_KEY_CERT_ID] = { + .path = SOC_FW_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB + }, + [TRUSTED_OS_FW_KEY_CERT_ID] = { + .path = TOS_FW_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB + }, + [NON_TRUSTED_FW_KEY_CERT_ID] = { + .path = NT_FW_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB + }, + [SOC_FW_CONTENT_CERT_ID] = { + .path = SOC_FW_CONTENT_CERT_NAME, + .mode = FOPEN_MODE_RB + }, + [TRUSTED_OS_FW_CONTENT_CERT_ID] = { + .path = TOS_FW_CONTENT_CERT_NAME, + .mode = FOPEN_MODE_RB + }, + [NON_TRUSTED_FW_CONTENT_CERT_ID] = { + .path = NT_FW_CONTENT_CERT_NAME, + .mode = FOPEN_MODE_RB + }, +#endif /* TRUSTED_BOARD_BOOT */ +}; + + + +static int open_fip(const uintptr_t spec); +static int open_memmap(const uintptr_t spec); + +struct plat_io_policy { + uintptr_t *dev_handle; + uintptr_t image_spec; + int (*check)(const uintptr_t spec); +}; + +/* By default, ARM platforms load images from the FIP */ +static const struct plat_io_policy policies[] = { + [FIP_IMAGE_ID] = { + &memmap_dev_handle, + (uintptr_t)&fip_block_spec, + open_memmap + }, + [BL2_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl2_uuid_spec, + open_fip + }, + [BL31_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl31_uuid_spec, + open_fip + }, + [BL32_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl32_uuid_spec, + open_fip + }, + [BL32_EXTRA1_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl32_extra1_uuid_spec, + open_fip + }, + [BL32_EXTRA2_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl32_extra2_uuid_spec, + open_fip + }, + [BL33_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl33_uuid_spec, + open_fip + }, +#if TRUSTED_BOARD_BOOT + [TRUSTED_BOOT_FW_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&tb_fw_cert_uuid_spec, + open_fip + }, + [TRUSTED_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&trusted_key_cert_uuid_spec, + open_fip + }, + [SOC_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&soc_fw_key_cert_uuid_spec, + open_fip + }, + [TRUSTED_OS_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&tos_fw_key_cert_uuid_spec, + open_fip + }, + [NON_TRUSTED_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&nt_fw_key_cert_uuid_spec, + open_fip + }, + [SOC_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&soc_fw_cert_uuid_spec, + open_fip + }, + [TRUSTED_OS_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&tos_fw_cert_uuid_spec, + open_fip + }, + [NON_TRUSTED_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&nt_fw_cert_uuid_spec, + open_fip + }, +#endif /* TRUSTED_BOARD_BOOT */ +}; + +static int open_fip(const uintptr_t spec) +{ + int result; + uintptr_t local_image_handle; + + /* See if a Firmware Image Package is available */ + result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); + if (result == 0) { + result = io_open(fip_dev_handle, spec, &local_image_handle); + if (result == 0) { + VERBOSE("Using FIP\n"); + io_close(local_image_handle); + } + } + return result; +} + +static int open_memmap(const uintptr_t spec) +{ + int result; + uintptr_t local_image_handle; + + result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); + if (result == 0) { + result = io_open(memmap_dev_handle, spec, &local_image_handle); + if (result == 0) { + VERBOSE("Using Memmap\n"); + io_close(local_image_handle); + } + } + return result; +} + +static int open_semihosting(const uintptr_t spec) +{ + int result; + uintptr_t local_image_handle; + + /* See if the file exists on semi-hosting.*/ + result = io_dev_init(sh_dev_handle, (uintptr_t)NULL); + if (result == 0) { + result = io_open(sh_dev_handle, spec, &local_image_handle); + if (result == 0) { + VERBOSE("Using Semi-hosting IO\n"); + io_close(local_image_handle); + } + } + return result; +} + +void plat_qemu_io_setup(void) +{ + int io_result; + + io_result = register_io_dev_fip(&fip_dev_con); + assert(io_result == 0); + + io_result = register_io_dev_memmap(&memmap_dev_con); + assert(io_result == 0); + + /* Open connections to devices and cache the handles */ + io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, + &fip_dev_handle); + assert(io_result == 0); + + io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, + &memmap_dev_handle); + assert(io_result == 0); + + /* Register the additional IO devices on this platform */ + io_result = register_io_dev_sh(&sh_dev_con); + assert(io_result == 0); + + /* Open connections to devices and cache the handles */ + io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle); + assert(io_result == 0); + + /* Ignore improbable errors in release builds */ + (void)io_result; +} + +static int get_alt_image_source(unsigned int image_id, uintptr_t *dev_handle, + uintptr_t *image_spec) +{ + int result = open_semihosting((const uintptr_t)&sh_file_spec[image_id]); + + if (result == 0) { + *dev_handle = sh_dev_handle; + *image_spec = (uintptr_t)&sh_file_spec[image_id]; + } + + return result; +} + +/* + * Return an IO device handle and specification which can be used to access + * an image. Use this to enforce platform load policy + */ +int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, + uintptr_t *image_spec) +{ + int result; + const struct plat_io_policy *policy; + + assert(image_id < ARRAY_SIZE(policies)); + + policy = &policies[image_id]; + result = policy->check(policy->image_spec); + if (result == 0) { + *image_spec = policy->image_spec; + *dev_handle = *(policy->dev_handle); + } else { + VERBOSE("Trying alternative IO\n"); + result = get_alt_image_source(image_id, dev_handle, image_spec); + } + + return result; +} diff --git a/plat/qemu/common/qemu_pm.c b/plat/qemu/common/qemu_pm.c new file mode 100644 index 0000000..a199688 --- /dev/null +++ b/plat/qemu/common/qemu_pm.c @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include + +#include "qemu_private.h" + +/* + * The secure entry point to be used on warm reset. + */ +static unsigned long secure_entrypoint; + +/* Make composite power state parameter till power level 0 */ +#if PSCI_EXTENDED_STATE_ID + +#define qemu_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type) \ + (((lvl0_state) << PSTATE_ID_SHIFT) | \ + ((type) << PSTATE_TYPE_SHIFT)) +#else +#define qemu_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type) \ + (((lvl0_state) << PSTATE_ID_SHIFT) | \ + ((pwr_lvl) << PSTATE_PWR_LVL_SHIFT) | \ + ((type) << PSTATE_TYPE_SHIFT)) +#endif /* PSCI_EXTENDED_STATE_ID */ + + +#define qemu_make_pwrstate_lvl1(lvl1_state, lvl0_state, pwr_lvl, type) \ + (((lvl1_state) << PLAT_LOCAL_PSTATE_WIDTH) | \ + qemu_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type)) + + + +/* + * The table storing the valid idle power states. Ensure that the + * array entries are populated in ascending order of state-id to + * enable us to use binary search during power state validation. + * The table must be terminated by a NULL entry. + */ +static const unsigned int qemu_pm_idle_states[] = { + /* State-id - 0x01 */ + qemu_make_pwrstate_lvl1(PLAT_LOCAL_STATE_RUN, PLAT_LOCAL_STATE_RET, + MPIDR_AFFLVL0, PSTATE_TYPE_STANDBY), + /* State-id - 0x02 */ + qemu_make_pwrstate_lvl1(PLAT_LOCAL_STATE_RUN, PLAT_LOCAL_STATE_OFF, + MPIDR_AFFLVL0, PSTATE_TYPE_POWERDOWN), + /* State-id - 0x22 */ + qemu_make_pwrstate_lvl1(PLAT_LOCAL_STATE_OFF, PLAT_LOCAL_STATE_OFF, + MPIDR_AFFLVL1, PSTATE_TYPE_POWERDOWN), + 0, +}; + +/******************************************************************************* + * Platform handler called to check the validity of the power state + * parameter. The power state parameter has to be a composite power state. + ******************************************************************************/ +static int qemu_validate_power_state(unsigned int power_state, + psci_power_state_t *req_state) +{ + unsigned int state_id; + int i; + + assert(req_state); + + /* + * Currently we are using a linear search for finding the matching + * entry in the idle power state array. This can be made a binary + * search if the number of entries justify the additional complexity. + */ + for (i = 0; !!qemu_pm_idle_states[i]; i++) { + if (power_state == qemu_pm_idle_states[i]) + break; + } + + /* Return error if entry not found in the idle state array */ + if (!qemu_pm_idle_states[i]) + return PSCI_E_INVALID_PARAMS; + + i = 0; + state_id = psci_get_pstate_id(power_state); + + /* Parse the State ID and populate the state info parameter */ + while (state_id) { + req_state->pwr_domain_state[i++] = state_id & + PLAT_LOCAL_PSTATE_MASK; + state_id >>= PLAT_LOCAL_PSTATE_WIDTH; + } + + return PSCI_E_SUCCESS; +} + +/******************************************************************************* + * Platform handler called to check the validity of the non secure + * entrypoint. + ******************************************************************************/ +static int qemu_validate_ns_entrypoint(uintptr_t entrypoint) +{ + /* + * Check if the non secure entrypoint lies within the non + * secure DRAM. + */ + if ((entrypoint >= NS_DRAM0_BASE) && + (entrypoint < (NS_DRAM0_BASE + NS_DRAM0_SIZE))) + return PSCI_E_SUCCESS; + return PSCI_E_INVALID_ADDRESS; +} + +/******************************************************************************* + * Platform handler called when a CPU is about to enter standby. + ******************************************************************************/ +static void qemu_cpu_standby(plat_local_state_t cpu_state) +{ + + assert(cpu_state == PLAT_LOCAL_STATE_RET); + + /* + * Enter standby state + * dsb is good practice before using wfi to enter low power states + */ + dsb(); + wfi(); +} + +/******************************************************************************* + * Platform handler called when a power domain is about to be turned on. The + * mpidr determines the CPU to be turned on. + ******************************************************************************/ +static int qemu_pwr_domain_on(u_register_t mpidr) +{ + int rc = PSCI_E_SUCCESS; + unsigned pos = plat_core_pos_by_mpidr(mpidr); + uint64_t *hold_base = (uint64_t *)PLAT_QEMU_HOLD_BASE; + + hold_base[pos] = PLAT_QEMU_HOLD_STATE_GO; + sev(); + + return rc; +} + +/******************************************************************************* + * Platform handler called when a power domain is about to be turned off. The + * target_state encodes the power state that each level should transition to. + ******************************************************************************/ +void qemu_pwr_domain_off(const psci_power_state_t *target_state) +{ + assert(0); +} + +/******************************************************************************* + * Platform handler called when a power domain is about to be suspended. The + * target_state encodes the power state that each level should transition to. + ******************************************************************************/ +void qemu_pwr_domain_suspend(const psci_power_state_t *target_state) +{ + assert(0); +} + +/******************************************************************************* + * Platform handler called when a power domain has just been powered on after + * being turned off earlier. The target_state encodes the low power state that + * each level has woken up from. + ******************************************************************************/ +void qemu_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] == + PLAT_LOCAL_STATE_OFF); + + qemu_pwr_gic_on_finish(); +} + +/******************************************************************************* + * Platform handler called when a power domain has just been powered on after + * having been suspended earlier. The target_state encodes the low power state + * that each level has woken up from. + ******************************************************************************/ +void qemu_pwr_domain_suspend_finish(const psci_power_state_t *target_state) +{ + assert(0); +} + +/******************************************************************************* + * Platform handlers to shutdown/reboot the system + ******************************************************************************/ +static void __dead2 qemu_system_off(void) +{ + ERROR("QEMU System Off: operation not handled.\n"); + panic(); +} + +static void __dead2 qemu_system_reset(void) +{ + ERROR("QEMU System Reset: operation not handled.\n"); + panic(); +} + +static const plat_psci_ops_t plat_qemu_psci_pm_ops = { + .cpu_standby = qemu_cpu_standby, + .pwr_domain_on = qemu_pwr_domain_on, + .pwr_domain_off = qemu_pwr_domain_off, + .pwr_domain_suspend = qemu_pwr_domain_suspend, + .pwr_domain_on_finish = qemu_pwr_domain_on_finish, + .pwr_domain_suspend_finish = qemu_pwr_domain_suspend_finish, + .system_off = qemu_system_off, + .system_reset = qemu_system_reset, + .validate_power_state = qemu_validate_power_state, + .validate_ns_entrypoint = qemu_validate_ns_entrypoint +}; + +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + uintptr_t *mailbox = (void *) PLAT_QEMU_TRUSTED_MAILBOX_BASE; + + *mailbox = sec_entrypoint; + secure_entrypoint = (unsigned long) sec_entrypoint; + *psci_ops = &plat_qemu_psci_pm_ops; + + return 0; +} diff --git a/plat/qemu/common/qemu_private.h b/plat/qemu/common/qemu_private.h new file mode 100644 index 0000000..71ea4de --- /dev/null +++ b/plat/qemu/common/qemu_private.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef QEMU_PRIVATE_H +#define QEMU_PRIVATE_H + +#include + +void qemu_configure_mmu_svc_mon(unsigned long total_base, + unsigned long total_size, + unsigned long code_start, unsigned long code_limit, + unsigned long ro_start, unsigned long ro_limit, + unsigned long coh_start, unsigned long coh_limit); + +void qemu_configure_mmu_el1(unsigned long total_base, unsigned long total_size, + unsigned long code_start, unsigned long code_limit, + unsigned long ro_start, unsigned long ro_limit, + unsigned long coh_start, unsigned long coh_limit); + +void qemu_configure_mmu_el3(unsigned long total_base, unsigned long total_size, + unsigned long code_start, unsigned long code_limit, + unsigned long ro_start, unsigned long ro_limit, + unsigned long coh_start, unsigned long coh_limit); + +void plat_qemu_io_setup(void); +unsigned int plat_qemu_calc_core_pos(u_register_t mpidr); + +void qemu_console_init(void); + +void plat_qemu_gic_init(void); +void qemu_pwr_gic_on_finish(void); + +#endif /* QEMU_PRIVATE_H */ diff --git a/plat/qemu/common/qemu_rotpk.S b/plat/qemu/common/qemu_rotpk.S new file mode 100644 index 0000000..5d1b83f --- /dev/null +++ b/plat/qemu/common/qemu_rotpk.S @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + .global qemu_rotpk_hash + .global qemu_rotpk_hash_end +qemu_rotpk_hash: + /* DER header */ + .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48 + .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 + /* SHA256 */ + .incbin ROTPK_HASH +qemu_rotpk_hash_end: diff --git a/plat/qemu/common/qemu_stack_protector.c b/plat/qemu/common/qemu_stack_protector.c new file mode 100644 index 0000000..c226158 --- /dev/null +++ b/plat/qemu/common/qemu_stack_protector.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#define RANDOM_CANARY_VALUE ((u_register_t) 3288484550995823360ULL) + +u_register_t plat_get_stack_protector_canary(void) +{ + /* + * Ideally, a random number should be returned instead of the + * combination of a timer's value and a compile-time constant. + * As the virt platform does not have any random number generator, + * this is better than nothing but not necessarily really secure. + */ + return RANDOM_CANARY_VALUE ^ read_cntpct_el0(); +} + diff --git a/plat/qemu/common/qemu_trusted_boot.c b/plat/qemu/common/qemu_trusted_boot.c new file mode 100644 index 0000000..1ef7e43 --- /dev/null +++ b/plat/qemu/common/qemu_trusted_boot.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +extern char qemu_rotpk_hash[], qemu_rotpk_hash_end[]; + +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + *key_ptr = qemu_rotpk_hash; + *key_len = qemu_rotpk_hash_end - qemu_rotpk_hash; + *flags = ROTPK_IS_HASH; + + return 0; +} + +int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr) +{ + *nv_ctr = 0; + + return 0; +} + +int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) +{ + return 1; +} + +int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size) +{ + return get_mbedtls_heap_helper(heap_addr, heap_size); +} diff --git a/plat/qemu/common/sp_min/sp_min-qemu.mk b/plat/qemu/common/sp_min/sp_min-qemu.mk new file mode 100644 index 0000000..e93a0c2 --- /dev/null +++ b/plat/qemu/common/sp_min/sp_min-qemu.mk @@ -0,0 +1,22 @@ +# +# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +BL32_SOURCES += plat/qemu/sp_min/sp_min_setup.c \ + plat/qemu/aarch32/plat_helpers.S \ + plat/qemu/qemu_pm.c \ + plat/qemu/topology.c + +BL32_SOURCES += lib/cpus/aarch32/aem_generic.S \ + lib/cpus/aarch32/cortex_a15.S + +BL32_SOURCES += plat/common/aarch32/platform_mp_stack.S \ + plat/common/plat_psci_common.c \ + plat/common/plat_gicv2.c + + +BL32_SOURCES += drivers/arm/gic/v2/gicv2_helpers.c \ + drivers/arm/gic/v2/gicv2_main.c \ + drivers/arm/gic/common/gic_common.c diff --git a/plat/qemu/common/sp_min/sp_min_setup.c b/plat/qemu/common/sp_min/sp_min_setup.c new file mode 100644 index 0000000..7ec657b --- /dev/null +++ b/plat/qemu/common/sp_min/sp_min_setup.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../qemu_private.h" + +#if RESET_TO_SP_MIN +#error qemu does not support RESET_TO_SP_MIN +#endif + +static entry_point_info_t bl33_image_ep_info; + +/****************************************************************************** + * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0 + * interrupts. + *****************************************************************************/ +#define PLATFORM_G1S_PROPS(grp) \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_LEVEL) + +#define PLATFORM_G0_PROPS(grp) + +static const interrupt_prop_t stih410_interrupt_props[] = { + PLATFORM_G1S_PROPS(GICV2_INTR_GROUP0), + PLATFORM_G0_PROPS(GICV2_INTR_GROUP0) +}; + +static unsigned int target_mask_array[PLATFORM_CORE_COUNT]; + +static const struct gicv2_driver_data plat_gicv2_driver_data = { + .gicd_base = GICD_BASE, + .gicc_base = GICC_BASE, + .interrupt_props = stih410_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(stih410_interrupt_props), + .target_masks = target_mask_array, + .target_masks_num = ARRAY_SIZE(target_mask_array), +}; + +/******************************************************************************* + * Return a pointer to the 'entry_point_info' structure of the next image for + * the security state specified. BL33 corresponds to the non-secure image type + * while BL32 corresponds to the secure image type. A NULL pointer is returned + * if the image does not exist. + ******************************************************************************/ +entry_point_info_t *sp_min_plat_get_bl33_ep_info(void) +{ + entry_point_info_t *next_image_info = &bl33_image_ep_info; + + /* + * None of the images on the ARM development platforms can have 0x0 + * as the entrypoint + */ + if (next_image_info->pc) + return next_image_info; + else + return NULL; +} + +void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + bl_params_t *params_from_bl2 = (bl_params_t *)arg0; + + /* Initialize the console to provide early debug support */ + qemu_console_init(); + + ERROR("qemu sp_min, console init\n"); + /* + * Check params passed from BL2 + */ + assert(params_from_bl2); + assert(params_from_bl2->h.type == PARAM_BL_PARAMS); + assert(params_from_bl2->h.version >= VERSION_2); + + bl_params_node_t *bl_params = params_from_bl2->head; + + /* + * Copy BL33 entry point information from BL2's address space. + */ + while (bl_params) { + 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) + panic(); +} + +void sp_min_plat_arch_setup(void) +{ + qemu_configure_mmu_svc_mon(BL32_RO_BASE, BL32_END - BL32_RO_BASE, + BL_CODE_BASE, BL_CODE_END, + BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END); + +} + +void sp_min_platform_setup(void) +{ + /* Initialize the gic cpu and distributor interfaces */ + gicv2_driver_init(&plat_gicv2_driver_data); + gicv2_distif_init(); + gicv2_pcpu_distif_init(); + gicv2_cpuif_enable(); +} + +unsigned int plat_get_syscnt_freq2(void) +{ + return SYS_COUNTER_FREQ_IN_TICKS; +} + +void sp_min_plat_fiq_handler(uint32_t id) +{ + VERBOSE("[sp_min] interrupt #%d\n", id); +} diff --git a/plat/qemu/common/topology.c b/plat/qemu/common/topology.c new file mode 100644 index 0000000..6352706 --- /dev/null +++ b/plat/qemu/common/topology.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include + +#include "qemu_private.h" + +/* The power domain tree descriptor */ +static unsigned char power_domain_tree_desc[] = { + /* Number of root nodes */ + PLATFORM_CLUSTER_COUNT, + /* Number of children for the first node */ + PLATFORM_CLUSTER0_CORE_COUNT, + /* Number of children for the second node */ + PLATFORM_CLUSTER1_CORE_COUNT, +}; + +/******************************************************************************* + * This function returns the ARM default topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return power_domain_tree_desc; +} + +/******************************************************************************* + * This function implements a part of the critical interface between the psci + * generic layer and the platform that allows the former to query the platform + * to convert an MPIDR to a unique linear index. An error code (-1) is returned + * in case the MPIDR is invalid. + ******************************************************************************/ +int plat_core_pos_by_mpidr(u_register_t mpidr) +{ + unsigned int cluster_id, cpu_id; + + mpidr &= MPIDR_AFFINITY_MASK; + if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) + return -1; + + cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; + cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK; + + if (cluster_id >= PLATFORM_CLUSTER_COUNT) + return -1; + + if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER) + return -1; + + return plat_qemu_calc_core_pos(mpidr); +} diff --git a/plat/qemu/include/plat_macros.S b/plat/qemu/include/plat_macros.S deleted file mode 100644 index b6cdb07..0000000 --- a/plat/qemu/include/plat_macros.S +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -#ifndef PLAT_MACROS_S -#define PLAT_MACROS_S - -#include -#include - - /* --------------------------------------------- - * The below required platform porting macro - * prints out relevant GIC and CCI registers - * whenever an unhandled exception is taken in - * BL31. - * Clobbers: x0 - x10, x16, x17, sp - * --------------------------------------------- - */ - .macro plat_crash_print_regs - mov_imm x17, GICC_BASE - mov_imm x16, GICD_BASE - arm_print_gic_regs - .endm - -#endif /* PLAT_MACROS_S */ diff --git a/plat/qemu/include/platform_def.h b/plat/qemu/include/platform_def.h deleted file mode 100644 index d7f77cc..0000000 --- a/plat/qemu/include/platform_def.h +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef PLATFORM_DEF_H -#define PLATFORM_DEF_H - -#include -#include -#include -#include - -/* Special value used to verify platform parameters from BL2 to BL3-1 */ -#define QEMU_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL - -#define PLATFORM_STACK_SIZE 0x1000 - -#if ARM_ARCH_MAJOR == 7 -#define PLATFORM_MAX_CPUS_PER_CLUSTER 4 -#define PLATFORM_CLUSTER_COUNT 1 -#define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER -#define PLATFORM_CLUSTER1_CORE_COUNT 0 -#else -#define PLATFORM_MAX_CPUS_PER_CLUSTER 4 -#define PLATFORM_CLUSTER_COUNT 2 -#define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER -#define PLATFORM_CLUSTER1_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER -#endif -#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT + \ - PLATFORM_CLUSTER1_CORE_COUNT) - -#define QEMU_PRIMARY_CPU 0 - -#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \ - PLATFORM_CORE_COUNT) -#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 - -#define PLAT_MAX_RET_STATE U(1) -#define PLAT_MAX_OFF_STATE U(2) - -/* Local power state for power domains in Run state. */ -#define PLAT_LOCAL_STATE_RUN U(0) -/* Local power state for retention. Valid only for CPU power domains */ -#define PLAT_LOCAL_STATE_RET U(1) -/* - * Local power state for OFF/power-down. Valid for CPU and cluster power - * domains. - */ -#define PLAT_LOCAL_STATE_OFF 2 - -/* - * Macros used to parse state information from State-ID if it is using the - * recommended encoding for State-ID. - */ -#define PLAT_LOCAL_PSTATE_WIDTH 4 -#define PLAT_LOCAL_PSTATE_MASK ((1 << PLAT_LOCAL_PSTATE_WIDTH) - 1) - -/* - * Some data must be aligned on the biggest cache line size in the platform. - * This is known only to the platform as it might have a combination of - * integrated and external caches. - */ -#define CACHE_WRITEBACK_SHIFT 6 -#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT) - -/* - * Partition memory into secure ROM, non-secure DRAM, secure "SRAM", - * and secure DRAM. - */ -#define SEC_ROM_BASE 0x00000000 -#define SEC_ROM_SIZE 0x00020000 - -#define NS_DRAM0_BASE 0x40000000 -#define NS_DRAM0_SIZE 0x3de00000 - -#define SEC_SRAM_BASE 0x0e000000 -#define SEC_SRAM_SIZE 0x00060000 - -#define SEC_DRAM_BASE 0x0e100000 -#define SEC_DRAM_SIZE 0x00f00000 - -/* Load pageable part of OP-TEE 2MB above secure DRAM base */ -#define QEMU_OPTEE_PAGEABLE_LOAD_BASE (SEC_DRAM_BASE + 0x00200000) -#define QEMU_OPTEE_PAGEABLE_LOAD_SIZE 0x00400000 - -/* - * ARM-TF lives in SRAM, partition it here - */ - -#define SHARED_RAM_BASE SEC_SRAM_BASE -#define SHARED_RAM_SIZE 0x00001000 - -#define PLAT_QEMU_TRUSTED_MAILBOX_BASE SHARED_RAM_BASE -#define PLAT_QEMU_TRUSTED_MAILBOX_SIZE (8 + PLAT_QEMU_HOLD_SIZE) -#define PLAT_QEMU_HOLD_BASE (PLAT_QEMU_TRUSTED_MAILBOX_BASE + 8) -#define PLAT_QEMU_HOLD_SIZE (PLATFORM_CORE_COUNT * \ - PLAT_QEMU_HOLD_ENTRY_SIZE) -#define PLAT_QEMU_HOLD_ENTRY_SHIFT 3 -#define PLAT_QEMU_HOLD_ENTRY_SIZE (1 << PLAT_QEMU_HOLD_ENTRY_SHIFT) -#define PLAT_QEMU_HOLD_STATE_WAIT 0 -#define PLAT_QEMU_HOLD_STATE_GO 1 - -#define BL_RAM_BASE (SHARED_RAM_BASE + SHARED_RAM_SIZE) -#define BL_RAM_SIZE (SEC_SRAM_SIZE - SHARED_RAM_SIZE) - -/* - * BL1 specific defines. - * - * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of - * addresses. - * 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_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_LIMIT (BL_RAM_BASE + BL_RAM_SIZE) - -/* - * BL2 specific defines. - * - * 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 - 0x25000) -#define BL2_LIMIT BL31_BASE - -/* - * BL3-1 specific defines. - * - * 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_PROGBITS_LIMIT BL1_RW_BASE - - -/* - * BL3-2 specific defines. - * - * 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 SEC_SRAM_ID 0 -#define SEC_DRAM_ID 1 - -#if BL32_RAM_LOCATION_ID == SEC_SRAM_ID -# define BL32_MEM_BASE BL_RAM_BASE -# define BL32_MEM_SIZE BL_RAM_SIZE -# define BL32_BASE BL32_SRAM_BASE -# define BL32_LIMIT BL32_SRAM_LIMIT -#elif BL32_RAM_LOCATION_ID == SEC_DRAM_ID -# define BL32_MEM_BASE SEC_DRAM_BASE -# define BL32_MEM_SIZE SEC_DRAM_SIZE -# define BL32_BASE BL32_DRAM_BASE -# define BL32_LIMIT BL32_DRAM_LIMIT -#else -# error "Unsupported BL32_RAM_LOCATION_ID value" -#endif - -#define NS_IMAGE_OFFSET 0x60000000 - -#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) -#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) -#define MAX_MMAP_REGIONS 10 -#define MAX_XLAT_TABLES 6 -#define MAX_IO_DEVICES 3 -#define MAX_IO_HANDLES 4 - -/* - * PL011 related constants - */ -#define UART0_BASE 0x09000000 -#define UART1_BASE 0x09040000 -#define UART0_CLK_IN_HZ 1 -#define UART1_CLK_IN_HZ 1 - -#define PLAT_QEMU_BOOT_UART_BASE UART0_BASE -#define PLAT_QEMU_BOOT_UART_CLK_IN_HZ UART0_CLK_IN_HZ - -#define PLAT_QEMU_CRASH_UART_BASE UART1_BASE -#define PLAT_QEMU_CRASH_UART_CLK_IN_HZ UART1_CLK_IN_HZ - -#define PLAT_QEMU_CONSOLE_BAUDRATE 115200 - -#define QEMU_FLASH0_BASE 0x04000000 -#define QEMU_FLASH0_SIZE 0x04000000 - -#define PLAT_QEMU_FIP_BASE QEMU_FLASH0_BASE -#define PLAT_QEMU_FIP_MAX_SIZE QEMU_FLASH0_SIZE - -#define DEVICE0_BASE 0x08000000 -#define DEVICE0_SIZE 0x01000000 -#define DEVICE1_BASE 0x09000000 -#define DEVICE1_SIZE 0x00041000 - -/* - * GIC related constants - */ - -#define GICD_BASE 0x8000000 -#define GICC_BASE 0x8010000 -#define GICR_BASE 0x80A0000 - - -#define QEMU_IRQ_SEC_SGI_0 8 -#define QEMU_IRQ_SEC_SGI_1 9 -#define QEMU_IRQ_SEC_SGI_2 10 -#define QEMU_IRQ_SEC_SGI_3 11 -#define QEMU_IRQ_SEC_SGI_4 12 -#define QEMU_IRQ_SEC_SGI_5 13 -#define QEMU_IRQ_SEC_SGI_6 14 -#define QEMU_IRQ_SEC_SGI_7 15 - -/****************************************************************************** - * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0 - * interrupts. - *****************************************************************************/ -#define PLATFORM_G1S_PROPS(grp) \ - INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, \ - grp, GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, \ - grp, GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, \ - grp, GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, \ - grp, GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, \ - grp, GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, \ - grp, GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, \ - grp, GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, \ - grp, GIC_INTR_CFG_EDGE) - -#define PLATFORM_G0_PROPS(grp) - -/* - * DT related constants - */ -#define PLAT_QEMU_DT_BASE NS_DRAM0_BASE -#define PLAT_QEMU_DT_MAX_SIZE 0x100000 - -/* - * System counter - */ -#define SYS_COUNTER_FREQ_IN_TICKS ((1000 * 1000 * 1000) / 16) - -#endif /* PLATFORM_DEF_H */ diff --git a/plat/qemu/platform.mk b/plat/qemu/platform.mk deleted file mode 100644 index bc4a21b..0000000 --- a/plat/qemu/platform.mk +++ /dev/null @@ -1,186 +0,0 @@ -# -# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause -# - -# Use the GICv2 driver on QEMU by default -QEMU_USE_GIC_DRIVER := QEMU_GICV2 - -ifeq (${ARM_ARCH_MAJOR},7) -# ARMv7 Qemu support in trusted firmware expects the Cortex-A15 model. -# Qemu Cortex-A15 model does not implement the virtualization extension. -# For this reason, we cannot set ARM_CORTEX_A15=yes and must define all -# the ARMv7 build directives. -MARCH32_DIRECTIVE := -mcpu=cortex-a15 -$(eval $(call add_define,ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING)) -$(eval $(call add_define,ARMV7_SUPPORTS_GENERIC_TIMER)) -# Qemu expects a BL32 boot stage. -NEED_BL32 := yes -endif # ARMv7 - -ifeq (${SPD},opteed) -add-lib-optee := yes -endif -ifeq ($(AARCH32_SP),optee) -add-lib-optee := yes -endif - -include lib/libfdt/libfdt.mk - -ifeq ($(NEED_BL32),yes) -$(eval $(call add_define,QEMU_LOAD_BL32)) -endif - -PLAT_PATH := plat/qemu/ -PLAT_INCLUDES := -Iplat/qemu/include - -ifeq (${ARM_ARCH_MAJOR},8) -PLAT_INCLUDES += -Iinclude/plat/arm/common/${ARCH} -endif - -PLAT_BL_COMMON_SOURCES := plat/qemu/qemu_common.c \ - plat/qemu/qemu_console.c \ - drivers/arm/pl011/${ARCH}/pl011_console.S \ - -include lib/xlat_tables_v2/xlat_tables.mk -PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} - -ifneq (${TRUSTED_BOARD_BOOT},0) - - include drivers/auth/mbedtls/mbedtls_crypto.mk - include drivers/auth/mbedtls/mbedtls_x509.mk - - AUTH_SOURCES := drivers/auth/auth_mod.c \ - drivers/auth/crypto_mod.c \ - drivers/auth/img_parser_mod.c \ - drivers/auth/tbbr/tbbr_cot.c - - BL1_SOURCES += ${AUTH_SOURCES} \ - bl1/tbbr/tbbr_img_desc.c \ - plat/common/tbbr/plat_tbbr.c \ - plat/qemu/qemu_trusted_boot.c \ - $(PLAT_PATH)/qemu_rotpk.S - - BL2_SOURCES += ${AUTH_SOURCES} \ - plat/common/tbbr/plat_tbbr.c \ - plat/qemu/qemu_trusted_boot.c \ - $(PLAT_PATH)/qemu_rotpk.S - - ROT_KEY = $(BUILD_PLAT)/rot_key.pem - ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin - - $(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"')) - - $(BUILD_PLAT)/bl1/qemu_rotpk.o: $(ROTPK_HASH) - $(BUILD_PLAT)/bl2/qemu_rotpk.o: $(ROTPK_HASH) - - certificates: $(ROT_KEY) - - $(ROT_KEY): - @echo " OPENSSL $@" - $(Q)openssl genrsa 2048 > $@ 2>/dev/null - - $(ROTPK_HASH): $(ROT_KEY) - @echo " OPENSSL $@" - $(Q)openssl rsa -in $< -pubout -outform DER 2>/dev/null |\ - openssl dgst -sha256 -binary > $@ 2>/dev/null -endif - -BL1_SOURCES += drivers/io/io_semihosting.c \ - drivers/io/io_storage.c \ - drivers/io/io_fip.c \ - drivers/io/io_memmap.c \ - lib/semihosting/semihosting.c \ - lib/semihosting/${ARCH}/semihosting_call.S \ - plat/qemu/qemu_io_storage.c \ - plat/qemu/${ARCH}/plat_helpers.S \ - plat/qemu/qemu_bl1_setup.c - -ifeq (${ARM_ARCH_MAJOR},8) -BL1_SOURCES += lib/cpus/aarch64/aem_generic.S \ - lib/cpus/aarch64/cortex_a53.S \ - lib/cpus/aarch64/cortex_a57.S -else -BL1_SOURCES += lib/cpus/${ARCH}/cortex_a15.S -endif - -BL2_SOURCES += drivers/io/io_semihosting.c \ - drivers/io/io_storage.c \ - drivers/io/io_fip.c \ - drivers/io/io_memmap.c \ - lib/semihosting/semihosting.c \ - lib/semihosting/${ARCH}/semihosting_call.S\ - plat/qemu/qemu_io_storage.c \ - plat/qemu/${ARCH}/plat_helpers.S \ - plat/qemu/qemu_bl2_setup.c \ - common/fdt_fixup.c \ - plat/qemu/qemu_bl2_mem_params_desc.c \ - plat/qemu/qemu_image_load.c \ - common/desc_image_load.c - -ifeq ($(add-lib-optee),yes) -BL2_SOURCES += lib/optee/optee_utils.c -endif - -QEMU_GICV2_SOURCES := drivers/arm/gic/v2/gicv2_helpers.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/common/gic_common.c \ - plat/common/plat_gicv2.c \ - plat/qemu/qemu_gicv2.c - -QEMU_GICV3_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gicv3_main.c \ - drivers/arm/gic/common/gic_common.c \ - plat/common/plat_gicv3.c \ - plat/qemu/qemu_gicv3.c - -ifeq (${QEMU_USE_GIC_DRIVER}, QEMU_GICV2) -QEMU_GIC_SOURCES := ${QEMU_GICV2_SOURCES} -else ifeq (${QEMU_USE_GIC_DRIVER}, QEMU_GICV3) -QEMU_GIC_SOURCES := ${QEMU_GICV3_SOURCES} -else -$(error "Incorrect GIC driver chosen for QEMU platform") -endif - -ifeq (${ARM_ARCH_MAJOR},8) -BL31_SOURCES += lib/cpus/aarch64/aem_generic.S \ - lib/cpus/aarch64/cortex_a53.S \ - lib/cpus/aarch64/cortex_a57.S \ - plat/common/plat_psci_common.c \ - plat/qemu/qemu_pm.c \ - plat/qemu/topology.c \ - plat/qemu/aarch64/plat_helpers.S \ - plat/qemu/qemu_bl31_setup.c \ - ${QEMU_GIC_SOURCES} -endif - -# Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images -# in the FIP if the platform requires. -ifneq ($(BL32_EXTRA1),) -$(eval $(call TOOL_ADD_IMG,bl32_extra1,--tos-fw-extra1)) -endif -ifneq ($(BL32_EXTRA2),) -$(eval $(call TOOL_ADD_IMG,bl32_extra2,--tos-fw-extra2)) -endif - -SEPARATE_CODE_AND_RODATA := 1 -ENABLE_STACK_PROTECTOR := 0 -ifneq ($(ENABLE_STACK_PROTECTOR), 0) - PLAT_BL_COMMON_SOURCES += plat/qemu/qemu_stack_protector.c -endif - -BL32_RAM_LOCATION := tdram -ifeq (${BL32_RAM_LOCATION}, tsram) - BL32_RAM_LOCATION_ID = SEC_SRAM_ID -else ifeq (${BL32_RAM_LOCATION}, tdram) - BL32_RAM_LOCATION_ID = SEC_DRAM_ID -else - $(error "Unsupported BL32_RAM_LOCATION value") -endif - -# Process flags -$(eval $(call add_define,BL32_RAM_LOCATION_ID)) - -# Do not enable SVE -ENABLE_SVE_FOR_NS := 0 diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h new file mode 100644 index 0000000..d7f77cc --- /dev/null +++ b/plat/qemu/qemu/include/platform_def.h @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include +#include +#include +#include + +/* Special value used to verify platform parameters from BL2 to BL3-1 */ +#define QEMU_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL + +#define PLATFORM_STACK_SIZE 0x1000 + +#if ARM_ARCH_MAJOR == 7 +#define PLATFORM_MAX_CPUS_PER_CLUSTER 4 +#define PLATFORM_CLUSTER_COUNT 1 +#define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER +#define PLATFORM_CLUSTER1_CORE_COUNT 0 +#else +#define PLATFORM_MAX_CPUS_PER_CLUSTER 4 +#define PLATFORM_CLUSTER_COUNT 2 +#define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER +#define PLATFORM_CLUSTER1_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER +#endif +#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT + \ + PLATFORM_CLUSTER1_CORE_COUNT) + +#define QEMU_PRIMARY_CPU 0 + +#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \ + PLATFORM_CORE_COUNT) +#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 + +#define PLAT_MAX_RET_STATE U(1) +#define PLAT_MAX_OFF_STATE U(2) + +/* Local power state for power domains in Run state. */ +#define PLAT_LOCAL_STATE_RUN U(0) +/* Local power state for retention. Valid only for CPU power domains */ +#define PLAT_LOCAL_STATE_RET U(1) +/* + * Local power state for OFF/power-down. Valid for CPU and cluster power + * domains. + */ +#define PLAT_LOCAL_STATE_OFF 2 + +/* + * Macros used to parse state information from State-ID if it is using the + * recommended encoding for State-ID. + */ +#define PLAT_LOCAL_PSTATE_WIDTH 4 +#define PLAT_LOCAL_PSTATE_MASK ((1 << PLAT_LOCAL_PSTATE_WIDTH) - 1) + +/* + * Some data must be aligned on the biggest cache line size in the platform. + * This is known only to the platform as it might have a combination of + * integrated and external caches. + */ +#define CACHE_WRITEBACK_SHIFT 6 +#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT) + +/* + * Partition memory into secure ROM, non-secure DRAM, secure "SRAM", + * and secure DRAM. + */ +#define SEC_ROM_BASE 0x00000000 +#define SEC_ROM_SIZE 0x00020000 + +#define NS_DRAM0_BASE 0x40000000 +#define NS_DRAM0_SIZE 0x3de00000 + +#define SEC_SRAM_BASE 0x0e000000 +#define SEC_SRAM_SIZE 0x00060000 + +#define SEC_DRAM_BASE 0x0e100000 +#define SEC_DRAM_SIZE 0x00f00000 + +/* Load pageable part of OP-TEE 2MB above secure DRAM base */ +#define QEMU_OPTEE_PAGEABLE_LOAD_BASE (SEC_DRAM_BASE + 0x00200000) +#define QEMU_OPTEE_PAGEABLE_LOAD_SIZE 0x00400000 + +/* + * ARM-TF lives in SRAM, partition it here + */ + +#define SHARED_RAM_BASE SEC_SRAM_BASE +#define SHARED_RAM_SIZE 0x00001000 + +#define PLAT_QEMU_TRUSTED_MAILBOX_BASE SHARED_RAM_BASE +#define PLAT_QEMU_TRUSTED_MAILBOX_SIZE (8 + PLAT_QEMU_HOLD_SIZE) +#define PLAT_QEMU_HOLD_BASE (PLAT_QEMU_TRUSTED_MAILBOX_BASE + 8) +#define PLAT_QEMU_HOLD_SIZE (PLATFORM_CORE_COUNT * \ + PLAT_QEMU_HOLD_ENTRY_SIZE) +#define PLAT_QEMU_HOLD_ENTRY_SHIFT 3 +#define PLAT_QEMU_HOLD_ENTRY_SIZE (1 << PLAT_QEMU_HOLD_ENTRY_SHIFT) +#define PLAT_QEMU_HOLD_STATE_WAIT 0 +#define PLAT_QEMU_HOLD_STATE_GO 1 + +#define BL_RAM_BASE (SHARED_RAM_BASE + SHARED_RAM_SIZE) +#define BL_RAM_SIZE (SEC_SRAM_SIZE - SHARED_RAM_SIZE) + +/* + * BL1 specific defines. + * + * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of + * addresses. + * 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_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_LIMIT (BL_RAM_BASE + BL_RAM_SIZE) + +/* + * BL2 specific defines. + * + * 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 - 0x25000) +#define BL2_LIMIT BL31_BASE + +/* + * BL3-1 specific defines. + * + * 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_PROGBITS_LIMIT BL1_RW_BASE + + +/* + * BL3-2 specific defines. + * + * 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 SEC_SRAM_ID 0 +#define SEC_DRAM_ID 1 + +#if BL32_RAM_LOCATION_ID == SEC_SRAM_ID +# define BL32_MEM_BASE BL_RAM_BASE +# define BL32_MEM_SIZE BL_RAM_SIZE +# define BL32_BASE BL32_SRAM_BASE +# define BL32_LIMIT BL32_SRAM_LIMIT +#elif BL32_RAM_LOCATION_ID == SEC_DRAM_ID +# define BL32_MEM_BASE SEC_DRAM_BASE +# define BL32_MEM_SIZE SEC_DRAM_SIZE +# define BL32_BASE BL32_DRAM_BASE +# define BL32_LIMIT BL32_DRAM_LIMIT +#else +# error "Unsupported BL32_RAM_LOCATION_ID value" +#endif + +#define NS_IMAGE_OFFSET 0x60000000 + +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) +#define MAX_MMAP_REGIONS 10 +#define MAX_XLAT_TABLES 6 +#define MAX_IO_DEVICES 3 +#define MAX_IO_HANDLES 4 + +/* + * PL011 related constants + */ +#define UART0_BASE 0x09000000 +#define UART1_BASE 0x09040000 +#define UART0_CLK_IN_HZ 1 +#define UART1_CLK_IN_HZ 1 + +#define PLAT_QEMU_BOOT_UART_BASE UART0_BASE +#define PLAT_QEMU_BOOT_UART_CLK_IN_HZ UART0_CLK_IN_HZ + +#define PLAT_QEMU_CRASH_UART_BASE UART1_BASE +#define PLAT_QEMU_CRASH_UART_CLK_IN_HZ UART1_CLK_IN_HZ + +#define PLAT_QEMU_CONSOLE_BAUDRATE 115200 + +#define QEMU_FLASH0_BASE 0x04000000 +#define QEMU_FLASH0_SIZE 0x04000000 + +#define PLAT_QEMU_FIP_BASE QEMU_FLASH0_BASE +#define PLAT_QEMU_FIP_MAX_SIZE QEMU_FLASH0_SIZE + +#define DEVICE0_BASE 0x08000000 +#define DEVICE0_SIZE 0x01000000 +#define DEVICE1_BASE 0x09000000 +#define DEVICE1_SIZE 0x00041000 + +/* + * GIC related constants + */ + +#define GICD_BASE 0x8000000 +#define GICC_BASE 0x8010000 +#define GICR_BASE 0x80A0000 + + +#define QEMU_IRQ_SEC_SGI_0 8 +#define QEMU_IRQ_SEC_SGI_1 9 +#define QEMU_IRQ_SEC_SGI_2 10 +#define QEMU_IRQ_SEC_SGI_3 11 +#define QEMU_IRQ_SEC_SGI_4 12 +#define QEMU_IRQ_SEC_SGI_5 13 +#define QEMU_IRQ_SEC_SGI_6 14 +#define QEMU_IRQ_SEC_SGI_7 15 + +/****************************************************************************** + * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0 + * interrupts. + *****************************************************************************/ +#define PLATFORM_G1S_PROPS(grp) \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE) + +#define PLATFORM_G0_PROPS(grp) + +/* + * DT related constants + */ +#define PLAT_QEMU_DT_BASE NS_DRAM0_BASE +#define PLAT_QEMU_DT_MAX_SIZE 0x100000 + +/* + * System counter + */ +#define SYS_COUNTER_FREQ_IN_TICKS ((1000 * 1000 * 1000) / 16) + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk new file mode 100644 index 0000000..5fda2cd --- /dev/null +++ b/plat/qemu/qemu/platform.mk @@ -0,0 +1,190 @@ +# +# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# Use the GICv2 driver on QEMU by default +QEMU_USE_GIC_DRIVER := QEMU_GICV2 + +ifeq (${ARM_ARCH_MAJOR},7) +# ARMv7 Qemu support in trusted firmware expects the Cortex-A15 model. +# Qemu Cortex-A15 model does not implement the virtualization extension. +# For this reason, we cannot set ARM_CORTEX_A15=yes and must define all +# the ARMv7 build directives. +MARCH32_DIRECTIVE := -mcpu=cortex-a15 +$(eval $(call add_define,ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING)) +$(eval $(call add_define,ARMV7_SUPPORTS_GENERIC_TIMER)) +# Qemu expects a BL32 boot stage. +NEED_BL32 := yes +endif # ARMv7 + +ifeq (${SPD},opteed) +add-lib-optee := yes +endif +ifeq ($(AARCH32_SP),optee) +add-lib-optee := yes +endif + +include lib/libfdt/libfdt.mk + +ifeq ($(NEED_BL32),yes) +$(eval $(call add_define,QEMU_LOAD_BL32)) +endif + +PLAT_QEMU_PATH := plat/qemu/qemu +PLAT_QEMU_COMMON_PATH := plat/qemu/common +PLAT_INCLUDES := -Iinclude/plat/arm/common/ \ + -I${PLAT_QEMU_COMMON_PATH}/include \ + -I${PLAT_QEMU_PATH}/include \ + -Iinclude/common/tbbr + +ifeq (${ARM_ARCH_MAJOR},8) +PLAT_INCLUDES += -Iinclude/plat/arm/common/${ARCH} +endif + +PLAT_BL_COMMON_SOURCES := ${PLAT_QEMU_COMMON_PATH}/qemu_common.c \ + ${PLAT_QEMU_COMMON_PATH}/qemu_console.c \ + drivers/arm/pl011/${ARCH}/pl011_console.S + +include lib/xlat_tables_v2/xlat_tables.mk +PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} + +ifneq (${TRUSTED_BOARD_BOOT},0) + + include drivers/auth/mbedtls/mbedtls_crypto.mk + include drivers/auth/mbedtls/mbedtls_x509.mk + + AUTH_SOURCES := drivers/auth/auth_mod.c \ + drivers/auth/crypto_mod.c \ + drivers/auth/img_parser_mod.c \ + drivers/auth/tbbr/tbbr_cot.c + + BL1_SOURCES += ${AUTH_SOURCES} \ + bl1/tbbr/tbbr_img_desc.c \ + plat/common/tbbr/plat_tbbr.c \ + ${PLAT_QEMU_COMMON_PATH}/qemu_trusted_boot.c \ + $(PLAT_QEMU_COMMON_PATH)/qemu_rotpk.S + + BL2_SOURCES += ${AUTH_SOURCES} \ + plat/common/tbbr/plat_tbbr.c \ + ${PLAT_QEMU_COMMON_PATH}/qemu_trusted_boot.c \ + $(PLAT_QEMU_COMMON_PATH)/qemu_rotpk.S + + ROT_KEY = $(BUILD_PLAT)/rot_key.pem + ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin + + $(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"')) + + $(BUILD_PLAT)/bl1/qemu_rotpk.o: $(ROTPK_HASH) + $(BUILD_PLAT)/bl2/qemu_rotpk.o: $(ROTPK_HASH) + + certificates: $(ROT_KEY) + + $(ROT_KEY): + @echo " OPENSSL $@" + $(Q)openssl genrsa 2048 > $@ 2>/dev/null + + $(ROTPK_HASH): $(ROT_KEY) + @echo " OPENSSL $@" + $(Q)openssl rsa -in $< -pubout -outform DER 2>/dev/null |\ + openssl dgst -sha256 -binary > $@ 2>/dev/null +endif + +BL1_SOURCES += drivers/io/io_semihosting.c \ + drivers/io/io_storage.c \ + drivers/io/io_fip.c \ + drivers/io/io_memmap.c \ + lib/semihosting/semihosting.c \ + lib/semihosting/${ARCH}/semihosting_call.S \ + ${PLAT_QEMU_COMMON_PATH}/qemu_io_storage.c \ + ${PLAT_QEMU_COMMON_PATH}/${ARCH}/plat_helpers.S \ + ${PLAT_QEMU_COMMON_PATH}/qemu_bl1_setup.c + +ifeq (${ARM_ARCH_MAJOR},8) +BL1_SOURCES += lib/cpus/aarch64/aem_generic.S \ + lib/cpus/aarch64/cortex_a53.S \ + lib/cpus/aarch64/cortex_a57.S +else +BL1_SOURCES += lib/cpus/${ARCH}/cortex_a15.S +endif + +BL2_SOURCES += drivers/io/io_semihosting.c \ + drivers/io/io_storage.c \ + drivers/io/io_fip.c \ + drivers/io/io_memmap.c \ + lib/semihosting/semihosting.c \ + lib/semihosting/${ARCH}/semihosting_call.S \ + ${PLAT_QEMU_COMMON_PATH}/qemu_io_storage.c \ + ${PLAT_QEMU_COMMON_PATH}/${ARCH}/plat_helpers.S \ + ${PLAT_QEMU_COMMON_PATH}/qemu_bl2_setup.c \ + ${PLAT_QEMU_COMMON_PATH}/qemu_bl2_mem_params_desc.c \ + ${PLAT_QEMU_COMMON_PATH}/qemu_image_load.c \ + common/fdt_fixup.c \ + common/desc_image_load.c + +ifeq ($(add-lib-optee),yes) +BL2_SOURCES += lib/optee/optee_utils.c +endif + +QEMU_GICV2_SOURCES := drivers/arm/gic/v2/gicv2_helpers.c \ + drivers/arm/gic/v2/gicv2_main.c \ + drivers/arm/gic/common/gic_common.c \ + plat/common/plat_gicv2.c \ + ${PLAT_QEMU_COMMON_PATH}/qemu_gicv2.c + +QEMU_GICV3_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicv3_main.c \ + drivers/arm/gic/common/gic_common.c \ + plat/common/plat_gicv3.c \ + ${PLAT_QEMU_COMMON_PATH}/qemu_gicv3.c + +ifeq (${QEMU_USE_GIC_DRIVER}, QEMU_GICV2) +QEMU_GIC_SOURCES := ${QEMU_GICV2_SOURCES} +else ifeq (${QEMU_USE_GIC_DRIVER}, QEMU_GICV3) +QEMU_GIC_SOURCES := ${QEMU_GICV3_SOURCES} +else +$(error "Incorrect GIC driver chosen for QEMU platform") +endif + +ifeq (${ARM_ARCH_MAJOR},8) +BL31_SOURCES += lib/cpus/aarch64/aem_generic.S \ + lib/cpus/aarch64/cortex_a53.S \ + lib/cpus/aarch64/cortex_a57.S \ + plat/common/plat_psci_common.c \ + ${PLAT_QEMU_COMMON_PATH}/qemu_pm.c \ + ${PLAT_QEMU_COMMON_PATH}/topology.c \ + ${PLAT_QEMU_COMMON_PATH}/aarch64/plat_helpers.S \ + ${PLAT_QEMU_COMMON_PATH}/qemu_bl31_setup.c \ + ${QEMU_GIC_SOURCES} +endif + +# Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images +# in the FIP if the platform requires. +ifneq ($(BL32_EXTRA1),) +$(eval $(call TOOL_ADD_IMG,bl32_extra1,--tos-fw-extra1)) +endif +ifneq ($(BL32_EXTRA2),) +$(eval $(call TOOL_ADD_IMG,bl32_extra2,--tos-fw-extra2)) +endif + +SEPARATE_CODE_AND_RODATA := 1 +ENABLE_STACK_PROTECTOR := 0 +ifneq ($(ENABLE_STACK_PROTECTOR), 0) + PLAT_BL_COMMON_SOURCES += ${PLAT_QEMU_COMMON_PATH}/qemu_stack_protector.c +endif + +BL32_RAM_LOCATION := tdram +ifeq (${BL32_RAM_LOCATION}, tsram) + BL32_RAM_LOCATION_ID = SEC_SRAM_ID +else ifeq (${BL32_RAM_LOCATION}, tdram) + BL32_RAM_LOCATION_ID = SEC_DRAM_ID +else + $(error "Unsupported BL32_RAM_LOCATION value") +endif + +# Process flags +$(eval $(call add_define,BL32_RAM_LOCATION_ID)) + +# Do not enable SVE +ENABLE_SVE_FOR_NS := 0 diff --git a/plat/qemu/qemu_bl1_setup.c b/plat/qemu/qemu_bl1_setup.c deleted file mode 100644 index 67f3327..0000000 --- a/plat/qemu/qemu_bl1_setup.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include - -#include -#include -#include - -#include "qemu_private.h" - -/* Data structure which holds the extents of the trusted SRAM for BL1*/ -static meminfo_t bl1_tzram_layout; - - -meminfo_t *bl1_plat_sec_mem_layout(void) -{ - return &bl1_tzram_layout; -} - -/******************************************************************************* - * Perform any BL1 specific platform actions. - ******************************************************************************/ -void bl1_early_platform_setup(void) -{ - /* Initialize the console to provide early debug support */ - qemu_console_init(); - - /* Allow BL1 to see the whole Trusted RAM */ - bl1_tzram_layout.total_base = BL_RAM_BASE; - bl1_tzram_layout.total_size = BL_RAM_SIZE; -} - -/****************************************************************************** - * Perform the very early platform specific architecture setup. This only - * does basic initialization. Later architectural setup (bl1_arch_setup()) - * does not do anything platform specific. - *****************************************************************************/ -#ifdef __aarch64__ -#define QEMU_CONFIGURE_BL1_MMU(...) qemu_configure_mmu_el3(__VA_ARGS__) -#else -#define QEMU_CONFIGURE_BL1_MMU(...) qemu_configure_mmu_svc_mon(__VA_ARGS__) -#endif - -void bl1_plat_arch_setup(void) -{ - QEMU_CONFIGURE_BL1_MMU(bl1_tzram_layout.total_base, - bl1_tzram_layout.total_size, - BL_CODE_BASE, BL1_CODE_END, - BL1_RO_DATA_BASE, BL1_RO_DATA_END, - BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END); -} - -void bl1_platform_setup(void) -{ - plat_qemu_io_setup(); -} diff --git a/plat/qemu/qemu_bl2_mem_params_desc.c b/plat/qemu/qemu_bl2_mem_params_desc.c deleted file mode 100644 index a01f2dc..0000000 --- a/plat/qemu/qemu_bl2_mem_params_desc.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include - -/******************************************************************************* - * Following descriptor provides BL image/ep information that gets used - * by BL2 to load the images and also subset of this information is - * passed to next BL image. The image loading sequence is managed by - * populating the images in required loading order. The image execution - * sequence is managed by populating the `next_handoff_image_id` with - * the next executable image id. - ******************************************************************************/ -static bl_mem_params_node_t bl2_mem_params_descs[] = { -#ifdef EL3_PAYLOAD_BASE - /* Fill EL3 payload related information (BL31 is EL3 payload) */ - { .image_id = BL31_IMAGE_ID, - - SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, - entry_point_info_t, - SECURE | EXECUTABLE | EP_FIRST_EXE), - .ep_info.pc = EL3_PAYLOAD_BASE, - .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, - DISABLE_ALL_EXCEPTIONS), - - SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, image_info_t, - IMAGE_ATTRIB_PLAT_SETUP | IMAGE_ATTRIB_SKIP_LOADING), - - .next_handoff_image_id = INVALID_IMAGE_ID, - }, -#else /* EL3_PAYLOAD_BASE */ -#ifdef __aarch64__ - /* Fill BL31 related information */ - { .image_id = BL31_IMAGE_ID, - - SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, - entry_point_info_t, - SECURE | EXECUTABLE | EP_FIRST_EXE), - .ep_info.pc = BL31_BASE, - .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, - DISABLE_ALL_EXCEPTIONS), -# if DEBUG - .ep_info.args.arg1 = QEMU_BL31_PLAT_PARAM_VAL, -# endif - SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, image_info_t, - IMAGE_ATTRIB_PLAT_SETUP), - .image_info.image_base = BL31_BASE, - .image_info.image_max_size = BL31_LIMIT - BL31_BASE, - -# ifdef QEMU_LOAD_BL32 - .next_handoff_image_id = BL32_IMAGE_ID, -# else - .next_handoff_image_id = BL33_IMAGE_ID, -# endif - }, -#endif /* __aarch64__ */ -# ifdef QEMU_LOAD_BL32 - -#ifdef __aarch64__ -#define BL32_EP_ATTRIBS (SECURE | EXECUTABLE) -#define BL32_IMG_ATTRIBS 0 -#else -#define BL32_EP_ATTRIBS (SECURE | EXECUTABLE | EP_FIRST_EXE) -#define BL32_IMG_ATTRIBS IMAGE_ATTRIB_PLAT_SETUP -#endif - - /* Fill BL32 related information */ - { .image_id = BL32_IMAGE_ID, - - SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, - entry_point_info_t, BL32_EP_ATTRIBS), - .ep_info.pc = BL32_BASE, - - SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, - image_info_t, BL32_IMG_ATTRIBS), - - .image_info.image_base = BL32_BASE, - .image_info.image_max_size = BL32_LIMIT - BL32_BASE, - - .next_handoff_image_id = BL33_IMAGE_ID, - }, - - /* - * Fill BL32 external 1 related information. - * A typical use for extra1 image is with OP-TEE where it is the - * pager image. - */ - { .image_id = BL32_EXTRA1_IMAGE_ID, - - SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, - entry_point_info_t, SECURE | NON_EXECUTABLE), - - SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, - image_info_t, IMAGE_ATTRIB_SKIP_LOADING), - .image_info.image_base = BL32_BASE, - .image_info.image_max_size = BL32_LIMIT - BL32_BASE, - - .next_handoff_image_id = INVALID_IMAGE_ID, - }, - - /* - * Fill BL32 external 2 related information. - * A typical use for extra2 image is with OP-TEE where it is the - * paged image. - */ - { .image_id = BL32_EXTRA2_IMAGE_ID, - - SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, - entry_point_info_t, SECURE | NON_EXECUTABLE), - - SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, - image_info_t, IMAGE_ATTRIB_SKIP_LOADING), -#if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE) - .image_info.image_base = QEMU_OPTEE_PAGEABLE_LOAD_BASE, - .image_info.image_max_size = QEMU_OPTEE_PAGEABLE_LOAD_SIZE, -#endif - .next_handoff_image_id = INVALID_IMAGE_ID, - }, -# endif /* QEMU_LOAD_BL32 */ - - /* Fill BL33 related information */ - { .image_id = BL33_IMAGE_ID, - SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, - entry_point_info_t, NON_SECURE | EXECUTABLE), -# ifdef PRELOADED_BL33_BASE - .ep_info.pc = PRELOADED_BL33_BASE, - - SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, image_info_t, - IMAGE_ATTRIB_SKIP_LOADING), -# else /* PRELOADED_BL33_BASE */ - .ep_info.pc = NS_IMAGE_OFFSET, - - SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, image_info_t, - 0), - .image_info.image_base = NS_IMAGE_OFFSET, - .image_info.image_max_size = NS_DRAM0_BASE + NS_DRAM0_SIZE - - NS_IMAGE_OFFSET, -# endif /* !PRELOADED_BL33_BASE */ - - .next_handoff_image_id = INVALID_IMAGE_ID, - } -#endif /* !EL3_PAYLOAD_BASE */ -}; - -REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs) diff --git a/plat/qemu/qemu_bl2_setup.c b/plat/qemu/qemu_bl2_setup.c deleted file mode 100644 index 166d245..0000000 --- a/plat/qemu/qemu_bl2_setup.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "qemu_private.h" - - -/* Data structure which holds the extents of the trusted SRAM for BL2 */ -static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); - -void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, - u_register_t arg2, u_register_t arg3) -{ - meminfo_t *mem_layout = (void *)arg1; - - /* Initialize the console to provide early debug support */ - qemu_console_init(); - - /* Setup the BL2 memory layout */ - bl2_tzram_layout = *mem_layout; - - plat_qemu_io_setup(); -} - -static void security_setup(void) -{ - /* - * This is where a TrustZone address space controller and other - * security related peripherals, would be configured. - */ -} - -static void update_dt(void) -{ - int ret; - void *fdt = (void *)(uintptr_t)PLAT_QEMU_DT_BASE; - - ret = fdt_open_into(fdt, fdt, PLAT_QEMU_DT_MAX_SIZE); - if (ret < 0) { - ERROR("Invalid Device Tree at %p: error %d\n", fdt, ret); - return; - } - - if (dt_add_psci_node(fdt)) { - ERROR("Failed to add PSCI Device Tree node\n"); - return; - } - - if (dt_add_psci_cpu_enable_methods(fdt)) { - ERROR("Failed to add PSCI cpu enable methods in Device Tree\n"); - return; - } - - ret = fdt_pack(fdt); - if (ret < 0) - ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, ret); -} - -void bl2_platform_setup(void) -{ - security_setup(); - update_dt(); - - /* TODO Initialize timer */ -} - -#ifdef __aarch64__ -#define QEMU_CONFIGURE_BL2_MMU(...) qemu_configure_mmu_el1(__VA_ARGS__) -#else -#define QEMU_CONFIGURE_BL2_MMU(...) qemu_configure_mmu_svc_mon(__VA_ARGS__) -#endif - -void bl2_plat_arch_setup(void) -{ - QEMU_CONFIGURE_BL2_MMU(bl2_tzram_layout.total_base, - bl2_tzram_layout.total_size, - BL_CODE_BASE, BL_CODE_END, - BL_RO_DATA_BASE, BL_RO_DATA_END, - BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END); -} - -/******************************************************************************* - * Gets SPSR for BL32 entry - ******************************************************************************/ -static uint32_t qemu_get_spsr_for_bl32_entry(void) -{ -#ifdef __aarch64__ - /* - * The Secure Payload Dispatcher service is responsible for - * setting the SPSR prior to entry into the BL3-2 image. - */ - return 0; -#else - return SPSR_MODE32(MODE32_svc, SPSR_T_ARM, SPSR_E_LITTLE, - DISABLE_ALL_EXCEPTIONS); -#endif -} - -/******************************************************************************* - * Gets SPSR for BL33 entry - ******************************************************************************/ -static uint32_t qemu_get_spsr_for_bl33_entry(void) -{ - uint32_t spsr; -#ifdef __aarch64__ - unsigned int mode; - - /* Figure out what mode we enter the non-secure world in */ - mode = (el_implemented(2) != EL_IMPL_NONE) ? MODE_EL2 : MODE_EL1; - - /* - * TODO: Consider the possibility of specifying the SPSR in - * the FIP ToC and allowing the platform to have a say as - * well. - */ - spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); -#else - spsr = SPSR_MODE32(MODE32_svc, - plat_get_ns_image_entrypoint() & 0x1, - SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS); -#endif - return spsr; -} - -static int qemu_bl2_handle_post_image_load(unsigned int image_id) -{ - int err = 0; - bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); -#if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE) - bl_mem_params_node_t *pager_mem_params = NULL; - bl_mem_params_node_t *paged_mem_params = NULL; -#endif - - assert(bl_mem_params); - - switch (image_id) { - case BL32_IMAGE_ID: -#if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE) - pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID); - assert(pager_mem_params); - - paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID); - assert(paged_mem_params); - - err = parse_optee_header(&bl_mem_params->ep_info, - &pager_mem_params->image_info, - &paged_mem_params->image_info); - if (err != 0) { - WARN("OPTEE header parse error.\n"); - } - -#if defined(SPD_opteed) - /* - * OP-TEE expect to receive DTB address in x2. - * This will be copied into x2 by dispatcher. - */ - bl_mem_params->ep_info.args.arg3 = PLAT_QEMU_DT_BASE; -#else /* case AARCH32_SP_OPTEE */ - bl_mem_params->ep_info.args.arg0 = - bl_mem_params->ep_info.args.arg1; - bl_mem_params->ep_info.args.arg1 = 0; - bl_mem_params->ep_info.args.arg2 = PLAT_QEMU_DT_BASE; - bl_mem_params->ep_info.args.arg3 = 0; -#endif -#endif - bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl32_entry(); - break; - - case BL33_IMAGE_ID: -#ifdef AARCH32_SP_OPTEE - /* AArch32 only core: OP-TEE expects NSec EP in register LR */ - pager_mem_params = get_bl_mem_params_node(BL32_IMAGE_ID); - assert(pager_mem_params); - pager_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc; -#endif - - /* BL33 expects to receive the primary CPU MPID (through r0) */ - bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); - bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl33_entry(); - break; - default: - /* Do nothing in default case */ - break; - } - - return err; -} - -/******************************************************************************* - * This function can be used by the platforms to update/use image - * information for given `image_id`. - ******************************************************************************/ -int bl2_plat_handle_post_image_load(unsigned int image_id) -{ - return qemu_bl2_handle_post_image_load(image_id); -} - -uintptr_t plat_get_ns_image_entrypoint(void) -{ - return NS_IMAGE_OFFSET; -} diff --git a/plat/qemu/qemu_bl31_setup.c b/plat/qemu/qemu_bl31_setup.c deleted file mode 100644 index 4d36b03..0000000 --- a/plat/qemu/qemu_bl31_setup.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include - -#include "qemu_private.h" - -/* - * Placeholder variables for copying the arguments that have been passed to - * BL3-1 from BL2. - */ -static entry_point_info_t bl32_image_ep_info; -static entry_point_info_t bl33_image_ep_info; - -/******************************************************************************* - * Perform any BL3-1 early platform setup. Here is an opportunity to copy - * parameters passed by the calling EL (S-EL1 in BL2 & EL3 in BL1) before - * they are lost (potentially). This needs to be done before the MMU is - * initialized so that the memory layout can be used while creating page - * tables. BL2 has flushed this information to memory, so we are guaranteed - * to pick up good data. - ******************************************************************************/ -void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, - u_register_t arg2, u_register_t arg3) -{ - /* Initialize the console to provide early debug support */ - qemu_console_init(); - - /* - * Check params passed from BL2 - */ - bl_params_t *params_from_bl2 = (bl_params_t *)arg0; - - assert(params_from_bl2); - assert(params_from_bl2->h.type == PARAM_BL_PARAMS); - assert(params_from_bl2->h.version >= VERSION_2); - - bl_params_node_t *bl_params = params_from_bl2->head; - - /* - * Copy BL33 and BL32 (if present), entry point information. - * They are stored in Secure RAM, in BL2's address space. - */ - while (bl_params) { - if (bl_params->image_id == BL32_IMAGE_ID) - bl32_image_ep_info = *bl_params->ep_info; - - 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) - panic(); -} - -void bl31_plat_arch_setup(void) -{ - qemu_configure_mmu_el3(BL31_BASE, (BL31_END - BL31_BASE), - BL_CODE_BASE, BL_CODE_END, - BL_RO_DATA_BASE, BL_RO_DATA_END, - BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END); -} - -void bl31_platform_setup(void) -{ - plat_qemu_gic_init(); -} - -unsigned int plat_get_syscnt_freq2(void) -{ - return SYS_COUNTER_FREQ_IN_TICKS; -} - -/******************************************************************************* - * Return a pointer to the 'entry_point_info' structure of the next image - * for the security state specified. BL3-3 corresponds to the non-secure - * image type while BL3-2 corresponds to the secure image type. A NULL - * pointer is returned if the image does not exist. - ******************************************************************************/ -entry_point_info_t *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; - /* - * None of the images on the ARM development platforms can have 0x0 - * as the entrypoint - */ - if (next_image_info->pc) - return next_image_info; - else - return NULL; -} diff --git a/plat/qemu/qemu_common.c b/plat/qemu/qemu_common.c deleted file mode 100644 index 56bf953..0000000 --- a/plat/qemu/qemu_common.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include - -#include "qemu_private.h" - -#define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \ - DEVICE0_SIZE, \ - MT_DEVICE | MT_RW | MT_SECURE) - -#ifdef DEVICE1_BASE -#define MAP_DEVICE1 MAP_REGION_FLAT(DEVICE1_BASE, \ - DEVICE1_SIZE, \ - MT_DEVICE | MT_RW | MT_SECURE) -#endif - -#ifdef DEVICE2_BASE -#define MAP_DEVICE2 MAP_REGION_FLAT(DEVICE2_BASE, \ - DEVICE2_SIZE, \ - MT_DEVICE | MT_RO | MT_SECURE) -#endif - -#define MAP_SHARED_RAM MAP_REGION_FLAT(SHARED_RAM_BASE, \ - SHARED_RAM_SIZE, \ - MT_DEVICE | MT_RW | MT_SECURE) - -#define MAP_BL32_MEM MAP_REGION_FLAT(BL32_MEM_BASE, BL32_MEM_SIZE, \ - MT_MEMORY | MT_RW | MT_SECURE) - -#define MAP_NS_DRAM0 MAP_REGION_FLAT(NS_DRAM0_BASE, NS_DRAM0_SIZE, \ - MT_MEMORY | MT_RW | MT_NS) - -#define MAP_FLASH0 MAP_REGION_FLAT(QEMU_FLASH0_BASE, QEMU_FLASH0_SIZE, \ - MT_MEMORY | MT_RO | MT_SECURE) - -/* - * Table of regions for various BL stages to map using the MMU. - * This doesn't include TZRAM as the 'mem_layout' argument passed to - * arm_configure_mmu_elx() will give the available subset of that, - */ -#ifdef IMAGE_BL1 -static const mmap_region_t plat_qemu_mmap[] = { - MAP_FLASH0, - MAP_SHARED_RAM, - MAP_DEVICE0, -#ifdef MAP_DEVICE1 - MAP_DEVICE1, -#endif -#ifdef MAP_DEVICE2 - MAP_DEVICE2, -#endif - {0} -}; -#endif -#ifdef IMAGE_BL2 -static const mmap_region_t plat_qemu_mmap[] = { - MAP_FLASH0, - MAP_SHARED_RAM, - MAP_DEVICE0, -#ifdef MAP_DEVICE1 - MAP_DEVICE1, -#endif -#ifdef MAP_DEVICE2 - MAP_DEVICE2, -#endif - MAP_NS_DRAM0, - MAP_BL32_MEM, - {0} -}; -#endif -#ifdef IMAGE_BL31 -static const mmap_region_t plat_qemu_mmap[] = { - MAP_SHARED_RAM, - MAP_DEVICE0, -#ifdef MAP_DEVICE1 - MAP_DEVICE1, -#endif - MAP_BL32_MEM, - {0} -}; -#endif -#ifdef IMAGE_BL32 -static const mmap_region_t plat_qemu_mmap[] = { - MAP_SHARED_RAM, - MAP_DEVICE0, -#ifdef MAP_DEVICE1 - MAP_DEVICE1, -#endif - {0} -}; -#endif - -/******************************************************************************* - * Macro generating the code for the function setting up the pagetables as per - * the platform memory map & initialize the mmu, for the given exception level - ******************************************************************************/ - -#define DEFINE_CONFIGURE_MMU_EL(_el) \ - void qemu_configure_mmu_##_el(unsigned long total_base, \ - unsigned long total_size, \ - unsigned long code_start, \ - unsigned long code_limit, \ - unsigned long ro_start, \ - unsigned long ro_limit, \ - unsigned long coh_start, \ - unsigned long coh_limit) \ - { \ - mmap_add_region(total_base, total_base, \ - total_size, \ - MT_MEMORY | MT_RW | MT_SECURE); \ - mmap_add_region(code_start, code_start, \ - code_limit - code_start, \ - MT_CODE | MT_SECURE); \ - mmap_add_region(ro_start, ro_start, \ - ro_limit - ro_start, \ - MT_RO_DATA | MT_SECURE); \ - mmap_add_region(coh_start, coh_start, \ - coh_limit - coh_start, \ - MT_DEVICE | MT_RW | MT_SECURE); \ - mmap_add(plat_qemu_mmap); \ - init_xlat_tables(); \ - \ - enable_mmu_##_el(0); \ - } - -/* Define EL1 and EL3 variants of the function initialising the MMU */ -#ifdef __aarch64__ -DEFINE_CONFIGURE_MMU_EL(el1) -DEFINE_CONFIGURE_MMU_EL(el3) -#else -DEFINE_CONFIGURE_MMU_EL(svc_mon) -#endif - - diff --git a/plat/qemu/qemu_console.c b/plat/qemu/qemu_console.c deleted file mode 100644 index fec1828..0000000 --- a/plat/qemu/qemu_console.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include - -static console_pl011_t console; - -void qemu_console_init(void) -{ - (void)console_pl011_register(PLAT_QEMU_BOOT_UART_BASE, - PLAT_QEMU_BOOT_UART_CLK_IN_HZ, - PLAT_QEMU_CONSOLE_BAUDRATE, &console); - - console_set_scope(&console.console, CONSOLE_FLAG_BOOT | - CONSOLE_FLAG_RUNTIME); -} - diff --git a/plat/qemu/qemu_gicv2.c b/plat/qemu/qemu_gicv2.c deleted file mode 100644 index fb56622..0000000 --- a/plat/qemu/qemu_gicv2.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include - -static const interrupt_prop_t qemu_interrupt_props[] = { - PLATFORM_G1S_PROPS(GICV2_INTR_GROUP0), - PLATFORM_G0_PROPS(GICV2_INTR_GROUP0) -}; - -static const struct gicv2_driver_data plat_gicv2_driver_data = { - .gicd_base = GICD_BASE, - .gicc_base = GICC_BASE, - .interrupt_props = qemu_interrupt_props, - .interrupt_props_num = ARRAY_SIZE(qemu_interrupt_props), -}; - -void plat_qemu_gic_init(void) -{ - /* Initialize the gic cpu and distributor interfaces */ - gicv2_driver_init(&plat_gicv2_driver_data); - gicv2_distif_init(); - gicv2_pcpu_distif_init(); - gicv2_cpuif_enable(); -} - -void qemu_pwr_gic_on_finish(void) -{ - /* TODO: This setup is needed only after a cold boot */ - gicv2_pcpu_distif_init(); - - /* Enable the gic cpu interface */ - gicv2_cpuif_enable(); -} diff --git a/plat/qemu/qemu_gicv3.c b/plat/qemu/qemu_gicv3.c deleted file mode 100644 index 28572c5..0000000 --- a/plat/qemu/qemu_gicv3.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2019, Linaro Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include - -static const interrupt_prop_t qemu_interrupt_props[] = { - PLATFORM_G1S_PROPS(INTR_GROUP1S), - PLATFORM_G0_PROPS(INTR_GROUP0) -}; - -static uintptr_t qemu_rdistif_base_addrs[PLATFORM_CORE_COUNT]; - -static unsigned int qemu_mpidr_to_core_pos(unsigned long mpidr) -{ - return (unsigned int)plat_core_pos_by_mpidr(mpidr); -} - -static const gicv3_driver_data_t qemu_gicv3_driver_data = { - .gicd_base = GICD_BASE, - .gicr_base = GICR_BASE, - .interrupt_props = qemu_interrupt_props, - .interrupt_props_num = ARRAY_SIZE(qemu_interrupt_props), - .rdistif_num = PLATFORM_CORE_COUNT, - .rdistif_base_addrs = qemu_rdistif_base_addrs, - .mpidr_to_core_pos = qemu_mpidr_to_core_pos -}; - -void plat_qemu_gic_init(void) -{ - gicv3_driver_init(&qemu_gicv3_driver_data); - gicv3_distif_init(); - gicv3_rdistif_init(plat_my_core_pos()); - gicv3_cpuif_enable(plat_my_core_pos()); -} - -void qemu_pwr_gic_on_finish(void) -{ - gicv3_rdistif_init(plat_my_core_pos()); - gicv3_cpuif_enable(plat_my_core_pos()); -} diff --git a/plat/qemu/qemu_image_load.c b/plat/qemu/qemu_image_load.c deleted file mode 100644 index 9970d1d..0000000 --- a/plat/qemu/qemu_image_load.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -/******************************************************************************* - * This function is a wrapper of a common function which flushes the data - * structures so that they are visible in memory for the next BL image. - ******************************************************************************/ -void plat_flush_next_bl_params(void) -{ - flush_bl_params_desc(); -} - -/******************************************************************************* - * This function is a wrapper of a common function which returns the list of - * loadable images. - ******************************************************************************/ -bl_load_info_t *plat_get_bl_image_load_info(void) -{ - return get_bl_load_info_from_mem_params_desc(); -} - -/******************************************************************************* - * This function is a wrapper of a common function which returns the data - * structures of the next BL image. - ******************************************************************************/ -bl_params_t *plat_get_next_bl_params(void) -{ - return get_next_bl_params_from_mem_params_desc(); -} diff --git a/plat/qemu/qemu_io_storage.c b/plat/qemu/qemu_io_storage.c deleted file mode 100644 index 0e81cd1..0000000 --- a/plat/qemu/qemu_io_storage.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Semihosting filenames */ -#define BL2_IMAGE_NAME "bl2.bin" -#define BL31_IMAGE_NAME "bl31.bin" -#define BL32_IMAGE_NAME "bl32.bin" -#define BL32_EXTRA1_IMAGE_NAME "bl32_extra1.bin" -#define BL32_EXTRA2_IMAGE_NAME "bl32_extra2.bin" -#define BL33_IMAGE_NAME "bl33.bin" - -#if TRUSTED_BOARD_BOOT -#define TRUSTED_BOOT_FW_CERT_NAME "tb_fw.crt" -#define TRUSTED_KEY_CERT_NAME "trusted_key.crt" -#define SOC_FW_KEY_CERT_NAME "soc_fw_key.crt" -#define TOS_FW_KEY_CERT_NAME "tos_fw_key.crt" -#define NT_FW_KEY_CERT_NAME "nt_fw_key.crt" -#define SOC_FW_CONTENT_CERT_NAME "soc_fw_content.crt" -#define TOS_FW_CONTENT_CERT_NAME "tos_fw_content.crt" -#define NT_FW_CONTENT_CERT_NAME "nt_fw_content.crt" -#endif /* TRUSTED_BOARD_BOOT */ - - - -/* IO devices */ -static const io_dev_connector_t *fip_dev_con; -static uintptr_t fip_dev_handle; -static const io_dev_connector_t *memmap_dev_con; -static uintptr_t memmap_dev_handle; -static const io_dev_connector_t *sh_dev_con; -static uintptr_t sh_dev_handle; - -static const io_block_spec_t fip_block_spec = { - .offset = PLAT_QEMU_FIP_BASE, - .length = PLAT_QEMU_FIP_MAX_SIZE -}; - -static const io_uuid_spec_t bl2_uuid_spec = { - .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, -}; - -static const io_uuid_spec_t bl31_uuid_spec = { - .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, -}; - -static const io_uuid_spec_t bl32_uuid_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32, -}; - -static const io_uuid_spec_t bl32_extra1_uuid_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, -}; - -static const io_uuid_spec_t bl32_extra2_uuid_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, -}; - -static const io_uuid_spec_t bl33_uuid_spec = { - .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, -}; - -#if TRUSTED_BOARD_BOOT -static const io_uuid_spec_t tb_fw_cert_uuid_spec = { - .uuid = UUID_TRUSTED_BOOT_FW_CERT, -}; - -static const io_uuid_spec_t trusted_key_cert_uuid_spec = { - .uuid = UUID_TRUSTED_KEY_CERT, -}; - -static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { - .uuid = UUID_SOC_FW_KEY_CERT, -}; - -static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { - .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, -}; - -static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { - .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, -}; - -static const io_uuid_spec_t soc_fw_cert_uuid_spec = { - .uuid = UUID_SOC_FW_CONTENT_CERT, -}; - -static const io_uuid_spec_t tos_fw_cert_uuid_spec = { - .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, -}; - -static const io_uuid_spec_t nt_fw_cert_uuid_spec = { - .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, -}; -#endif /* TRUSTED_BOARD_BOOT */ - -static const io_file_spec_t sh_file_spec[] = { - [BL2_IMAGE_ID] = { - .path = BL2_IMAGE_NAME, - .mode = FOPEN_MODE_RB - }, - [BL31_IMAGE_ID] = { - .path = BL31_IMAGE_NAME, - .mode = FOPEN_MODE_RB - }, - [BL32_IMAGE_ID] = { - .path = BL32_IMAGE_NAME, - .mode = FOPEN_MODE_RB - }, - [BL32_EXTRA1_IMAGE_ID] = { - .path = BL32_EXTRA1_IMAGE_NAME, - .mode = FOPEN_MODE_RB - }, - [BL32_EXTRA2_IMAGE_ID] = { - .path = BL32_EXTRA2_IMAGE_NAME, - .mode = FOPEN_MODE_RB - }, - [BL33_IMAGE_ID] = { - .path = BL33_IMAGE_NAME, - .mode = FOPEN_MODE_RB - }, -#if TRUSTED_BOARD_BOOT - [TRUSTED_BOOT_FW_CERT_ID] = { - .path = TRUSTED_BOOT_FW_CERT_NAME, - .mode = FOPEN_MODE_RB - }, - [TRUSTED_KEY_CERT_ID] = { - .path = TRUSTED_KEY_CERT_NAME, - .mode = FOPEN_MODE_RB - }, - [SOC_FW_KEY_CERT_ID] = { - .path = SOC_FW_KEY_CERT_NAME, - .mode = FOPEN_MODE_RB - }, - [TRUSTED_OS_FW_KEY_CERT_ID] = { - .path = TOS_FW_KEY_CERT_NAME, - .mode = FOPEN_MODE_RB - }, - [NON_TRUSTED_FW_KEY_CERT_ID] = { - .path = NT_FW_KEY_CERT_NAME, - .mode = FOPEN_MODE_RB - }, - [SOC_FW_CONTENT_CERT_ID] = { - .path = SOC_FW_CONTENT_CERT_NAME, - .mode = FOPEN_MODE_RB - }, - [TRUSTED_OS_FW_CONTENT_CERT_ID] = { - .path = TOS_FW_CONTENT_CERT_NAME, - .mode = FOPEN_MODE_RB - }, - [NON_TRUSTED_FW_CONTENT_CERT_ID] = { - .path = NT_FW_CONTENT_CERT_NAME, - .mode = FOPEN_MODE_RB - }, -#endif /* TRUSTED_BOARD_BOOT */ -}; - - - -static int open_fip(const uintptr_t spec); -static int open_memmap(const uintptr_t spec); - -struct plat_io_policy { - uintptr_t *dev_handle; - uintptr_t image_spec; - int (*check)(const uintptr_t spec); -}; - -/* By default, ARM platforms load images from the FIP */ -static const struct plat_io_policy policies[] = { - [FIP_IMAGE_ID] = { - &memmap_dev_handle, - (uintptr_t)&fip_block_spec, - open_memmap - }, - [BL2_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl2_uuid_spec, - open_fip - }, - [BL31_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl31_uuid_spec, - open_fip - }, - [BL32_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl32_uuid_spec, - open_fip - }, - [BL32_EXTRA1_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl32_extra1_uuid_spec, - open_fip - }, - [BL32_EXTRA2_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl32_extra2_uuid_spec, - open_fip - }, - [BL33_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl33_uuid_spec, - open_fip - }, -#if TRUSTED_BOARD_BOOT - [TRUSTED_BOOT_FW_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&tb_fw_cert_uuid_spec, - open_fip - }, - [TRUSTED_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&trusted_key_cert_uuid_spec, - open_fip - }, - [SOC_FW_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&soc_fw_key_cert_uuid_spec, - open_fip - }, - [TRUSTED_OS_FW_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&tos_fw_key_cert_uuid_spec, - open_fip - }, - [NON_TRUSTED_FW_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&nt_fw_key_cert_uuid_spec, - open_fip - }, - [SOC_FW_CONTENT_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&soc_fw_cert_uuid_spec, - open_fip - }, - [TRUSTED_OS_FW_CONTENT_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&tos_fw_cert_uuid_spec, - open_fip - }, - [NON_TRUSTED_FW_CONTENT_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&nt_fw_cert_uuid_spec, - open_fip - }, -#endif /* TRUSTED_BOARD_BOOT */ -}; - -static int open_fip(const uintptr_t spec) -{ - int result; - uintptr_t local_image_handle; - - /* See if a Firmware Image Package is available */ - result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); - if (result == 0) { - result = io_open(fip_dev_handle, spec, &local_image_handle); - if (result == 0) { - VERBOSE("Using FIP\n"); - io_close(local_image_handle); - } - } - return result; -} - -static int open_memmap(const uintptr_t spec) -{ - int result; - uintptr_t local_image_handle; - - result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); - if (result == 0) { - result = io_open(memmap_dev_handle, spec, &local_image_handle); - if (result == 0) { - VERBOSE("Using Memmap\n"); - io_close(local_image_handle); - } - } - return result; -} - -static int open_semihosting(const uintptr_t spec) -{ - int result; - uintptr_t local_image_handle; - - /* See if the file exists on semi-hosting.*/ - result = io_dev_init(sh_dev_handle, (uintptr_t)NULL); - if (result == 0) { - result = io_open(sh_dev_handle, spec, &local_image_handle); - if (result == 0) { - VERBOSE("Using Semi-hosting IO\n"); - io_close(local_image_handle); - } - } - return result; -} - -void plat_qemu_io_setup(void) -{ - int io_result; - - io_result = register_io_dev_fip(&fip_dev_con); - assert(io_result == 0); - - io_result = register_io_dev_memmap(&memmap_dev_con); - assert(io_result == 0); - - /* Open connections to devices and cache the handles */ - io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, - &fip_dev_handle); - assert(io_result == 0); - - io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, - &memmap_dev_handle); - assert(io_result == 0); - - /* Register the additional IO devices on this platform */ - io_result = register_io_dev_sh(&sh_dev_con); - assert(io_result == 0); - - /* Open connections to devices and cache the handles */ - io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle); - assert(io_result == 0); - - /* Ignore improbable errors in release builds */ - (void)io_result; -} - -static int get_alt_image_source(unsigned int image_id, uintptr_t *dev_handle, - uintptr_t *image_spec) -{ - int result = open_semihosting((const uintptr_t)&sh_file_spec[image_id]); - - if (result == 0) { - *dev_handle = sh_dev_handle; - *image_spec = (uintptr_t)&sh_file_spec[image_id]; - } - - return result; -} - -/* - * Return an IO device handle and specification which can be used to access - * an image. Use this to enforce platform load policy - */ -int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, - uintptr_t *image_spec) -{ - int result; - const struct plat_io_policy *policy; - - assert(image_id < ARRAY_SIZE(policies)); - - policy = &policies[image_id]; - result = policy->check(policy->image_spec); - if (result == 0) { - *image_spec = policy->image_spec; - *dev_handle = *(policy->dev_handle); - } else { - VERBOSE("Trying alternative IO\n"); - result = get_alt_image_source(image_id, dev_handle, image_spec); - } - - return result; -} diff --git a/plat/qemu/qemu_pm.c b/plat/qemu/qemu_pm.c deleted file mode 100644 index a199688..0000000 --- a/plat/qemu/qemu_pm.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include -#include -#include -#include - -#include "qemu_private.h" - -/* - * The secure entry point to be used on warm reset. - */ -static unsigned long secure_entrypoint; - -/* Make composite power state parameter till power level 0 */ -#if PSCI_EXTENDED_STATE_ID - -#define qemu_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type) \ - (((lvl0_state) << PSTATE_ID_SHIFT) | \ - ((type) << PSTATE_TYPE_SHIFT)) -#else -#define qemu_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type) \ - (((lvl0_state) << PSTATE_ID_SHIFT) | \ - ((pwr_lvl) << PSTATE_PWR_LVL_SHIFT) | \ - ((type) << PSTATE_TYPE_SHIFT)) -#endif /* PSCI_EXTENDED_STATE_ID */ - - -#define qemu_make_pwrstate_lvl1(lvl1_state, lvl0_state, pwr_lvl, type) \ - (((lvl1_state) << PLAT_LOCAL_PSTATE_WIDTH) | \ - qemu_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type)) - - - -/* - * The table storing the valid idle power states. Ensure that the - * array entries are populated in ascending order of state-id to - * enable us to use binary search during power state validation. - * The table must be terminated by a NULL entry. - */ -static const unsigned int qemu_pm_idle_states[] = { - /* State-id - 0x01 */ - qemu_make_pwrstate_lvl1(PLAT_LOCAL_STATE_RUN, PLAT_LOCAL_STATE_RET, - MPIDR_AFFLVL0, PSTATE_TYPE_STANDBY), - /* State-id - 0x02 */ - qemu_make_pwrstate_lvl1(PLAT_LOCAL_STATE_RUN, PLAT_LOCAL_STATE_OFF, - MPIDR_AFFLVL0, PSTATE_TYPE_POWERDOWN), - /* State-id - 0x22 */ - qemu_make_pwrstate_lvl1(PLAT_LOCAL_STATE_OFF, PLAT_LOCAL_STATE_OFF, - MPIDR_AFFLVL1, PSTATE_TYPE_POWERDOWN), - 0, -}; - -/******************************************************************************* - * Platform handler called to check the validity of the power state - * parameter. The power state parameter has to be a composite power state. - ******************************************************************************/ -static int qemu_validate_power_state(unsigned int power_state, - psci_power_state_t *req_state) -{ - unsigned int state_id; - int i; - - assert(req_state); - - /* - * Currently we are using a linear search for finding the matching - * entry in the idle power state array. This can be made a binary - * search if the number of entries justify the additional complexity. - */ - for (i = 0; !!qemu_pm_idle_states[i]; i++) { - if (power_state == qemu_pm_idle_states[i]) - break; - } - - /* Return error if entry not found in the idle state array */ - if (!qemu_pm_idle_states[i]) - return PSCI_E_INVALID_PARAMS; - - i = 0; - state_id = psci_get_pstate_id(power_state); - - /* Parse the State ID and populate the state info parameter */ - while (state_id) { - req_state->pwr_domain_state[i++] = state_id & - PLAT_LOCAL_PSTATE_MASK; - state_id >>= PLAT_LOCAL_PSTATE_WIDTH; - } - - return PSCI_E_SUCCESS; -} - -/******************************************************************************* - * Platform handler called to check the validity of the non secure - * entrypoint. - ******************************************************************************/ -static int qemu_validate_ns_entrypoint(uintptr_t entrypoint) -{ - /* - * Check if the non secure entrypoint lies within the non - * secure DRAM. - */ - if ((entrypoint >= NS_DRAM0_BASE) && - (entrypoint < (NS_DRAM0_BASE + NS_DRAM0_SIZE))) - return PSCI_E_SUCCESS; - return PSCI_E_INVALID_ADDRESS; -} - -/******************************************************************************* - * Platform handler called when a CPU is about to enter standby. - ******************************************************************************/ -static void qemu_cpu_standby(plat_local_state_t cpu_state) -{ - - assert(cpu_state == PLAT_LOCAL_STATE_RET); - - /* - * Enter standby state - * dsb is good practice before using wfi to enter low power states - */ - dsb(); - wfi(); -} - -/******************************************************************************* - * Platform handler called when a power domain is about to be turned on. The - * mpidr determines the CPU to be turned on. - ******************************************************************************/ -static int qemu_pwr_domain_on(u_register_t mpidr) -{ - int rc = PSCI_E_SUCCESS; - unsigned pos = plat_core_pos_by_mpidr(mpidr); - uint64_t *hold_base = (uint64_t *)PLAT_QEMU_HOLD_BASE; - - hold_base[pos] = PLAT_QEMU_HOLD_STATE_GO; - sev(); - - return rc; -} - -/******************************************************************************* - * Platform handler called when a power domain is about to be turned off. The - * target_state encodes the power state that each level should transition to. - ******************************************************************************/ -void qemu_pwr_domain_off(const psci_power_state_t *target_state) -{ - assert(0); -} - -/******************************************************************************* - * Platform handler called when a power domain is about to be suspended. The - * target_state encodes the power state that each level should transition to. - ******************************************************************************/ -void qemu_pwr_domain_suspend(const psci_power_state_t *target_state) -{ - assert(0); -} - -/******************************************************************************* - * Platform handler called when a power domain has just been powered on after - * being turned off earlier. The target_state encodes the low power state that - * each level has woken up from. - ******************************************************************************/ -void qemu_pwr_domain_on_finish(const psci_power_state_t *target_state) -{ - assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] == - PLAT_LOCAL_STATE_OFF); - - qemu_pwr_gic_on_finish(); -} - -/******************************************************************************* - * Platform handler called when a power domain has just been powered on after - * having been suspended earlier. The target_state encodes the low power state - * that each level has woken up from. - ******************************************************************************/ -void qemu_pwr_domain_suspend_finish(const psci_power_state_t *target_state) -{ - assert(0); -} - -/******************************************************************************* - * Platform handlers to shutdown/reboot the system - ******************************************************************************/ -static void __dead2 qemu_system_off(void) -{ - ERROR("QEMU System Off: operation not handled.\n"); - panic(); -} - -static void __dead2 qemu_system_reset(void) -{ - ERROR("QEMU System Reset: operation not handled.\n"); - panic(); -} - -static const plat_psci_ops_t plat_qemu_psci_pm_ops = { - .cpu_standby = qemu_cpu_standby, - .pwr_domain_on = qemu_pwr_domain_on, - .pwr_domain_off = qemu_pwr_domain_off, - .pwr_domain_suspend = qemu_pwr_domain_suspend, - .pwr_domain_on_finish = qemu_pwr_domain_on_finish, - .pwr_domain_suspend_finish = qemu_pwr_domain_suspend_finish, - .system_off = qemu_system_off, - .system_reset = qemu_system_reset, - .validate_power_state = qemu_validate_power_state, - .validate_ns_entrypoint = qemu_validate_ns_entrypoint -}; - -int plat_setup_psci_ops(uintptr_t sec_entrypoint, - const plat_psci_ops_t **psci_ops) -{ - uintptr_t *mailbox = (void *) PLAT_QEMU_TRUSTED_MAILBOX_BASE; - - *mailbox = sec_entrypoint; - secure_entrypoint = (unsigned long) sec_entrypoint; - *psci_ops = &plat_qemu_psci_pm_ops; - - return 0; -} diff --git a/plat/qemu/qemu_private.h b/plat/qemu/qemu_private.h deleted file mode 100644 index 71ea4de..0000000 --- a/plat/qemu/qemu_private.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef QEMU_PRIVATE_H -#define QEMU_PRIVATE_H - -#include - -void qemu_configure_mmu_svc_mon(unsigned long total_base, - unsigned long total_size, - unsigned long code_start, unsigned long code_limit, - unsigned long ro_start, unsigned long ro_limit, - unsigned long coh_start, unsigned long coh_limit); - -void qemu_configure_mmu_el1(unsigned long total_base, unsigned long total_size, - unsigned long code_start, unsigned long code_limit, - unsigned long ro_start, unsigned long ro_limit, - unsigned long coh_start, unsigned long coh_limit); - -void qemu_configure_mmu_el3(unsigned long total_base, unsigned long total_size, - unsigned long code_start, unsigned long code_limit, - unsigned long ro_start, unsigned long ro_limit, - unsigned long coh_start, unsigned long coh_limit); - -void plat_qemu_io_setup(void); -unsigned int plat_qemu_calc_core_pos(u_register_t mpidr); - -void qemu_console_init(void); - -void plat_qemu_gic_init(void); -void qemu_pwr_gic_on_finish(void); - -#endif /* QEMU_PRIVATE_H */ diff --git a/plat/qemu/qemu_rotpk.S b/plat/qemu/qemu_rotpk.S deleted file mode 100644 index 5d1b83f..0000000 --- a/plat/qemu/qemu_rotpk.S +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - - .global qemu_rotpk_hash - .global qemu_rotpk_hash_end -qemu_rotpk_hash: - /* DER header */ - .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48 - .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 - /* SHA256 */ - .incbin ROTPK_HASH -qemu_rotpk_hash_end: diff --git a/plat/qemu/qemu_stack_protector.c b/plat/qemu/qemu_stack_protector.c deleted file mode 100644 index c226158..0000000 --- a/plat/qemu/qemu_stack_protector.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include - -#define RANDOM_CANARY_VALUE ((u_register_t) 3288484550995823360ULL) - -u_register_t plat_get_stack_protector_canary(void) -{ - /* - * Ideally, a random number should be returned instead of the - * combination of a timer's value and a compile-time constant. - * As the virt platform does not have any random number generator, - * this is better than nothing but not necessarily really secure. - */ - return RANDOM_CANARY_VALUE ^ read_cntpct_el0(); -} - diff --git a/plat/qemu/qemu_trusted_boot.c b/plat/qemu/qemu_trusted_boot.c deleted file mode 100644 index 1ef7e43..0000000 --- a/plat/qemu/qemu_trusted_boot.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -extern char qemu_rotpk_hash[], qemu_rotpk_hash_end[]; - -int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, - unsigned int *flags) -{ - *key_ptr = qemu_rotpk_hash; - *key_len = qemu_rotpk_hash_end - qemu_rotpk_hash; - *flags = ROTPK_IS_HASH; - - return 0; -} - -int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr) -{ - *nv_ctr = 0; - - return 0; -} - -int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) -{ - return 1; -} - -int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size) -{ - return get_mbedtls_heap_helper(heap_addr, heap_size); -} diff --git a/plat/qemu/sp_min/sp_min-qemu.mk b/plat/qemu/sp_min/sp_min-qemu.mk deleted file mode 100644 index e93a0c2..0000000 --- a/plat/qemu/sp_min/sp_min-qemu.mk +++ /dev/null @@ -1,22 +0,0 @@ -# -# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause -# - -BL32_SOURCES += plat/qemu/sp_min/sp_min_setup.c \ - plat/qemu/aarch32/plat_helpers.S \ - plat/qemu/qemu_pm.c \ - plat/qemu/topology.c - -BL32_SOURCES += lib/cpus/aarch32/aem_generic.S \ - lib/cpus/aarch32/cortex_a15.S - -BL32_SOURCES += plat/common/aarch32/platform_mp_stack.S \ - plat/common/plat_psci_common.c \ - plat/common/plat_gicv2.c - - -BL32_SOURCES += drivers/arm/gic/v2/gicv2_helpers.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/common/gic_common.c diff --git a/plat/qemu/sp_min/sp_min_setup.c b/plat/qemu/sp_min/sp_min_setup.c deleted file mode 100644 index 7ec657b..0000000 --- a/plat/qemu/sp_min/sp_min_setup.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../qemu_private.h" - -#if RESET_TO_SP_MIN -#error qemu does not support RESET_TO_SP_MIN -#endif - -static entry_point_info_t bl33_image_ep_info; - -/****************************************************************************** - * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0 - * interrupts. - *****************************************************************************/ -#define PLATFORM_G1S_PROPS(grp) \ - INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, \ - grp, GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, \ - grp, GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, \ - grp, GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, \ - grp, GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, \ - grp, GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, \ - grp, GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, \ - grp, GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, \ - grp, GIC_INTR_CFG_LEVEL) - -#define PLATFORM_G0_PROPS(grp) - -static const interrupt_prop_t stih410_interrupt_props[] = { - PLATFORM_G1S_PROPS(GICV2_INTR_GROUP0), - PLATFORM_G0_PROPS(GICV2_INTR_GROUP0) -}; - -static unsigned int target_mask_array[PLATFORM_CORE_COUNT]; - -static const struct gicv2_driver_data plat_gicv2_driver_data = { - .gicd_base = GICD_BASE, - .gicc_base = GICC_BASE, - .interrupt_props = stih410_interrupt_props, - .interrupt_props_num = ARRAY_SIZE(stih410_interrupt_props), - .target_masks = target_mask_array, - .target_masks_num = ARRAY_SIZE(target_mask_array), -}; - -/******************************************************************************* - * Return a pointer to the 'entry_point_info' structure of the next image for - * the security state specified. BL33 corresponds to the non-secure image type - * while BL32 corresponds to the secure image type. A NULL pointer is returned - * if the image does not exist. - ******************************************************************************/ -entry_point_info_t *sp_min_plat_get_bl33_ep_info(void) -{ - entry_point_info_t *next_image_info = &bl33_image_ep_info; - - /* - * None of the images on the ARM development platforms can have 0x0 - * as the entrypoint - */ - if (next_image_info->pc) - return next_image_info; - else - return NULL; -} - -void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, - u_register_t arg2, u_register_t arg3) -{ - bl_params_t *params_from_bl2 = (bl_params_t *)arg0; - - /* Initialize the console to provide early debug support */ - qemu_console_init(); - - ERROR("qemu sp_min, console init\n"); - /* - * Check params passed from BL2 - */ - assert(params_from_bl2); - assert(params_from_bl2->h.type == PARAM_BL_PARAMS); - assert(params_from_bl2->h.version >= VERSION_2); - - bl_params_node_t *bl_params = params_from_bl2->head; - - /* - * Copy BL33 entry point information from BL2's address space. - */ - while (bl_params) { - 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) - panic(); -} - -void sp_min_plat_arch_setup(void) -{ - qemu_configure_mmu_svc_mon(BL32_RO_BASE, BL32_END - BL32_RO_BASE, - BL_CODE_BASE, BL_CODE_END, - BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END); - -} - -void sp_min_platform_setup(void) -{ - /* Initialize the gic cpu and distributor interfaces */ - gicv2_driver_init(&plat_gicv2_driver_data); - gicv2_distif_init(); - gicv2_pcpu_distif_init(); - gicv2_cpuif_enable(); -} - -unsigned int plat_get_syscnt_freq2(void) -{ - return SYS_COUNTER_FREQ_IN_TICKS; -} - -void sp_min_plat_fiq_handler(uint32_t id) -{ - VERBOSE("[sp_min] interrupt #%d\n", id); -} diff --git a/plat/qemu/topology.c b/plat/qemu/topology.c deleted file mode 100644 index 6352706..0000000 --- a/plat/qemu/topology.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include - -#include - -#include "qemu_private.h" - -/* The power domain tree descriptor */ -static unsigned char power_domain_tree_desc[] = { - /* Number of root nodes */ - PLATFORM_CLUSTER_COUNT, - /* Number of children for the first node */ - PLATFORM_CLUSTER0_CORE_COUNT, - /* Number of children for the second node */ - PLATFORM_CLUSTER1_CORE_COUNT, -}; - -/******************************************************************************* - * This function returns the ARM default topology tree information. - ******************************************************************************/ -const unsigned char *plat_get_power_domain_tree_desc(void) -{ - return power_domain_tree_desc; -} - -/******************************************************************************* - * This function implements a part of the critical interface between the psci - * generic layer and the platform that allows the former to query the platform - * to convert an MPIDR to a unique linear index. An error code (-1) is returned - * in case the MPIDR is invalid. - ******************************************************************************/ -int plat_core_pos_by_mpidr(u_register_t mpidr) -{ - unsigned int cluster_id, cpu_id; - - mpidr &= MPIDR_AFFINITY_MASK; - if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) - return -1; - - cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; - cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK; - - if (cluster_id >= PLATFORM_CLUSTER_COUNT) - return -1; - - if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER) - return -1; - - return plat_qemu_calc_core_pos(mpidr); -}