Commit 3dd9835f authored by danh-arm's avatar danh-arm Committed by GitHub
Browse files

Merge pull request #667 from soby-mathew/sm/PSCI_lib

Introduce PSCI library
parents bc469a84 738b1fd7
Showing with 309 additions and 232 deletions
+309 -232
...@@ -226,20 +226,24 @@ BL_COMMON_SOURCES += common/bl_common.c \ ...@@ -226,20 +226,24 @@ BL_COMMON_SOURCES += common/bl_common.c \
plat/common/aarch64/platform_helpers.S \ plat/common/aarch64/platform_helpers.S \
${STDLIB_SRCS} ${STDLIB_SRCS}
INCLUDES += -Iinclude/bl1 \ INCLUDES += -Iinclude/bl1 \
-Iinclude/bl31 \ -Iinclude/bl31 \
-Iinclude/bl31/services \ -Iinclude/common \
-Iinclude/common \ -Iinclude/common/aarch64 \
-Iinclude/drivers \ -Iinclude/drivers \
-Iinclude/drivers/arm \ -Iinclude/drivers/arm \
-Iinclude/drivers/auth \ -Iinclude/drivers/auth \
-Iinclude/drivers/io \ -Iinclude/drivers/io \
-Iinclude/drivers/ti/uart \ -Iinclude/drivers/ti/uart \
-Iinclude/lib \ -Iinclude/lib \
-Iinclude/lib/aarch64 \ -Iinclude/lib/aarch64 \
-Iinclude/lib/cpus/aarch64 \ -Iinclude/lib/cpus/aarch64 \
-Iinclude/plat/common \ -Iinclude/lib/el3_runtime \
${PLAT_INCLUDES} \ -Iinclude/lib/el3_runtime/aarch64 \
-Iinclude/lib/psci \
-Iinclude/plat/common \
-Iinclude/services \
${PLAT_INCLUDES} \
${SPD_INCLUDES} ${SPD_INCLUDES}
......
# #
# Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. # Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met: # modification, are permitted provided that the following conditions are met:
...@@ -33,9 +33,9 @@ BL1_SOURCES += bl1/bl1_main.c \ ...@@ -33,9 +33,9 @@ BL1_SOURCES += bl1/bl1_main.c \
bl1/aarch64/bl1_entrypoint.S \ bl1/aarch64/bl1_entrypoint.S \
bl1/aarch64/bl1_exceptions.S \ bl1/aarch64/bl1_exceptions.S \
bl1/bl1_context_mgmt.c \ bl1/bl1_context_mgmt.c \
common/aarch64/context.S \
common/context_mgmt.c \
lib/cpus/aarch64/cpu_helpers.S \ lib/cpus/aarch64/cpu_helpers.S \
lib/el3_runtime/aarch64/context.S \
lib/el3_runtime/aarch64/context_mgmt.c \
plat/common/plat_bl1_common.c plat/common/plat_bl1_common.c
ifeq (${TRUSTED_BOARD_BOOT},1) ifeq (${TRUSTED_BOARD_BOOT},1)
......
/* /*
* Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -31,9 +31,10 @@ ...@@ -31,9 +31,10 @@
#include <arch.h> #include <arch.h>
#include <bl_common.h> #include <bl_common.h>
#include <el3_common_macros.S> #include <el3_common_macros.S>
#include <xlat_tables.h>
.globl bl31_entrypoint .globl bl31_entrypoint
.globl bl31_warm_entrypoint
/* ----------------------------------------------------- /* -----------------------------------------------------
* bl31_entrypoint() is the cold boot entrypoint, * bl31_entrypoint() is the cold boot entrypoint,
...@@ -132,3 +133,60 @@ func bl31_entrypoint ...@@ -132,3 +133,60 @@ func bl31_entrypoint
b el3_exit b el3_exit
endfunc bl31_entrypoint endfunc bl31_entrypoint
/* --------------------------------------------------------------------
* This CPU has been physically powered up. It is either resuming from
* suspend or has simply been turned on. In both cases, call the BL31
* warmboot entrypoint
* --------------------------------------------------------------------
*/
func bl31_warm_entrypoint
/*
* On the warm boot path, most of the EL3 initialisations performed by
* 'el3_entrypoint_common' must be skipped:
*
* - Only when the platform bypasses the BL1/BL31 entrypoint by
* programming the reset address do we need to set the CPU endianness.
* In other cases, we assume this has been taken care by the
* entrypoint code.
*
* - No need to determine the type of boot, we know it is a warm boot.
*
* - Do not try to distinguish between primary and secondary CPUs, this
* notion only exists for a cold boot.
*
* - No need to initialise the memory or the C runtime environment,
* it has been done once and for all on the cold boot path.
*/
el3_entrypoint_common \
_set_endian=PROGRAMMABLE_RESET_ADDRESS \
_warm_boot_mailbox=0 \
_secondary_cold_boot=0 \
_init_memory=0 \
_init_c_runtime=0 \
_exception_vectors=runtime_exceptions
/* --------------------------------------------
* Enable the MMU with the DCache disabled. It
* is safe to use stacks allocated in normal
* memory as a result. All memory accesses are
* marked nGnRnE when the MMU is disabled. So
* all the stack writes will make it to memory.
* All memory accesses are marked Non-cacheable
* when the MMU is enabled but D$ is disabled.
* So used stack memory is guaranteed to be
* visible immediately after the MMU is enabled
* Enabling the DCache at the same time as the
* MMU can lead to speculatively fetched and
* possibly stale stack memory being read from
* other caches. This can lead to coherency
* issues.
* --------------------------------------------
*/
mov x0, #DISABLE_DCACHE
bl bl31_plat_enable_mmu
bl psci_warmboot_entrypoint
b el3_exit
endfunc bl31_warm_entrypoint
...@@ -28,45 +28,22 @@ ...@@ -28,45 +28,22 @@
# POSSIBILITY OF SUCH DAMAGE. # POSSIBILITY OF SUCH DAMAGE.
# #
include lib/psci/psci_lib.mk
BL31_SOURCES += bl31/bl31_main.c \ BL31_SOURCES += bl31/bl31_main.c \
bl31/cpu_data_array.c \
bl31/runtime_svc.c \
bl31/interrupt_mgmt.c \ bl31/interrupt_mgmt.c \
bl31/aarch64/bl31_arch_setup.c \
bl31/aarch64/bl31_entrypoint.S \ bl31/aarch64/bl31_entrypoint.S \
bl31/aarch64/cpu_data.S \
bl31/aarch64/runtime_exceptions.S \ bl31/aarch64/runtime_exceptions.S \
bl31/aarch64/crash_reporting.S \ bl31/aarch64/crash_reporting.S \
bl31/bl31_context_mgmt.c \ bl31/bl31_context_mgmt.c \
common/aarch64/context.S \ common/runtime_svc.c \
common/context_mgmt.c \
lib/cpus/aarch64/cpu_helpers.S \
lib/locks/exclusive/spinlock.S \
services/std_svc/std_svc_setup.c \ services/std_svc/std_svc_setup.c \
services/std_svc/psci/psci_off.c \ ${PSCI_LIB_SOURCES}
services/std_svc/psci/psci_on.c \
services/std_svc/psci/psci_suspend.c \
services/std_svc/psci/psci_common.c \
services/std_svc/psci/psci_entry.S \
services/std_svc/psci/psci_helpers.S \
services/std_svc/psci/psci_main.c \
services/std_svc/psci/psci_setup.c \
services/std_svc/psci/psci_system_off.c
ifeq (${USE_COHERENT_MEM}, 1)
BL31_SOURCES += lib/locks/bakery/bakery_lock_coherent.c
else
BL31_SOURCES += lib/locks/bakery/bakery_lock_normal.c
endif
ifeq (${ENABLE_PMF}, 1) ifeq (${ENABLE_PMF}, 1)
BL31_SOURCES += lib/pmf/pmf_main.c BL31_SOURCES += lib/pmf/pmf_main.c
endif endif
ifeq (${ENABLE_PSCI_STAT}, 1)
BL31_SOURCES += services/std_svc/psci/psci_stat.c
endif
BL31_LINKERFILE := bl31/bl31.ld.S BL31_LINKERFILE := bl31/bl31.ld.S
# Flag used to indicate if Crash reporting via console should be included # Flag used to indicate if Crash reporting via console should be included
......
/* /*
* Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <assert.h> #include <assert.h>
#include <bl31.h> #include <bl31.h>
#include <bl_common.h>
#include <context.h> #include <context.h>
#include <context_mgmt.h> #include <context_mgmt.h>
#include <cpu_data.h> #include <cpu_data.h>
...@@ -130,4 +131,4 @@ void cm_init_context(unsigned long mpidr, const entry_point_info_t *ep) ...@@ -130,4 +131,4 @@ void cm_init_context(unsigned long mpidr, const entry_point_info_t *ep)
else else
cm_init_context_by_index(platform_get_core_pos(mpidr), ep); cm_init_context_by_index(platform_get_core_pos(mpidr), ep);
} }
#endif #endif
\ No newline at end of file
/* /*
* Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -59,6 +59,12 @@ static uint32_t next_image_type = NON_SECURE; ...@@ -59,6 +59,12 @@ static uint32_t next_image_type = NON_SECURE;
void bl31_lib_init(void) void bl31_lib_init(void)
{ {
cm_init(); cm_init();
/*
* Initialize the PSCI library here. This also does EL3 architectural
* setup.
*/
psci_setup((uintptr_t)bl31_warm_entrypoint);
} }
/******************************************************************************* /*******************************************************************************
...@@ -74,9 +80,6 @@ void bl31_main(void) ...@@ -74,9 +80,6 @@ void bl31_main(void)
NOTICE("BL31: %s\n", version_string); NOTICE("BL31: %s\n", version_string);
NOTICE("BL31: %s\n", build_message); NOTICE("BL31: %s\n", build_message);
/* Perform remaining generic architectural setup from EL3 */
bl31_arch_setup();
/* Perform platform setup in BL31 */ /* Perform platform setup in BL31 */
bl31_platform_setup(); bl31_platform_setup();
......
/* /*
* Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -40,24 +40,20 @@ ...@@ -40,24 +40,20 @@
#include <string.h> #include <string.h>
#include <xlat_tables.h> #include <xlat_tables.h>
unsigned long page_align(unsigned long value, unsigned dir) uintptr_t page_align(uintptr_t value, unsigned dir)
{ {
unsigned long page_size = 1 << FOUR_KB_SHIFT;
/* Round up the limit to the next page boundary */ /* Round up the limit to the next page boundary */
if (value & (page_size - 1)) { if (value & (PAGE_SIZE - 1)) {
value &= ~(page_size - 1); value &= ~(PAGE_SIZE - 1);
if (dir == UP) if (dir == UP)
value += page_size; value += PAGE_SIZE;
} }
return value; return value;
} }
static inline unsigned int is_page_aligned (unsigned long addr) { static inline unsigned int is_page_aligned (uintptr_t addr) {
const unsigned long page_size = 1 << FOUR_KB_SHIFT; return (addr & (PAGE_SIZE - 1)) == 0;
return (addr & (page_size - 1)) == 0;
} }
/****************************************************************************** /******************************************************************************
...@@ -65,8 +61,8 @@ static inline unsigned int is_page_aligned (unsigned long addr) { ...@@ -65,8 +61,8 @@ static inline unsigned int is_page_aligned (unsigned long addr) {
* given the extents of free memory. * given the extents of free memory.
* Return 1 if it is free, 0 otherwise. * Return 1 if it is free, 0 otherwise.
*****************************************************************************/ *****************************************************************************/
static int is_mem_free(uint64_t free_base, size_t free_size, static int is_mem_free(uintptr_t free_base, size_t free_size,
uint64_t addr, size_t size) uintptr_t addr, size_t size)
{ {
return (addr >= free_base) && (addr + size <= free_base + free_size); return (addr >= free_base) && (addr + size <= free_base + free_size);
} }
...@@ -77,9 +73,9 @@ static int is_mem_free(uint64_t free_base, size_t free_size, ...@@ -77,9 +73,9 @@ static int is_mem_free(uint64_t free_base, size_t free_size,
* size of the smallest chunk of free memory surrounding the sub-region in * size of the smallest chunk of free memory surrounding the sub-region in
* 'small_chunk_size'. * 'small_chunk_size'.
*****************************************************************************/ *****************************************************************************/
static unsigned int choose_mem_pos(uint64_t mem_start, uint64_t mem_end, static unsigned int choose_mem_pos(uintptr_t mem_start, uintptr_t mem_end,
uint64_t submem_start, uint64_t submem_end, uintptr_t submem_start, uintptr_t submem_end,
size_t *small_chunk_size) size_t *small_chunk_size)
{ {
size_t top_chunk_size, bottom_chunk_size; size_t top_chunk_size, bottom_chunk_size;
...@@ -106,8 +102,8 @@ static unsigned int choose_mem_pos(uint64_t mem_start, uint64_t mem_end, ...@@ -106,8 +102,8 @@ static unsigned int choose_mem_pos(uint64_t mem_start, uint64_t mem_end,
* reflect the memory usage. * reflect the memory usage.
* The caller must ensure the memory to reserve is free. * The caller must ensure the memory to reserve is free.
*****************************************************************************/ *****************************************************************************/
void reserve_mem(uint64_t *free_base, size_t *free_size, void reserve_mem(uintptr_t *free_base, size_t *free_size,
uint64_t addr, size_t size) uintptr_t addr, size_t size)
{ {
size_t discard_size; size_t discard_size;
size_t reserved_size; size_t reserved_size;
...@@ -127,26 +123,26 @@ void reserve_mem(uint64_t *free_base, size_t *free_size, ...@@ -127,26 +123,26 @@ void reserve_mem(uint64_t *free_base, size_t *free_size,
if (pos == BOTTOM) if (pos == BOTTOM)
*free_base = addr + size; *free_base = addr + size;
VERBOSE("Reserved 0x%lx bytes (discarded 0x%lx bytes %s)\n", VERBOSE("Reserved 0x%zx bytes (discarded 0x%zx bytes %s)\n",
reserved_size, discard_size, reserved_size, discard_size,
pos == TOP ? "above" : "below"); pos == TOP ? "above" : "below");
} }
static void dump_load_info(unsigned long image_load_addr, static void dump_load_info(uintptr_t image_load_addr,
unsigned long image_size, size_t image_size,
const meminfo_t *mem_layout) const meminfo_t *mem_layout)
{ {
INFO("Trying to load image at address 0x%lx, size = 0x%lx\n", INFO("Trying to load image at address %p, size = 0x%zx\n",
image_load_addr, image_size); (void *)image_load_addr, image_size);
INFO("Current memory layout:\n"); INFO("Current memory layout:\n");
INFO(" total region = [0x%lx, 0x%lx]\n", mem_layout->total_base, INFO(" total region = [%p, %p]\n", (void *)mem_layout->total_base,
mem_layout->total_base + mem_layout->total_size); (void *)(mem_layout->total_base + mem_layout->total_size));
INFO(" free region = [0x%lx, 0x%lx]\n", mem_layout->free_base, INFO(" free region = [%p, %p]\n", (void *)mem_layout->free_base,
mem_layout->free_base + mem_layout->free_size); (void *)(mem_layout->free_base + mem_layout->free_size));
} }
/* Generic function to return the size of an image */ /* Generic function to return the size of an image */
unsigned long image_size(unsigned int image_id) size_t image_size(unsigned int image_id)
{ {
uintptr_t dev_handle; uintptr_t dev_handle;
uintptr_t image_handle; uintptr_t image_handle;
...@@ -367,9 +363,8 @@ int load_auth_image(meminfo_t *mem_layout, ...@@ -367,9 +363,8 @@ int load_auth_image(meminfo_t *mem_layout,
******************************************************************************/ ******************************************************************************/
void print_entry_point_info(const entry_point_info_t *ep_info) void print_entry_point_info(const entry_point_info_t *ep_info)
{ {
INFO("Entry point address = 0x%llx\n", INFO("Entry point address = %p\n", (void *)ep_info->pc);
(unsigned long long) ep_info->pc); INFO("SPSR = 0x%x\n", ep_info->spsr);
INFO("SPSR = 0x%lx\n", (unsigned long) ep_info->spsr);
#define PRINT_IMAGE_ARG(n) \ #define PRINT_IMAGE_ARG(n) \
VERBOSE("Argument #" #n " = 0x%llx\n", \ VERBOSE("Argument #" #n " = 0x%llx\n", \
......
/* /*
* Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <assert.h>
#include <debug.h> #include <debug.h>
#include <errno.h> #include <errno.h>
#include <runtime_svc.h> #include <runtime_svc.h>
...@@ -42,11 +43,14 @@ ...@@ -42,11 +43,14 @@
* 'rt_svc_descs_indices' array. This gives the index of the descriptor in the * 'rt_svc_descs_indices' array. This gives the index of the descriptor in the
* 'rt_svc_descs' array which contains the SMC handler. * 'rt_svc_descs' array which contains the SMC handler.
******************************************************************************/ ******************************************************************************/
#define RT_SVC_DESCS_START ((uint64_t) (&__RT_SVC_DESCS_START__)) #define RT_SVC_DESCS_START ((uintptr_t) (&__RT_SVC_DESCS_START__))
#define RT_SVC_DESCS_END ((uint64_t) (&__RT_SVC_DESCS_END__)) #define RT_SVC_DESCS_END ((uintptr_t) (&__RT_SVC_DESCS_END__))
uint8_t rt_svc_descs_indices[MAX_RT_SVCS]; uint8_t rt_svc_descs_indices[MAX_RT_SVCS];
static rt_svc_desc_t *rt_svc_descs; static rt_svc_desc_t *rt_svc_descs;
#define RT_SVC_DECS_NUM ((RT_SVC_DESCS_END - RT_SVC_DESCS_START)\
/ sizeof(rt_svc_desc_t))
/******************************************************************************* /*******************************************************************************
* Simple routine to sanity check a runtime service descriptor before using it * Simple routine to sanity check a runtime service descriptor before using it
******************************************************************************/ ******************************************************************************/
...@@ -80,21 +84,20 @@ static int32_t validate_rt_svc_desc(rt_svc_desc_t *desc) ...@@ -80,21 +84,20 @@ static int32_t validate_rt_svc_desc(rt_svc_desc_t *desc)
******************************************************************************/ ******************************************************************************/
void runtime_svc_init(void) void runtime_svc_init(void)
{ {
int32_t rc = 0; int rc = 0, index, start_idx, end_idx;
uint32_t index, start_idx, end_idx;
uint64_t rt_svc_descs_num; /* Assert the number of descriptors detected are less than maximum indices */
assert((RT_SVC_DECS_NUM >= 0) && (RT_SVC_DECS_NUM < MAX_RT_SVCS));
/* If no runtime services are implemented then simply bail out */ /* If no runtime services are implemented then simply bail out */
rt_svc_descs_num = RT_SVC_DESCS_END - RT_SVC_DESCS_START; if (RT_SVC_DECS_NUM == 0)
rt_svc_descs_num /= sizeof(rt_svc_desc_t);
if (rt_svc_descs_num == 0)
return; return;
/* Initialise internal variables to invalid state */ /* Initialise internal variables to invalid state */
memset(rt_svc_descs_indices, -1, sizeof(rt_svc_descs_indices)); memset(rt_svc_descs_indices, -1, sizeof(rt_svc_descs_indices));
rt_svc_descs = (rt_svc_desc_t *) RT_SVC_DESCS_START; rt_svc_descs = (rt_svc_desc_t *) RT_SVC_DESCS_START;
for (index = 0; index < rt_svc_descs_num; index++) { for (index = 0; index < RT_SVC_DECS_NUM; index++) {
/* /*
* An invalid descriptor is an error condition since it is * An invalid descriptor is an error condition since it is
......
...@@ -1779,10 +1779,11 @@ following categories (present as directories in the source code): ...@@ -1779,10 +1779,11 @@ following categories (present as directories in the source code):
the platform. the platform.
* **Common code.** This is platform and architecture agnostic code. * **Common code.** This is platform and architecture agnostic code.
* **Library code.** This code comprises of functionality commonly used by all * **Library code.** This code comprises of functionality commonly used by all
other code. other code. The PSCI implementation and other EL3 runtime frameworks reside
as Library components.
* **Stage specific.** Code specific to a boot stage. * **Stage specific.** Code specific to a boot stage.
* **Drivers.** * **Drivers.**
* **Services.** EL3 runtime services, e.g. PSCI or SPD. Specific SPD services * **Services.** EL3 runtime services (eg: SPD). Specific SPD services
reside in the `services/spd` directory (e.g. `services/spd/tspd`). reside in the `services/spd` directory (e.g. `services/spd/tspd`).
Each boot loader stage uses code from one or more of the above mentioned Each boot loader stage uses code from one or more of the above mentioned
......
...@@ -545,7 +545,7 @@ reset vector code to perform the above tasks. ...@@ -545,7 +545,7 @@ reset vector code to perform the above tasks.
### Function : plat_get_my_entrypoint() [mandatory when PROGRAMMABLE_RESET_ADDRESS == 0] ### Function : plat_get_my_entrypoint() [mandatory when PROGRAMMABLE_RESET_ADDRESS == 0]
Argument : void Argument : void
Return : unsigned long Return : uintptr_t
This function is called with the called with the MMU and caches disabled This function is called with the called with the MMU and caches disabled
(`SCTLR_EL3.M` = 0 and `SCTLR_EL3.C` = 0). The function is responsible for (`SCTLR_EL3.M` = 0 and `SCTLR_EL3.C` = 0). The function is responsible for
...@@ -748,7 +748,7 @@ provided in [plat/common/aarch64/platform_up_stack.S] and ...@@ -748,7 +748,7 @@ provided in [plat/common/aarch64/platform_up_stack.S] and
### Function : plat_get_my_stack() ### Function : plat_get_my_stack()
Argument : void Argument : void
Return : unsigned long Return : uintptr_t
This function returns the base address of the normal memory stack that This function returns the base address of the normal memory stack that
has been allocated for the current CPU. For BL images that only require a has been allocated for the current CPU. For BL images that only require a
...@@ -966,7 +966,7 @@ This function helps fulfill requirements 4 and 5 above. ...@@ -966,7 +966,7 @@ This function helps fulfill requirements 4 and 5 above.
### Function : bl1_init_bl2_mem_layout() [optional] ### Function : bl1_init_bl2_mem_layout() [optional]
Argument : meminfo *, meminfo *, unsigned int, unsigned long Argument : meminfo *, meminfo *
Return : void Return : void
BL1 needs to tell the next stage the amount of secure RAM available BL1 needs to tell the next stage the amount of secure RAM available
......
...@@ -203,7 +203,7 @@ typedef struct non_cpu_pwr_domain_node { ...@@ -203,7 +203,7 @@ typedef struct non_cpu_pwr_domain_node {
} non_cpu_pd_node_t; } non_cpu_pd_node_t;
typedef struct cpu_pwr_domain_node { typedef struct cpu_pwr_domain_node {
unsigned long mpidr; u_register_t mpidr;
/* Index of the parent power domain node */ /* Index of the parent power domain node */
unsigned int parent_node; unsigned int parent_node;
......
...@@ -95,8 +95,7 @@ handler will be responsible for all SMC Functions within a given service type. ...@@ -95,8 +95,7 @@ handler will be responsible for all SMC Functions within a given service type.
ARM Trusted Firmware has a [`services`] directory in the source tree under which ARM Trusted Firmware has a [`services`] directory in the source tree under which
each owning entity can place the implementation of its runtime service. The each owning entity can place the implementation of its runtime service. The
[PSCI] implementation is located here in the [`services/std_svc/psci`] [PSCI] implementation is located here in the [`lib/psci`] directory.
directory.
Runtime service sources will need to include the [`runtime_svc.h`] header file. Runtime service sources will need to include the [`runtime_svc.h`] header file.
...@@ -114,7 +113,7 @@ initialization and call handler functions. ...@@ -114,7 +113,7 @@ initialization and call handler functions.
is also used for diagnostic purposes is also used for diagnostic purposes
* `_start` and `_end` values must be based on the `OEN_*` values defined in * `_start` and `_end` values must be based on the `OEN_*` values defined in
[`smcc_helpers.h`] [`smcc.h`]
* `_type` must be one of `SMC_TYPE_FAST` or `SMC_TYPE_STD` * `_type` must be one of `SMC_TYPE_FAST` or `SMC_TYPE_STD`
...@@ -124,12 +123,12 @@ initialization and call handler functions. ...@@ -124,12 +123,12 @@ initialization and call handler functions.
* `_smch` is the SMC handler function with the `rt_svc_handle` signature: * `_smch` is the SMC handler function with the `rt_svc_handle` signature:
typedef uint64_t (*rt_svc_handle)(uint32_t smc_fid, typedef uintptr_t (*rt_svc_handle_t)(uint32_t smc_fid,
uint64_t x1, uint64_t x2, u_register_t x1, u_register_t x2,
uint64_t x3, uint64_t x4, u_register_t x3, u_register_t x4,
void *cookie, void *cookie,
void *handle, void *handle,
uint64_t flags); u_register_t flags);
Details of the requirements and behavior of the two callbacks is provided in Details of the requirements and behavior of the two callbacks is provided in
the following sections. the following sections.
...@@ -189,12 +188,12 @@ SMC calls for a service are forwarded by the framework to the service's SMC ...@@ -189,12 +188,12 @@ SMC calls for a service are forwarded by the framework to the service's SMC
handler function (`_smch` in the service declaration). This function must have handler function (`_smch` in the service declaration). This function must have
the following signature: the following signature:
typedef uint64_t (*rt_svc_handle)(uint32_t smc_fid, typedef uintptr_t (*rt_svc_handle_t)(uint32_t smc_fid,
uint64_t x1, uint64_t x2, u_register_t x1, u_register_t x2,
uint64_t x3, uint64_t x4, u_register_t x3, u_register_t x4,
void *reserved, void *cookie,
void *handle, void *handle,
uint64_t flags); u_register_t flags);
The handler is responsible for: The handler is responsible for:
...@@ -253,10 +252,9 @@ The handler is responsible for: ...@@ -253,10 +252,9 @@ The handler is responsible for:
SMC_RET3(handle, x0, x1, x2); SMC_RET3(handle, x0, x1, x2);
SMC_RET4(handle, x0, x1, x2, x3); SMC_RET4(handle, x0, x1, x2, x3);
The `reserved` parameter to the handler is reserved for future use and can be The `cookie` parameter to the handler is reserved for future use and can be
ignored. The value returned by a SMC handler is also reserved for future use - ignored. The `handle` is returned by the SMC handler - completion of the
completion of the handler function must always be via one of the `SMC_RETn()` handler function must always be via one of the `SMC_RETn()` macros.
macros.
NOTE: The PSCI and Test Secure-EL1 Payload Dispatcher services do not follow NOTE: The PSCI and Test Secure-EL1 Payload Dispatcher services do not follow
all of the above requirements yet. all of the above requirements yet.
...@@ -299,12 +297,11 @@ provide this information.... ...@@ -299,12 +297,11 @@ provide this information....
_Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved._ _Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved._
[Firmware Design]: ./firmware-design.md [Firmware Design]: ./firmware-design.md
[`services`]: ../services [`services`]: ../services
[`services/std_svc/psci`]: ../services/std_svc/psci [`lib/psci`]: ../lib/psci
[`std_svc_setup.c`]: ../services/std_svc/std_svc_setup.c [`std_svc_setup.c`]: ../services/std_svc/std_svc_setup.c
[`runtime_svc.h`]: ../include/bl31/runtime_svc.h [`runtime_svc.h`]: ../include/common/runtime_svc.h
[`smcc_helpers.h`]: ../include/common/smcc_helpers.h [`smcc.h`]: ../include/lib/smcc.h
[PSCI]: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf "Power State Coordination Interface PDD (ARM DEN 0022C)" [PSCI]: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf "Power State Coordination Interface PDD (ARM DEN 0022C)"
[SMCCC]: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html "SMC Calling Convention PDD (ARM DEN 0028A)" [SMCCC]: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html "SMC Calling Convention PDD (ARM DEN 0028A)"
/* /*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -104,7 +104,7 @@ typedef enum rn_types { ...@@ -104,7 +104,7 @@ typedef enum rn_types {
#define WAIT_FOR_DOMAIN_CTRL_OP_COMPLETION(region_id, stat_reg_offset, \ #define WAIT_FOR_DOMAIN_CTRL_OP_COMPLETION(region_id, stat_reg_offset, \
op_reg_offset, rn_id_map) \ op_reg_offset, rn_id_map) \
{ \ { \
uint64_t status_reg; \ unsigned long long status_reg; \
do { \ do { \
status_reg = ccn_reg_read((ccn_plat_desc->periphbase), \ status_reg = ccn_reg_read((ccn_plat_desc->periphbase), \
(region_id), \ (region_id), \
...@@ -208,7 +208,7 @@ typedef enum rn_types { ...@@ -208,7 +208,7 @@ typedef enum rn_types {
/* /*
* Helper function to return number of set bits in bitmap * Helper function to return number of set bits in bitmap
*/ */
static inline unsigned int count_set_bits(uint64_t bitmap) static inline unsigned int count_set_bits(unsigned long long bitmap)
{ {
unsigned int count = 0; unsigned int count = 0;
......
...@@ -250,7 +250,7 @@ void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs, ...@@ -250,7 +250,7 @@ void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs,
uintptr_t gicr_base, uintptr_t gicr_base,
mpidr_hash_fn mpidr_to_core_pos) mpidr_hash_fn mpidr_to_core_pos)
{ {
unsigned long mpidr; u_register_t mpidr;
unsigned int proc_num; unsigned int proc_num;
unsigned long long typer_val; unsigned long long typer_val;
uintptr_t rdistif_base = gicr_base; uintptr_t rdistif_base = gicr_base;
...@@ -320,7 +320,7 @@ void gicv3_secure_spis_configure(uintptr_t gicd_base, ...@@ -320,7 +320,7 @@ void gicv3_secure_spis_configure(uintptr_t gicd_base,
unsigned int int_grp) unsigned int int_grp)
{ {
unsigned int index, irq_num; unsigned int index, irq_num;
uint64_t gic_affinity_val; unsigned long long gic_affinity_val;
assert((int_grp == INTR_GROUP1S) || (int_grp == INTR_GROUP0)); assert((int_grp == INTR_GROUP1S) || (int_grp == INTR_GROUP0));
/* If `num_ints` is not 0, ensure that `sec_intr_list` is not NULL */ /* If `num_ints` is not 0, ensure that `sec_intr_list` is not NULL */
......
/* /*
* Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -36,11 +36,11 @@ ...@@ -36,11 +36,11 @@
/******************************************************************************* /*******************************************************************************
* Function prototypes * Function prototypes
******************************************************************************/ ******************************************************************************/
void bl31_arch_setup(void);
void bl31_next_el_arch_setup(uint32_t security_state); void bl31_next_el_arch_setup(uint32_t security_state);
void bl31_set_next_image_type(uint32_t type); void bl31_set_next_image_type(uint32_t type);
uint32_t bl31_get_next_image_type(void); uint32_t bl31_get_next_image_type(void);
void bl31_prepare_next_image_entry(void); void bl31_prepare_next_image_entry(void);
void bl31_register_bl32_init(int32_t (*)(void)); void bl31_register_bl32_init(int32_t (*)(void));
void bl31_warm_entrypoint(void);
#endif /* __BL31_H__ */ #endif /* __BL31_H__ */
/* /*
* Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#define __ASM_MACROS_S__ #define __ASM_MACROS_S__
#include <arch.h> #include <arch.h>
#include <asm_macros_common.S>
.macro func_prologue .macro func_prologue
...@@ -104,81 +105,6 @@ ...@@ -104,81 +105,6 @@
.endif .endif
.endm .endm
/*
* This macro is used to create a function label and place the
* code into a separate text section based on the function name
* to enable elimination of unused code during linking
*/
.macro func _name
.section .text.\_name, "ax"
.type \_name, %function
.func \_name
\_name:
.endm
/*
* This macro is used to mark the end of a function.
*/
.macro endfunc _name
.endfunc
.size \_name, . - \_name
.endm
/*
* Theses macros are used to create function labels for deprecated
* APIs. If ERROR_DEPRECATED is non zero, the callers of these APIs
* will fail to link and cause build failure.
*/
#if ERROR_DEPRECATED
.macro func_deprecated _name
func deprecated\_name
.endm
.macro endfunc_deprecated _name
endfunc deprecated\_name
.endm
#else
.macro func_deprecated _name
func \_name
.endm
.macro endfunc_deprecated _name
endfunc \_name
.endm
#endif
/*
* Helper assembler macro to count trailing zeros. The output is
* populated in the `TZ_COUNT` symbol.
*/
.macro count_tz _value, _tz_count
.if \_value
count_tz "(\_value >> 1)", "(\_tz_count + 1)"
.else
.equ TZ_COUNT, (\_tz_count - 1)
.endif
.endm
/*
* This macro declares an array of 1 or more stacks, properly
* aligned and in the requested section
*/
#define DEFAULT_STACK_ALIGN (1 << 6) /* In case the caller doesnt provide alignment */
.macro declare_stack _name, _section, _size, _count, _align=DEFAULT_STACK_ALIGN
count_tz \_align, 0
.if (\_align - (1 << TZ_COUNT))
.error "Incorrect stack alignment specified (Must be a power of 2)."
.endif
.if ((\_size & ((1 << TZ_COUNT) - 1)) <> 0)
.error "Stack size not correctly aligned"
.endif
.section \_section, "aw", %nobits
.align TZ_COUNT
\_name:
.space ((\_count) * (\_size)), 0
.endm
#if ENABLE_PLAT_COMPAT #if ENABLE_PLAT_COMPAT
/* /*
* This macro calculates the base address of an MP stack using the * This macro calculates the base address of an MP stack using the
......
/* /*
* Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
......
/* /*
* Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -27,85 +27,85 @@ ...@@ -27,85 +27,85 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef __ASM_MACROS_COMMON_S__
#define __ASM_MACROS_COMMON_S__
#include <arch.h> #include <arch.h>
#include <asm_macros.S>
#include <el3_common_macros.S>
#include <psci.h>
#include <xlat_tables.h>
.globl psci_entrypoint /*
.globl psci_power_down_wfi * This macro is used to create a function label and place the
* code into a separate text section based on the function name
/* -------------------------------------------------------------------- * to enable elimination of unused code during linking
* This CPU has been physically powered up. It is either resuming from
* suspend or has simply been turned on. In both cases, call the power
* on finisher.
* --------------------------------------------------------------------
*/ */
func psci_entrypoint .macro func _name
.section .text.\_name, "ax"
.type \_name, %function
.func \_name
\_name:
.endm
/* /*
* On the warm boot path, most of the EL3 initialisations performed by * This macro is used to mark the end of a function.
* 'el3_entrypoint_common' must be skipped:
*
* - Only when the platform bypasses the BL1/BL31 entrypoint by
* programming the reset address do we need to set the CPU endianness.
* In other cases, we assume this has been taken care by the
* entrypoint code.
*
* - No need to determine the type of boot, we know it is a warm boot.
*
* - Do not try to distinguish between primary and secondary CPUs, this
* notion only exists for a cold boot.
*
* - No need to initialise the memory or the C runtime environment,
* it has been done once and for all on the cold boot path.
*/ */
el3_entrypoint_common \ .macro endfunc _name
_set_endian=PROGRAMMABLE_RESET_ADDRESS \ .endfunc
_warm_boot_mailbox=0 \ .size \_name, . - \_name
_secondary_cold_boot=0 \ .endm
_init_memory=0 \
_init_c_runtime=0 \
_exception_vectors=runtime_exceptions
/* -------------------------------------------- /*
* Enable the MMU with the DCache disabled. It * Theses macros are used to create function labels for deprecated
* is safe to use stacks allocated in normal * APIs. If ERROR_DEPRECATED is non zero, the callers of these APIs
* memory as a result. All memory accesses are * will fail to link and cause build failure.
* marked nGnRnE when the MMU is disabled. So
* all the stack writes will make it to memory.
* All memory accesses are marked Non-cacheable
* when the MMU is enabled but D$ is disabled.
* So used stack memory is guaranteed to be
* visible immediately after the MMU is enabled
* Enabling the DCache at the same time as the
* MMU can lead to speculatively fetched and
* possibly stale stack memory being read from
* other caches. This can lead to coherency
* issues.
* --------------------------------------------
*/ */
mov x0, #DISABLE_DCACHE #if ERROR_DEPRECATED
bl bl31_plat_enable_mmu .macro func_deprecated _name
func deprecated\_name
.endm
.macro endfunc_deprecated _name
endfunc deprecated\_name
.endm
#else
.macro func_deprecated _name
func \_name
.endm
bl psci_power_up_finish .macro endfunc_deprecated _name
endfunc \_name
.endm
#endif
b el3_exit /*
endfunc psci_entrypoint * Helper assembler macro to count trailing zeros. The output is
* populated in the `TZ_COUNT` symbol.
*/
.macro count_tz _value, _tz_count
.if \_value
count_tz "(\_value >> 1)", "(\_tz_count + 1)"
.else
.equ TZ_COUNT, (\_tz_count - 1)
.endif
.endm
/* -------------------------------------------- /*
* This function is called to indicate to the * This macro declares an array of 1 or more stacks, properly
* power controller that it is safe to power * aligned and in the requested section
* down this cpu. It should not exit the wfi
* and will be released from reset upon power
* up. 'wfi_spill' is used to catch erroneous
* exits from wfi.
* --------------------------------------------
*/ */
func psci_power_down_wfi #define DEFAULT_STACK_ALIGN (1 << 6) /* In case the caller doesnt provide alignment */
dsb sy // ensure write buffer empty
wfi .macro declare_stack _name, _section, _size, _count, _align=DEFAULT_STACK_ALIGN
bl plat_panic_handler count_tz \_align, 0
endfunc psci_power_down_wfi .if (\_align - (1 << TZ_COUNT))
.error "Incorrect stack alignment specified (Must be a power of 2)."
.endif
.if ((\_size & ((1 << TZ_COUNT) - 1)) <> 0)
.error "Stack size not correctly aligned"
.endif
.section \_section, "aw", %nobits
.align TZ_COUNT
\_name:
.space ((\_count) * (\_size)), 0
.endm
#endif /* __ASM_MACROS_COMMON_S__ */
...@@ -137,6 +137,7 @@ ...@@ -137,6 +137,7 @@
#include <cassert.h> #include <cassert.h>
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <types.h>
#include <utils.h> /* To retain compatibility */ #include <utils.h> /* To retain compatibility */
/* /*
...@@ -144,28 +145,28 @@ ...@@ -144,28 +145,28 @@
* BL images * BL images
*/ */
#if SEPARATE_CODE_AND_RODATA #if SEPARATE_CODE_AND_RODATA
extern unsigned long __TEXT_START__; extern uintptr_t __TEXT_START__;
extern unsigned long __TEXT_END__; extern uintptr_t __TEXT_END__;
extern unsigned long __RODATA_START__; extern uintptr_t __RODATA_START__;
extern unsigned long __RODATA_END__; extern uintptr_t __RODATA_END__;
#else #else
extern unsigned long __RO_START__; extern uintptr_t __RO_START__;
extern unsigned long __RO_END__; extern uintptr_t __RO_END__;
#endif #endif
#if IMAGE_BL2 #if IMAGE_BL2
extern unsigned long __BL2_END__; extern uintptr_t __BL2_END__;
#elif IMAGE_BL2U #elif IMAGE_BL2U
extern unsigned long __BL2U_END__; extern uintptr_t __BL2U_END__;
#elif IMAGE_BL31 #elif IMAGE_BL31
extern unsigned long __BL31_END__; extern uintptr_t __BL31_END__;
#elif IMAGE_BL32 #elif IMAGE_BL32
extern unsigned long __BL32_END__; extern uintptr_t __BL32_END__;
#endif /* IMAGE_BLX */ #endif /* IMAGE_BLX */
#if USE_COHERENT_MEM #if USE_COHERENT_MEM
extern unsigned long __COHERENT_RAM_START__; extern uintptr_t __COHERENT_RAM_START__;
extern unsigned long __COHERENT_RAM_END__; extern uintptr_t __COHERENT_RAM_END__;
#endif #endif
...@@ -174,21 +175,21 @@ extern unsigned long __COHERENT_RAM_END__; ...@@ -174,21 +175,21 @@ extern unsigned long __COHERENT_RAM_END__;
* memory is available for its use and how much is already used. * memory is available for its use and how much is already used.
******************************************************************************/ ******************************************************************************/
typedef struct meminfo { typedef struct meminfo {
uint64_t total_base; uintptr_t total_base;
size_t total_size; size_t total_size;
uint64_t free_base; uintptr_t free_base;
size_t free_size; size_t free_size;
} meminfo_t; } meminfo_t;
typedef struct aapcs64_params { typedef struct aapcs64_params {
unsigned long arg0; u_register_t arg0;
unsigned long arg1; u_register_t arg1;
unsigned long arg2; u_register_t arg2;
unsigned long arg3; u_register_t arg3;
unsigned long arg4; u_register_t arg4;
unsigned long arg5; u_register_t arg5;
unsigned long arg6; u_register_t arg6;
unsigned long arg7; u_register_t arg7;
} aapcs64_params_t; } aapcs64_params_t;
/*************************************************************************** /***************************************************************************
...@@ -284,7 +285,7 @@ CASSERT(ENTRY_POINT_INFO_ARGS_OFFSET == \ ...@@ -284,7 +285,7 @@ CASSERT(ENTRY_POINT_INFO_ARGS_OFFSET == \
__builtin_offsetof(entry_point_info_t, args), \ __builtin_offsetof(entry_point_info_t, args), \
assert_BL31_args_offset_mismatch); assert_BL31_args_offset_mismatch);
CASSERT(sizeof(unsigned long) == CASSERT(sizeof(uintptr_t) ==
__builtin_offsetof(entry_point_info_t, spsr) - \ __builtin_offsetof(entry_point_info_t, spsr) - \
__builtin_offsetof(entry_point_info_t, pc), \ __builtin_offsetof(entry_point_info_t, pc), \
assert_entrypoint_and_spsr_should_be_adjacent); assert_entrypoint_and_spsr_should_be_adjacent);
...@@ -292,8 +293,8 @@ CASSERT(sizeof(unsigned long) == ...@@ -292,8 +293,8 @@ CASSERT(sizeof(unsigned long) ==
/******************************************************************************* /*******************************************************************************
* Function & variable prototypes * Function & variable prototypes
******************************************************************************/ ******************************************************************************/
unsigned long page_align(unsigned long, unsigned); uintptr_t page_align(uintptr_t, unsigned);
unsigned long image_size(unsigned int image_id); size_t image_size(unsigned int image_id);
int load_image(meminfo_t *mem_layout, int load_image(meminfo_t *mem_layout,
unsigned int image_id, unsigned int image_id,
uintptr_t image_base, uintptr_t image_base,
...@@ -307,8 +308,8 @@ int load_auth_image(meminfo_t *mem_layout, ...@@ -307,8 +308,8 @@ int load_auth_image(meminfo_t *mem_layout,
extern const char build_message[]; extern const char build_message[];
extern const char version_string[]; extern const char version_string[];
void reserve_mem(uint64_t *free_base, size_t *free_size, void reserve_mem(uintptr_t *free_base, size_t *free_size,
uint64_t addr, size_t size); uintptr_t addr, size_t size);
void print_entry_point_info(const entry_point_info_t *ep_info); void print_entry_point_info(const entry_point_info_t *ep_info);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment