diff options
51 files changed, 1514 insertions, 473 deletions
@@ -246,6 +246,12 @@ endif # over the sources. endif +################################################################################ +# Include libraries' Makefile that are used in all BL +################################################################################ + +include lib/stack_protector/stack_protector.mk + ################################################################################ # Include the platform specific Makefile after the SPD Makefile (the platform @@ -374,6 +380,55 @@ CRTTOOL ?= ${CRTTOOLPATH}/cert_create${BIN_EXT} FIPTOOLPATH ?= tools/fiptool FIPTOOL ?= ${FIPTOOLPATH}/fiptool${BIN_EXT} +################################################################################ +# Include BL specific makefiles +################################################################################ +ifdef BL1_SOURCES +NEED_BL1 := yes +include bl1/bl1.mk +endif + +ifdef BL2_SOURCES +NEED_BL2 := yes +include bl2/bl2.mk +endif + +# For AArch32, BL31 is not applicable, and BL2U is not supported at present. +ifneq (${ARCH},aarch32) +ifdef BL2U_SOURCES +NEED_BL2U := yes +include bl2u/bl2u.mk +endif + +ifdef BL31_SOURCES +# When booting an EL3 payload, there is no need to compile the BL31 image nor +# put it in the FIP. +ifndef EL3_PAYLOAD_BASE +NEED_BL31 := yes +include bl31/bl31.mk +endif +endif +endif + +ifeq (${ARCH},aarch32) +NEED_BL32 := yes + +################################################################################ +# Build `AARCH32_SP` as BL32 image for AArch32 +################################################################################ +ifneq (${AARCH32_SP},none) +# We expect to locate an sp.mk under the specified AARCH32_SP directory +AARCH32_SP_MAKE := $(wildcard bl32/${AARCH32_SP}/${AARCH32_SP}.mk) + +ifeq (${AARCH32_SP_MAKE},) + $(error Error: No bl32/${AARCH32_SP}/${AARCH32_SP}.mk located) +endif + +$(info Including ${AARCH32_SP_MAKE}) +include ${AARCH32_SP_MAKE} +endif + +endif ################################################################################ # Build options checks @@ -460,56 +515,6 @@ else endif ################################################################################ -# Include BL specific makefiles -################################################################################ -ifdef BL1_SOURCES -NEED_BL1 := yes -include bl1/bl1.mk -endif - -ifdef BL2_SOURCES -NEED_BL2 := yes -include bl2/bl2.mk -endif - -# For AArch32, BL31 is not applicable, and BL2U is not supported at present. -ifneq (${ARCH},aarch32) -ifdef BL2U_SOURCES -NEED_BL2U := yes -include bl2u/bl2u.mk -endif - -ifdef BL31_SOURCES -# When booting an EL3 payload, there is no need to compile the BL31 image nor -# put it in the FIP. -ifndef EL3_PAYLOAD_BASE -NEED_BL31 := yes -include bl31/bl31.mk -endif -endif -endif - -ifeq (${ARCH},aarch32) -NEED_BL32 := yes - -################################################################################ -# Build `AARCH32_SP` as BL32 image for AArch32 -################################################################################ -ifneq (${AARCH32_SP},none) -# We expect to locate an sp.mk under the specified AARCH32_SP directory -AARCH32_SP_MAKE := $(wildcard bl32/${AARCH32_SP}/${AARCH32_SP}.mk) - -ifeq (${AARCH32_SP_MAKE},) - $(error Error: No bl32/${AARCH32_SP}/${AARCH32_SP}.mk located) -endif - -$(info Including ${AARCH32_SP_MAKE}) -include ${AARCH32_SP_MAKE} -endif - -endif - -################################################################################ # Build targets ################################################################################ diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S index b69065ee..2cfb24c1 100644 --- a/bl1/bl1.ld.S +++ b/bl1/bl1.ld.S @@ -111,14 +111,20 @@ SECTIONS ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__, "cpu_ops not defined for this platform.") + . = BL1_RW_BASE; + ASSERT(BL1_RW_BASE == ALIGN(4096), + "BL1_RW_BASE address is not aligned on a page boundary.") + /* * The .data section gets copied from ROM to RAM at runtime. - * Its LMA must be 16-byte aligned. + * Its LMA should be 16-byte aligned to allow efficient copying of 16-bytes + * aligned regions in it. * Its VMA must be page-aligned as it marks the first read/write page. + * + * It must be placed at a lower address than the stacks if the stack + * protector is enabled. Alternatively, the .data.stack_protector_canary + * section can be placed independently of the main .data section. */ - . = BL1_RW_BASE; - ASSERT(. == ALIGN(4096), - "BL1_RW_BASE address is not aligned on a page boundary.") .data . : ALIGN(16) { __DATA_RAM_START__ = .; *(.data*) diff --git a/bl2/aarch32/bl2_entrypoint.S b/bl2/aarch32/bl2_entrypoint.S index bb0b7f31..c82456f2 100644 --- a/bl2/aarch32/bl2_entrypoint.S +++ b/bl2/aarch32/bl2_entrypoint.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2017, 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: @@ -122,6 +122,15 @@ func bl2_entrypoint bl plat_set_my_stack /* --------------------------------------------- + * Initialize the stack protector canary before + * any C code is called. + * --------------------------------------------- + */ +#if STACK_PROTECTOR_ENABLED + bl update_stack_protector_canary +#endif + + /* --------------------------------------------- * Perform early platform setup & platform * specific early arch. setup e.g. mmu setup * --------------------------------------------- diff --git a/bl2/aarch64/bl2_entrypoint.S b/bl2/aarch64/bl2_entrypoint.S index 31f77879..15a217d0 100644 --- a/bl2/aarch64/bl2_entrypoint.S +++ b/bl2/aarch64/bl2_entrypoint.S @@ -113,6 +113,15 @@ func bl2_entrypoint bl plat_set_my_stack /* --------------------------------------------- + * Initialize the stack protector canary before + * any C code is called. + * --------------------------------------------- + */ +#if STACK_PROTECTOR_ENABLED + bl update_stack_protector_canary +#endif + + /* --------------------------------------------- * Perform early platform setup & platform * specific early arch. setup e.g. mmu setup * --------------------------------------------- diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S index b9275f34..07e0bccd 100644 --- a/bl2/bl2.ld.S +++ b/bl2/bl2.ld.S @@ -99,6 +99,11 @@ SECTIONS */ __RW_START__ = . ; + /* + * .data must be placed at a lower address than the stacks if the stack + * protector is enabled. Alternatively, the .data.stack_protector_canary + * section can be placed independently of the main .data section. + */ .data . : { __DATA_START__ = .; *(.data*) diff --git a/bl2u/aarch64/bl2u_entrypoint.S b/bl2u/aarch64/bl2u_entrypoint.S index 9fa84bf4..81aabc77 100644 --- a/bl2u/aarch64/bl2u_entrypoint.S +++ b/bl2u/aarch64/bl2u_entrypoint.S @@ -107,6 +107,15 @@ func bl2u_entrypoint bl plat_set_my_stack /* --------------------------------------------- + * Initialize the stack protector canary before + * any C code is called. + * --------------------------------------------- + */ +#if STACK_PROTECTOR_ENABLED + bl update_stack_protector_canary +#endif + + /* --------------------------------------------- * Perform early platform setup & platform * specific early arch. setup e.g. mmu setup * --------------------------------------------- diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S index 91e8556e..aebf84f4 100644 --- a/bl2u/bl2u.ld.S +++ b/bl2u/bl2u.ld.S @@ -86,6 +86,11 @@ SECTIONS */ __RW_START__ = . ; + /* + * .data must be placed at a lower address than the stacks if the stack + * protector is enabled. Alternatively, the .data.stack_protector_canary + * section can be placed independently of the main .data section. + */ .data . : { __DATA_START__ = .; *(.data*) diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S index e5d6232e..3a3fbd9a 100644 --- a/bl31/bl31.ld.S +++ b/bl31/bl31.ld.S @@ -140,7 +140,12 @@ SECTIONS */ __RW_START__ = . ; - .data . : { + /* + * .data must be placed at a lower address than the stacks if the stack + * protector is enabled. Alternatively, the .data.stack_protector_canary + * section can be placed independently of the main .data section. + */ + .data . : { __DATA_START__ = .; *(.data*) __DATA_END__ = .; diff --git a/bl32/tsp/aarch64/tsp_entrypoint.S b/bl32/tsp/aarch64/tsp_entrypoint.S index 182f3148..3f281394 100644 --- a/bl32/tsp/aarch64/tsp_entrypoint.S +++ b/bl32/tsp/aarch64/tsp_entrypoint.S @@ -139,6 +139,15 @@ func tsp_entrypoint bl plat_set_my_stack /* --------------------------------------------- + * Initialize the stack protector canary before + * any C code is called. + * --------------------------------------------- + */ +#if STACK_PROTECTOR_ENABLED + bl update_stack_protector_canary +#endif + + /* --------------------------------------------- * Perform early platform setup & platform * specific early arch. setup e.g. mmu setup * --------------------------------------------- diff --git a/docs/porting-guide.md b/docs/porting-guide.md index 65518ffb..690f307a 100644 --- a/docs/porting-guide.md +++ b/docs/porting-guide.md @@ -920,6 +920,20 @@ kept aside to pass trusted firmware related information that next BL image needs. This function is currently invoked in BL2 to pass this information to the next BL image, when LOAD_IMAGE_V2 is enabled. +### Function : plat_get_stack_protector_canary() + Argument : void + Return : u_register_t + +This function returns a random value that is used to initialize the canary used +when the stack protector is enabled with ENABLE_STACK_PROTECTOR. A predictable +value will weaken the protection as the attacker could easily write the right +value as part of the attack most of the time. Therefore, it should return a +true random number. + +Note: For the protection to be effective, the global data need to be placed at +a lower address than the stack bases. Failure to do so would allow an attacker +to overwrite the canary as part of the stack buffer overflow attack. + ### Function : plat_flush_next_bl_params() Argument : void diff --git a/docs/user-guide.md b/docs/user-guide.md index 2770b2cd..a1df9652 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -301,6 +301,14 @@ performed. Currently, only PSCI is instrumented. Enabling this option enables the `ENABLE_PMF` build option as well. Default is 0. +* `ENABLE_STACK_PROTECTOR`: String option to enable the stack protection + checks in GCC. Allowed values are "all", "strong" and "0" (default). + "strong" is the recommended stack protection level if this feature is + desired. 0 disables the stack protection. For all values other than 0, the + `plat_get_stack_protector_canary()` platform hook needs to be implemented. + The value is passed as the last component of the option + `-fstack-protector-$ENABLE_STACK_PROTECTOR`. + * `ERROR_DEPRECATED`: This option decides whether to treat the usage of deprecated platform APIs, helper functions or drivers within Trusted Firmware as error. It can take the value 1 (flag the use of deprecated @@ -799,7 +807,7 @@ images with support for these features: modules by checking out a recent version of the [mbed TLS Repository]. It is important to use a version that is compatible with TF and fixes any known security vulnerabilities. See [mbed TLS Security Center] for more - information. This version of TF is tested with tag `mbedtls-2.2.1`. + information. The latest version of TF is tested with tag `mbedtls-2.4.2`. The `drivers/auth/mbedtls/mbedtls_*.mk` files contain the list of mbed TLS source files the modules depend upon. diff --git a/drivers/auth/mbedtls/mbedtls_common.c b/drivers/auth/mbedtls/mbedtls_common.c index 053bf1a4..1d2df5a5 100644 --- a/drivers/auth/mbedtls/mbedtls_common.c +++ b/drivers/auth/mbedtls/mbedtls_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2017, 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: @@ -36,9 +36,9 @@ /* * mbed TLS heap */ -#if (MBEDTLS_KEY_ALG_ID == MBEDTLS_ECDSA) +#if (TBBR_KEY_ALG_ID == TBBR_ECDSA) #define MBEDTLS_HEAP_SIZE (14*1024) -#elif (MBEDTLS_KEY_ALG_ID == MBEDTLS_RSA) +#elif (TBBR_KEY_ALG_ID == TBBR_RSA) #define MBEDTLS_HEAP_SIZE (8*1024) #endif static unsigned char heap[MBEDTLS_HEAP_SIZE]; diff --git a/drivers/auth/mbedtls/mbedtls_crypto.mk b/drivers/auth/mbedtls/mbedtls_crypto.mk index b7880971..302a0a1c 100644 --- a/drivers/auth/mbedtls/mbedtls_crypto.mk +++ b/drivers/auth/mbedtls/mbedtls_crypto.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2017, 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: @@ -55,18 +55,18 @@ ifeq (${MBEDTLS_KEY_ALG},ecdsa) ecp_curves.c \ ecp.c \ ) - MBEDTLS_KEY_ALG_ID := MBEDTLS_ECDSA + TBBR_KEY_ALG_ID := TBBR_ECDSA else ifeq (${MBEDTLS_KEY_ALG},rsa) MBEDTLS_CRYPTO_SOURCES += $(addprefix ${MBEDTLS_DIR}/library/, \ rsa.c \ ) - MBEDTLS_KEY_ALG_ID := MBEDTLS_RSA + TBBR_KEY_ALG_ID := TBBR_RSA else $(error "MBEDTLS_KEY_ALG=${MBEDTLS_KEY_ALG} not supported on mbed TLS") endif -# mbed TLS libraries rely on this define to build correctly -$(eval $(call add_define,MBEDTLS_KEY_ALG_ID)) +# Needs to be set to drive mbed TLS configuration correctly +$(eval $(call add_define,TBBR_KEY_ALG_ID)) BL1_SOURCES += ${MBEDTLS_CRYPTO_SOURCES} BL2_SOURCES += ${MBEDTLS_CRYPTO_SOURCES} diff --git a/include/common/aarch32/el3_common_macros.S b/include/common/aarch32/el3_common_macros.S index f6b7527e..d7e0b3f5 100644 --- a/include/common/aarch32/el3_common_macros.S +++ b/include/common/aarch32/el3_common_macros.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2017, 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: @@ -278,6 +278,12 @@ * --------------------------------------------------------------------- */ bl plat_set_my_stack + +#if STACK_PROTECTOR_ENABLED + .if \_init_c_runtime + bl update_stack_protector_canary + .endif /* _init_c_runtime */ +#endif .endm #endif /* __EL3_COMMON_MACROS_S__ */ diff --git a/include/common/aarch64/el3_common_macros.S b/include/common/aarch64/el3_common_macros.S index e085f9f1..5c6aa069 100644 --- a/include/common/aarch64/el3_common_macros.S +++ b/include/common/aarch64/el3_common_macros.S @@ -283,6 +283,12 @@ * --------------------------------------------------------------------- */ bl plat_set_my_stack + +#if STACK_PROTECTOR_ENABLED + .if \_init_c_runtime + bl update_stack_protector_canary + .endif /* _init_c_runtime */ +#endif .endm #endif /* __EL3_COMMON_MACROS_S__ */ diff --git a/include/common/bl_common.h b/include/common/bl_common.h index 66c20fc5..38be6283 100644 --- a/include/common/bl_common.h +++ b/include/common/bl_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2017, 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: @@ -31,9 +31,8 @@ #ifndef __BL_COMMON_H__ #define __BL_COMMON_H__ -#define SECURE 0x0 -#define NON_SECURE 0x1 -#define sec_state_is_valid(s) (((s) == SECURE) || ((s) == NON_SECURE)) +#include <ep_info.h> +#include <param_header.h> #define UP 1 #define DOWN 0 @@ -45,25 +44,6 @@ #define TOP 0x1 #define BOTTOM !TOP -/******************************************************************************* - * Constants that allow assembler code to access members of and the - * 'entry_point_info' structure at their correct offsets. - ******************************************************************************/ -#define ENTRY_POINT_INFO_PC_OFFSET 0x08 -#ifdef AARCH32 -#define ENTRY_POINT_INFO_ARGS_OFFSET 0x10 -#else -#define ENTRY_POINT_INFO_ARGS_OFFSET 0x18 -#endif - -/* The following are used to set/get image attributes. */ -#define PARAM_EP_SECURITY_MASK (0x1) - -#define GET_SECURITY_STATE(x) (x & PARAM_EP_SECURITY_MASK) -#define SET_SECURITY_STATE(x, security) \ - ((x) = ((x) & ~PARAM_EP_SECURITY_MASK) | (security)) - - /* * The following are used for image state attributes. * Image can only be in one of the following state. @@ -75,59 +55,11 @@ #define IMAGE_STATE_EXECUTED 4 #define IMAGE_STATE_INTERRUPTED 5 -#define EP_EE_MASK 0x2 -#define EP_EE_LITTLE 0x0 -#define EP_EE_BIG 0x2 -#define EP_GET_EE(x) (x & EP_EE_MASK) -#define EP_SET_EE(x, ee) ((x) = ((x) & ~EP_EE_MASK) | (ee)) - -#define EP_ST_MASK 0x4 -#define EP_ST_DISABLE 0x0 -#define EP_ST_ENABLE 0x4 -#define EP_GET_ST(x) (x & EP_ST_MASK) -#define EP_SET_ST(x, ee) ((x) = ((x) & ~EP_ST_MASK) | (ee)) - -#define EP_EXE_MASK 0x8 -#define NON_EXECUTABLE 0x0 -#define EXECUTABLE 0x8 -#define EP_GET_EXE(x) (x & EP_EXE_MASK) -#define EP_SET_EXE(x, ee) ((x) = ((x) & ~EP_EXE_MASK) | (ee)) - -#define EP_FIRST_EXE_MASK 0x10 -#define EP_FIRST_EXE 0x10 -#define EP_GET_FIRST_EXE(x) ((x) & EP_FIRST_EXE_MASK) -#define EP_SET_FIRST_EXE(x, ee) ((x) = ((x) & ~EP_FIRST_EXE_MASK) | (ee)) - -#define PARAM_EP 0x01 -#define PARAM_IMAGE_BINARY 0x02 -#define PARAM_BL31 0x03 -#define PARAM_BL_LOAD_INFO 0x04 -#define PARAM_BL_PARAMS 0x05 -#define PARAM_PSCI_LIB_ARGS 0x06 - #define IMAGE_ATTRIB_SKIP_LOADING 0x02 #define IMAGE_ATTRIB_PLAT_SETUP 0x04 -#define VERSION_1 0x01 -#define VERSION_2 0x02 - #define INVALID_IMAGE_ID (0xFFFFFFFF) -#define SET_PARAM_HEAD(_p, _type, _ver, _attr) do { \ - (_p)->h.type = (uint8_t)(_type); \ - (_p)->h.version = (uint8_t)(_ver); \ - (_p)->h.size = (uint16_t)sizeof(*_p); \ - (_p)->h.attr = (uint32_t)(_attr) ; \ - } while (0) - -/* Following is used for populating structure members statically. */ -#define SET_STATIC_PARAM_HEAD(_p, _type, _ver, _p_type, _attr) \ - ._p.h.type = (uint8_t)(_type), \ - ._p.h.version = (uint8_t)(_ver), \ - ._p.h.size = (uint16_t)sizeof(_p_type), \ - ._p.h.attr = (uint32_t)(_attr) - - /******************************************************************************* * Constants to indicate type of exception to the common exception handler. ******************************************************************************/ @@ -149,10 +81,9 @@ #define SERROR_AARCH32 0xf #ifndef __ASSEMBLY__ -#include <cdefs.h> /* For __dead2 */ #include <cassert.h> -#include <stdint.h> #include <stddef.h> +#include <stdint.h> #include <types.h> #include <utils.h> /* To retain compatibility */ @@ -185,7 +116,6 @@ extern uintptr_t __COHERENT_RAM_START__; extern uintptr_t __COHERENT_RAM_END__; #endif - /******************************************************************************* * Structure used for telling the next BL how much of a particular type of * memory is available for its use and how much is already used. @@ -199,55 +129,6 @@ typedef struct meminfo { #endif } meminfo_t; -typedef struct aapcs64_params { - u_register_t arg0; - u_register_t arg1; - u_register_t arg2; - u_register_t arg3; - u_register_t arg4; - u_register_t arg5; - u_register_t arg6; - u_register_t arg7; -} aapcs64_params_t; - -typedef struct aapcs32_params { - u_register_t arg0; - u_register_t arg1; - u_register_t arg2; - u_register_t arg3; -} aapcs32_params_t; - -/*************************************************************************** - * This structure provides version information and the size of the - * structure, attributes for the structure it represents - ***************************************************************************/ -typedef struct param_header { - uint8_t type; /* type of the structure */ - uint8_t version; /* version of this structure */ - uint16_t size; /* size of this structure in bytes */ - uint32_t attr; /* attributes: unused bits SBZ */ -} param_header_t; - -/***************************************************************************** - * This structure represents the superset of information needed while - * switching exception levels. The only two mechanisms to do so are - * ERET & SMC. Security state is indicated using bit zero of header - * attribute - * NOTE: BL1 expects entrypoint followed by spsr at an offset from the start - * of this structure defined by the macro `ENTRY_POINT_INFO_PC_OFFSET` while - * processing SMC to jump to BL31. - *****************************************************************************/ -typedef struct entry_point_info { - param_header_t h; - uintptr_t pc; - uint32_t spsr; -#ifdef AARCH32 - aapcs32_params_t args; -#else - aapcs64_params_t args; -#endif -} entry_point_info_t; - /***************************************************************************** * Image info binary provides information from the image loader that * can be used by the firmware to manage available trusted RAM. @@ -338,24 +219,6 @@ typedef struct bl31_params { #endif /* LOAD_IMAGE_V2 */ -/* - * Compile time assertions related to the 'entry_point_info' structure to - * ensure that the assembler and the compiler view of the offsets of - * the structure members is the same. - */ -CASSERT(ENTRY_POINT_INFO_PC_OFFSET == - __builtin_offsetof(entry_point_info_t, pc), \ - assert_BL31_pc_offset_mismatch); - -CASSERT(ENTRY_POINT_INFO_ARGS_OFFSET == \ - __builtin_offsetof(entry_point_info_t, args), \ - assert_BL31_args_offset_mismatch); - -CASSERT(sizeof(uintptr_t) == - __builtin_offsetof(entry_point_info_t, spsr) - \ - __builtin_offsetof(entry_point_info_t, pc), \ - assert_entrypoint_and_spsr_should_be_adjacent); - /******************************************************************************* * Function & variable prototypes ******************************************************************************/ diff --git a/include/common/debug.h b/include/common/debug.h index 41c8df0c..c6f211f3 100644 --- a/include/common/debug.h +++ b/include/common/debug.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2017, 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: @@ -84,6 +84,9 @@ void __dead2 do_panic(void); #define panic() do_panic() +/* Function called when stack protection check code detects a corrupted stack */ +void __dead2 __stack_chk_fail(void); + void tf_printf(const char *fmt, ...) __printflike(1, 2); #endif /* __ASSEMBLY__ */ diff --git a/include/common/ep_info.h b/include/common/ep_info.h new file mode 100644 index 00000000..36136142 --- /dev/null +++ b/include/common/ep_info.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2017, 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. + */ + +#ifndef __EP_INFO_H__ +#define __EP_INFO_H__ + +#include <param_header.h> + +#define SECURE 0x0 +#define NON_SECURE 0x1 +#define sec_state_is_valid(s) (((s) == SECURE) || ((s) == NON_SECURE)) + +/******************************************************************************* + * Constants that allow assembler code to access members of and the + * 'entry_point_info' structure at their correct offsets. + ******************************************************************************/ +#define ENTRY_POINT_INFO_PC_OFFSET 0x08 +#ifdef AARCH32 +#define ENTRY_POINT_INFO_ARGS_OFFSET 0x10 +#else +#define ENTRY_POINT_INFO_ARGS_OFFSET 0x18 +#endif + +/* The following are used to set/get image attributes. */ +#define PARAM_EP_SECURITY_MASK (0x1) + +#define GET_SECURITY_STATE(x) (x & PARAM_EP_SECURITY_MASK) +#define SET_SECURITY_STATE(x, security) \ + ((x) = ((x) & ~PARAM_EP_SECURITY_MASK) | (security)) + +#define EP_EE_MASK 0x2 +#define EP_EE_LITTLE 0x0 +#define EP_EE_BIG 0x2 +#define EP_GET_EE(x) (x & EP_EE_MASK) +#define EP_SET_EE(x, ee) ((x) = ((x) & ~EP_EE_MASK) | (ee)) + +#define EP_ST_MASK 0x4 +#define EP_ST_DISABLE 0x0 +#define EP_ST_ENABLE 0x4 +#define EP_GET_ST(x) (x & EP_ST_MASK) +#define EP_SET_ST(x, ee) ((x) = ((x) & ~EP_ST_MASK) | (ee)) + +#define EP_EXE_MASK 0x8 +#define NON_EXECUTABLE 0x0 +#define EXECUTABLE 0x8 +#define EP_GET_EXE(x) (x & EP_EXE_MASK) +#define EP_SET_EXE(x, ee) ((x) = ((x) & ~EP_EXE_MASK) | (ee)) + +#define EP_FIRST_EXE_MASK 0x10 +#define EP_FIRST_EXE 0x10 +#define EP_GET_FIRST_EXE(x) ((x) & EP_FIRST_EXE_MASK) +#define EP_SET_FIRST_EXE(x, ee) ((x) = ((x) & ~EP_FIRST_EXE_MASK) | (ee)) + +#ifndef __ASSEMBLY__ + +#include <cassert.h> +#include <types.h> + +typedef struct aapcs64_params { + u_register_t arg0; + u_register_t arg1; + u_register_t arg2; + u_register_t arg3; + u_register_t arg4; + u_register_t arg5; + u_register_t arg6; + u_register_t arg7; +} aapcs64_params_t; + +typedef struct aapcs32_params { + u_register_t arg0; + u_register_t arg1; + u_register_t arg2; + u_register_t arg3; +} aapcs32_params_t; + +/***************************************************************************** + * This structure represents the superset of information needed while + * switching exception levels. The only two mechanisms to do so are + * ERET & SMC. Security state is indicated using bit zero of header + * attribute + * NOTE: BL1 expects entrypoint followed by spsr at an offset from the start + * of this structure defined by the macro `ENTRY_POINT_INFO_PC_OFFSET` while + * processing SMC to jump to BL31. + *****************************************************************************/ +typedef struct entry_point_info { + param_header_t h; + uintptr_t pc; + uint32_t spsr; +#ifdef AARCH32 + aapcs32_params_t args; +#else + aapcs64_params_t args; +#endif +} entry_point_info_t; + +/* + * Compile time assertions related to the 'entry_point_info' structure to + * ensure that the assembler and the compiler view of the offsets of + * the structure members is the same. + */ +CASSERT(ENTRY_POINT_INFO_PC_OFFSET == + __builtin_offsetof(entry_point_info_t, pc), \ + assert_BL31_pc_offset_mismatch); + +CASSERT(ENTRY_POINT_INFO_ARGS_OFFSET == \ + __builtin_offsetof(entry_point_info_t, args), \ + assert_BL31_args_offset_mismatch); + +CASSERT(sizeof(uintptr_t) == + __builtin_offsetof(entry_point_info_t, spsr) - \ + __builtin_offsetof(entry_point_info_t, pc), \ + assert_entrypoint_and_spsr_should_be_adjacent); + +#endif /*__ASSEMBLY__*/ + +#endif /* __EP_INFO_H__ */ + diff --git a/include/common/param_header.h b/include/common/param_header.h new file mode 100644 index 00000000..176fc958 --- /dev/null +++ b/include/common/param_header.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2017, 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. + */ + +#ifndef __PARAM_HEADER_H__ +#define __PARAM_HEADER_H__ + +/* Param header types */ +#define PARAM_EP 0x01 +#define PARAM_IMAGE_BINARY 0x02 +#define PARAM_BL31 0x03 +#define PARAM_BL_LOAD_INFO 0x04 +#define PARAM_BL_PARAMS 0x05 +#define PARAM_PSCI_LIB_ARGS 0x06 + +/* Param header version */ +#define VERSION_1 0x01 +#define VERSION_2 0x02 + +#define SET_PARAM_HEAD(_p, _type, _ver, _attr) do { \ + (_p)->h.type = (uint8_t)(_type); \ + (_p)->h.version = (uint8_t)(_ver); \ + (_p)->h.size = (uint16_t)sizeof(*_p); \ + (_p)->h.attr = (uint32_t)(_attr) ; \ + } while (0) + +/* Following is used for populating structure members statically. */ +#define SET_STATIC_PARAM_HEAD(_p, _type, _ver, _p_type, _attr) \ + ._p.h.type = (uint8_t)(_type), \ + ._p.h.version = (uint8_t)(_ver), \ + ._p.h.size = (uint16_t)sizeof(_p_type), \ + ._p.h.attr = (uint32_t)(_attr) + +#ifndef __ASSEMBLY__ + +#include <types.h> + +/*************************************************************************** + * This structure provides version information and the size of the + * structure, attributes for the structure it represents + ***************************************************************************/ +typedef struct param_header { + uint8_t type; /* type of the structure */ + uint8_t version; /* version of this structure */ + uint16_t size; /* size of this structure in bytes */ + uint32_t attr; /* attributes: unused bits SBZ */ +} param_header_t; + +#endif /*__ASSEMBLY__*/ + +#endif /* __PARAM_HEADER_H__ */ + diff --git a/include/drivers/auth/mbedtls/mbedtls_config.h b/include/drivers/auth/mbedtls/mbedtls_config.h index a8d72415..9fce4242 100644 --- a/include/drivers/auth/mbedtls/mbedtls_config.h +++ b/include/drivers/auth/mbedtls/mbedtls_config.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2017, 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: @@ -33,8 +33,8 @@ /* * Key algorithms currently supported on mbed TLS libraries */ -#define MBEDTLS_RSA 1 -#define MBEDTLS_ECDSA 2 +#define TBBR_RSA 1 +#define TBBR_ECDSA 2 /* * Configuration file to build mbed TLS with the required features for @@ -69,11 +69,11 @@ #define MBEDTLS_PLATFORM_C -#if (MBEDTLS_KEY_ALG_ID == MBEDTLS_ECDSA) +#if (TBBR_KEY_ALG_ID == TBBR_ECDSA) #define MBEDTLS_ECDSA_C #define MBEDTLS_ECP_C #define MBEDTLS_ECP_DP_SECP256R1_ENABLED -#elif (MBEDTLS_KEY_ALG_ID == MBEDTLS_RSA) +#elif (TBBR_KEY_ALG_ID == TBBR_RSA) #define MBEDTLS_RSA_C #endif diff --git a/include/lib/el3_runtime/context_mgmt.h b/include/lib/el3_runtime/context_mgmt.h index 676973ce..ca868ddb 100644 --- a/include/lib/el3_runtime/context_mgmt.h +++ b/include/lib/el3_runtime/context_mgmt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2017, 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: @@ -31,7 +31,9 @@ #ifndef __CM_H__ #define __CM_H__ +#ifndef AARCH32 #include <arch.h> +#endif /******************************************************************************* * Forward declarations diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h index 34de4c28..fa85e0bc 100644 --- a/include/lib/psci/psci.h +++ b/include/lib/psci/psci.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2017, 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: @@ -37,6 +37,7 @@ #if ENABLE_PLAT_COMPAT #include <psci_compat.h> #endif +#include <psci_lib.h> /* To maintain compatibility for SPDs */ /******************************************************************************* * Number of power domains whose state this PSCI implementation can track @@ -311,24 +312,6 @@ typedef struct plat_psci_ops { } plat_psci_ops_t; /******************************************************************************* - * Optional structure populated by the Secure Payload Dispatcher to be given a - * chance to perform any bookkeeping before PSCI executes a power management - * operation. It also allows PSCI to determine certain properties of the SP e.g. - * migrate capability etc. - ******************************************************************************/ -typedef struct spd_pm_ops { - void (*svc_on)(u_register_t target_cpu); - int32_t (*svc_off)(u_register_t __unused); - void (*svc_suspend)(u_register_t max_off_pwrlvl); - void (*svc_on_finish)(u_register_t __unused); - void (*svc_suspend_finish)(u_register_t max_off_pwrlvl); - int32_t (*svc_migrate)(u_register_t from_cpu, u_register_t to_cpu); - int32_t (*svc_migrate_info)(u_register_t *resident_cpu); - void (*svc_system_off)(void); - void (*svc_system_reset)(void); -} spd_pm_ops_t; - -/******************************************************************************* * Function & Data prototypes ******************************************************************************/ unsigned int psci_version(void); @@ -357,63 +340,6 @@ void psci_arch_setup(void); */ void psci_entrypoint(void) __deprecated; -/* - * Function prototype for the warmboot entrypoint function which will be - * programmed in the mailbox by the platform. - */ -typedef void (*mailbox_entrypoint_t)(void); - -/****************************************************************************** - * Structure to pass PSCI Library arguments. - *****************************************************************************/ -typedef struct psci_lib_args { - /* The version information of PSCI Library Interface */ - param_header_t h; - /* The warm boot entrypoint function */ - mailbox_entrypoint_t mailbox_ep; -} psci_lib_args_t; - -/* Helper macro to set the psci_lib_args_t structure at runtime */ -#define SET_PSCI_LIB_ARGS_V1(_p, _entry) do { \ - SET_PARAM_HEAD(_p, PARAM_PSCI_LIB_ARGS, VERSION_1, 0); \ - (_p)->mailbox_ep = (_entry); \ - } while (0) - -/* Helper macro to define the psci_lib_args_t statically */ -#define DEFINE_STATIC_PSCI_LIB_ARGS_V1(_name, _entry) \ - static const psci_lib_args_t (_name) = { \ - .h.type = (uint8_t)PARAM_PSCI_LIB_ARGS, \ - .h.version = (uint8_t)VERSION_1, \ - .h.size = (uint16_t)sizeof(_name), \ - .h.attr = 0, \ - .mailbox_ep = (_entry) \ - } - -/* Helper macro to verify the pointer to psci_lib_args_t structure */ -#define VERIFY_PSCI_LIB_ARGS_V1(_p) ((_p) \ - && ((_p)->h.type == PARAM_PSCI_LIB_ARGS) \ - && ((_p)->h.version == VERSION_1) \ - && ((_p)->h.size == sizeof(*(_p))) \ - && ((_p)->h.attr == 0) \ - && ((_p)->mailbox_ep)) - -/****************************************************************************** - * PSCI Library Interfaces - *****************************************************************************/ -u_register_t psci_smc_handler(uint32_t smc_fid, - u_register_t x1, - u_register_t x2, - u_register_t x3, - u_register_t x4, - void *cookie, - void *handle, - u_register_t flags); -int psci_setup(const psci_lib_args_t *lib_args); -void psci_warmboot_entrypoint(void); -void psci_register_spd_pm_hook(const spd_pm_ops_t *pm); -void psci_prepare_next_non_secure_ctx( - entry_point_info_t *next_image_info); - #endif /*__ASSEMBLY__*/ #endif /* __PSCI_H__ */ diff --git a/include/lib/psci/psci_lib.h b/include/lib/psci/psci_lib.h new file mode 100644 index 00000000..2169d6de --- /dev/null +++ b/include/lib/psci/psci_lib.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2017, 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. + */ + +#ifndef __PSCI_LIB_H__ +#define __PSCI_LIB_H__ + +#include <ep_info.h> + +#ifndef __ASSEMBLY__ +#include <types.h> + +/******************************************************************************* + * Optional structure populated by the Secure Payload Dispatcher to be given a + * chance to perform any bookkeeping before PSCI executes a power management + * operation. It also allows PSCI to determine certain properties of the SP e.g. + * migrate capability etc. + ******************************************************************************/ +typedef struct spd_pm_ops { + void (*svc_on)(u_register_t target_cpu); + int32_t (*svc_off)(u_register_t __unused); + void (*svc_suspend)(u_register_t max_off_pwrlvl); + void (*svc_on_finish)(u_register_t __unused); + void (*svc_suspend_finish)(u_register_t max_off_pwrlvl); + int32_t (*svc_migrate)(u_register_t from_cpu, u_register_t to_cpu); + int32_t (*svc_migrate_info)(u_register_t *resident_cpu); + void (*svc_system_off)(void); + void (*svc_system_reset)(void); +} spd_pm_ops_t; + +/* + * Function prototype for the warmboot entrypoint function which will be + * programmed in the mailbox by the platform. + */ +typedef void (*mailbox_entrypoint_t)(void); + +/****************************************************************************** + * Structure to pass PSCI Library arguments. + *****************************************************************************/ +typedef struct psci_lib_args { + /* The version information of PSCI Library Interface */ + param_header_t h; + /* The warm boot entrypoint function */ + mailbox_entrypoint_t mailbox_ep; +} psci_lib_args_t; + +/* Helper macro to set the psci_lib_args_t structure at runtime */ +#define SET_PSCI_LIB_ARGS_V1(_p, _entry) do { \ + SET_PARAM_HEAD(_p, PARAM_PSCI_LIB_ARGS, VERSION_1, 0); \ + (_p)->mailbox_ep = (_entry); \ + } while (0) + +/* Helper macro to define the psci_lib_args_t statically */ +#define DEFINE_STATIC_PSCI_LIB_ARGS_V1(_name, _entry) \ + static const psci_lib_args_t (_name) = { \ + .h.type = (uint8_t)PARAM_PSCI_LIB_ARGS, \ + .h.version = (uint8_t)VERSION_1, \ + .h.size = (uint16_t)sizeof(_name), \ + .h.attr = 0, \ + .mailbox_ep = (_entry) \ + } + +/* Helper macro to verify the pointer to psci_lib_args_t structure */ +#define VERIFY_PSCI_LIB_ARGS_V1(_p) ((_p) \ + && ((_p)->h.type == PARAM_PSCI_LIB_ARGS) \ + && ((_p)->h.version == VERSION_1) \ + && ((_p)->h.size == sizeof(*(_p))) \ + && ((_p)->h.attr == 0) \ + && ((_p)->mailbox_ep)) + +/****************************************************************************** + * PSCI Library Interfaces + *****************************************************************************/ +u_register_t psci_smc_handler(uint32_t smc_fid, + u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4, + void *cookie, + void *handle, + u_register_t flags); +int psci_setup(const psci_lib_args_t *lib_args); +void psci_warmboot_entrypoint(void); +void psci_register_spd_pm_hook(const spd_pm_ops_t *pm); +void psci_prepare_next_non_secure_ctx( + entry_point_info_t *next_image_info); +#endif /* __ASSEMBLY__ */ + +#endif /* __PSCI_LIB_H */ + diff --git a/include/lib/utils.h b/include/lib/utils.h index 69bbb430..279c9135 100644 --- a/include/lib/utils.h +++ b/include/lib/utils.h @@ -42,6 +42,20 @@ #define BIT(nr) (1UL << (nr)) +#define MIN(x, y) __extension__ ({ \ + __typeof__(x) _x = (x); \ + __typeof__(y) _y = (y); \ + (void)(&_x == &_y); \ + _x < _y ? _x : _y; \ +}) + +#define MAX(x, y) __extension__ ({ \ + __typeof__(x) _x = (x); \ + __typeof__(y) _y = (y); \ + (void)(&_x == &_y); \ + _x > _y ? _x : _y; \ +}) + /* * The round_up() macro rounds up a value to the given boundary in a * type-agnostic yet type-safe manner. The boundary must be a power of two. diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 73bb6431..f13b30d8 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -72,6 +72,16 @@ uintptr_t plat_get_ns_image_entrypoint(void); unsigned int plat_my_core_pos(void); int plat_core_pos_by_mpidr(u_register_t mpidr); +#if STACK_PROTECTOR_ENABLED +/* + * Return a new value to be used for the stack protection's canary. + * + * Ideally, this value is a random number that is impossible to predict by an + * attacker. + */ +u_register_t plat_get_stack_protector_canary(void); +#endif /* STACK_PROTECTOR_ENABLED */ + /******************************************************************************* * Mandatory interrupt management functions ******************************************************************************/ @@ -326,7 +336,7 @@ int platform_setup_pm(const plat_pm_ops_t **); unsigned int plat_get_aff_count(unsigned int, unsigned long); unsigned int plat_get_aff_state(unsigned int, unsigned long); -#else +#else /* __ENABLE_PLAT_COMPAT__ */ /* * The below function enable Trusted Firmware components like SPDs which * haven't migrated to the new platform API to compile on platforms which @@ -335,4 +345,6 @@ unsigned int plat_get_aff_state(unsigned int, unsigned long); unsigned int platform_get_core_pos(unsigned long mpidr) __deprecated; #endif /* __ENABLE_PLAT_COMPAT__ */ + #endif /* __PLATFORM_H__ */ + diff --git a/lib/stack_protector/aarch32/asm_stack_protector.S b/lib/stack_protector/aarch32/asm_stack_protector.S new file mode 100644 index 00000000..9d2d77dc --- /dev/null +++ b/lib/stack_protector/aarch32/asm_stack_protector.S @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017, 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 <arch.h> +#include <asm_macros.S> +#include <assert_macros.S> + + .globl update_stack_protector_canary + +/* ----------------------------------------------------------------------- + * void update_stack_protector_canary(void) + * + * Change the value of the canary used for stack smashing attacks protection. + * Note: This must be called when it is safe to call C code, but this cannot be + * called by C code. Doing this will make the check fail when the calling + * function returns. + * ----------------------------------------------------------------------- + */ + +func update_stack_protector_canary + /* Use r4 as it is callee-saved */ + mov r4, lr + bl plat_get_stack_protector_canary + + /* Update the canary with the returned value */ + ldr r1, =__stack_chk_guard + str r0, [r1] + bx r4 +endfunc update_stack_protector_canary + + diff --git a/lib/stack_protector/aarch64/asm_stack_protector.S b/lib/stack_protector/aarch64/asm_stack_protector.S new file mode 100644 index 00000000..36f8f068 --- /dev/null +++ b/lib/stack_protector/aarch64/asm_stack_protector.S @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017, 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 <arch.h> +#include <asm_macros.S> +#include <assert_macros.S> + + .globl update_stack_protector_canary + +/* ----------------------------------------------------------------------- + * void update_stack_protector_canary(void) + * + * Change the value of the canary used for stack smashing attacks protection. + * Note: This must be called when it is safe to call C code, but this cannot be + * called by C code. Doing this will make the check fail when the calling + * function returns. + * ----------------------------------------------------------------------- + */ + +func update_stack_protector_canary + /* Use x19 as it is callee-saved */ + mov x19, x30 + bl plat_get_stack_protector_canary + + /* Update the canary with the returned value */ + adrp x1, __stack_chk_guard + str x0, [x1, #:lo12:__stack_chk_guard] + ret x19 +endfunc update_stack_protector_canary + + diff --git a/lib/stack_protector/stack_protector.c b/lib/stack_protector/stack_protector.c new file mode 100644 index 00000000..ccf2af48 --- /dev/null +++ b/lib/stack_protector/stack_protector.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017, 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 <platform.h> +#include <stdint.h> + +/* + * Canary value used by the compiler runtime checks to detect stack corruption. + * + * Force the canary to be in .data to allow predictable memory layout relatively + * to the stacks. + */ +u_register_t __attribute__((section(".data.stack_protector_canary"))) + __stack_chk_guard = (u_register_t) 3288484550995823360ULL; + +/* + * Function called when the stack's canary check fails, which means the stack + * was corrupted. It must not return. + */ +void __dead2 __stack_chk_fail(void) +{ +#if DEBUG + ERROR("Stack corruption detected\n"); +#endif + panic(); +} + diff --git a/lib/stack_protector/stack_protector.mk b/lib/stack_protector/stack_protector.mk new file mode 100644 index 00000000..03d47c47 --- /dev/null +++ b/lib/stack_protector/stack_protector.mk @@ -0,0 +1,43 @@ +# +# Copyright (c) 2017, 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. +# + +# Boolean macro to be used in C code +STACK_PROTECTOR_ENABLED := 0 + +ifneq (${ENABLE_STACK_PROTECTOR},0) +STACK_PROTECTOR_ENABLED := 1 +BL_COMMON_SOURCES += lib/stack_protector/stack_protector.c \ + lib/stack_protector/${ARCH}/asm_stack_protector.S + +TF_CFLAGS += -fstack-protector-${ENABLE_STACK_PROTECTOR} +endif + +$(eval $(call add_define,STACK_PROTECTOR_ENABLED)) + diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index de506be5..e66f5112 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -90,6 +90,9 @@ ENABLE_PSCI_STAT := 0 # Flag to enable runtime instrumentation using PMF ENABLE_RUNTIME_INSTRUMENTATION := 0 +# Flag to enable stack corruption protection +ENABLE_STACK_PROTECTOR := 0 + # Build flag to treat usage of deprecated platform and framework APIs as error. ERROR_DEPRECATED := 0 diff --git a/plat/arm/board/fvp/fvp_stack_protector.c b/plat/arm/board/fvp/fvp_stack_protector.c new file mode 100644 index 00000000..0375c1e2 --- /dev/null +++ b/plat/arm/board/fvp/fvp_stack_protector.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017, 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 <arch_helpers.h> +#include <platform.h> +#include <stdint.h> + +#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 + * FVP 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/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 9b827a6b..8bac0be9 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2017, 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: @@ -157,5 +157,9 @@ BL31_SOURCES += plat/arm/board/fvp/fvp_bl31_setup.c \ # Disable the PSCI platform compatibility layer ENABLE_PLAT_COMPAT := 0 +ifneq (${ENABLE_STACK_PROTECTOR},0) +PLAT_BL_COMMON_SOURCES += plat/arm/board/fvp/fvp_stack_protector.c +endif + include plat/arm/board/common/board_common.mk include plat/arm/common/arm_common.mk diff --git a/plat/arm/board/juno/juno_decl.h b/plat/arm/board/juno/juno_decl.h new file mode 100644 index 00000000..75ed5b03 --- /dev/null +++ b/plat/arm/board/juno/juno_decl.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017, 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. + */ + +#ifndef __JUNO_DECL_H__ +#define __JUNO_DECL_H__ + +int juno_getentropy(void *buf, size_t len); + +#endif /* __JUNO_DECL_H__ */ diff --git a/plat/arm/board/juno/juno_def.h b/plat/arm/board/juno/juno_def.h index f27bbb22..a8e9872b 100644 --- a/plat/arm/board/juno/juno_def.h +++ b/plat/arm/board/juno/juno_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2017, 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: @@ -75,6 +75,17 @@ #define TZC400_NSAID_CORESIGHT 12 /******************************************************************************* + * TRNG related constants + ******************************************************************************/ +#define TRNG_BASE 0x7FE60000ULL +#define TRNG_NOUTPUTS 4 +#define TRNG_STATUS 0x10 +#define TRNG_INTMASK 0x14 +#define TRNG_CONFIG 0x18 +#define TRNG_CONTROL 0x1C +#define TRNG_NBYTES 16 /* Number of bytes generated per round. */ + +/******************************************************************************* * MMU-401 related constants ******************************************************************************/ #define MMU401_SSD_OFFSET 0x4000 diff --git a/plat/arm/board/juno/juno_stack_protector.c b/plat/arm/board/juno/juno_stack_protector.c new file mode 100644 index 00000000..720a522e --- /dev/null +++ b/plat/arm/board/juno/juno_stack_protector.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017, 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 <arch_helpers.h> +#include <debug.h> +#include <utils.h> +#include "juno_decl.h" +#include "juno_def.h" + +u_register_t plat_get_stack_protector_canary(void) +{ + u_register_t c[TRNG_NBYTES / sizeof(u_register_t)]; + u_register_t ret = 0; + size_t i; + + if (juno_getentropy(c, sizeof(c)) != 0) { + ERROR("Not enough entropy to initialize canary value\n"); + panic(); + } + + /* + * On Juno we get 128-bits of entropy in one round. + * Fuse the values together to form the canary. + */ + for (i = 0; i < ARRAY_SIZE(c); i++) + ret ^= c[i]; + return ret; +} diff --git a/plat/arm/board/juno/juno_trng.c b/plat/arm/board/juno/juno_trng.c new file mode 100644 index 00000000..2fcddcdb --- /dev/null +++ b/plat/arm/board/juno/juno_trng.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2017, 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 <assert.h> +#include <mmio.h> +#include <string.h> +#include <utils.h> +#include "juno_def.h" + +#define NSAMPLE_CLOCKS 1 /* min 1 cycle, max 231 cycles */ +#define NRETRIES 5 + +static inline int output_valid(void) +{ + int i; + + for (i = 0; i < NRETRIES; i++) { + uint32_t val; + + val = mmio_read_32(TRNG_BASE + TRNG_STATUS); + if (val & 1U) + break; + } + if (i >= NRETRIES) + return 0; /* No output data available. */ + return 1; +} + +/* + * This function fills `buf` with `len` bytes of entropy. + * It uses the Trusted Entropy Source peripheral on Juno. + * Returns 0 when the buffer has been filled with entropy + * successfully and -1 otherwise. + */ +int juno_getentropy(void *buf, size_t len) +{ + uint8_t *bp = buf; + + assert(buf); + assert(len); + assert(!check_uptr_overflow((uintptr_t)bp, len)); + + /* Disable interrupt mode. */ + mmio_write_32(TRNG_BASE + TRNG_INTMASK, 0); + /* Program TRNG to sample for `NSAMPLE_CLOCKS`. */ + mmio_write_32(TRNG_BASE + TRNG_CONFIG, NSAMPLE_CLOCKS); + + while (len > 0) { + int i; + + /* Start TRNG. */ + mmio_write_32(TRNG_BASE + TRNG_CONTROL, 1); + + /* Check if output is valid. */ + if (!output_valid()) + return -1; + + /* Fill entropy buffer. */ + for (i = 0; i < TRNG_NOUTPUTS; i++) { + size_t n; + uint32_t val; + + val = mmio_read_32(TRNG_BASE + i * sizeof(uint32_t)); + n = MIN(len, sizeof(uint32_t)); + memcpy(bp, &val, n); + bp += n; + len -= n; + if (len == 0) + break; + } + + /* Reset TRNG outputs. */ + mmio_write_32(TRNG_BASE + TRNG_STATUS, 1); + } + + return 0; +} diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index 7571582b..39977240 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2017, 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: @@ -39,8 +39,12 @@ JUNO_INTERCONNECT_SOURCES := drivers/arm/cci/cci.c \ JUNO_SECURITY_SOURCES := drivers/arm/tzc/tzc400.c \ plat/arm/board/juno/juno_security.c \ + plat/arm/board/juno/juno_trng.c \ plat/arm/common/arm_tzc400.c +ifneq (${ENABLE_STACK_PROTECTOR}, 0) +JUNO_SECURITY_SOURCES += plat/arm/board/juno/juno_stack_protector.c +endif PLAT_INCLUDES := -Iplat/arm/board/juno/include @@ -51,7 +55,8 @@ BL1_SOURCES += lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a72.S \ plat/arm/board/juno/juno_bl1_setup.c \ plat/arm/board/juno/juno_err.c \ - ${JUNO_INTERCONNECT_SOURCES} + ${JUNO_INTERCONNECT_SOURCES} \ + ${JUNO_SECURITY_SOURCES} BL2_SOURCES += plat/arm/board/juno/juno_err.c \ ${JUNO_SECURITY_SOURCES} @@ -67,11 +72,20 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ ${JUNO_INTERCONNECT_SOURCES} \ ${JUNO_SECURITY_SOURCES} -# Enable workarounds for selected Cortex-A53 and A57 erratas. +# Enable workarounds for selected Cortex-A53 and A57 errata. ERRATA_A53_855873 := 1 ERRATA_A57_806969 := 0 ERRATA_A57_813419 := 1 ERRATA_A57_813420 := 1 +ERRATA_A57_826974 := 1 +ERRATA_A57_826977 := 1 +ERRATA_A57_828024 := 1 +ERRATA_A57_829520 := 1 +ERRATA_A57_833471 := 1 + +# Enable workarounds for selected Cortex-A53 errata. +ERRATA_A53_826319 := 1 +ERRATA_A53_836870 := 1 # Enable option to skip L1 data cache flush during the Cortex-A57 cluster # power down sequence diff --git a/plat/mediatek/mt6795/bl31.ld.S b/plat/mediatek/mt6795/bl31.ld.S index 472cd2e0..73d5fdf9 100644 --- a/plat/mediatek/mt6795/bl31.ld.S +++ b/plat/mediatek/mt6795/bl31.ld.S @@ -95,6 +95,11 @@ SECTIONS */ __RW_START__ = . ; + /* + * .data must be placed at a lower address than the stacks if the stack + * protector is enabled. Alternatively, the .data.stack_protector_canary + * section can be placed independently of the main .data section. + */ .data . : { __DATA_START__ = .; *(.data*) diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index a03b6ef7..bd16b991 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -38,6 +38,7 @@ #include <smmu.h> #include <string.h> #include <tegra_def.h> +#include <tegra_platform.h> #include <xlat_tables.h> #define TEGRA_GPU_RESET_REG_OFFSET 0x30 @@ -495,7 +496,6 @@ void tegra_memctrl_setup(void) uint32_t num_overrides = sizeof(streamid_overrides) / sizeof(uint32_t); uint32_t num_sec_cfgs = sizeof(sec_cfgs) / sizeof(mc_streamid_security_cfg_t); uint32_t num_txn_overrides = sizeof(mc_override_cfgs) / sizeof(mc_txn_override_cfg_t); - uint32_t chip_minor, chip_major; int i; INFO("Tegra Memory Controller (v2)\n"); @@ -543,12 +543,8 @@ void tegra_memctrl_setup(void) /* * Set the MC_TXN_OVERRIDE registers for write clients. */ - chip_major = (mmio_read_32(TEGRA_MISC_BASE + HARDWARE_REVISION_OFFSET) >> - MAJOR_VERSION_SHIFT) & MAJOR_VERSION_MASK; - chip_minor = (mmio_read_32(TEGRA_MISC_BASE + HARDWARE_REVISION_OFFSET) >> - MINOR_VERSION_SHIFT) & MINOR_VERSION_MASK; - - if ((chip_major == 0) || (chip_major > 0 && chip_minor == 1)) { + if (!tegra_platform_is_silicon() || + (tegra_platform_is_silicon() && tegra_get_chipid_minor() == 1)) { /* GPU and NVENC settings for rev. A01 */ val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR); @@ -641,33 +637,55 @@ void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes) */ void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes) { - uint64_t tzram_end = phys_base + size_in_bytes - 1; + uint32_t index; + uint32_t total_128kb_blocks = size_in_bytes >> 17; + uint32_t residual_4kb_blocks = (size_in_bytes & 0x1FFFF) >> 12; uint32_t val; /* - * Check if the TZRAM is locked already. + * Reset the access configuration registers to restrict access + * to the TZRAM aperture */ - if (tegra_mc_read_32(MC_TZRAM_REG_CTRL) == DISABLE_TZRAM_ACCESS) - return; + for (index = MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG0; + index <= MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS5; + index += 4) + tegra_mc_write_32(index, 0); /* - * Setup the Memory controller to allow only secure accesses to - * the TZRAM carveout + * Allow CPU read/write access to the aperture */ - INFO("Configuring TrustZone RAM (SysRAM) Memory Carveout\n"); + tegra_mc_write_32(MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG1, + TZRAM_CARVEOUT_CPU_WRITE_ACCESS_BIT | + TZRAM_CARVEOUT_CPU_READ_ACCESS_BIT); - /* Program the base and end values */ - tegra_mc_write_32(MC_TZRAM_BASE, (uint32_t)phys_base); - tegra_mc_write_32(MC_TZRAM_END, (uint32_t)tzram_end); + /* + * Set the TZRAM base. TZRAM base must be 4k aligned, at least. + */ + assert(!(phys_base & 0xFFF)); + tegra_mc_write_32(MC_TZRAM_BASE_LO, (uint32_t)phys_base); + tegra_mc_write_32(MC_TZRAM_BASE_HI, + (uint32_t)(phys_base >> 32) & TZRAM_BASE_HI_MASK); - /* Extract the high address bits from the base/end values */ - val = (uint32_t)(phys_base >> 32) & TZRAM_ADDR_HI_BITS_MASK; - val |= (((uint32_t)(tzram_end >> 32) & TZRAM_ADDR_HI_BITS_MASK) << - TZRAM_END_HI_BITS_SHIFT); - tegra_mc_write_32(MC_TZRAM_HI_ADDR_BITS, val); + /* + * Set the TZRAM size + * + * total size = (number of 128KB blocks) + (number of remaining 4KB + * blocks) + * + */ + val = (residual_4kb_blocks << TZRAM_SIZE_RANGE_4KB_SHIFT) | + total_128kb_blocks; + tegra_mc_write_32(MC_TZRAM_SIZE, val); - /* Disable further writes to the TZRAM setup registers */ - tegra_mc_write_32(MC_TZRAM_REG_CTRL, DISABLE_TZRAM_ACCESS); + /* + * Lock the configuration settings by disabling TZ-only lock + * and locking the configuration against any future changes + * at all. + */ + val = tegra_mc_read_32(MC_TZRAM_CARVEOUT_CFG); + val &= ~TZRAM_ENABLE_TZ_LOCK_BIT; + val |= TZRAM_LOCK_CFG_SETTINGS_BIT; + tegra_mc_write_32(MC_TZRAM_CARVEOUT_CFG, val); /* * MCE propogates the security configuration values across the diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h index a7ab6503..e1abe143 100644 --- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h +++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h @@ -350,7 +350,7 @@ typedef struct mc_streamid_security_cfg { .override_enable = OVERRIDE_ ## access \ } -#endif /* __ASSMEBLY__ */ +#endif /* __ASSEMBLY__ */ /******************************************************************************* * TZDRAM carveout configuration registers @@ -367,15 +367,35 @@ typedef struct mc_streamid_security_cfg { #define MC_VIDEO_PROTECT_SIZE_MB 0x64c /******************************************************************************* - * TZRAM carveout configuration registers + * TZRAM carveout (MC_SECURITY_CARVEOUT11) configuration registers ******************************************************************************/ -#define MC_TZRAM_BASE 0x1850 -#define MC_TZRAM_END 0x1854 -#define MC_TZRAM_HI_ADDR_BITS 0x1588 - #define TZRAM_ADDR_HI_BITS_MASK 0x3 - #define TZRAM_END_HI_BITS_SHIFT 8 -#define MC_TZRAM_REG_CTRL 0x185c - #define DISABLE_TZRAM_ACCESS 1 +#define MC_TZRAM_BASE_LO 0x2194 +#define TZRAM_BASE_LO_SHIFT 12 +#define TZRAM_BASE_LO_MASK 0xFFFFF +#define MC_TZRAM_BASE_HI 0x2198 +#define TZRAM_BASE_HI_SHIFT 0 +#define TZRAM_BASE_HI_MASK 3 +#define MC_TZRAM_SIZE 0x219C +#define TZRAM_SIZE_RANGE_4KB_SHIFT 27 + +#define MC_TZRAM_CARVEOUT_CFG 0x2190 +#define TZRAM_LOCK_CFG_SETTINGS_BIT (1 << 1) +#define TZRAM_ENABLE_TZ_LOCK_BIT (1 << 0) +#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG0 0x21A0 +#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG1 0x21A4 +#define TZRAM_CARVEOUT_CPU_WRITE_ACCESS_BIT (1 << 25) +#define TZRAM_CARVEOUT_CPU_READ_ACCESS_BIT (1 << 7) +#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG2 0x21A8 +#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG3 0x21AC +#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG4 0x21B0 +#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG5 0x21B4 + +#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS0 0x21B8 +#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS1 0x21BC +#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS2 0x21C0 +#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS3 0x21C4 +#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS4 0x21C8 +#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS5 0x21CC /******************************************************************************* * Memory Controller Reset Control registers diff --git a/plat/nvidia/tegra/include/drivers/smmu.h b/plat/nvidia/tegra/include/drivers/smmu.h index 0867c11a..0640846a 100644 --- a/plat/nvidia/tegra/include/drivers/smmu.h +++ b/plat/nvidia/tegra/include/drivers/smmu.h @@ -599,9 +599,16 @@ * SMMU Global Secure Aux. Configuration Register ******************************************************************************/ #define SMMU_GSR0_SECURE_ACR 0x10 +#define SMMU_GNSR_ACR (SMMU_GSR0_SECURE_ACR + 0x400) #define SMMU_GSR0_PGSIZE_SHIFT 16 #define SMMU_GSR0_PGSIZE_4K (0 << SMMU_GSR0_PGSIZE_SHIFT) #define SMMU_GSR0_PGSIZE_64K (1 << SMMU_GSR0_PGSIZE_SHIFT) +#define SMMU_ACR_CACHE_LOCK_ENABLE_BIT (1 << 26) + +/******************************************************************************* + * SMMU Global Aux. Control Register + ******************************************************************************/ +#define SMMU_CBn_ACTLR_CPRE_BIT (1 << 1) /******************************************************************************* * SMMU configuration constants diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index 7f85351e..e0eddfd3 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -76,10 +76,6 @@ ******************************************************************************/ #define TEGRA_MISC_BASE 0x00100000 #define HARDWARE_REVISION_OFFSET 0x4 -#define MAJOR_VERSION_SHIFT 0x4 -#define MAJOR_VERSION_MASK 0xF -#define MINOR_VERSION_SHIFT 0x10 -#define MINOR_VERSION_MASK 0xF #define MISCREG_PFCFG 0x200C @@ -106,6 +102,13 @@ #define TEGRA_UARTG_BASE 0x0C290000 /******************************************************************************* + * Tegra Fuse Controller related constants + ******************************************************************************/ +#define TEGRA_FUSE_BASE 0x03820000 +#define OPT_SUBREVISION 0x248 +#define SUBREVISION_MASK 0xFF + +/******************************************************************************* * GICv2 & interrupt handling related constants ******************************************************************************/ #define TEGRA_GICD_BASE 0x03881000 @@ -143,6 +146,8 @@ #define SECURE_SCRATCH_RSV6 0x680 #define SECURE_SCRATCH_RSV11_LO 0x6A8 #define SECURE_SCRATCH_RSV11_HI 0x6AC +#define SECURE_SCRATCH_RSV53_LO 0x7F8 +#define SECURE_SCRATCH_RSV53_HI 0x7FC /******************************************************************************* * Tegra Memory Mapped Control Register Access Bus constants @@ -158,6 +163,6 @@ * Tegra TZRAM constants ******************************************************************************/ #define TEGRA_TZRAM_BASE 0x30000000 -#define TEGRA_TZRAM_SIZE 0x50000 +#define TEGRA_TZRAM_SIZE 0x40000 #endif /* __TEGRA_DEF_H__ */ diff --git a/plat/nvidia/tegra/soc/t186/drivers/include/mce.h b/plat/nvidia/tegra/soc/t186/drivers/include/mce.h index 60656923..66e212bf 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/include/mce.h +++ b/plat/nvidia/tegra/soc/t186/drivers/include/mce.h @@ -95,6 +95,7 @@ typedef enum mce_cmd { MCE_CMD_ROC_FLUSH_CACHE, MCE_CMD_ROC_CLEAN_CACHE, MCE_CMD_ENABLE_LATIC, + MCE_CMD_UNCORE_PERFMON_REQ, MCE_CMD_IS_CCX_ALLOWED = 0xFE, MCE_CMD_MAX = 0xFF, } mce_cmd_t; @@ -102,6 +103,24 @@ typedef enum mce_cmd { #define MCE_CMD_MASK 0xFF /******************************************************************************* + * Struct to prepare UPDATE_CSTATE_INFO request + ******************************************************************************/ +typedef struct mce_cstate_info { + /* cluster cstate value */ + uint32_t cluster; + /* ccplex cstate value */ + uint32_t ccplex; + /* system cstate value */ + uint32_t system; + /* force system state? */ + uint8_t system_state_force; + /* wake mask value */ + uint32_t wake_mask; + /* update the wake mask? */ + uint8_t update_wake_mask; +} mce_cstate_info_t; + +/******************************************************************************* * Macros to prepare CSTATE info request ******************************************************************************/ /* Description of the parameters for UPDATE_CSTATE_INFO request */ @@ -184,6 +203,54 @@ typedef union mca_arg { } mca_arg_t; /******************************************************************************* + * Uncore PERFMON ARI struct + ******************************************************************************/ +typedef union uncore_perfmon_req { + struct perfmon_command { + /* + * Commands: 0 = READ, 1 = WRITE + */ + uint64_t cmd:8; + /* + * The unit group: L2=0, L3=1, ROC=2, MC=3, IOB=4 + */ + uint64_t grp:4; + /* + * Unit selector: Selects the unit instance, with 0 = Unit + * = (number of units in group) - 1. + */ + uint64_t unit:4; + /* + * Selects the uncore perfmon register to access + */ + uint64_t reg:8; + /* + * Counter number. Selects which counter to use for + * registers NV_PMEVCNTR and NV_PMEVTYPER. + */ + uint64_t counter:8; + } perfmon_command; + struct perfmon_status { + /* + * Resulting command status + */ + uint64_t val:8; + uint64_t unused:24; + } perfmon_status; + uint64_t data; +} uncore_perfmon_req_t; + +#define UNCORE_PERFMON_CMD_READ 0 +#define UNCORE_PERFMON_CMD_WRITE 1 + +#define UNCORE_PERFMON_CMD_MASK 0xFF +#define UNCORE_PERFMON_UNIT_GRP_MASK 0xF +#define UNCORE_PERFMON_SELECTOR_MASK 0xF +#define UNCORE_PERFMON_REG_MASK 0xFF +#define UNCORE_PERFMON_CTR_MASK 0xFF +#define UNCORE_PERFMON_RESP_STATUS_MASK 0xFF + +/******************************************************************************* * Structure populated by arch specific code to export routines which perform * common low level MCE functions ******************************************************************************/ @@ -313,6 +380,12 @@ typedef struct arch_mce_ops { * reset the entire system */ void (*enter_ccplex_state)(uint32_t ari_base, uint32_t state_idx); + /* + * This ARI request reads/writes data from/to Uncore PERFMON + * registers + */ + int (*read_write_uncore_perfmon)(uint32_t ari_base, + uncore_perfmon_req_t req, uint64_t *data); } arch_mce_ops_t; int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1, @@ -322,6 +395,7 @@ int mce_update_gsc_videomem(void); int mce_update_gsc_tzdram(void); int mce_update_gsc_tzram(void); __dead2 void mce_enter_ccplex_state(uint32_t state_idx); +void mce_update_cstate_info(mce_cstate_info_t *cstate); void mce_verify_firmware_version(void); /* declarations for ARI/NVG handler functions */ @@ -344,6 +418,8 @@ int ari_roc_clean_cache(uint32_t ari_base); uint64_t ari_read_write_mca(uint32_t ari_base, mca_cmd_t cmd, uint64_t *data); int ari_update_ccplex_gsc(uint32_t ari_base, uint32_t gsc_idx); void ari_enter_ccplex_state(uint32_t ari_base, uint32_t state_idx); +int ari_read_write_uncore_perfmon(uint32_t ari_base, + uncore_perfmon_req_t req, uint64_t *data); int nvg_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time); int nvg_update_cstate_info(uint32_t ari_base, uint32_t cluster, uint32_t ccplex, diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c index 147a358a..e11d1600 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c +++ b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c @@ -389,3 +389,41 @@ void ari_enter_ccplex_state(uint32_t ari_base, uint32_t state_idx) */ (void)ari_request_wait(ari_base, 0, TEGRA_ARI_MISC_CCPLEX, state_idx, 0); } + +int ari_read_write_uncore_perfmon(uint32_t ari_base, + uncore_perfmon_req_t req, uint64_t *data) +{ + int ret; + uint32_t val; + + /* sanity check input parameters */ + if (req.perfmon_command.cmd == UNCORE_PERFMON_CMD_READ && !data) { + ERROR("invalid parameters\n"); + return EINVAL; + } + + /* + * For "write" commands get the value that has to be written + * to the uncore perfmon registers + */ + val = (req.perfmon_command.cmd == UNCORE_PERFMON_CMD_WRITE) ? + *data : 0; + + ret = ari_request_wait(ari_base, 0, TEGRA_ARI_PERFMON, val, req.data); + if (ret) + return ret; + + /* read the command status value */ + req.perfmon_status.val = ari_get_response_high(ari_base) & + UNCORE_PERFMON_RESP_STATUS_MASK; + + /* + * For "read" commands get the data from the uncore + * perfmon registers + */ + if ((req.perfmon_status.val == 0) && (req.perfmon_command.cmd == + UNCORE_PERFMON_CMD_READ)) + *data = ari_get_response_low(ari_base); + + return (int)req.perfmon_status.val; +} diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c index 9d0d71fd..f87dfa4d 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c +++ b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c @@ -42,6 +42,7 @@ #include <sys/errno.h> #include <t18x_ari.h> #include <tegra_def.h> +#include <tegra_platform.h> /* NVG functions handlers */ static arch_mce_ops_t nvg_mce_ops = { @@ -61,7 +62,8 @@ static arch_mce_ops_t nvg_mce_ops = { .roc_clean_cache = ari_roc_clean_cache, .read_write_mca = ari_read_write_mca, .update_ccplex_gsc = ari_update_ccplex_gsc, - .enter_ccplex_state = ari_enter_ccplex_state + .enter_ccplex_state = ari_enter_ccplex_state, + .read_write_uncore_perfmon = ari_read_write_uncore_perfmon }; /* ARI functions handlers */ @@ -82,7 +84,8 @@ static arch_mce_ops_t ari_mce_ops = { .roc_clean_cache = ari_roc_clean_cache, .read_write_mca = ari_read_write_mca, .update_ccplex_gsc = ari_update_ccplex_gsc, - .enter_ccplex_state = ari_enter_ccplex_state + .enter_ccplex_state = ari_enter_ccplex_state, + .read_write_uncore_perfmon = ari_read_write_uncore_perfmon }; typedef struct mce_config { @@ -173,6 +176,7 @@ int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1, uint64_t ret64 = 0, arg3, arg4, arg5; int ret = 0; mca_cmd_t mca_cmd; + uncore_perfmon_req_t req; cpu_context_t *ctx = cm_get_context(NON_SECURE); gp_regs_t *gp_regs = get_gpregs_ctx(ctx); @@ -374,6 +378,15 @@ int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1, break; #endif + + case MCE_CMD_UNCORE_PERFMON_REQ: + memcpy(&req, &arg0, sizeof(arg0)); + ret = ops->read_write_uncore_perfmon(cpu_ari_base, req, &arg1); + + /* update context to return data */ + write_ctx_reg(gp_regs, CTX_GPREG_X1, arg1); + break; + default: ERROR("unknown MCE command (%d)\n", cmd); return EINVAL; @@ -449,6 +462,19 @@ __dead2 void mce_enter_ccplex_state(uint32_t state_idx) } /******************************************************************************* + * Handler to issue the UPDATE_CSTATE_INFO request + ******************************************************************************/ +void mce_update_cstate_info(mce_cstate_info_t *cstate) +{ + arch_mce_ops_t *ops = mce_get_curr_cpu_ops(); + + /* issue the UPDATE_CSTATE_INFO request */ + ops->update_cstate_info(mce_get_curr_cpu_ari_base(), cstate->cluster, + cstate->ccplex, cstate->system, cstate->system_state_force, + cstate->wake_mask, cstate->update_wake_mask); +} + +/******************************************************************************* * Handler to read the MCE firmware version and check if it is compatible * with interface header the BL3-1 was compiled against ******************************************************************************/ @@ -457,7 +483,13 @@ void mce_verify_firmware_version(void) arch_mce_ops_t *ops; uint32_t cpu_ari_base; uint64_t version; - uint32_t major, minor, chip_minor, chip_major; + uint32_t major, minor; + + /* + * MCE firmware is not running on simulation platforms. + */ + if (tegra_platform_is_emulation()) + return; /* get a pointer to the CPU's arch_mce_ops_t struct */ ops = mce_get_curr_cpu_ops(); @@ -477,17 +509,6 @@ void mce_verify_firmware_version(void) TEGRA_ARI_VERSION_MAJOR, TEGRA_ARI_VERSION_MINOR); /* - * MCE firmware is not running on simulation platforms. Simulation - * platforms are identified by v0.3 from the Tegra Chip ID value. - */ - chip_major = (mmio_read_32(TEGRA_MISC_BASE + HARDWARE_REVISION_OFFSET) >> - MAJOR_VERSION_SHIFT) & MAJOR_VERSION_MASK; - chip_minor = (mmio_read_32(TEGRA_MISC_BASE + HARDWARE_REVISION_OFFSET) >> - MINOR_VERSION_SHIFT) & MINOR_VERSION_MASK; - if ((chip_major == 0) && (chip_minor == 3)) - return; - - /* * Verify that the MCE firmware version and the interface header * match */ diff --git a/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c b/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c index d1e1804e..bca6f2ec 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c +++ b/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c @@ -465,15 +465,42 @@ void tegra_smmu_save_context(uint64_t smmu_ctx_addr) (uint32_t)(smmu_ctx_addr >> 32)); } +#define SMMU_NUM_CONTEXTS 64 +#define SMMU_CONTEXT_BANK_MAX_IDX 64 + /* * Init SMMU during boot or "System Suspend" exit */ void tegra_smmu_init(void) { - uint32_t val; + uint32_t val, i, ctx_base; - /* Program the SMMU pagesize */ + /* Program the SMMU pagesize and reset CACHE_LOCK bit */ val = tegra_smmu_read_32(SMMU_GSR0_SECURE_ACR); val |= SMMU_GSR0_PGSIZE_64K; + val &= ~SMMU_ACR_CACHE_LOCK_ENABLE_BIT; + tegra_smmu_write_32(SMMU_GSR0_SECURE_ACR, val); + + /* reset CACHE LOCK bit for NS Aux. Config. Register */ + val = tegra_smmu_read_32(SMMU_GNSR_ACR); + val &= ~SMMU_ACR_CACHE_LOCK_ENABLE_BIT; + tegra_smmu_write_32(SMMU_GNSR_ACR, val); + + /* disable TCU prefetch for all contexts */ + ctx_base = (SMMU_GSR0_PGSIZE_64K * SMMU_NUM_CONTEXTS) + SMMU_CBn_ACTLR; + for (i = 0; i < SMMU_CONTEXT_BANK_MAX_IDX; i++) { + val = tegra_smmu_read_32(ctx_base + (SMMU_GSR0_PGSIZE_64K * i)); + val &= ~SMMU_CBn_ACTLR_CPRE_BIT; + tegra_smmu_write_32(ctx_base + (SMMU_GSR0_PGSIZE_64K * i), val); + } + + /* set CACHE LOCK bit for NS Aux. Config. Register */ + val = tegra_smmu_read_32(SMMU_GNSR_ACR); + val |= SMMU_ACR_CACHE_LOCK_ENABLE_BIT; + tegra_smmu_write_32(SMMU_GNSR_ACR, val); + + /* set CACHE LOCK bit for S Aux. Config. Register */ + val = tegra_smmu_read_32(SMMU_GSR0_SECURE_ACR); + val |= SMMU_ACR_CACHE_LOCK_ENABLE_BIT; tegra_smmu_write_32(SMMU_GSR0_SECURE_ACR, val); } diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index 83552700..35828787 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -37,6 +37,7 @@ #include <debug.h> #include <denver.h> #include <mce.h> +#include <platform.h> #include <psci.h> #include <smmu.h> #include <string.h> @@ -71,12 +72,9 @@ int32_t tegra_soc_validate_power_state(unsigned int power_state, psci_power_state_t *req_state) { int state_id = psci_get_pstate_id(power_state) & TEGRA186_STATE_ID_MASK; - int cpu = read_mpidr() & MPIDR_CPU_MASK; - int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; - - if (impl == DENVER_IMPL) - cpu |= 0x4; + int cpu = plat_my_core_pos(); + /* save the core wake time (us) */ wake_time[cpu] = (power_state >> TEGRA186_WAKE_TIME_SHIFT) & TEGRA186_WAKE_TIME_MASK; @@ -84,10 +82,10 @@ int32_t tegra_soc_validate_power_state(unsigned int power_state, switch (state_id) { case PSTATE_ID_CORE_IDLE: case PSTATE_ID_CORE_POWERDN: - /* - * Core powerdown request only for afflvl 0 - */ + + /* Core powerdown request */ req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id; + req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id; break; @@ -103,20 +101,12 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) { const plat_local_state_t *pwr_domain_state; unsigned int stateid_afflvl0, stateid_afflvl2; - int cpu = read_mpidr() & MPIDR_CPU_MASK; - int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; - cpu_context_t *ctx = cm_get_context(NON_SECURE); - gp_regs_t *gp_regs = get_gpregs_ctx(ctx); + int cpu = plat_my_core_pos(); plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); + mce_cstate_info_t cstate_info = { 0 }; uint64_t smmu_ctx_base; uint32_t val; - assert(ctx); - assert(gp_regs); - - if (impl == DENVER_IMPL) - cpu |= 0x4; - /* get the state ID */ pwr_domain_state = target_state->pwr_domain_state; stateid_afflvl0 = pwr_domain_state[MPIDR_AFFLVL0] & @@ -124,29 +114,14 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] & TEGRA186_STATE_ID_MASK; - if (stateid_afflvl0 == PSTATE_ID_CORE_IDLE) { + if ((stateid_afflvl0 == PSTATE_ID_CORE_IDLE) || + (stateid_afflvl0 == PSTATE_ID_CORE_POWERDN)) { - /* Program default wake mask */ - write_ctx_reg(gp_regs, CTX_GPREG_X4, 0); - write_ctx_reg(gp_regs, CTX_GPREG_X5, TEGRA186_CORE_WAKE_MASK); - write_ctx_reg(gp_regs, CTX_GPREG_X6, 1); - (void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, 0, 0, 0); - - /* Prepare for cpu idle */ - (void)mce_command_handler(MCE_CMD_ENTER_CSTATE, - TEGRA_ARI_CORE_C6, wake_time[cpu], 0); - - } else if (stateid_afflvl0 == PSTATE_ID_CORE_POWERDN) { - - /* Program default wake mask */ - write_ctx_reg(gp_regs, CTX_GPREG_X4, 0); - write_ctx_reg(gp_regs, CTX_GPREG_X5, TEGRA186_CORE_WAKE_MASK); - write_ctx_reg(gp_regs, CTX_GPREG_X6, 1); - (void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, 0, 0, 0); - - /* Prepare for cpu powerdn */ - (void)mce_command_handler(MCE_CMD_ENTER_CSTATE, - TEGRA_ARI_CORE_C7, wake_time[cpu], 0); + /* Enter CPU idle/powerdown */ + val = (stateid_afflvl0 == PSTATE_ID_CORE_IDLE) ? + TEGRA_ARI_CORE_C6 : TEGRA_ARI_CORE_C7; + (void)mce_command_handler(MCE_CMD_ENTER_CSTATE, val, + wake_time[cpu], 0); } else if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { @@ -170,11 +145,11 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) tegra_smmu_save_context((uintptr_t)smmu_ctx_base); /* Prepare for system suspend */ - write_ctx_reg(gp_regs, CTX_GPREG_X4, 1); - write_ctx_reg(gp_regs, CTX_GPREG_X5, 0); - write_ctx_reg(gp_regs, CTX_GPREG_X6, 1); - (void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, - TEGRA_ARI_CLUSTER_CC7, 0, TEGRA_ARI_SYSTEM_SC7); + cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7; + cstate_info.system = TEGRA_ARI_SYSTEM_SC7; + cstate_info.system_state_force = 1; + cstate_info.update_wake_mask = 1; + mce_update_cstate_info(&cstate_info); /* Loop until system suspend is allowed */ do { @@ -187,15 +162,84 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) /* Instruct the MCE to enter system suspend state */ (void)mce_command_handler(MCE_CMD_ENTER_CSTATE, TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0); - - } else { - ERROR("%s: Unknown state id\n", __func__); - return PSCI_E_NOT_SUPPORTED; } return PSCI_E_SUCCESS; } +/******************************************************************************* + * Platform handler to calculate the proper target power level at the + * specified affinity level + ******************************************************************************/ +plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl, + const plat_local_state_t *states, + unsigned int ncpu) +{ + plat_local_state_t target = *states; + int cpu = plat_my_core_pos(), ret, cluster_powerdn = 1; + int core_pos = read_mpidr() & MPIDR_CPU_MASK; + mce_cstate_info_t cstate_info = { 0 }; + + /* get the current core's power state */ + target = *(states + core_pos); + + /* CPU suspend */ + if (lvl == MPIDR_AFFLVL1 && target == PSTATE_ID_CORE_POWERDN) { + + /* Program default wake mask */ + cstate_info.wake_mask = TEGRA186_CORE_WAKE_MASK; + cstate_info.update_wake_mask = 1; + mce_update_cstate_info(&cstate_info); + + /* Check if CCx state is allowed. */ + ret = mce_command_handler(MCE_CMD_IS_CCX_ALLOWED, + TEGRA_ARI_CORE_C7, wake_time[cpu], 0); + if (ret) + return PSTATE_ID_CORE_POWERDN; + } + + /* CPU off */ + if (lvl == MPIDR_AFFLVL1 && target == PLAT_MAX_OFF_STATE) { + + /* find out the number of ON cpus in the cluster */ + do { + target = *states++; + if (target != PLAT_MAX_OFF_STATE) + cluster_powerdn = 0; + } while (--ncpu); + + /* Enable cluster powerdn from last CPU in the cluster */ + if (cluster_powerdn) { + + /* Enable CC7 state and turn off wake mask */ + cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7; + cstate_info.update_wake_mask = 1; + mce_update_cstate_info(&cstate_info); + + /* Check if CCx state is allowed. */ + ret = mce_command_handler(MCE_CMD_IS_CCX_ALLOWED, + TEGRA_ARI_CORE_C7, + MCE_CORE_SLEEP_TIME_INFINITE, + 0); + if (ret) + return PSTATE_ID_CORE_POWERDN; + + } else { + + /* Turn off wake_mask */ + cstate_info.update_wake_mask = 1; + mce_update_cstate_info(&cstate_info); + } + } + + /* System Suspend */ + if ((lvl == MPIDR_AFFLVL2) || (target == PSTATE_ID_SOC_POWERDN)) + return PSTATE_ID_SOC_POWERDN; + + /* default state */ + return PSCI_LOCAL_STATE_RUN; +} + int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state) { const plat_local_state_t *pwr_domain_state = @@ -244,8 +288,7 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) { int stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]; int stateid_afflvl0 = target_state->pwr_domain_state[MPIDR_AFFLVL0]; - cpu_context_t *ctx = cm_get_context(NON_SECURE); - gp_regs_t *gp_regs = get_gpregs_ctx(ctx); + mce_cstate_info_t cstate_info = { 0 }; /* * Reset power state info for CPUs when onlining, we set @@ -256,11 +299,9 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) */ if (stateid_afflvl0 == PLAT_MAX_OFF_STATE) { - write_ctx_reg(gp_regs, CTX_GPREG_X4, 0); - write_ctx_reg(gp_regs, CTX_GPREG_X5, 0); - write_ctx_reg(gp_regs, CTX_GPREG_X6, 1); - mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, - TEGRA_ARI_CLUSTER_CC1, 0, 0); + cstate_info.cluster = TEGRA_ARI_CLUSTER_CC1; + cstate_info.update_wake_mask = 1; + mce_update_cstate_info(&cstate_info); } /* @@ -280,15 +321,15 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) tegra_smmu_init(); /* - * Reset power state info for the last core doing SC7 entry and exit, - * we set deepest power state as CC7 and SC7 for SC7 entry which - * may not be requested by non-secure SW which controls idle states. + * Reset power state info for the last core doing SC7 + * entry and exit, we set deepest power state as CC7 + * and SC7 for SC7 entry which may not be requested by + * non-secure SW which controls idle states. */ - write_ctx_reg(gp_regs, CTX_GPREG_X4, 0); - write_ctx_reg(gp_regs, CTX_GPREG_X5, 0); - write_ctx_reg(gp_regs, CTX_GPREG_X6, 1); - (void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, - TEGRA_ARI_CLUSTER_CC7, 0, TEGRA_ARI_SYSTEM_SC1); + cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7; + cstate_info.system = TEGRA_ARI_SYSTEM_SC1; + cstate_info.update_wake_mask = 1; + mce_update_cstate_info(&cstate_info); } return PSCI_E_SUCCESS; @@ -296,33 +337,22 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state) { - cpu_context_t *ctx = cm_get_context(NON_SECURE); - gp_regs_t *gp_regs = get_gpregs_ctx(ctx); int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; - assert(ctx); - assert(gp_regs); - - /* Turn off wake_mask */ - write_ctx_reg(gp_regs, CTX_GPREG_X4, 0); - write_ctx_reg(gp_regs, CTX_GPREG_X5, 0); - write_ctx_reg(gp_regs, CTX_GPREG_X6, 1); - mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, TEGRA_ARI_CLUSTER_CC7, - 0, 0); - /* Disable Denver's DCO operations */ if (impl == DENVER_IMPL) denver_disable_dco(); /* Turn off CPU */ - return mce_command_handler(MCE_CMD_ENTER_CSTATE, TEGRA_ARI_CORE_C7, + (void)mce_command_handler(MCE_CMD_ENTER_CSTATE, TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0); + + return PSCI_E_SUCCESS; } __dead2 void tegra_soc_prepare_system_off(void) { - cpu_context_t *ctx = cm_get_context(NON_SECURE); - gp_regs_t *gp_regs = get_gpregs_ctx(ctx); + mce_cstate_info_t cstate_info = { 0 }; uint32_t val; if (tegra186_system_powerdn_state == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) { @@ -333,11 +363,11 @@ __dead2 void tegra_soc_prepare_system_off(void) } else if (tegra186_system_powerdn_state == TEGRA_ARI_SYSTEM_SC8) { /* Prepare for quasi power down */ - write_ctx_reg(gp_regs, CTX_GPREG_X4, 1); - write_ctx_reg(gp_regs, CTX_GPREG_X5, 0); - write_ctx_reg(gp_regs, CTX_GPREG_X6, 1); - (void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, - TEGRA_ARI_CLUSTER_CC7, 0, TEGRA_ARI_SYSTEM_SC8); + cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7; + cstate_info.system = TEGRA_ARI_SYSTEM_SC8; + cstate_info.system_state_force = 1; + cstate_info.update_wake_mask = 1; + mce_update_cstate_info(&cstate_info); /* loop until other CPUs power down */ do { @@ -357,6 +387,9 @@ __dead2 void tegra_soc_prepare_system_off(void) /* power down core */ prepare_cpu_pwr_dwn(); + /* flush L1/L2 data caches */ + dcsw_op_all(DCCISW); + } else { ERROR("%s: unsupported power down state (%d)\n", __func__, tegra186_system_powerdn_state); diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index 49f45892..e848eabb 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -30,19 +30,25 @@ #include <arch_helpers.h> #include <assert.h> +#include <bl31.h> #include <bl_common.h> #include <console.h> #include <context.h> #include <context_mgmt.h> +#include <cortex_a57.h> #include <debug.h> #include <denver.h> #include <interrupt_mgmt.h> #include <mce.h> #include <platform.h> #include <tegra_def.h> +#include <tegra_platform.h> #include <tegra_private.h> #include <xlat_tables.h> +DEFINE_RENAME_SYSREG_RW_FUNCS(l2ctlr_el1, L2CTLR_EL1) +extern uint64_t tegra_enable_l2_ecc_parity_prot; + /******************************************************************************* * The Tegra power domain tree has a single system level power domain i.e. a * single root node. The first entry in the power domain descriptor specifies @@ -72,7 +78,13 @@ static const mmap_region_t tegra_mmap[] = { MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(TEGRA_MC_BASE, 0x10000, /* 64KB */ MT_DEVICE | MT_RW | MT_SECURE), - MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000, /* 128KB */ + MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000, /* 128KB - UART A, B*/ + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(TEGRA_UARTC_BASE, 0x20000, /* 128KB - UART C, G */ + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(TEGRA_UARTD_BASE, 0x30000, /* 192KB - UART D, E, F */ + MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(TEGRA_FUSE_BASE, 0x10000, /* 64KB */ MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(TEGRA_GICD_BASE, 0x20000, /* 128KB */ MT_DEVICE | MT_RW | MT_SECURE), @@ -142,6 +154,51 @@ uint32_t plat_get_console_from_id(int id) return tegra186_uart_addresses[id]; } +/* represent chip-version as concatenation of major (15:12), minor (11:8) and subrev (7:0) */ +#define TEGRA186_VER_A02P 0x1201 + +/******************************************************************************* + * Handler for early platform setup + ******************************************************************************/ +void plat_early_platform_setup(void) +{ + int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; + uint32_t chip_subrev, val; + + /* sanity check MCE firmware compatibility */ + mce_verify_firmware_version(); + + /* + * Enable ECC and Parity Protection for Cortex-A57 CPUs + * for Tegra A02p SKUs + */ + if (impl != DENVER_IMPL) { + + /* get the major, minor and sub-version values */ + chip_subrev = mmio_read_32(TEGRA_FUSE_BASE + OPT_SUBREVISION) & + SUBREVISION_MASK; + + /* prepare chip version number */ + val = (tegra_get_chipid_major() << 12) | + (tegra_get_chipid_minor() << 8) | + chip_subrev; + + /* enable L2 ECC for Tegra186 A02P and beyond */ + if (val >= TEGRA186_VER_A02P) { + + val = read_l2ctlr_el1(); + val |= L2_ECC_PARITY_PROTECTION_BIT; + write_l2ctlr_el1(val); + + /* + * Set the flag to enable ECC/Parity Protection + * when we exit System Suspend or Cluster Powerdn + */ + tegra_enable_l2_ecc_parity_prot = 1; + } + } +} + /* Secure IRQs for Tegra186 */ static const irq_sec_cfg_t tegra186_sec_irqs[] = { { @@ -173,9 +230,25 @@ void plat_gic_setup(void) } /******************************************************************************* - * Handler for early platform setup + * Return pointer to the BL31 params from previous bootloader ******************************************************************************/ -void plat_early_platform_setup(void) +bl31_params_t *plat_get_bl31_params(void) { - mce_verify_firmware_version(); + uint32_t val; + + val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_LO); + + return (bl31_params_t *)(uintptr_t)val; +} + +/******************************************************************************* + * Return pointer to the BL31 platform params from previous bootloader + ******************************************************************************/ +plat_params_from_bl2_t *plat_get_bl31_plat_params(void) +{ + uint32_t val; + + val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_HI); + + return (plat_params_from_bl2_t *)(uintptr_t)val; } diff --git a/plat/nvidia/tegra/soc/t186/plat_sip_calls.c b/plat/nvidia/tegra/soc/t186/plat_sip_calls.c index c7a2c416..8e337184 100644 --- a/plat/nvidia/tegra/soc/t186/plat_sip_calls.c +++ b/plat/nvidia/tegra/soc/t186/plat_sip_calls.c @@ -65,6 +65,7 @@ extern uint32_t tegra186_system_powerdn_state; #define TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE 0x82FFFF0E #define TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE 0x82FFFF0F #define TEGRA_SIP_MCE_CMD_ENABLE_LATIC 0x82FFFF10 +#define TEGRA_SIP_MCE_CMD_UNCORE_PERFMON_REQ 0x82FFFF11 /******************************************************************************* * This function is responsible for handling all T186 SiP calls @@ -102,6 +103,7 @@ int plat_sip_handler(uint32_t smc_fid, case TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE: case TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE: case TEGRA_SIP_MCE_CMD_ENABLE_LATIC: + case TEGRA_SIP_MCE_CMD_UNCORE_PERFMON_REQ: /* clean up the high bits */ smc_fid &= MCE_CMD_MASK; @@ -112,32 +114,6 @@ int plat_sip_handler(uint32_t smc_fid, return 0; - case TEGRA_SIP_NEW_VIDEOMEM_REGION: - /* clean up the high bits */ - x1 = (uint32_t)x1; - x2 = (uint32_t)x2; - - /* - * Check if Video Memory overlaps TZDRAM (contains bl31/bl32) - * or falls outside of the valid DRAM range - */ - mce_ret = bl31_check_ns_address(x1, x2); - if (mce_ret) - return -ENOTSUP; - - /* - * Check if Video Memory is aligned to 1MB. - */ - if ((x1 & 0xFFFFF) || (x2 & 0xFFFFF)) { - ERROR("Unaligned Video Memory base address!\n"); - return -ENOTSUP; - } - - /* new video memory carveout settings */ - tegra_memctrl_videomem_setup(x1, x2); - - return 0; - case TEGRA_SIP_SYSTEM_SHUTDOWN_STATE: /* clean up the high bits */ diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk index 4a4d9bbd..b62d47da 100644 --- a/plat/nvidia/tegra/soc/t186/platform_t186.mk +++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk @@ -32,9 +32,18 @@ ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS := 1 $(eval $(call add_define,ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS)) +RELOCATE_TO_BL31_BASE := 1 +$(eval $(call add_define,RELOCATE_TO_BL31_BASE)) + ENABLE_CHIP_VERIFICATION_HARNESS := 0 $(eval $(call add_define,ENABLE_CHIP_VERIFICATION_HARNESS)) +RESET_TO_BL31 := 1 + +PROGRAMMABLE_RESET_ADDRESS := 1 + +COLD_BOOT_SINGLE_CPU := 1 + # platform settings TZDRAM_BASE := 0x30000000 $(eval $(call add_define,TZDRAM_BASE)) diff --git a/plat/rockchip/common/plat_pm.c b/plat/rockchip/common/plat_pm.c index 09c5397c..2d4dc99a 100644 --- a/plat/rockchip/common/plat_pm.c +++ b/plat/rockchip/common/plat_pm.c @@ -391,15 +391,6 @@ static void __dead2 rockchip_system_poweroff(void) rockchip_soc_system_off(); } -static void __dead2 rockchip_pd_pwr_down_wfi( - const psci_power_state_t *target_state) -{ - if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) - rockchip_soc_sys_pd_pwr_dn_wfi(); - else - rockchip_soc_cores_pd_pwr_dn_wfi(target_state); -} - /******************************************************************************* * Export the platform handlers via plat_rockchip_psci_pm_ops. The rockchip * standard |