diff --git a/bl31/bl31.mk b/bl31/bl31.mk index 735d1fc..cd6549b 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -7,6 +7,12 @@ ################################################################################ # Include Makefile for the SPM-MM implementation ################################################################################ +ifeq (${SUPPORT_UNKNOWN_MPID},1) + ifeq (${DEBUG},0) + $(warning WARNING: SUPPORT_UNKNOWN_MPID enabled) + endif +endif + ifeq (${SPM_MM},1) ifeq (${EL3_EXCEPTION_HANDLING},0) $(error EL3_EXCEPTION_HANDLING must be 1 for SPM-MM support) diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c index 92a2027..44bf32c 100644 --- a/bl31/bl31_main.c +++ b/bl31/bl31_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -41,6 +41,15 @@ ******************************************************************************/ static uint32_t next_image_type = NON_SECURE; +#ifdef SUPPORT_UNKNOWN_MPID +/* + * Flag to know whether an unsupported MPID has been detected. To avoid having it + * landing on the .bss section, it is initialized to a non-zero value, this way + * we avoid potential WAW hazards during system bring up. + * */ +volatile uint32_t unsupported_mpid_flag = 1; +#endif + /* * Implement the ARM Standard Service function to get arguments for a * particular service. @@ -98,6 +107,12 @@ NOTICE("BL31: %s\n", version_string); NOTICE("BL31: %s\n", build_message); +#ifdef SUPPORT_UNKNOWN_MPID + if (unsupported_mpid_flag == 0) { + NOTICE("Unsupported MPID detected!\n"); + } +#endif + /* Perform platform setup in BL31 */ bl31_platform_setup(); diff --git a/include/lib/cpus/aarch64/generic.h b/include/lib/cpus/aarch64/generic.h new file mode 100644 index 0000000..53df587 --- /dev/null +++ b/include/lib/cpus/aarch64/generic.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserverd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef AARCH64_GENERIC_H +#define AARCH64_GENERIC_H + +#include + +/* + * 0x0 value on the MIDR implementer value is reserved for software use, + * so use an MIDR value of 0 for a default CPU library. + */ +#define AARCH64_GENERIC_MIDR U(0) + +#endif /* AARCH64_GENERIC_H */ diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S index da663be..730b09b 100644 --- a/lib/cpus/aarch64/cpu_helpers.S +++ b/lib/cpus/aarch64/cpu_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -140,6 +140,13 @@ * midr of the core. It reads the MIDR_EL1 and finds the matching * entry in cpu_ops entries. Only the implementation and part number * are used to match the entries. + * + * If cpu_ops for the MIDR_EL1 cannot be found and + * SUPPORT_UNKNOWN_MPID is enabled, it will try to look for a + * default cpu_ops with an MIDR value of 0. + * (Implementation number 0x0 should be reseverd for software use + * and therefore no clashes should happen with that default value). + * * Return : * x0 - The matching cpu_ops pointer on Success * x0 - 0 on failure. @@ -147,23 +154,26 @@ */ .globl get_cpu_ops_ptr func get_cpu_ops_ptr - /* Get the cpu_ops start and end locations */ - adr x4, (__CPU_OPS_START__ + CPU_MIDR) - adr x5, (__CPU_OPS_END__ + CPU_MIDR) - - /* Initialize the return parameter */ - mov x0, #0 - /* Read the MIDR_EL1 */ mrs x2, midr_el1 mov_imm x3, CPU_IMPL_PN_MASK /* Retain only the implementation and part number using mask */ and w2, w2, w3 + + /* Get the cpu_ops end location */ + adr x5, (__CPU_OPS_END__ + CPU_MIDR) + + /* Initialize the return parameter */ + mov x0, #0 1: + /* Get the cpu_ops start location */ + adr x4, (__CPU_OPS_START__ + CPU_MIDR) + +2: /* Check if we have reached end of list */ cmp x4, x5 - b.eq error_exit + b.eq search_def_ptr /* load the midr from the cpu_ops */ ldr x1, [x4], #CPU_OPS_SIZE @@ -171,7 +181,7 @@ /* Check if midr matches to midr of this core */ cmp w1, w2 - b.ne 1b + b.ne 2b /* Subtract the increment and offset to get the cpu-ops pointer */ sub x0, x4, #(CPU_OPS_SIZE + CPU_MIDR) @@ -179,7 +189,27 @@ cmp x0, #0 ASM_ASSERT(ne) #endif +#ifdef SUPPORT_UNKNOWN_MPID + cbnz x2, exit_mpid_found + /* Mark the unsupported MPID flag */ + adrp x1, unsupported_mpid_flag + add x1, x1, :lo12:unsupported_mpid_flag + str w2, [x1] +exit_mpid_found: +#endif + ret + + /* + * Search again for a default pointer (MIDR = 0x0) + * or return error if already searched. + */ +search_def_ptr: +#ifdef SUPPORT_UNKNOWN_MPID + cbz x2, error_exit + mov x2, #0 + b 1b error_exit: +#endif ret endfunc get_cpu_ops_ptr diff --git a/lib/cpus/aarch64/generic.S b/lib/cpus/aarch64/generic.S new file mode 100644 index 0000000..ef1f048 --- /dev/null +++ b/lib/cpus/aarch64/generic.S @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + + /* --------------------------------------------- + * Disable L1 data cache and unified L2 cache + * --------------------------------------------- + */ +func generic_disable_dcache + mrs x1, sctlr_el3 + bic x1, x1, #SCTLR_C_BIT + msr sctlr_el3, x1 + isb + ret +endfunc generic_disable_dcache + +func generic_core_pwr_dwn + mov x18, x30 + + /* --------------------------------------------- + * Turn off caches. + * --------------------------------------------- + */ + bl generic_disable_dcache + + /* --------------------------------------------- + * Flush L1 caches. + * --------------------------------------------- + */ + mov x0, #DCCISW + bl dcsw_op_level1 + + ret x18 +endfunc generic_core_pwr_dwn + +func generic_cluster_pwr_dwn + mov x18, x30 + + /* --------------------------------------------- + * Turn off caches. + * --------------------------------------------- + */ + bl generic_disable_dcache + + /* --------------------------------------------- + * Flush L1 caches. + * --------------------------------------------- + */ + mov x0, #DCCISW + bl dcsw_op_level1 + + /* --------------------------------------------- + * Disable the optional ACP. + * --------------------------------------------- + */ + bl plat_disable_acp + + /* --------------------------------------------- + * Flush L2 caches. + * --------------------------------------------- + */ + mov x0, #DCCISW + bl dcsw_op_level2 + + ret x18 + +endfunc generic_cluster_pwr_dwn + +/* --------------------------------------------- + * Unimplemented functions. + * --------------------------------------------- + */ +.equ generic_errata_report, 0 +.equ generic_cpu_reg_dump, 0 +.equ generic_reset_func, 0 + +declare_cpu_ops generic, AARCH64_GENERIC_MIDR, \ + generic_reset_func, \ + generic_core_pwr_dwn, \ + generic_cluster_pwr_dwn diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index 8904339..8f0ff0b 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -40,6 +40,8 @@ PL011_GENERIC_UART := 1 +SUPPORT_UNKNOWN_MPID ?= 1 + FPGA_CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S # select a different set of CPU files, depending on whether we compile for @@ -71,6 +73,12 @@ lib/cpus/aarch64/cortex_a75.S endif +ifeq (${SUPPORT_UNKNOWN_MPID}, 1) +# Add support for unknown/invalid MPIDs (aarch64 only) +$(eval $(call add_define,SUPPORT_UNKNOWN_MPID)) + FPGA_CPU_LIBS += lib/cpus/aarch64/generic.S +endif + # Allow detection of GIC-600 GICV3_SUPPORT_GIC600 := 1