diff options
author | danh-arm <dan.handley@arm.com> | 2014-05-06 17:54:03 +0100 |
---|---|---|
committer | danh-arm <dan.handley@arm.com> | 2014-05-06 17:54:03 +0100 |
commit | 408c37682a0233c8c4fa88700b603f0b09d6361f (patch) | |
tree | 18133148dea88d9a2313113111b24b56e8130505 /bl31 | |
parent | b495bdef190acf166c713e138b61c5bb25402fc0 (diff) | |
parent | 97043ac98e13a726dbf8b3b41654dca759e3da2c (diff) | |
download | arm-trusted-firmware-408c37682a0233c8c4fa88700b603f0b09d6361f.tar.gz |
Merge pull request #48 from danh-arm/dh/major-refactoring
dh/major refactoring
Diffstat (limited to 'bl31')
-rw-r--r-- | bl31/aarch64/bl31_arch_setup.c | 5 | ||||
-rw-r--r-- | bl31/aarch64/bl31_entrypoint.S | 5 | ||||
-rw-r--r-- | bl31/aarch64/context.S | 3 | ||||
-rw-r--r-- | bl31/aarch64/runtime_exceptions.S | 8 | ||||
-rw-r--r-- | bl31/bl31.mk | 61 | ||||
-rw-r--r-- | bl31/bl31_main.c | 17 | ||||
-rw-r--r-- | bl31/context_mgmt.c | 36 | ||||
-rw-r--r-- | bl31/runtime_svc.c | 145 |
8 files changed, 200 insertions, 80 deletions
diff --git a/bl31/aarch64/bl31_arch_setup.c b/bl31/aarch64/bl31_arch_setup.c index 793b895..acaa6b5 100644 --- a/bl31/aarch64/bl31_arch_setup.c +++ b/bl31/aarch64/bl31_arch_setup.c @@ -28,9 +28,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include <arch.h> #include <arch_helpers.h> -#include <platform.h> #include <assert.h> +#include <bl_common.h> +#include <bl31.h> +#include <platform.h> /******************************************************************************* * This duplicates what the primary cpu did after a cold boot in BL1. The same diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S index d35b50a..39fa605 100644 --- a/bl31/aarch64/bl31_entrypoint.S +++ b/bl31/aarch64/bl31_entrypoint.S @@ -28,11 +28,10 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <bl_common.h> -#include <platform.h> #include <arch.h> -#include "cm_macros.S" #include <asm_macros.S> +#include <bl_common.h> +#include <cm_macros.S> .globl bl31_entrypoint diff --git a/bl31/aarch64/context.S b/bl31/aarch64/context.S index 2b2e7bf..45d4a22 100644 --- a/bl31/aarch64/context.S +++ b/bl31/aarch64/context.S @@ -28,8 +28,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <context.h> +#include <arch.h> #include <asm_macros.S> +#include <context.h> /* ----------------------------------------------------- * The following function strictly follows the AArch64 diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S index d00c1d7..53cc176 100644 --- a/bl31/aarch64/runtime_exceptions.S +++ b/bl31/aarch64/runtime_exceptions.S @@ -29,11 +29,11 @@ */ #include <arch.h> -#include <runtime_svc.h> -#include <platform.h> +#include <asm_macros.S> +#include <cm_macros.S> #include <context.h> -#include "asm_macros.S" -#include "cm_macros.S" +#include <platform.h> +#include <runtime_svc.h> .globl runtime_exceptions .globl el3_exit diff --git a/bl31/bl31.mk b/bl31/bl31.mk index 38765bc..ef40f67 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -28,46 +28,23 @@ # POSSIBILITY OF SUCH DAMAGE. # -vpath %.c common \ - lib \ - arch/system/gic \ - plat/${PLAT} \ - arch/${ARCH} \ - services/std_svc \ - services/std_svc/psci \ - lib/sync/locks/bakery \ - plat/${PLAT}/${ARCH} \ - ${PLAT_BL31_C_VPATH} +BL31_SOURCES += bl31/bl31_main.c \ + bl31/context_mgmt.c \ + bl31/runtime_svc.c \ + bl31/aarch64/bl31_arch_setup.c \ + bl31/aarch64/bl31_entrypoint.S \ + bl31/aarch64/context.S \ + bl31/aarch64/runtime_exceptions.S \ + common/aarch64/early_exceptions.S \ + lib/locks/bakery/bakery_lock.c \ + lib/locks/exclusive/spinlock.S \ + services/std_svc/std_svc_setup.c \ + services/std_svc/psci/psci_afflvl_off.c \ + services/std_svc/psci/psci_afflvl_on.c \ + services/std_svc/psci/psci_afflvl_suspend.c \ + services/std_svc/psci/psci_common.c \ + services/std_svc/psci/psci_entry.S \ + services/std_svc/psci/psci_main.c \ + services/std_svc/psci/psci_setup.c -vpath %.S lib/arch/${ARCH} \ - services/std_svc \ - services/std_svc/psci \ - include \ - plat/${PLAT}/${ARCH} \ - lib/sync/locks/exclusive \ - plat/common/${ARCH} \ - arch/system/gic/${ARCH} \ - common/${ARCH} \ - ${PLAT_BL31_S_VPATH} - -BL31_SOURCES += bl31_arch_setup.c \ - bl31_entrypoint.S \ - runtime_exceptions.S \ - bl31_main.c \ - std_svc_setup.c \ - psci_entry.S \ - psci_setup.c \ - psci_common.c \ - psci_afflvl_on.c \ - psci_main.c \ - psci_afflvl_off.c \ - psci_afflvl_suspend.c \ - spinlock.S \ - gic_v3_sysregs.S \ - bakery_lock.c \ - runtime_svc.c \ - early_exceptions.S \ - context_mgmt.c \ - context.S - -BL31_LINKERFILE := bl31.ld.S +BL31_LINKERFILE := bl31/bl31.ld.S diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c index 536bb86..cf826d0 100644 --- a/bl31/bl31_main.c +++ b/bl31/bl31_main.c @@ -28,17 +28,14 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <stdio.h> -#include <string.h> -#include <assert.h> +#include <arch.h> #include <arch_helpers.h> -#include <console.h> -#include <platform.h> -#include <semihosting.h> +#include <assert.h> #include <bl_common.h> #include <bl31.h> -#include <runtime_svc.h> #include <context_mgmt.h> +#include <runtime_svc.h> +#include <stdio.h> /******************************************************************************* @@ -47,7 +44,7 @@ * for SP execution. In cases where both SPD and SP are absent, or when SPD * finds it impossible to execute SP, this pointer is left as NULL ******************************************************************************/ -static int32_t (*bl32_init)(meminfo *); +static int32_t (*bl32_init)(meminfo_t *); /******************************************************************************* * Variable to indicate whether next image to execute after BL31 is BL33 @@ -153,7 +150,7 @@ uint32_t bl31_get_next_image_type(void) ******************************************************************************/ void bl31_prepare_next_image_entry() { - el_change_info *next_image_info; + el_change_info_t *next_image_info; uint32_t scr, image_type; /* Determine which image to execute next */ @@ -190,7 +187,7 @@ void bl31_prepare_next_image_entry() * This function initializes the pointer to BL32 init function. This is expected * to be called by the SPD after it finishes all its initialization ******************************************************************************/ -void bl31_register_bl32_init(int32_t (*func)(meminfo *)) +void bl31_register_bl32_init(int32_t (*func)(meminfo_t *)) { bl32_init = func; } diff --git a/bl31/context_mgmt.c b/bl31/context_mgmt.c index 60c3492..8d1396e 100644 --- a/bl31/context_mgmt.c +++ b/bl31/context_mgmt.c @@ -28,15 +28,13 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <assert.h> #include <arch_helpers.h> -#include <platform.h> +#include <assert.h> #include <bl_common.h> -#include <runtime_svc.h> +#include <context.h> #include <context_mgmt.h> +#include <platform.h> +#include <runtime_svc.h> /******************************************************************************* * Data structure which holds the pointers to non-secure and secure security @@ -45,9 +43,9 @@ ******************************************************************************/ typedef struct { void *ptr[2]; -} __aligned (CACHE_WRITEBACK_GRANULE) context_info; +} __aligned (CACHE_WRITEBACK_GRANULE) context_info_t; -static context_info cm_context_info[PLATFORM_CORE_COUNT]; +static context_info_t cm_context_info[PLATFORM_CORE_COUNT]; /******************************************************************************* * Context management library initialisation routine. This library is used by @@ -104,7 +102,7 @@ void cm_set_context(uint64_t mpidr, void *context, uint32_t security_state) ******************************************************************************/ void cm_el3_sysregs_context_save(uint32_t security_state) { - cpu_context *ctx; + cpu_context_t *ctx; ctx = cm_get_context(read_mpidr(), security_state); assert(ctx); @@ -114,7 +112,7 @@ void cm_el3_sysregs_context_save(uint32_t security_state) void cm_el3_sysregs_context_restore(uint32_t security_state) { - cpu_context *ctx; + cpu_context_t *ctx; ctx = cm_get_context(read_mpidr(), security_state); assert(ctx); @@ -124,7 +122,7 @@ void cm_el3_sysregs_context_restore(uint32_t security_state) void cm_el1_sysregs_context_save(uint32_t security_state) { - cpu_context *ctx; + cpu_context_t *ctx; ctx = cm_get_context(read_mpidr(), security_state); assert(ctx); @@ -134,7 +132,7 @@ void cm_el1_sysregs_context_save(uint32_t security_state) void cm_el1_sysregs_context_restore(uint32_t security_state) { - cpu_context *ctx; + cpu_context_t *ctx; ctx = cm_get_context(read_mpidr(), security_state); assert(ctx); @@ -151,8 +149,8 @@ void cm_el1_sysregs_context_restore(uint32_t security_state) void cm_set_el3_eret_context(uint32_t security_state, uint64_t entrypoint, uint32_t spsr, uint32_t scr) { - cpu_context *ctx; - el3_state *state; + cpu_context_t *ctx; + el3_state_t *state; ctx = cm_get_context(read_mpidr(), security_state); assert(ctx); @@ -170,8 +168,8 @@ void cm_set_el3_eret_context(uint32_t security_state, uint64_t entrypoint, ******************************************************************************/ void cm_set_el3_elr(uint32_t security_state, uint64_t entrypoint) { - cpu_context *ctx; - el3_state *state; + cpu_context_t *ctx; + el3_state_t *state; ctx = cm_get_context(read_mpidr(), security_state); assert(ctx); @@ -188,7 +186,7 @@ void cm_set_el3_elr(uint32_t security_state, uint64_t entrypoint) ******************************************************************************/ void cm_set_next_eret_context(uint32_t security_state) { - cpu_context *ctx; + cpu_context_t *ctx; #if DEBUG uint64_t sp_mode; #endif @@ -220,8 +218,8 @@ void cm_set_next_eret_context(uint32_t security_state) ******************************************************************************/ void cm_init_exception_stack(uint64_t mpidr, uint32_t security_state) { - cpu_context *ctx; - el3_state *state; + cpu_context_t *ctx; + el3_state_t *state; ctx = cm_get_context(mpidr, security_state); assert(ctx); diff --git a/bl31/runtime_svc.c b/bl31/runtime_svc.c new file mode 100644 index 0000000..9a68e50 --- /dev/null +++ b/bl31/runtime_svc.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <debug.h> +#include <errno.h> +#include <runtime_svc.h> +#include <string.h> + +/******************************************************************************* + * The 'rt_svc_descs' array holds the runtime service descriptors exported by + * services by placing them in the 'rt_svc_descs' linker section. + * The 'rt_svc_descs_indices' array holds the index of a descriptor in the + * 'rt_svc_descs' array. When an SMC arrives, the OEN[29:24] bits and the call + * type[31] bit in the function id are combined to get an index into the + * 'rt_svc_descs_indices' array. This gives the index of the descriptor in the + * 'rt_svc_descs' array which contains the SMC handler. + ******************************************************************************/ +#define RT_SVC_DESCS_START ((uint64_t) (&__RT_SVC_DESCS_START__)) +#define RT_SVC_DESCS_END ((uint64_t) (&__RT_SVC_DESCS_END__)) +uint8_t rt_svc_descs_indices[MAX_RT_SVCS]; +static rt_svc_desc_t *rt_svc_descs; + +/******************************************************************************* + * Simple routine to sanity check a runtime service descriptor before using it + ******************************************************************************/ +static int32_t validate_rt_svc_desc(rt_svc_desc_t *desc) +{ + if (desc == NULL) + return -EINVAL; + + if (desc->start_oen > desc->end_oen) + return -EINVAL; + + if (desc->end_oen >= OEN_LIMIT) + return -EINVAL; + + if (desc->call_type != SMC_TYPE_FAST && desc->call_type != SMC_TYPE_STD) + return -EINVAL; + + /* A runtime service having no init or handle function doesn't make sense */ + if (desc->init == NULL && desc->handle == NULL) + return -EINVAL; + + return 0; +} + +/******************************************************************************* + * This function calls the initialisation routine in the descriptor exported by + * a runtime service. Once a descriptor has been validated, its start & end + * owning entity numbers and the call type are combined to form a unique oen. + * The unique oen is used as an index into the 'rt_svc_descs_indices' array. + * The index of the runtime service descriptor is stored at this index. + ******************************************************************************/ +void runtime_svc_init() +{ + int32_t rc = 0; + uint32_t index, start_idx, end_idx; + uint64_t rt_svc_descs_num; + + /* If no runtime services are implemented then simply bail out */ + rt_svc_descs_num = RT_SVC_DESCS_END - RT_SVC_DESCS_START; + rt_svc_descs_num /= sizeof(rt_svc_desc_t); + if (rt_svc_descs_num == 0) + return; + + /* Initialise internal variables to invalid state */ + memset(rt_svc_descs_indices, -1, sizeof(rt_svc_descs_indices)); + + rt_svc_descs = (rt_svc_desc_t *) RT_SVC_DESCS_START; + for (index = 0; index < rt_svc_descs_num; index++) { + + /* + * An invalid descriptor is an error condition since it is + * difficult to predict the system behaviour in the absence + * of this service. + */ + rc = validate_rt_svc_desc(&rt_svc_descs[index]); + if (rc) { + ERROR("Invalid runtime service descriptor 0x%x (%s)\n", + &rt_svc_descs[index], + rt_svc_descs[index].name); + goto error; + } + + /* Call the initialisation routine for this runtime service */ + rc = rt_svc_descs[index].init(); + if (rc) { + ERROR("Error initializing runtime service %s\n", + rt_svc_descs[index].name); + } else { + /* + * Fill the indices corresponding to the start and end + * owning entity numbers with the index of the + * descriptor which will handle the SMCs for this owning + * entity range. + */ + start_idx = get_unique_oen(rt_svc_descs[index].start_oen, + rt_svc_descs[index].call_type); + end_idx = get_unique_oen(rt_svc_descs[index].end_oen, + rt_svc_descs[index].call_type); + + for (; start_idx <= end_idx; start_idx++) + rt_svc_descs_indices[start_idx] = index; + } + } + + return; +error: + panic(); +} + +void fault_handler(void *handle) +{ + gp_regs_t *gpregs_ctx = get_gpregs_ctx(handle); + ERROR("Unhandled synchronous fault. Register dump @ 0x%x \n", + gpregs_ctx); + panic(); +} |