Merge "Measured Boot Driver: Fix MISRA-C 2012 defects" into integration
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/common/aarch32/debug.S b/common/aarch32/debug.S
index f506356..9d410df 100644
--- a/common/aarch32/debug.S
+++ b/common/aarch32/debug.S
@@ -1,71 +1,25 @@
/*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
+#include <common/debug.h>
+ .globl asm_print_str
+ .globl asm_print_hex
+ .globl asm_print_hex_bits
.globl asm_assert
.globl do_panic
.globl report_exception
/* Since the max decimal input number is 65536 */
#define MAX_DEC_DIVISOR 10000
-
/* The offset to add to get ascii for numerals '0 - 9' */
#define ASCII_OFFSET_NUM '0'
- .section .rodata.panic_str, "aS"
-panic_msg:
- .asciz "PANIC at PC : 0x"
-panic_end:
- .asciz "\r\n"
-
- /***********************************************************
- * The common implementation of do_panic for all BL stages
- ***********************************************************/
-func do_panic
- /* Have LR copy point to PC at the time of panic */
- sub r6, lr, #4
-
- /* Initialize crash console and verify success */
- bl plat_crash_console_init
- cmp r0, #0
- beq 1f
-
- /* Print panic message */
- ldr r4, =panic_msg
- bl asm_print_str
-
- /* Print LR in hex */
- mov r4, r6
- bl asm_print_hex
-
- /* Print new line */
- ldr r4, =panic_end
- bl asm_print_str
-
- bl plat_crash_console_flush
-
-1:
- mov lr, r6
- b plat_panic_handler
-endfunc do_panic
-
- /***********************************************************
- * This function is called from the vector table for
- * unhandled exceptions. It reads the current mode and
- * passes it to platform.
- ***********************************************************/
-func report_exception
- mrs r0, cpsr
- and r0, #MODE32_MASK
- bl plat_report_exception
- no_ret plat_panic_handler
-endfunc report_exception
-
#if ENABLE_ASSERTIONS
.section .rodata.assert_str, "aS"
assert_msg1:
@@ -79,6 +33,26 @@
.asciz " Line 0x"
#else
.asciz " Line "
+
+ /*
+ * This macro is intended to be used to print the
+ * line number in decimal. Used by asm_assert macro.
+ * The max number expected is 65536.
+ * In: r4 = the decimal to print.
+ * Clobber: lr, r0, r1, r2, r5, r6
+ */
+ .macro asm_print_line_dec
+ mov r6, #10 /* Divide by 10 after every loop iteration */
+ ldr r5, =MAX_DEC_DIVISOR
+dec_print_loop:
+ udiv r0, r4, r5 /* Get the quotient */
+ mls r4, r0, r5, r4 /* Find the remainder */
+ add r0, r0, #ASCII_OFFSET_NUM /* Convert to ascii */
+ bl plat_crash_console_putc
+ udiv r5, r5, r6 /* Reduce divisor */
+ cmp r5, #0
+ bne dec_print_loop
+ .endm
#endif
/* ---------------------------------------------------------------------------
@@ -100,25 +74,25 @@
mov r5, r0
mov r6, r1
- /* Initialize crash console and verify success */
+ /* Ensure the console is initialized */
bl plat_crash_console_init
+
+ /* Check if the console is initialized */
cmp r0, #0
- beq 1f
+ beq _assert_loop
- /* Print file name */
+ /* The console is initialized */
ldr r4, =assert_msg1
bl asm_print_str
mov r4, r5
bl asm_print_str
-
- /* Print line number string */
ldr r4, =assert_msg2
bl asm_print_str
- /* Test for maximum supported line number */
+ /* Check if line number higher than max permitted */
ldr r4, =~0xffff
tst r6, r4
- bne 1f
+ bne _assert_loop
mov r4, r6
#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
@@ -128,22 +102,10 @@
******************************************************************/
bl asm_print_hex
#else
- /* Print line number in decimal */
- mov r6, #10 /* Divide by 10 after every loop iteration */
- ldr r5, =MAX_DEC_DIVISOR
-dec_print_loop:
- udiv r0, r4, r5 /* Quotient */
- mls r4, r0, r5, r4 /* Remainder */
- add r0, r0, #ASCII_OFFSET_NUM /* Convert to ASCII */
- bl plat_crash_console_putc
- udiv r5, r5, r6 /* Reduce divisor */
- cmp r5, #0
- bne dec_print_loop
+ asm_print_line_dec
#endif
-
bl plat_crash_console_flush
-
-1:
+_assert_loop:
#endif /* LOG_LEVEL >= LOG_LEVEL_INFO */
no_ret plat_panic_handler
endfunc asm_assert
@@ -171,8 +133,11 @@
* Clobber: lr, r0 - r3, r5
*/
func asm_print_hex
- mov r3, lr
mov r5, #32 /* No of bits to convert to ascii */
+
+ /* Convert to ascii number of bits in r5 */
+asm_print_hex_bits:
+ mov r3, lr
1:
sub r5, r5, #4
lsr r0, r4, r5
@@ -190,3 +155,53 @@
bne 1b
bx r3
endfunc asm_print_hex
+
+ /***********************************************************
+ * The common implementation of do_panic for all BL stages
+ ***********************************************************/
+
+.section .rodata.panic_str, "aS"
+ panic_msg: .asciz "PANIC at PC : 0x"
+ panic_end: .asciz "\r\n"
+
+func do_panic
+ /* Have LR copy point to PC at the time of panic */
+ sub r6, lr, #4
+
+ /* Initialize crash console and verify success */
+ bl plat_crash_console_init
+
+ /* Check if the console is initialized */
+ cmp r0, #0
+ beq _panic_handler
+
+ /* The console is initialized */
+ ldr r4, =panic_msg
+ bl asm_print_str
+
+ /* Print LR in hex */
+ mov r4, r6
+ bl asm_print_hex
+
+ /* Print new line */
+ ldr r4, =panic_end
+ bl asm_print_str
+
+ bl plat_crash_console_flush
+
+_panic_handler:
+ mov lr, r6
+ b plat_panic_handler
+endfunc do_panic
+
+ /***********************************************************
+ * This function is called from the vector table for
+ * unhandled exceptions. It reads the current mode and
+ * passes it to platform.
+ ***********************************************************/
+func report_exception
+ mrs r0, cpsr
+ and r0, #MODE32_MASK
+ bl plat_report_exception
+ no_ret plat_panic_handler
+endfunc report_exception
diff --git a/common/aarch64/debug.S b/common/aarch64/debug.S
index 7db2439..ad6acd9 100644
--- a/common/aarch64/debug.S
+++ b/common/aarch64/debug.S
@@ -38,11 +38,11 @@
mov x6, #10 /* Divide by 10 after every loop iteration */
mov x5, #MAX_DEC_DIVISOR
dec_print_loop:
- udiv x0, x4, x5 /* Get the quotient */
- msub x4, x0, x5, x4 /* Find the remainder */
- add x0, x0, #ASCII_OFFSET_NUM /* Convert to ascii */
+ udiv x0, x4, x5 /* Get the quotient */
+ msub x4, x0, x5, x4 /* Find the remainder */
+ add x0, x0, #ASCII_OFFSET_NUM /* Convert to ascii */
bl plat_crash_console_putc
- udiv x5, x5, x6 /* Reduce divisor */
+ udiv x5, x5, x6 /* Reduce divisor */
cbnz x5, dec_print_loop
.endm
@@ -64,10 +64,13 @@
*/
mov x5, x0
mov x6, x1
+
/* Ensure the console is initialized */
bl plat_crash_console_init
+
/* Check if the console is initialized */
cbz x0, _assert_loop
+
/* The console is initialized */
adr x4, assert_msg1
bl asm_print_str
@@ -75,6 +78,7 @@
bl asm_print_str
adr x4, assert_msg2
bl asm_print_str
+
/* Check if line number higher than max permitted */
tst x6, #~0xffff
b.ne _assert_loop
@@ -191,12 +195,15 @@
el3_panic:
mov x6, x30
bl plat_crash_console_init
+
/* Check if the console is initialized */
cbz x0, _panic_handler
+
/* The console is initialized */
adr x4, panic_msg
bl asm_print_str
mov x4, x6
+
/* The panic location is lr -4 */
sub x4, x4, #4
bl asm_print_hex
diff --git a/common/fdt_fixup.c b/common/fdt_fixup.c
index 980e60d..a1604e7 100644
--- a/common/fdt_fixup.c
+++ b/common/fdt_fixup.c
@@ -377,3 +377,64 @@
return offs;
}
+
+/**
+ * fdt_adjust_gic_redist() - Adjust GICv3 redistributor size
+ * @dtb: Pointer to the DT blob in memory
+ * @nr_cores: Number of CPU cores on this system.
+ * @gicr_frame_size: Size of the GICR frame per core
+ *
+ * On a GICv3 compatible interrupt controller, the redistributor provides
+ * a number of 64k pages per each supported core. So with a dynamic topology,
+ * this size cannot be known upfront and thus can't be hardcoded into the DTB.
+ *
+ * Find the DT node describing the GICv3 interrupt controller, and adjust
+ * the size of the redistributor to match the number of actual cores on
+ * this system.
+ * A GICv4 compatible redistributor uses four 64K pages per core, whereas GICs
+ * without support for direct injection of virtual interrupts use two 64K pages.
+ * The @gicr_frame_size parameter should be 262144 and 131072, respectively.
+ *
+ * Return: 0 on success, negative error value otherwise.
+ */
+int fdt_adjust_gic_redist(void *dtb, unsigned int nr_cores,
+ unsigned int gicr_frame_size)
+{
+ int offset = fdt_node_offset_by_compatible(dtb, 0, "arm,gic-v3");
+ uint64_t redist_size_64;
+ uint32_t redist_size_32;
+ void *val;
+ int parent;
+ int ac, sc;
+
+ if (offset < 0) {
+ return offset;
+ }
+
+ parent = fdt_parent_offset(dtb, offset);
+ if (parent < 0) {
+ return parent;
+ }
+ ac = fdt_address_cells(dtb, parent);
+ sc = fdt_size_cells(dtb, parent);
+ if (ac < 0 || sc < 0) {
+ return -EINVAL;
+ }
+
+ if (sc == 1) {
+ redist_size_32 = cpu_to_fdt32(nr_cores * gicr_frame_size);
+ val = &redist_size_32;
+ } else {
+ redist_size_64 = cpu_to_fdt64(nr_cores * gicr_frame_size);
+ val = &redist_size_64;
+ }
+
+ /*
+ * The redistributor is described in the second "reg" entry.
+ * So we have to skip one address and one size cell, then another
+ * address cell to get to the second size cell.
+ */
+ return fdt_setprop_inplace_namelen_partial(dtb, offset, "reg", 3,
+ (ac + sc + ac) * 4,
+ val, sc * 4);
+}
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 3c0e30f..e9ff17e 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -251,6 +251,9 @@
For Cortex-A77, the following errata build flags are defined :
+- ``ERRATA_A77_1508412``: This applies errata 1508412 workaround to Cortex-A77
+ CPU. This needs to be enabled only for revision <= r1p0 of the CPU.
+
- ``ERRATA_A77_1800714``: This applies errata 1800714 workaround to Cortex-A77
CPU. This needs to be enabled only for revision <= r1p1 of the CPU.
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index b4fe404..40fc5db 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -300,6 +300,10 @@
handled at EL3, and a panic will result. This is supported only for AArch64
builds.
+- ``EVENT_LOG_LEVEL``: Chooses the log level to use for Measured Boot when
+ ``MEASURED_BOOT`` is enabled. For a list of valid values, see ``LOG_LEVEL``.
+ Default value is 40 (LOG_LEVEL_INFO).
+
- ``FAULT_INJECTION_SUPPORT``: ARMv8.4 extensions introduced support for fault
injection from lower ELs, and this build option enables lower ELs to use
Error Records accessed via System Registers to inject faults. This is
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index 13e25cd..91ecdf3 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -60,7 +60,7 @@
The following libraries are required for Trusted Board Boot support:
-- mbed TLS == 2.18.0 (tag: ``mbedtls-2.18.0``)
+- mbed TLS == 2.24.0 (tag: ``mbedtls-2.24.0``)
These tools are optional:
diff --git a/docs/plat/arm/arm_fpga/index.rst b/docs/plat/arm/arm_fpga/index.rst
new file mode 100644
index 0000000..5427c1d
--- /dev/null
+++ b/docs/plat/arm/arm_fpga/index.rst
@@ -0,0 +1,97 @@
+Arm FPGA Platform
+=================
+
+This platform supports FPGA images used internally in Arm Ltd., for
+testing and bringup of new cores. With that focus, peripheral support is
+minimal: there is no mass storage or display output, for instance. Also
+this port ignores any power management features of the platform.
+Some interconnect setup is done internally by the platform, so the TF-A code
+just needs to setup UART and GIC.
+
+The FPGA platform requires to pass on a DTB for the non-secure payload
+(mostly Linux), so we let TF-A use information from the DTB for dynamic
+configuration: the UART and GIC base addresses are read from there.
+
+As a result this port is a fairly generic BL31-only port, which can serve
+as a template for a minimal new (and possibly DT-based) platform port.
+
+The aim of this port is to support as many FPGA images as possible with
+a single build. Image specific data must be described in the DTB or should
+be auto-detected at runtime.
+
+As the number and topology layout of the CPU cores differs significantly
+across the various images, this is detected at runtime by BL31.
+The /cpus node in the DT will be added and filled accordingly, as long as
+it does not exist already.
+
+Platform-specific build options
+-------------------------------
+
+- ``SUPPORT_UNKNOWN_MPID`` : Boolean option to allow unknown MPIDR registers.
+ Normally TF-A panics if it encounters a MPID value not matched to its
+ internal list, but for new or experimental cores this creates a lot of
+ churn. With this option, the code will fall back to some basic CPU support
+ code (only architectural system registers, and no errata).
+ Default value of this flag is 1.
+
+- ``PRELOADED_BL33_BASE`` : Physical address of the BL33 non-secure payload.
+ It must have been loaded into DRAM already, typically this is done by
+ the script that also loads BL31 and the DTB.
+ It defaults to 0x80080000, which is the traditional load address for an
+ arm64 Linux kernel.
+
+- ``FPGA_PRELOADED_DTB_BASE`` : Physical address of the flattened device
+ tree blob (DTB). This DT will be used by TF-A for dynamic configuration,
+ so it must describe at least the UART and a GICv3 interrupt controller.
+ The DT gets amended by the code, to potentially add a command line and
+ fill the CPU topology nodes. It will also be passed on to BL33, by
+ putting its address into the x0 register before jumping to the entry
+ point (following the Linux kernel boot protocol).
+ It defaults to 0x80070000, which is 64KB before the BL33 load address.
+
+- ``FPGA_PRELOADED_CMD_LINE`` : Physical address of the command line to
+ put into the devicetree blob. Due to the lack of a proper bootloader,
+ a command line can be put somewhere into memory, so that BL31 will
+ detect it and copy it into the DTB passed on to BL33.
+ To avoid random garbage, there needs to be a "CMD:" signature before the
+ actual command line.
+ Defaults to 0x1000, which is normally in the "ROM" space of the typical
+ FPGA image (which can be written by the FPGA payload uploader, but is
+ read-only to the CPU). The FPGA payload tool should be given a text file
+ containing the desired command line, prefixed by the "CMD:" signature.
+
+Building the TF-A image
+-----------------------
+
+ .. code:: shell
+
+ make PLAT=arm_fgpa DEBUG=1
+
+ This will use the default load addresses as described above. When those
+ addresses need to differ for a certain setup, they can be passed on the
+ make command line:
+
+ .. code:: shell
+
+ make PLAT=arm_fgpa DEBUG=1 PRELOADED_BL33_BASE=0x80200000 FPGA_PRELOADED_DTB_BASE=0x80180000 bl31
+
+Running the TF-A image
+----------------------
+
+After building TF-A, the actual TF-A code will be located in ``bl31.bin`` in
+the build directory.
+Additionally there is a ``bl31.axf`` ELF file, which contains BL31, as well
+as some simple ROM trampoline code (required by the Arm FPGA boot flow) and
+a generic DTB to support most of the FPGA images. This can be simply handed
+over to the FPGA payload uploader, which will take care of loading the
+components at their respective load addresses. In addition to this file
+you need at least a BL33 payload (typically a Linux kernel image), optionally
+a Linux initrd image file and possibly a command line:
+
+ .. code:: shell
+
+ fpga-run ... -m bl31.axf -l auto -m Image -l 0x80080000 -m initrd.gz -l 0x84000000 -m cmdline.txt -l 0x1000
+
+--------------
+
+*Copyright (c) 2020, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/index.rst b/docs/plat/arm/index.rst
index 1afe475..9c2fcb1 100644
--- a/docs/plat/arm/index.rst
+++ b/docs/plat/arm/index.rst
@@ -9,6 +9,7 @@
fvp/index
fvp-ve/index
tc0/index
+ arm_fpga/index
arm-build-options
This chapter holds documentation related to Arm's development platforms,
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index bd23410..fb60e56 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -54,6 +54,7 @@
- Arm Neoverse Reference Design E1 Edge (RD-E1-Edge) FVP
- Arm SGI-575 and SGM-775
- MediaTek MT6795 and MT8173 SoCs
+ - Arm Morello Platform
--------------
diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c
index 09fa678..ff346f9 100644
--- a/drivers/arm/gic/v3/gicv3_helpers.c
+++ b/drivers/arm/gic/v3/gicv3_helpers.c
@@ -326,3 +326,33 @@
return ctlr_enable;
}
+
+/**
+ * gicv3_rdistif_get_number_frames() - determine size of GICv3 GICR region
+ * @gicr_frame: base address of the GICR region to check
+ *
+ * This iterates over the GICR_TYPER registers of multiple GICR frames in
+ * a GICR region, to find the instance which has the LAST bit set. For most
+ * systems this corresponds to the number of cores handled by a redistributor,
+ * but there could be disabled cores among them.
+ * It assumes that each GICR region is fully accessible (till the LAST bit
+ * marks the end of the region).
+ * If a platform has multiple GICR regions, this function would need to be
+ * called multiple times, providing the respective GICR base address each time.
+ *
+ * Return: number of valid GICR frames (at least 1, up to PLATFORM_CORE_COUNT)
+ ******************************************************************************/
+unsigned int gicv3_rdistif_get_number_frames(const uintptr_t gicr_frame)
+{
+ uintptr_t rdistif_base = gicr_frame;
+ unsigned int count;
+
+ for (count = 1; count < PLATFORM_CORE_COUNT; count++) {
+ if ((gicr_read_typer(rdistif_base) & TYPER_LAST_BIT) != 0U) {
+ break;
+ }
+ rdistif_base += (1U << GICR_PCPUBASE_SHIFT);
+ }
+
+ return count;
+}
diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk
index 8454105..53ebe30 100644
--- a/drivers/auth/mbedtls/mbedtls_common.mk
+++ b/drivers/auth/mbedtls/mbedtls_common.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2020, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -35,7 +35,6 @@
bignum.c \
gcm.c \
md.c \
- md_wrap.c \
pk.c \
pk_wrap.c \
pkparse.c \
diff --git a/drivers/measured_boot/measured_boot.mk b/drivers/measured_boot/measured_boot.mk
index b7aa48b..497fdba 100644
--- a/drivers/measured_boot/measured_boot.mk
+++ b/drivers/measured_boot/measured_boot.mk
@@ -4,6 +4,9 @@
# SPDX-License-Identifier: BSD-3-Clause
#
+# Default log level to dump the event log (LOG_LEVEL_INFO)
+EVENT_LOG_LEVEL ?= 40
+
# TPM hash algorithm
TPM_HASH_ALG := sha256
@@ -31,6 +34,7 @@
TPM_ALG_ID \
TCG_DIGEST_SIZE \
EVENT_LOG_SIZE \
+ EVENT_LOG_LEVEL \
)))
ifeq (${HASH_ALG}, sha256)
diff --git a/drivers/mtd/nand/raw_nand.c b/drivers/mtd/nand/raw_nand.c
index 48131fc..1fb5fac 100644
--- a/drivers/mtd/nand/raw_nand.c
+++ b/drivers/mtd/nand/raw_nand.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -190,7 +190,7 @@
return ret;
}
-int nand_wait_ready(unsigned long delay)
+int nand_wait_ready(unsigned int delay_ms)
{
uint8_t status;
int ret;
@@ -204,7 +204,7 @@
return ret;
}
- timeout = timeout_init_us(delay);
+ timeout = timeout_init_us(delay_ms * 1000U);
while (!timeout_elapsed(timeout)) {
ret = nand_read_data(&status, 1U, true);
if (ret != 0) {
diff --git a/drivers/mtd/nor/spi_nor.c b/drivers/mtd/nor/spi_nor.c
index 22d3ae3..108f893 100644
--- a/drivers/mtd/nor/spi_nor.c
+++ b/drivers/mtd/nor/spi_nor.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -368,7 +368,7 @@
if (nor_dev.read_op.data.buswidth == 4U) {
switch (id) {
case MACRONIX_ID:
- WARN("Enable Macronix quad support\n");
+ INFO("Enable Macronix quad support\n");
ret = spi_nor_macronix_quad_enable();
break;
case MICRON_ID:
diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c
index d6cd8b1..f8bc5a2 100644
--- a/drivers/st/clk/stm32mp1_clk.c
+++ b/drivers/st/clk/stm32mp1_clk.c
@@ -653,15 +653,17 @@
bool stm32mp1_rcc_is_secure(void)
{
uintptr_t rcc_base = stm32mp_rcc_base();
+ uint32_t mask = RCC_TZCR_TZEN;
- return (mmio_read_32(rcc_base + RCC_TZCR) & RCC_TZCR_TZEN) != 0;
+ return (mmio_read_32(rcc_base + RCC_TZCR) & mask) == mask;
}
bool stm32mp1_rcc_is_mckprot(void)
{
uintptr_t rcc_base = stm32mp_rcc_base();
+ uint32_t mask = RCC_TZCR_TZEN | RCC_TZCR_MCKPROT;
- return (mmio_read_32(rcc_base + RCC_TZCR) & RCC_TZCR_MCKPROT) != 0;
+ return (mmio_read_32(rcc_base + RCC_TZCR) & mask) == mask;
}
void stm32mp1_clk_rcc_regs_lock(void)
diff --git a/drivers/st/crypto/stm32_hash.c b/drivers/st/crypto/stm32_hash.c
index 515947c..317fd9e 100644
--- a/drivers/st/crypto/stm32_hash.c
+++ b/drivers/st/crypto/stm32_hash.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -252,6 +252,8 @@
mmio_clrsetbits_32(hash_base() + HASH_STR, HASH_STR_NBLW_MASK,
8U * stm32_remain.length);
zeromem(&stm32_remain, sizeof(stm32_remain));
+ } else {
+ mmio_clrbits_32(hash_base() + HASH_STR, HASH_STR_NBLW_MASK);
}
mmio_setbits_32(hash_base() + HASH_STR, HASH_STR_DCAL);
diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c
index bb77371..7d63262 100644
--- a/drivers/st/gpio/stm32_gpio.c
+++ b/drivers/st/gpio/stm32_gpio.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2020, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -161,13 +161,14 @@
const fdt32_t *cuint;
int lenp = 0;
uint32_t i;
- uint8_t status = fdt_get_status(node);
+ uint8_t status;
void *fdt;
if (fdt_get_address(&fdt) == 0) {
return -FDT_ERR_NOTFOUND;
}
+ status = fdt_get_status(node);
if (status == DT_DISABLED) {
return -FDT_ERR_NOTFOUND;
}
diff --git a/drivers/st/io/io_mmc.c b/drivers/st/io/io_mmc.c
index 44b7d19..0ed7154 100644
--- a/drivers/st/io/io_mmc.c
+++ b/drivers/st/io/io_mmc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -97,14 +97,21 @@
static int mmc_block_read(io_entity_t *entity, uintptr_t buffer,
size_t length, size_t *length_read)
{
- *length_read = mmc_read_blocks(seek_offset / MMC_BLOCK_SIZE,
- buffer, length);
+ uint8_t retries;
- if (*length_read != length) {
- return -EIO;
+ for (retries = 0U; retries < 3U; retries++) {
+ *length_read = mmc_read_blocks(seek_offset / MMC_BLOCK_SIZE,
+ buffer, length);
+
+ if (*length_read == length) {
+ return 0;
+ }
+ WARN("%s: length_read = %lu (!= %lu), retry %u\n", __func__,
+ (unsigned long)*length_read, (unsigned long)length,
+ retries + 1U);
}
- return 0;
+ return -EIO;
}
/* Close a file on the mmc device */
diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c
index 63fbb07..cff3a34 100644
--- a/drivers/st/mmc/stm32_sdmmc2.c
+++ b/drivers/st/mmc/stm32_sdmmc2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2018-2020, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -258,6 +258,18 @@
break;
}
+ mmio_write_32(base + SDMMC_ICR, SDMMC_STATIC_FLAGS);
+
+ /*
+ * Clear the SDMMC_DCTRLR if the command does not await data.
+ * Skip CMD55 as the next command could be data related, and
+ * the register could have been set in prepare function.
+ */
+ if (((cmd_reg & SDMMC_CMDR_CMDTRANS) == 0U) &&
+ (cmd->cmd_idx != MMC_CMD(55))) {
+ mmio_write_32(base + SDMMC_DCTRLR, 0U);
+ }
+
if ((cmd->resp_type & MMC_RSP_BUSY) != 0U) {
mmio_write_32(base + SDMMC_DTIMER, UINT32_MAX);
}
@@ -373,15 +385,15 @@
static int stm32_sdmmc2_send_cmd(struct mmc_cmd *cmd)
{
- int8_t retry;
- int err = 0;
+ uint8_t retry;
+ int err;
assert(cmd != NULL);
- for (retry = 0; retry <= 3; retry++) {
+ for (retry = 0U; retry < 3U; retry++) {
err = stm32_sdmmc2_send_cmd_req(cmd);
if (err == 0) {
- return err;
+ return 0;
}
if ((cmd->cmd_idx == MMC_CMD(1)) ||
@@ -390,12 +402,12 @@
}
/* Command 8 is expected to fail for eMMC */
- if (!(cmd->cmd_idx == MMC_CMD(8))) {
- WARN(" CMD%d, Retry: %d, Error: %d\n",
- cmd->cmd_idx, retry, err);
+ if (cmd->cmd_idx != MMC_CMD(8)) {
+ WARN(" CMD%u, Retry: %u, Error: %d\n",
+ cmd->cmd_idx, retry + 1U, err);
}
- udelay(10);
+ udelay(10U);
}
return err;
diff --git a/fdts/arm_fpga.dts b/fdts/arm_fpga.dts
new file mode 100644
index 0000000..6a966fd
--- /dev/null
+++ b/fdts/arm_fpga.dts
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: (GPL-2.0 or BSD-3-Clause)
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * Devicetree for the Arm Ltd. FPGA platform
+ * Number and kind of CPU cores differs from image to image, so the
+ * topology is auto-detected by BL31, and the /cpus node is created and
+ * populated accordingly at runtime.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/dts-v1/;
+
+/ {
+ model = "ARM FPGA";
+ compatible = "arm,fpga", "arm,vexpress";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ serial0 = &dbg_uart;
+ };
+
+ chosen {
+ stdout-path = "serial0:38400n8";
+ bootargs = "console=ttyAMA0,38400n8 earlycon";
+ /* Allow to upload a generous 100MB initrd payload. */
+ linux,initrd-start = <0x0 0x84000000>;
+ linux,initrd-end = <0x0 0x85400000>;
+ };
+
+ /* /cpus node will be added by BL31 at runtime. */
+
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ clock-frequency = <10000000>;
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ pmu {
+ compatible = "arm,armv8-pmuv3";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ /* This node will be removed at runtime on cores without SPE. */
+ spe-pmu {
+ compatible = "arm,statistical-profiling-extension-v1";
+ interrupts = <GIC_PPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x0 0x80000000>,
+ <0x8 0x80000000 0x1 0x80000000>;
+ };
+
+
+ bus_refclk: refclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ clock-output-names = "apb_pclk";
+ };
+
+ uartclk: baudclock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <10000000>;
+ clock-output-names = "uartclk";
+ };
+
+ dbg_uart: serial@7ff80000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x0 0x7ff80000 0x0 0x00001000>;
+ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uartclk>, <&bus_refclk>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ gic: interrupt-controller@30000000 {
+ compatible = "arm,gic-v3";
+ #address-cells = <2>;
+ #interrupt-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ interrupt-controller;
+ reg = <0x0 0x30000000 0x0 0x00010000>, /* GICD */
+ /* The GICR size will be adjusted at runtime to match the cores. */
+ <0x0 0x30040000 0x0 0x00020000>; /* GICR for one core */
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ };
+};
diff --git a/fdts/morello-fvp.dts b/fdts/morello-fvp.dts
new file mode 100644
index 0000000..ecbed5e
--- /dev/null
+++ b/fdts/morello-fvp.dts
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+#include "morello.dtsi"
+
+/ {
+
+ chosen {
+ stdout-path = "soc_uart0:115200n8";
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ secure-firmware@ff000000 {
+ reg = <0 0xff000000 0 0x01000000>;
+ no-map;
+ };
+ };
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+ cpu0@0 {
+ compatible = "arm,armv8";
+ reg = <0x0 0x0>;
+ device_type = "cpu";
+ enable-method = "psci";
+ clocks = <&scmi_dvfs 0>;
+ };
+ cpu1@100 {
+ compatible = "arm,armv8";
+ reg = <0x0 0x100>;
+ device_type = "cpu";
+ enable-method = "psci";
+ clocks = <&scmi_dvfs 0>;
+ };
+ cpu2@10000 {
+ compatible = "arm,armv8";
+ reg = <0x0 0x10000>;
+ device_type = "cpu";
+ enable-method = "psci";
+ clocks = <&scmi_dvfs 0>;
+ };
+ cpu3@10100 {
+ compatible = "arm,armv8";
+ reg = <0x0 0x10100>;
+ device_type = "cpu";
+ enable-method = "psci";
+ clocks = <&scmi_dvfs 0>;
+ };
+ };
+
+ /* The first bank of memory, memory map is actually provided by UEFI. */
+ memory@80000000 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ device_type = "memory";
+ /* [0x80000000-0xffffffff] */
+ reg = <0x00000000 0x80000000 0x0 0x80000000>;
+ };
+
+ memory@8080000000 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ device_type = "memory";
+ /* [0x8080000000-0x83ffffffff] */
+ reg = <0x00000080 0x80000000 0x1 0x80000000>;
+ };
+
+ virtio_block@1c170000 {
+ compatible = "virtio,mmio";
+ reg = <0x0 0x1c170000 0x0 0x200>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ ethernet@1d100000 {
+ compatible = "smsc,lan91c111";
+ reg = <0x0 0x1d100000 0x0 0x10000>;
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ kmi@1c150000 {
+ compatible = "arm,pl050", "arm,primecell";
+ reg = <0x0 0x1c150000 0x0 0x1000>;
+ interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
+ clock-names = "KMIREFCLK", "apb_pclk";
+ };
+
+ kmi@1c160000 {
+ compatible = "arm,pl050", "arm,primecell";
+ reg = <0x0 0x1c160000 0x0 0x1000>;
+ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
+ clock-names = "KMIREFCLK", "apb_pclk";
+ };
+
+ firmware {
+ scmi {
+ compatible = "arm,scmi";
+ mbox-names = "tx", "rx";
+ mboxes = <&mailbox 1 0 &mailbox 1 1>;
+ shmem = <&cpu_scp_hpri0 &cpu_scp_hpri1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ scmi_dvfs: protocol@13 {
+ reg = <0x13>;
+ #clock-cells = <1>;
+ };
+ };
+ };
+
+ bp_clock24mhz: clock24mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "bp:clock24mhz";
+ };
+};
+
+&gic {
+ reg = <0x0 0x30000000 0 0x10000>, /* GICD */
+ <0x0 0x300c0000 0 0x80000>; /* GICR */
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+};
diff --git a/fdts/morello.dtsi b/fdts/morello.dtsi
new file mode 100644
index 0000000..52c04cd
--- /dev/null
+++ b/fdts/morello.dtsi
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "arm,morello";
+
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ serial0 = &soc_uart0;
+ };
+
+ gic: interrupt-controller@2c010000 {
+ compatible = "arm,gic-600", "arm,gic-v3";
+ #address-cells = <2>;
+ #interrupt-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+ interrupt-controller;
+ };
+
+ pmu {
+ compatible = "arm,armv8-pmuv3";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ spe-pmu {
+ compatible = "arm,statistical-profiling-extension-v1";
+ interrupts = <GIC_PPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ mailbox: mhu@45000000 {
+ compatible = "arm,mhu-doorbell", "arm,primecell";
+ reg = <0x0 0x45000000 0x0 0x1000>;
+ interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "mhu_lpri_rx",
+ "mhu_hpri_rx";
+ #mbox-cells = <2>;
+ mbox-name = "ARM-MHU";
+ clocks = <&soc_refclk100mhz>;
+ clock-names = "apb_pclk";
+ };
+
+ sram: sram@45200000 {
+ compatible = "mmio-sram";
+ reg = <0x0 0x45200000 0x0 0x8000>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x0 0x45200000 0x8000>;
+
+ cpu_scp_hpri0: scp-shmem@0 {
+ compatible = "arm,scmi-shmem";
+ reg = <0x0 0x80>;
+ };
+
+ cpu_scp_hpri1: scp-shmem@80 {
+ compatible = "arm,scmi-shmem";
+ reg = <0x80 0x80>;
+ };
+ };
+
+ soc_refclk100mhz: refclk100mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ clock-output-names = "apb_pclk";
+ };
+
+ soc_uartclk: uartclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <50000000>;
+ clock-output-names = "uartclk";
+ };
+
+ soc_uart0: uart@2a400000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x0 0x2a400000 0x0 0x1000>;
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&soc_uartclk>, <&soc_refclk100mhz>;
+ clock-names = "uartclk", "apb_pclk";
+ status = "okay";
+ };
+};
diff --git a/fdts/tc0.dts b/fdts/tc0.dts
index ac097cd..15c14ca 100644
--- a/fdts/tc0.dts
+++ b/fdts/tc0.dts
@@ -134,7 +134,7 @@
clocks = <&soc_refclk100mhz>;
clock-names = "apb_pclk";
#mbox-cells = <1>;
- interrupts = <0 316 4>;
+ interrupts = <0 317 4>;
interrupt-names = "mhu_rx";
mhu-protocol = "doorbell";
};
diff --git a/include/common/fdt_fixup.h b/include/common/fdt_fixup.h
index 29d8b3a..2e9d49d 100644
--- a/include/common/fdt_fixup.h
+++ b/include/common/fdt_fixup.h
@@ -13,5 +13,7 @@
uintptr_t base, size_t size);
int fdt_add_cpus_node(void *dtb, unsigned int afflv0,
unsigned int afflv1, unsigned int afflv2);
+int fdt_adjust_gic_redist(void *dtb, unsigned int nr_cores,
+ unsigned int gicr_frame_size);
#endif /* FDT_FIXUP_H */
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index 18d5b73..d8ac4cb 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -488,6 +488,7 @@
void gicv3_rdistif_init(unsigned int proc_num);
void gicv3_rdistif_on(unsigned int proc_num);
void gicv3_rdistif_off(unsigned int proc_num);
+unsigned int gicv3_rdistif_get_number_frames(const uintptr_t gicr_frame);
void gicv3_cpuif_enable(unsigned int proc_num);
void gicv3_cpuif_disable(unsigned int proc_num);
unsigned int gicv3_get_pending_interrupt_type(void);
diff --git a/include/drivers/auth/mbedtls/mbedtls_config.h b/include/drivers/auth/mbedtls/mbedtls_config.h
index dc00da7..ad39fa9 100644
--- a/include/drivers/auth/mbedtls/mbedtls_config.h
+++ b/include/drivers/auth/mbedtls/mbedtls_config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -63,6 +63,7 @@
#define MBEDTLS_ECDSA_C
#define MBEDTLS_ECP_C
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
+#define MBEDTLS_ECP_NO_INTERNAL_RNG
#endif
#if TF_MBEDTLS_USE_RSA
#define MBEDTLS_RSA_C
@@ -101,6 +102,12 @@
/* Memory buffer allocator options */
#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 8
+/*
+ * Prevent the use of 128-bit division which
+ * creates dependency on external libraries.
+ */
+#define MBEDTLS_NO_UDBL_DIVISION
+
#ifndef __ASSEMBLER__
/* System headers required to build mbed TLS with the current configuration */
#include <stdlib.h>
diff --git a/include/drivers/measured_boot/event_log.h b/include/drivers/measured_boot/event_log.h
index 10dfbb3..efde117 100644
--- a/include/drivers/measured_boot/event_log.h
+++ b/include/drivers/measured_boot/event_log.h
@@ -20,8 +20,6 @@
* LOG_LEVEL_WARNING
* LOG_LEVEL_VERBOSE
*/
-#define EVENT_LOG_LEVEL LOG_LEVEL_INFO
-
#if EVENT_LOG_LEVEL == LOG_LEVEL_ERROR
#define LOG_EVENT ERROR
#elif EVENT_LOG_LEVEL == LOG_LEVEL_NOTICE
diff --git a/include/drivers/raw_nand.h b/include/drivers/raw_nand.h
index 9018f02..7152300 100644
--- a/include/drivers/raw_nand.h
+++ b/include/drivers/raw_nand.h
@@ -169,7 +169,7 @@
};
int nand_raw_init(unsigned long long *size, unsigned int *erase_size);
-int nand_wait_ready(unsigned long delay);
+int nand_wait_ready(unsigned int delay_ms);
int nand_read_page_cmd(unsigned int page, unsigned int offset,
uintptr_t buffer, unsigned int len);
int nand_change_read_column_cmd(unsigned int offset, uintptr_t buffer,
diff --git a/include/drivers/st/etzpc.h b/include/drivers/st/etzpc.h
index 6e3fec1..4cd2b4e 100644
--- a/include/drivers/st/etzpc.h
+++ b/include/drivers/st/etzpc.h
@@ -7,6 +7,9 @@
#ifndef DRIVERS_ST_ETZPC_H
#define DRIVERS_ST_ETZPC_H
+#include <stdbool.h>
+#include <stdint.h>
+
/* Define security level for each peripheral (DECPROT) */
enum etzpc_decprot_attributes {
ETZPC_DECPROT_S_RW = 0,
diff --git a/include/lib/cpus/aarch64/cortex_a77.h b/include/lib/cpus/aarch64/cortex_a77.h
index bbd647c..41aced8 100644
--- a/include/lib/cpus/aarch64/cortex_a77.h
+++ b/include/lib/cpus/aarch64/cortex_a77.h
@@ -24,4 +24,11 @@
#define CORTEX_A77_CPUPWRCTLR_EL1 S3_0_C15_C2_7
#define CORTEX_A77_CPUPWRCTLR_EL1_CORE_PWRDN_BIT (U(1) << 0)
+#define CORTEX_A77_CPUPSELR_EL3 S3_6_C15_C8_0
+#define CORTEX_A77_CPUPCR_EL3 S3_6_C15_C8_1
+#define CORTEX_A77_CPUPOR_EL3 S3_6_C15_C8_2
+#define CORTEX_A77_CPUPMR_EL3 S3_6_C15_C8_3
+#define CORTEX_A77_CPUPOR2_EL3 S3_6_C15_C8_4
+#define CORTEX_A77_CPUPMR2_EL3 S3_6_C15_C8_5
+
#endif /* CORTEX_A77_H */
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 <lib/utils_def.h>
+
+/*
+ * 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/include/lib/cpus/aarch64/rainier.h b/include/lib/cpus/aarch64/rainier.h
new file mode 100644
index 0000000..9ff1669
--- /dev/null
+++ b/include/lib/cpus/aarch64/rainier.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RAINIER_H
+#define RAINIER_H
+
+#include <lib/utils_def.h>
+
+/* RAINIER MIDR for revision 0 */
+#define RAINIER_MIDR U(0x3f0f4100)
+
+/* Exception Syndrome register EC code for IC Trap */
+#define RAINIER_EC_IC_TRAP U(0x1f)
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions.
+ ******************************************************************************/
+#define RAINIER_CPUPWRCTLR_EL1 S3_0_C15_C2_7
+
+/* Definitions of register field mask in RAINIER_CPUPWRCTLR_EL1 */
+#define RAINIER_CORE_PWRDN_EN_MASK U(0x1)
+
+#define RAINIER_ACTLR_AMEN_BIT (U(1) << 4)
+
+#define RAINIER_AMU_NR_COUNTERS U(5)
+#define RAINIER_AMU_GROUP0_MASK U(0x1f)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions.
+ ******************************************************************************/
+#define RAINIER_CPUECTLR_EL1 S3_0_C15_C1_4
+
+#define RAINIER_WS_THR_L2_MASK (ULL(3) << 24)
+#define RAINIER_CPUECTLR_EL1_MM_TLBPF_DIS_BIT (ULL(1) << 51)
+
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define RAINIER_CPUACTLR_EL1 S3_0_C15_C1_0
+
+#define RAINIER_CPUACTLR_EL1_BIT_6 (ULL(1) << 6)
+#define RAINIER_CPUACTLR_EL1_BIT_13 (ULL(1) << 13)
+
+#define RAINIER_CPUACTLR2_EL1 S3_0_C15_C1_1
+
+#define RAINIER_CPUACTLR2_EL1_BIT_0 (ULL(1) << 0)
+#define RAINIER_CPUACTLR2_EL1_BIT_2 (ULL(1) << 2)
+#define RAINIER_CPUACTLR2_EL1_BIT_11 (ULL(1) << 11)
+#define RAINIER_CPUACTLR2_EL1_BIT_15 (ULL(1) << 15)
+#define RAINIER_CPUACTLR2_EL1_BIT_16 (ULL(1) << 16)
+#define RAINIER_CPUACTLR2_EL1_BIT_59 (ULL(1) << 59)
+
+#define RAINIER_CPUACTLR3_EL1 S3_0_C15_C1_2
+
+#define RAINIER_CPUACTLR3_EL1_BIT_10 (ULL(1) << 10)
+
+/* Instruction patching registers */
+#define CPUPSELR_EL3 S3_6_C15_C8_0
+#define CPUPCR_EL3 S3_6_C15_C8_1
+#define CPUPOR_EL3 S3_6_C15_C8_2
+#define CPUPMR_EL3 S3_6_C15_C8_3
+
+#endif /* RAINIER_H */
diff --git a/include/lib/libc/string.h b/include/lib/libc/string.h
index 91cbafb..9894483 100644
--- a/include/lib/libc/string.h
+++ b/include/lib/libc/string.h
@@ -27,5 +27,6 @@
char *strrchr(const char *p, int ch);
size_t strlcpy(char * dst, const char * src, size_t dsize);
size_t strlcat(char * dst, const char * src, size_t dsize);
+char *strtok_r(char *s, const char *delim, char **last);
#endif /* STRING_H */
diff --git a/lib/cpus/aarch64/cortex_a77.S b/lib/cpus/aarch64/cortex_a77.S
index 0c30460..ea21999 100644
--- a/lib/cpus/aarch64/cortex_a77.S
+++ b/lib/cpus/aarch64/cortex_a77.S
@@ -22,6 +22,70 @@
#endif
/* --------------------------------------------------
+ * Errata Workaround for Cortex A77 Errata #1508412.
+ * This applies only to revision <= r1p0 of Cortex A77.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a77_1508412_wa
+ /*
+ * Compare x0 against revision r1p0
+ */
+ mov x17, x30
+ bl check_errata_1508412
+ cbz x0, 3f
+ /*
+ * Compare x0 against revision r0p0
+ */
+ bl check_errata_1508412_0
+ cbz x0, 1f
+ ldr x0, =0x0
+ msr CORTEX_A77_CPUPSELR_EL3, x0
+ ldr x0, =0x00E8400000
+ msr CORTEX_A77_CPUPOR_EL3, x0
+ ldr x0, =0x00FFE00000
+ msr CORTEX_A77_CPUPMR_EL3, x0
+ ldr x0, =0x4004003FF
+ msr CORTEX_A77_CPUPCR_EL3, x0
+ ldr x0, =0x1
+ msr CORTEX_A77_CPUPSELR_EL3, x0
+ ldr x0, =0x00E8C00040
+ msr CORTEX_A77_CPUPOR_EL3, x0
+ ldr x0, =0x00FFE00040
+ msr CORTEX_A77_CPUPMR_EL3, x0
+ b 2f
+1:
+ ldr x0, =0x0
+ msr CORTEX_A77_CPUPSELR_EL3, x0
+ ldr x0, =0x00E8400000
+ msr CORTEX_A77_CPUPOR_EL3, x0
+ ldr x0, =0x00FF600000
+ msr CORTEX_A77_CPUPMR_EL3, x0
+ ldr x0, =0x00E8E00080
+ msr CORTEX_A77_CPUPOR2_EL3, x0
+ ldr x0, =0x00FFE000C0
+ msr CORTEX_A77_CPUPMR2_EL3, x0
+2:
+ ldr x0, =0x04004003FF
+ msr CORTEX_A77_CPUPCR_EL3, x0
+ isb
+3:
+ ret x17
+endfunc errata_a77_1508412_wa
+
+func check_errata_1508412
+ mov x1, #0x10
+ b cpu_rev_var_ls
+endfunc check_errata_1508412
+
+func check_errata_1508412_0
+ mov x1, #0x0
+ b cpu_rev_var_ls
+endfunc check_errata_1508412_0
+
+ /* --------------------------------------------------
* Errata Workaround for Cortex A77 Errata #1800714.
* This applies to revision <= r1p1 of Cortex A77.
* Inputs:
@@ -60,6 +124,11 @@
bl cpu_get_rev_var
mov x18, x0
+#if ERRATA_A77_1508412
+ mov x0, x18
+ bl errata_a77_1508412_wa
+#endif
+
#if ERRATA_A77_1800714
mov x0, x18
bl errata_a77_1800714_wa
@@ -98,6 +167,7 @@
* Report all errata. The revision-variant information is passed to
* checking functions of each errata.
*/
+ report_errata ERRATA_A77_1508412, cortex_a77, 1508412
report_errata ERRATA_A77_1800714, cortex_a77, 1800714
ldp x8, x30, [sp], #16
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 <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <generic.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+ /* ---------------------------------------------
+ * 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/lib/cpus/aarch64/rainier.S b/lib/cpus/aarch64/rainier.S
new file mode 100644
index 0000000..f7afd0b
--- /dev/null
+++ b/lib/cpus/aarch64/rainier.S
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <context.h>
+#include <cpu_macros.S>
+#include <cpuamu.h>
+#include <rainier.h>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Rainier CPU must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Rainier CPU supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+#if ERRATA_RAINIER_IC_TRAP
+ .global rainier_errata_ic_trap_handler
+#endif
+
+/* --------------------------------------------------
+ * Disable speculative loads if Rainier supports
+ * SSBS.
+ *
+ * Shall clobber: x0.
+ * --------------------------------------------------
+ */
+func rainier_disable_speculative_loads
+ /* Check if the PE implements SSBS */
+ mrs x0, id_aa64pfr1_el1
+ tst x0, #(ID_AA64PFR1_EL1_SSBS_MASK << ID_AA64PFR1_EL1_SSBS_SHIFT)
+ b.eq 1f
+
+ /* Disable speculative loads */
+ msr SSBS, xzr
+
+1:
+ ret
+endfunc rainier_disable_speculative_loads
+
+/* --------------------------------------------------
+ * Errata Workaround for Neoverse N1 Erratum 1542419.
+ * This applies to revisions r3p0 - r4p0 of Neoverse N1
+ * Since Rainier core is based on Neoverse N1 r4p0, this
+ * errata applies to Rainier core r0p0
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_n1_1542419_wa
+ /* Compare x0 against revision r3p0 and r4p0 */
+ mov x17, x30
+ bl check_errata_1542419
+ cbz x0, 1f
+
+ /* Apply instruction patching sequence */
+ mov x0, xzr
+ msr CPUPSELR_EL3, x0
+ ldr x0, =0xEE670D35
+ msr CPUPOR_EL3, x0
+ ldr x0, =0xFFFF0FFF
+ msr CPUPMR_EL3, x0
+ ldr x0, =0x08000020007D
+ msr CPUPCR_EL3, x0
+ isb
+1:
+ ret x17
+endfunc errata_n1_1542419_wa
+
+func check_errata_1542419
+ /* Applies to Rainier core r0p0. */
+ mov x1, #0x00
+ b cpu_rev_var_ls
+endfunc check_errata_1542419
+
+func rainier_reset_func
+ mov x19, x30
+
+ bl rainier_disable_speculative_loads
+
+ /* Forces all cacheable atomic instructions to be near */
+ mrs x0, RAINIER_CPUACTLR2_EL1
+ orr x0, x0, #RAINIER_CPUACTLR2_EL1_BIT_2
+ msr RAINIER_CPUACTLR2_EL1, x0
+ isb
+
+ bl cpu_get_rev_var
+ mov x18, x0
+
+#if ERRATA_N1_1542419
+ mov x0, x18
+ bl errata_n1_1542419_wa
+#endif
+
+#if ENABLE_AMU
+ /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
+ mrs x0, actlr_el3
+ orr x0, x0, #RAINIER_ACTLR_AMEN_BIT
+ msr actlr_el3, x0
+
+ /* Make sure accesses from EL0/EL1 are not trapped to EL2 */
+ mrs x0, actlr_el2
+ orr x0, x0, #RAINIER_ACTLR_AMEN_BIT
+ msr actlr_el2, x0
+
+ /* Enable group0 counters */
+ mov x0, #RAINIER_AMU_GROUP0_MASK
+ msr CPUAMCNTENSET_EL0, x0
+#endif
+
+ isb
+ ret x19
+endfunc rainier_reset_func
+
+ /* ---------------------------------------------
+ * HW will do the cache maintenance while powering down
+ * ---------------------------------------------
+ */
+func rainier_core_pwr_dwn
+ /* ---------------------------------------------
+ * Enable CPU power down bit in power control register
+ * ---------------------------------------------
+ */
+ mrs x0, RAINIER_CPUPWRCTLR_EL1
+ orr x0, x0, #RAINIER_CORE_PWRDN_EN_MASK
+ msr RAINIER_CPUPWRCTLR_EL1, x0
+ isb
+ ret
+endfunc rainier_core_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Rainier. Must follow AAPCS.
+ */
+func rainier_errata_report
+ stp x8, x30, [sp, #-16]!
+
+ bl cpu_get_rev_var
+ mov x8, x0
+
+ /*
+ * Report all errata. The revision-variant information is passed to
+ * checking functions of each errata.
+ */
+ report_errata ERRATA_N1_1542419, rainier, 1542419
+
+ ldp x8, x30, [sp], #16
+ ret
+endfunc rainier_errata_report
+#endif
+
+/*
+ * Handle trap of EL0 IC IVAU instructions to EL3 by executing a TLB
+ * inner-shareable invalidation to an arbitrary address followed by a DSB.
+ *
+ * x1: Exception Syndrome
+ */
+func rainier_errata_ic_trap_handler
+ cmp x1, #RAINIER_EC_IC_TRAP
+ b.ne 1f
+ tlbi vae3is, xzr
+ dsb sy
+
+ # Skip the IC instruction itself
+ mrs x3, elr_el3
+ add x3, x3, #4
+ msr elr_el3, x3
+
+ ldp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
+ ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
+ ldp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
+ ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+
+#if IMAGE_BL31 && RAS_EXTENSION
+ /*
+ * Issue Error Synchronization Barrier to synchronize SErrors before
+ * exiting EL3. We're running with EAs unmasked, so any synchronized
+ * errors would be taken immediately; therefore no need to inspect
+ * DISR_EL1 register.
+ */
+ esb
+#endif
+ eret
+1:
+ ret
+endfunc rainier_errata_ic_trap_handler
+
+ /* ---------------------------------------------
+ * This function provides Rainier specific
+ * register information for crash reporting.
+ * It needs to return with x6 pointing to
+ * a list of register names in ascii and
+ * x8 - x15 having values of registers to be
+ * reported.
+ * ---------------------------------------------
+ */
+.section .rodata.rainier_regs, "aS"
+rainier_regs: /* The ascii list of register names to be reported */
+ .asciz "cpuectlr_el1", ""
+
+func rainier_cpu_reg_dump
+ adr x6, rainier_regs
+ mrs x8, RAINIER_CPUECTLR_EL1
+ ret
+endfunc rainier_cpu_reg_dump
+
+declare_cpu_ops_eh rainier, RAINIER_MIDR, \
+ rainier_reset_func, \
+ rainier_errata_ic_trap_handler, \
+ rainier_core_pwr_dwn
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 7cd8ed9..5df94cc 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -278,6 +278,10 @@
# to all revisions of Cortex A76 cpu.
ERRATA_A76_1165522 ?=0
+# Flag to apply erratum 1508412 workaround during reset. This erratum applies
+# only to revision <= r1p0 of the Cortex A77 cpu.
+ERRATA_A77_1508412 ?=0
+
# Flag to apply erratum 1800714 workaround during reset. This erratum applies
# only to revision <= r1p1 of the Cortex A77 cpu.
ERRATA_A77_1800714 ?=0
@@ -551,6 +555,10 @@
$(eval $(call assert_boolean,ERRATA_A76_1165522))
$(eval $(call add_define,ERRATA_A76_1165522))
+# Process ERRATA_A77_1508412 flag
+$(eval $(call assert_boolean,ERRATA_A77_1508412))
+$(eval $(call add_define,ERRATA_A77_1508412))
+
# Process ERRATA_A77_1800714 flag
$(eval $(call assert_boolean,ERRATA_A77_1800714))
$(eval $(call add_define,ERRATA_A77_1800714))
diff --git a/lib/libc/aarch32/memset.S b/lib/libc/aarch32/memset.S
new file mode 100644
index 0000000..880ba83
--- /dev/null
+++ b/lib/libc/aarch32/memset.S
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+
+ .syntax unified
+ .global memset
+
+/* -----------------------------------------------------------------------
+ * void *memset(void *dst, int val, size_t count)
+ *
+ * Copy the value of 'val' (converted to an unsigned char) into
+ * each of the first 'count' characters of the object pointed to by 'dst'.
+ *
+ * Returns the value of 'dst'.
+ * -----------------------------------------------------------------------
+ */
+func memset
+ mov r12, r0 /* keep r0 */
+ tst r0, #3
+ beq aligned /* 4-bytes aligned */
+
+ /* Unaligned 'dst' */
+unaligned:
+ subs r2, r2, #1
+ strbhs r1, [r12], #1
+ bxls lr /* return if 0 */
+ tst r12, #3
+ bne unaligned /* continue while unaligned */
+
+ /* 4-bytes aligned */
+aligned:bfi r1, r1, #8, #8 /* propagate 'val' */
+ bfi r1, r1, #16, #16
+
+ mov r3, r1
+
+ cmp r2, #16
+ blo less_16 /* < 16 */
+
+ push {r4, lr}
+ mov r4, r1
+ mov lr, r1
+
+write_32:
+ subs r2, r2, #32
+ stmiahs r12!, {r1, r3, r4, lr}
+ stmiahs r12!, {r1, r3, r4, lr}
+ bhi write_32 /* write 32 bytes in a loop */
+ popeq {r4, pc} /* return if 0 */
+ lsls r2, r2, #28 /* C = r2[4]; N = r2[3]; Z = r2[3:0] */
+ stmiacs r12!, {r1, r3, r4, lr} /* write 16 bytes */
+ popeq {r4, pc} /* return if 16 */
+ stmiami r12!, {r1, r3} /* write 8 bytes */
+ lsls r2, r2, #2 /* C = r2[2]; N = r2[1]; Z = r2[1:0] */
+ strcs r1, [r12], #4 /* write 4 bytes */
+ popeq {r4, pc} /* return if 8 or 4 */
+ strhmi r1, [r12], #2 /* write 2 bytes */
+ lsls r2, r2, #1 /* N = Z = r2[0] */
+ strbmi r1, [r12] /* write 1 byte */
+ pop {r4, pc}
+
+less_16:lsls r2, r2, #29 /* C = r2[3]; N = r2[2]; Z = r2[2:0] */
+ stmiacs r12!, {r1, r3} /* write 8 bytes */
+ bxeq lr /* return if 8 */
+ strmi r1, [r12], #4 /* write 4 bytes */
+ lsls r2, r2, #2 /* C = r2[1]; N = Z = r2[0] */
+ strhcs r1, [r12], #2 /* write 2 bytes */
+ strbmi r1, [r12] /* write 1 byte */
+ bx lr
+
+endfunc memset
diff --git a/lib/libc/aarch64/memset.S b/lib/libc/aarch64/memset.S
new file mode 100644
index 0000000..0543704
--- /dev/null
+++ b/lib/libc/aarch64/memset.S
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+
+ .global memset
+
+/* -----------------------------------------------------------------------
+ * void *memset(void *dst, int val, size_t count)
+ *
+ * Copy the value of 'val' (converted to an unsigned char) into
+ * each of the first 'count' characters of the object pointed to by 'dst'.
+ *
+ * Returns the value of 'dst'.
+ * -----------------------------------------------------------------------
+ */
+func memset
+ cbz x2, exit /* exit if 'count' = 0 */
+ mov x3, x0 /* keep x0 */
+ tst x0, #7
+ b.eq aligned /* 8-bytes aligned */
+
+ /* Unaligned 'dst' */
+unaligned:
+ strb w1, [x3], #1
+ subs x2, x2, #1
+ b.eq exit /* exit if 0 */
+ tst x3, #7
+ b.ne unaligned /* continue while unaligned */
+
+ /* 8-bytes aligned */
+aligned:cbz x1, x1_zero
+ bfi w1, w1, #8, #8 /* propagate 'val' */
+ bfi w1, w1, #16, #16
+ bfi x1, x1, #32, #32
+
+x1_zero:ands x4, x2, #~0x3f
+ b.eq less_64
+
+write_64:
+ .rept 4
+ stp x1, x1, [x3], #16 /* write 64 bytes in a loop */
+ .endr
+ subs x4, x4, #64
+ b.ne write_64
+less_64:tbz w2, #5, less_32 /* < 32 bytes */
+ stp x1, x1, [x3], #16 /* write 32 bytes */
+ stp x1, x1, [x3], #16
+less_32:tbz w2, #4, less_16 /* < 16 bytes */
+ stp x1, x1, [x3], #16 /* write 16 bytes */
+less_16:tbz w2, #3, less_8 /* < 8 bytes */
+ str x1, [x3], #8 /* write 8 bytes */
+less_8: tbz w2, #2, less_4 /* < 4 bytes */
+ str w1, [x3], #4 /* write 4 bytes */
+less_4: tbz w2, #1, less_2 /* < 2 bytes */
+ strh w1, [x3], #2 /* write 2 bytes */
+less_2: tbz w2, #0, exit
+ strb w1, [x3] /* write 1 byte */
+exit: ret
+
+endfunc memset
diff --git a/lib/libc/libc_asm.mk b/lib/libc/libc_asm.mk
new file mode 100644
index 0000000..6416a3c
--- /dev/null
+++ b/lib/libc/libc_asm.mk
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LIBC_SRCS := $(addprefix lib/libc/, \
+ abort.c \
+ assert.c \
+ exit.c \
+ memchr.c \
+ memcmp.c \
+ memcpy.c \
+ memmove.c \
+ memrchr.c \
+ printf.c \
+ putchar.c \
+ puts.c \
+ snprintf.c \
+ strchr.c \
+ strcmp.c \
+ strlcpy.c \
+ strlen.c \
+ strncmp.c \
+ strnlen.c \
+ strrchr.c)
+
+ifeq (${ARCH},aarch64)
+LIBC_SRCS += $(addprefix lib/libc/aarch64/, \
+ memset.S \
+ setjmp.S)
+else
+LIBC_SRCS += $(addprefix lib/libc/aarch32/, \
+ memset.S)
+endif
+
+INCLUDES += -Iinclude/lib/libc \
+ -Iinclude/lib/libc/$(ARCH) \
diff --git a/lib/libc/strtok.c b/lib/libc/strtok.c
new file mode 100644
index 0000000..7e1a4d2
--- /dev/null
+++ b/lib/libc/strtok.c
@@ -0,0 +1,83 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1998 Softweyr LLC. All rights reserved.
+ *
+ * strtok_r, from Berkeley strtok
+ * Oct 13, 1998 by Wes Peters <wes@softweyr.com>
+ *
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notices, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notices, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University 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 SOFTWEYR LLC, THE REGENTS 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 SOFTWEYR LLC, THE
+ * REGENTS, 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 <string.h>
+
+char *
+strtok_r(char *s, const char *delim, char **last)
+{
+ char *spanp, *tok;
+ int c, sc;
+
+ if (s == NULL && (s = *last) == NULL)
+ return (NULL);
+
+ /*
+ * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
+ */
+cont:
+ c = *s++;
+ for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
+ if (c == sc)
+ goto cont;
+ }
+
+ if (c == 0) { /* no non-delimiter characters */
+ *last = NULL;
+ return (NULL);
+ }
+ tok = s - 1;
+
+ /*
+ * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
+ * Note that delim must have one NUL; we stop if we see that, too.
+ */
+ for (;;) {
+ c = *s++;
+ spanp = (char *)delim;
+ do {
+ if ((sc = *spanp++) == c) {
+ if (c == 0)
+ s = NULL;
+ else
+ s[-1] = '\0';
+ *last = s;
+ return (tok);
+ }
+ } while (sc != 0);
+ }
+ /* NOTREACHED */
+}
diff --git a/plat/arm/board/arm_fpga/build_axf.ld.S b/plat/arm/board/arm_fpga/build_axf.ld.S
new file mode 100644
index 0000000..d7cd008
--- /dev/null
+++ b/plat/arm/board/arm_fpga/build_axf.ld.S
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Linker script for the Arm Ltd. FPGA boards to generate an ELF file that
+ * contains the ROM trampoline, BL31 and the DTB.
+ *
+ * This allows to pass just one file to the uploader tool, and automatically
+ * provides the correct load addresses.
+ */
+
+#include <platform_def.h>
+
+OUTPUT_FORMAT("elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+
+INPUT(./bl31/bl31.elf)
+INPUT(./rom_trampoline.o)
+
+TARGET(binary)
+INPUT(./fdts/arm_fpga.dtb)
+
+ENTRY(_start)
+
+SECTIONS
+{
+ .rom (0x0): {
+ *rom_trampoline.o(.text*)
+ KEEP(*(.rom))
+ }
+
+ .bl31 (BL31_BASE): {
+ ASSERT(. == ALIGN(PAGE_SIZE), "BL31_BASE is not page aligned");
+ *bl31.elf(.text* .data* .rodata* ro* .bss*)
+ *bl31.elf(.stack)
+ }
+
+ .dtb (FPGA_PRELOADED_DTB_BASE): {
+ ASSERT(. == ALIGN(8), "DTB address is not 8-byte aligned");
+ *arm_fpga.dtb
+ }
+
+ /DISCARD/ : { *(.debug_*) }
+ /DISCARD/ : { *(.note*) }
+ /DISCARD/ : { *(.comment*) }
+}
diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
index de6d9d5..a5f5ea0 100644
--- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c
+++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
@@ -9,8 +9,10 @@
#include <common/fdt_fixup.h>
#include <common/fdt_wrappers.h>
+#include <drivers/arm/gicv3.h>
#include <drivers/delay_timer.h>
#include <drivers/generic_delay_timer.h>
+#include <lib/extensions/spe.h>
#include <libfdt.h>
#include "fpga_private.h"
@@ -210,6 +212,26 @@
if (err < 0) {
ERROR("Error %d creating the /cpus DT node\n", err);
panic();
+ } else {
+ unsigned int nr_cores = fpga_get_nr_gic_cores();
+
+ INFO("Adjusting GICR DT region to cover %u cores\n",
+ nr_cores);
+ err = fdt_adjust_gic_redist(fdt, nr_cores,
+ 1U << GICR_PCPUBASE_SHIFT);
+ if (err < 0) {
+ ERROR("Error %d fixing up GIC DT node\n", err);
+ }
+ }
+ }
+
+ /* Check whether we support the SPE PMU. Remove the DT node if not. */
+ if (!spe_supported()) {
+ int node = fdt_node_offset_by_compatible(fdt, 0,
+ "arm,statistical-profiling-extension-v1");
+
+ if (node >= 0) {
+ fdt_del_node(fdt, node);
}
}
diff --git a/plat/arm/board/arm_fpga/fpga_gicv3.c b/plat/arm/board/arm_fpga/fpga_gicv3.c
index 9fb5fa9..bfc116b 100644
--- a/plat/arm/board/arm_fpga/fpga_gicv3.c
+++ b/plat/arm/board/arm_fpga/fpga_gicv3.c
@@ -77,3 +77,8 @@
gicv3_cpuif_disable(plat_my_core_pos());
gicv3_rdistif_off(plat_my_core_pos());
}
+
+unsigned int fpga_get_nr_gic_cores(void)
+{
+ return gicv3_rdistif_get_number_frames(fpga_gicv3_driver_data.gicr_base);
+}
diff --git a/plat/arm/board/arm_fpga/fpga_private.h b/plat/arm/board/arm_fpga/fpga_private.h
index 47059d6..1ca241f 100644
--- a/plat/arm/board/arm_fpga/fpga_private.h
+++ b/plat/arm/board/arm_fpga/fpga_private.h
@@ -24,6 +24,7 @@
void fpga_pwr_gic_on_finish(void);
void fpga_pwr_gic_off(void);
unsigned int plat_fpga_calc_core_pos(uint32_t mpid);
+unsigned int fpga_get_nr_gic_cores(void);
#endif /* __ASSEMBLER__ */
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index 8904339..ab576b6 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
@@ -81,6 +89,8 @@
plat/common/plat_gicv3.c \
plat/arm/board/arm_fpga/fpga_gicv3.c
+FDT_SOURCES := fdts/arm_fpga.dts
+
PLAT_INCLUDES := -Iplat/arm/board/arm_fpga/include
PLAT_BL_COMMON_SOURCES := plat/arm/board/arm_fpga/${ARCH}/fpga_helpers.S
@@ -98,4 +108,11 @@
${FPGA_CPU_LIBS} \
${FPGA_GIC_SOURCES}
+$(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/rom_trampoline.S,31))
+$(eval $(call MAKE_LD,$(BUILD_PLAT)/build_axf.ld,plat/arm/board/arm_fpga/build_axf.ld.S,31))
+
+bl31.axf: bl31 dtbs ${BUILD_PLAT}/rom_trampoline.o ${BUILD_PLAT}/build_axf.ld
+ $(ECHO) " LD $@"
+ $(Q)$(LD) -T ${BUILD_PLAT}/build_axf.ld -L ${BUILD_PLAT} --strip-debug -o ${BUILD_PLAT}/bl31.axf
+
-all: bl31
+all: bl31.axf
diff --git a/plat/arm/board/arm_fpga/rom_trampoline.S b/plat/arm/board/arm_fpga/rom_trampoline.S
new file mode 100644
index 0000000..cd66c79
--- /dev/null
+++ b/plat/arm/board/arm_fpga/rom_trampoline.S
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * The Arm Ltd. FPGA images start execution at address 0x0, which is
+ * mapped at an (emulated) ROM image. The payload uploader can write to
+ * this memory, but write access by the CPU cores is prohibited.
+ *
+ * Provide a simple trampoline to start BL31 execution at the actual
+ * load address. We put the DTB address in x0, so any code in DRAM could
+ * make use of that information (not yet used in BL31 right now).
+ */
+
+#include <asm_macros.S>
+#include <common/bl_common.ld.h>
+
+.text
+.global _start
+
+_start:
+ mov_imm x1, BL31_BASE /* beginning of DRAM */
+ mov_imm x0, FPGA_PRELOADED_DTB_BASE
+ br x1
diff --git a/plat/arm/board/morello/aarch64/morello_helper.S b/plat/arm/board/morello/aarch64/morello_helper.S
new file mode 100644
index 0000000..60470a8
--- /dev/null
+++ b/plat/arm/board/morello/aarch64/morello_helper.S
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <cpu_macros.S>
+#include <rainier.h>
+
+#include <platform_def.h>
+
+ .globl plat_arm_calc_core_pos
+ .globl plat_reset_handler
+
+ /* -----------------------------------------------------
+ * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
+ *
+ * Helper function to calculate the core position.
+ * ((ChipId * MORELLO_MAX_CLUSTERS_PER_CHIP + ClusterId) *
+ * MORELLO_MAX_CPUS_PER_CLUSTER * MORELLO_MAX_PE_PER_CPU) +
+ * (CPUId * MORELLO_MAX_PE_PER_CPU) + ThreadId
+ *
+ * which can be simplified as:
+ *
+ * (((ChipId * MORELLO_MAX_CLUSTERS_PER_CHIP + ClusterId) *
+ * MORELLO_MAX_CPUS_PER_CLUSTER + CPUId) * MORELLO_MAX_PE_PER_CPU) +
+ * ThreadId
+ * ------------------------------------------------------
+ */
+
+func plat_arm_calc_core_pos
+ mov x4, x0
+
+ /*
+ * The MT bit in MPIDR is always set for morello and the
+ * affinity level 0 corresponds to thread affinity level.
+ */
+
+ /* Extract individual affinity fields from MPIDR */
+ ubfx x0, x4, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x1, x4, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x2, x4, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x3, x4, #MPIDR_AFF3_SHIFT, #MPIDR_AFFINITY_BITS
+
+ /* Compute linear position */
+ mov x4, #MORELLO_MAX_CLUSTERS_PER_CHIP
+ madd x2, x3, x4, x2
+ mov x4, #MORELLO_MAX_CPUS_PER_CLUSTER
+ madd x1, x2, x4, x1
+ mov x4, #MORELLO_MAX_PE_PER_CPU
+ madd x0, x1, x4, x0
+ ret
+endfunc plat_arm_calc_core_pos
diff --git a/plat/arm/board/morello/include/plat_macros.S b/plat/arm/board/morello/include/plat_macros.S
new file mode 100644
index 0000000..195be84
--- /dev/null
+++ b/plat/arm/board/morello/include/plat_macros.S
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+#include <css_macros.S>
+
+/* ---------------------------------------------
+ * The below required platform porting macro
+ * prints out relevant platform registers
+ * whenever an unhandled exception is taken in
+ * BL31.
+ *
+ * There are currently no platform specific regs
+ * to print.
+ * ---------------------------------------------
+ */
+ .macro plat_crash_print_regs
+ .endm
+
+#endif /* PLAT_MACROS_S */
diff --git a/plat/arm/board/morello/include/platform_def.h b/plat/arm/board/morello/include/platform_def.h
new file mode 100644
index 0000000..07c06a1
--- /dev/null
+++ b/plat/arm/board/morello/include/platform_def.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/css/common/css_def.h>
+
+/* UART related constants */
+#define PLAT_ARM_BOOT_UART_BASE ULL(0x2A400000)
+#define PLAT_ARM_BOOT_UART_CLK_IN_HZ U(50000000)
+
+#define PLAT_ARM_RUN_UART_BASE ULL(0x2A410000)
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ U(50000000)
+
+#define PLAT_ARM_CRASH_UART_BASE PLAT_ARM_RUN_UART_BASE
+#define PLAT_ARM_CRASH_UART_CLK_IN_HZ PLAT_ARM_RUN_UART_CLK_IN_HZ
+
+#define PLAT_ARM_DRAM2_BASE ULL(0x8080000000)
+#define PLAT_ARM_DRAM2_SIZE ULL(0xF80000000)
+
+/*
+ * To access the complete DDR memory along with remote chip's DDR memory,
+ * which is at 4 TB offset, physical and virtual address space limits are
+ * extended to 43-bits.
+ */
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 43)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 43)
+
+#if CSS_USE_SCMI_SDS_DRIVER
+#define MORELLO_SCMI_PAYLOAD_BASE ULL(0x45400000)
+#else
+#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE ULL(0x45400000)
+#endif
+
+#define PLAT_ARM_TRUSTED_SRAM_SIZE UL(0x00080000)
+#define PLAT_ARM_MAX_BL31_SIZE UL(0x20000)
+
+/*******************************************************************************
+ * MORELLO topology related constants
+ ******************************************************************************/
+#define MORELLO_MAX_CPUS_PER_CLUSTER U(2)
+#define PLAT_ARM_CLUSTER_COUNT U(2)
+#define PLAT_MORELLO_CHIP_COUNT U(1)
+#define MORELLO_MAX_CLUSTERS_PER_CHIP U(2)
+#define MORELLO_MAX_PE_PER_CPU U(1)
+
+#define PLATFORM_CORE_COUNT (PLAT_MORELLO_CHIP_COUNT * \
+ PLAT_ARM_CLUSTER_COUNT * \
+ MORELLO_MAX_CPUS_PER_CLUSTER * \
+ MORELLO_MAX_PE_PER_CPU)
+
+/* System power domain level */
+#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL3
+
+/*
+ * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
+ * plat_arm_mmap array defined for each BL stage.
+ */
+#define PLAT_ARM_MMAP_ENTRIES U(9)
+#define MAX_XLAT_TABLES U(10)
+
+#define PLATFORM_STACK_SIZE U(0x400)
+
+#define PLAT_ARM_NSTIMER_FRAME_ID U(0)
+#define PLAT_CSS_MHU_BASE UL(0x45000000)
+#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
+#define PLAT_MAX_PWR_LVL U(2)
+
+#define PLAT_ARM_G1S_IRQ_PROPS(grp) CSS_G1S_IRQ_PROPS(grp)
+#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp)
+
+#define MORELLO_DEVICE_BASE ULL(0x08000000)
+#define MORELLO_DEVICE_SIZE ULL(0x48000000)
+
+#define MORELLO_MAP_DEVICE MAP_REGION_FLAT( \
+ MORELLO_DEVICE_BASE, \
+ MORELLO_DEVICE_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#define ARM_MAP_DRAM1 MAP_REGION_FLAT( \
+ ARM_DRAM1_BASE, \
+ ARM_DRAM1_SIZE, \
+ MT_MEMORY | MT_RW | MT_NS)
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE UL(0x30000000)
+#define PLAT_ARM_GICC_BASE UL(0x2C000000)
+#define PLAT_ARM_GICR_BASE UL(0x300C0000)
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/morello/morello_bl31_setup.c b/plat/arm/board/morello/morello_bl31_setup.c
new file mode 100644
index 0000000..43f5f7f
--- /dev/null
+++ b/plat/arm/board/morello/morello_bl31_setup.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+#include <drivers/arm/css/sds.h>
+#include <plat/arm/common/plat_arm.h>
+
+#include "morello_def.h"
+#include <platform_def.h>
+
+/*
+ * Platform information structure stored in SDS.
+ * This structure holds information about platform's DDR
+ * size which is an information about multichip setup
+ * - multichip mode
+ * - slave_count
+ * - Local DDR size in GB, DDR memory in master board
+ * - Remote DDR size in GB, DDR memory in slave board
+ */
+struct morello_plat_info {
+ bool multichip_mode;
+ uint8_t slave_count;
+ uint8_t local_ddr_size;
+ uint8_t remote_ddr_size;
+} __packed;
+
+/*
+ * BL33 image information structure stored in SDS.
+ * This structure holds the source & destination addresses and
+ * the size of the BL33 image which will be loaded by BL31.
+ */
+struct morello_bl33_info {
+ uint32_t bl33_src_addr;
+ uint32_t bl33_dst_addr;
+ uint32_t bl33_size;
+};
+
+static scmi_channel_plat_info_t morello_scmi_plat_info = {
+ .scmi_mbx_mem = MORELLO_SCMI_PAYLOAD_BASE,
+ .db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
+ .db_preserve_mask = 0xfffffffe,
+ .db_modify_mask = 0x1,
+ .ring_doorbell = &mhu_ring_doorbell
+};
+
+scmi_channel_plat_info_t *plat_css_get_scmi_info()
+{
+ return &morello_scmi_plat_info;
+}
+
+const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
+{
+ return css_scmi_override_pm_ops(ops);
+}
+
+static void copy_bl33(uint32_t src, uint32_t dst, uint32_t size)
+{
+ unsigned int i;
+
+ INFO("Copying BL33 to DDR memory...\n");
+ for (i = 0U; i < size; (i = i + 8U))
+ mmio_write_64((dst + i), mmio_read_64(src + i));
+
+ for (i = 0U; i < size; (i = i + 8U)) {
+ if (mmio_read_64(src + i) != mmio_read_64(dst + i)) {
+ ERROR("Copy failed!\n");
+ panic();
+ }
+ }
+ INFO("done\n");
+}
+
+void bl31_platform_setup(void)
+{
+ int ret;
+ struct morello_plat_info plat_info;
+ struct morello_bl33_info bl33_info;
+
+ ret = sds_init();
+ if (ret != SDS_OK) {
+ ERROR("SDS initialization failed. ret:%d\n", ret);
+ panic();
+ }
+
+ ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
+ MORELLO_SDS_PLATFORM_INFO_OFFSET,
+ &plat_info,
+ MORELLO_SDS_PLATFORM_INFO_SIZE,
+ SDS_ACCESS_MODE_NON_CACHED);
+ if (ret != SDS_OK) {
+ ERROR("Error getting platform info from SDS. ret:%d\n", ret);
+ panic();
+ }
+
+ /* Validate plat_info SDS */
+ if ((plat_info.local_ddr_size == 0U)
+ || (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY_GB)
+ || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY_GB)
+ || (plat_info.slave_count > MORELLO_MAX_SLAVE_COUNT)) {
+ ERROR("platform info SDS is corrupted\n");
+ panic();
+ }
+
+ arm_bl31_platform_setup();
+
+ ret = sds_struct_read(MORELLO_SDS_BL33_INFO_STRUCT_ID,
+ MORELLO_SDS_BL33_INFO_OFFSET,
+ &bl33_info,
+ MORELLO_SDS_BL33_INFO_SIZE,
+ SDS_ACCESS_MODE_NON_CACHED);
+ if (ret != SDS_OK) {
+ ERROR("Error getting BL33 info from SDS. ret:%d\n", ret);
+ panic();
+ }
+ copy_bl33(bl33_info.bl33_src_addr,
+ bl33_info.bl33_dst_addr,
+ bl33_info.bl33_size);
+ /*
+ * Pass platform information to BL33. This method is followed as
+ * currently there is no BL1/BL2 involved in boot flow of MORELLO.
+ * When TBBR is implemented for MORELLO, this method should be removed
+ * and platform information should be passed to BL33 using NT_FW_CONFIG
+ * passing mechanism.
+ */
+ mmio_write_32(MORELLO_PLATFORM_INFO_BASE, *(uint32_t *)&plat_info);
+}
diff --git a/plat/arm/board/morello/morello_def.h b/plat/arm/board/morello/morello_def.h
new file mode 100644
index 0000000..09db303
--- /dev/null
+++ b/plat/arm/board/morello/morello_def.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MORELLO_DEF_H
+#define MORELLO_DEF_H
+
+/* Non-secure SRAM MMU mapping */
+#define MORELLO_NS_SRAM_BASE UL(0x06000000)
+#define MORELLO_NS_SRAM_SIZE UL(0x00010000)
+#define MORELLO_MAP_NS_SRAM MAP_REGION_FLAT( \
+ MORELLO_NS_SRAM_BASE, \
+ MORELLO_NS_SRAM_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+/* SDS Platform information defines */
+#define MORELLO_SDS_PLATFORM_INFO_STRUCT_ID U(8)
+#define MORELLO_SDS_PLATFORM_INFO_OFFSET U(0)
+#define MORELLO_SDS_PLATFORM_INFO_SIZE U(4)
+#define MORELLO_MAX_DDR_CAPACITY_GB U(64)
+#define MORELLO_MAX_SLAVE_COUNT U(16)
+
+/* SDS BL33 image information defines */
+#define MORELLO_SDS_BL33_INFO_STRUCT_ID U(9)
+#define MORELLO_SDS_BL33_INFO_OFFSET U(0)
+#define MORELLO_SDS_BL33_INFO_SIZE U(12)
+
+/* Base address of non-secure SRAM where Platform information will be filled */
+#define MORELLO_PLATFORM_INFO_BASE UL(0x06008000)
+
+#endif /* MORELLO_DEF_H */
diff --git a/plat/arm/board/morello/morello_interconnect.c b/plat/arm/board/morello/morello_interconnect.c
new file mode 100644
index 0000000..d941bfe
--- /dev/null
+++ b/plat/arm/board/morello/morello_interconnect.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/*
+ * For MORELLO which supports FCM (with automatic interconnect enter/exit),
+ * we should not do anything in these interface functions.
+ * They are used to override the weak functions in cci drivers.
+ */
+
+/******************************************************************************
+ * Helper function to initialize ARM interconnect driver.
+ *****************************************************************************/
+void plat_arm_interconnect_init(void)
+{
+}
+
+/******************************************************************************
+ * Helper function to place current master into coherency
+ *****************************************************************************/
+void plat_arm_interconnect_enter_coherency(void)
+{
+}
+
+/******************************************************************************
+ * Helper function to remove current master from coherency
+ *****************************************************************************/
+void plat_arm_interconnect_exit_coherency(void)
+{
+}
diff --git a/plat/arm/board/morello/morello_plat.c b/plat/arm/board/morello/morello_plat.c
new file mode 100644
index 0000000..3830687
--- /dev/null
+++ b/plat/arm/board/morello/morello_plat.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/arm/common/plat_arm.h>
+
+#include "morello_def.h"
+
+/*
+ * Table of regions to map using the MMU.
+ * Replace or extend the below regions as required
+ */
+
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ MORELLO_MAP_DEVICE,
+ MORELLO_MAP_NS_SRAM,
+ ARM_MAP_DRAM1,
+ {0}
+};
diff --git a/plat/arm/board/morello/morello_security.c b/plat/arm/board/morello/morello_security.c
new file mode 100644
index 0000000..a388a80
--- /dev/null
+++ b/plat/arm/board/morello/morello_security.c
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * TZC programming is currently not done.
+ */
+void plat_arm_security_setup(void)
+{
+}
diff --git a/plat/arm/board/morello/morello_topology.c b/plat/arm/board/morello/morello_topology.c
new file mode 100644
index 0000000..ef2f753
--- /dev/null
+++ b/plat/arm/board/morello/morello_topology.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/cassert.h>
+#include <plat/arm/common/plat_arm.h>
+
+/* Compile time assertion to ensure the core count is 4 */
+CASSERT(PLATFORM_CORE_COUNT == 4U, assert_invalid_platform_core_count);
+
+/* Topology */
+typedef struct morello_topology {
+ const unsigned char *power_tree;
+ unsigned int plat_cluster_core_count;
+} morello_topology_t;
+
+/*
+ * The power domain tree descriptor. The cluster power domains are
+ * arranged so that when the PSCI generic code creates the power domain tree,
+ * the indices of the CPU power domain nodes it allocates match the linear
+ * indices returned by plat_core_pos_by_mpidr().
+ */
+const unsigned char morello_pd_tree_desc[] = {
+ PLAT_MORELLO_CHIP_COUNT,
+ PLAT_ARM_CLUSTER_COUNT,
+ MORELLO_MAX_CPUS_PER_CLUSTER,
+ MORELLO_MAX_CPUS_PER_CLUSTER,
+};
+
+/* Topology configuration for morello */
+const morello_topology_t morello_topology = {
+ .power_tree = morello_pd_tree_desc,
+ .plat_cluster_core_count = MORELLO_MAX_CPUS_PER_CLUSTER
+};
+
+/*******************************************************************************
+ * This function returns the topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ return morello_topology.power_tree;
+}
+
+/*******************************************************************************
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ ******************************************************************************/
+unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
+{
+ return morello_topology.plat_cluster_core_count;
+}
+
+/*******************************************************************************
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ ******************************************************************************/
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[PLATFORM_CORE_COUNT] = {
+ 0, 1, 2, 3};
diff --git a/plat/arm/board/morello/platform.mk b/plat/arm/board/morello/platform.mk
new file mode 100644
index 0000000..f62cd67
--- /dev/null
+++ b/plat/arm/board/morello/platform.mk
@@ -0,0 +1,66 @@
+#
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+MORELLO_BASE := plat/arm/board/morello
+
+INTERCONNECT_SOURCES := ${MORELLO_BASE}/morello_interconnect.c
+
+PLAT_INCLUDES := -I${MORELLO_BASE}/include
+
+MORELLO_CPU_SOURCES := lib/cpus/aarch64/rainier.S
+
+MORELLO_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
+ drivers/arm/gic/v3/gicv3_main.c \
+ drivers/arm/gic/v3/gicv3_helpers.c \
+ plat/common/plat_gicv3.c \
+ plat/arm/common/arm_gicv3.c \
+ drivers/arm/gic/v3/gic600.c
+
+PLAT_BL_COMMON_SOURCES := ${MORELLO_BASE}/morello_plat.c \
+ ${MORELLO_BASE}/aarch64/morello_helper.S
+
+BL31_SOURCES := ${MORELLO_CPU_SOURCES} \
+ ${INTERCONNECT_SOURCES} \
+ ${MORELLO_GIC_SOURCES} \
+ ${MORELLO_BASE}/morello_bl31_setup.c \
+ ${MORELLO_BASE}/morello_topology.c \
+ ${MORELLO_BASE}/morello_security.c \
+ drivers/arm/css/sds/sds.c
+
+FDT_SOURCES += fdts/morello-fvp.dts
+
+# TF-A not required to load the SCP Images
+override CSS_LOAD_SCP_IMAGES := 0
+
+# BL1/BL2 Image not a part of the capsule Image for morello
+override NEED_BL1 := no
+override NEED_BL2 := no
+override NEED_BL2U := no
+
+#TF-A for morello starts from BL31
+override RESET_TO_BL31 := 1
+
+# 32 bit mode not supported
+override CTX_INCLUDE_AARCH32_REGS := 0
+
+override ARM_PLAT_MT := 1
+
+# Select SCMI/SDS drivers instead of SCPI/BOM driver for communicating with the
+# SCP during power management operations and for SCP RAM Firmware transfer.
+CSS_USE_SCMI_SDS_DRIVER := 1
+
+# System coherency is managed in hardware
+HW_ASSISTED_COHERENCY := 1
+
+# When building for systems with hardware-assisted coherency, there's no need to
+# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
+USE_COHERENT_MEM := 0
+
+include plat/arm/common/arm_common.mk
+include plat/arm/css/common/css_common.mk
+include plat/arm/board/common/board_common.mk
+
+override ERRATA_N1_1542419 := 1
diff --git a/plat/arm/board/tc0/include/platform_def.h b/plat/arm/board/tc0/include/platform_def.h
index a8d471e..075c403 100644
--- a/plat/arm/board/tc0/include/platform_def.h
+++ b/plat/arm/board/tc0/include/platform_def.h
@@ -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
*/
@@ -191,4 +191,19 @@
*/
#define PLAT_CSS_MAX_SCP_BL2U_SIZE 0x20000
+/* TZC Related Constants */
+#define PLAT_ARM_TZC_BASE UL(0x25000000)
+#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT(0)
+
+#define TZC400_OFFSET UL(0x1000000)
+#define TZC400_COUNT 4
+
+#define TZC400_BASE(n) (PLAT_ARM_TZC_BASE + \
+ (n * TZC400_OFFSET))
+
+#define TZC_NSAID_DEFAULT U(0)
+
+#define PLAT_ARM_TZC_NS_DEV_ACCESS \
+ (TZC_REGION_ACCESS_RDWR(TZC_NSAID_DEFAULT))
+
#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/tc0/platform.mk b/plat/arm/board/tc0/platform.mk
index 903fabf..05d691e 100644
--- a/plat/arm/board/tc0/platform.mk
+++ b/plat/arm/board/tc0/platform.mk
@@ -1,4 +1,4 @@
-# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2020, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -61,6 +61,8 @@
${TC0_BASE}/tc0_err.c \
${TC0_BASE}/tc0_trusted_boot.c \
lib/utils/mem_region.c \
+ drivers/arm/tzc/tzc400.c \
+ plat/arm/common/arm_tzc400.c \
plat/arm/common/arm_nor_psci_mem_protect.c
BL31_SOURCES += ${INTERCONNECT_SOURCES} \
diff --git a/plat/arm/board/tc0/tc0_security.c b/plat/arm/board/tc0/tc0_security.c
index 6aa38c8..5f1cb11 100644
--- a/plat/arm/board/tc0/tc0_security.c
+++ b/plat/arm/board/tc0/tc0_security.c
@@ -1,12 +1,23 @@
/*
- * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <plat/arm/common/plat_arm.h>
#include <platform_def.h>
+static const arm_tzc_regions_info_t tzc_regions[] = {
+ ARM_TZC_REGIONS_DEF,
+ {}
+};
+
/* Initialize the secure environment */
void plat_arm_security_setup(void)
{
+ unsigned int i;
+
+ for (i = 0U; i < TZC400_COUNT; i++) {
+ arm_tzc400_setup(TZC400_BASE(i), tzc_regions);
+ }
}
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 1832c65..74afc53 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -121,6 +121,12 @@
ENABLE_PSCI_STAT := 1
ENABLE_PMF := 1
+# Override the standard libc with optimised libc_asm
+OVERRIDE_LIBC := 1
+ifeq (${OVERRIDE_LIBC},1)
+ include lib/libc/libc_asm.mk
+endif
+
# On ARM platforms, separate the code and read-only data sections to allow
# mapping the former as executable and the latter as execute-never.
SEPARATE_CODE_AND_RODATA := 1
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index 14cdb7e..159084f 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -39,7 +39,7 @@
# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
# else
# define PLAT_ARM_MMAP_ENTRIES (5 + ((CSS_SGI_CHIP_COUNT - 1) * 3))
-# define MAX_XLAT_TABLES (5 + ((CSS_SGI_CHIP_COUNT - 1) * 3))
+# define MAX_XLAT_TABLES (6 + ((CSS_SGI_CHIP_COUNT - 1) * 3))
# endif
#elif defined(IMAGE_BL32)
# define PLAT_ARM_MMAP_ENTRIES 8
diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c
index a2117f6..39eb89e 100644
--- a/plat/arm/css/sgi/sgi_plat.c
+++ b/plat/arm/css/sgi/sgi_plat.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -43,6 +43,9 @@
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
SGI_MAP_FLASH0_RO,
+#ifdef PLAT_ARM_MEM_PROT_ADDR
+ ARM_V2M_MAP_MEM_PROTECT,
+#endif
CSS_SGI_MAP_DEVICE,
SOC_CSS_MAP_DEVICE,
ARM_MAP_NS_DRAM1,
@@ -63,6 +66,9 @@
ARM_MAP_SHARED_RAM,
V2M_MAP_IOFPGA,
CSS_SGI_MAP_DEVICE,
+#ifdef PLAT_ARM_MEM_PROT_ADDR
+ ARM_V2M_MAP_MEM_PROTECT,
+#endif
SOC_CSS_MAP_DEVICE,
#if SPM_MM
ARM_SPM_BUF_EL3_MMAP,
diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S
index bfcd991..407eb39 100644
--- a/plat/st/stm32mp1/stm32mp1_helper.S
+++ b/plat/st/stm32mp1/stm32mp1_helper.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,7 +12,6 @@
#include <drivers/st/stm32_gpio.h>
#define GPIO_TX_SHIFT (DEBUG_UART_TX_GPIO_PORT << 1)
-#define GPIO_TX_ALT_SHIFT ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)
.globl platform_mem_init
.globl plat_report_exception
@@ -32,7 +31,48 @@
endfunc platform_mem_init
func plat_report_exception
+#if DEBUG
+ mov r8, lr
+
+ /* Test if an abort occurred */
+ cmp r0, #MODE32_abt
+ bne undef_inst_lbl
+ ldr r4, =abort_str
+ bl asm_print_str
+ mrs r4, lr_abt
+ sub r4, r4, #4
+ b print_exception_info
+
+undef_inst_lbl:
+ /* Test for an undefined instruction */
+ cmp r0, #MODE32_und
+ bne other_exception_lbl
+ ldr r4, =undefined_str
+ bl asm_print_str
+ mrs r4, lr_und
+ b print_exception_info
+
+other_exception_lbl:
+ /* Other exceptions */
+ mov r9, r0
+ ldr r4, =exception_start_str
+ bl asm_print_str
+ mov r4, r9
+ bl asm_print_hex
+ ldr r4, =exception_end_str
+ bl asm_print_str
+ mov r4, r6
+
+print_exception_info:
+ bl asm_print_hex
+
+ ldr r4, =end_error_str
+ bl asm_print_str
+
+ bx r8
+#else
bx lr
+#endif
endfunc plat_report_exception
func plat_reset_handler
@@ -129,10 +169,19 @@
bic r2, r2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT)
str r2, [r1, #GPIO_PUPD_OFFSET]
/* Set alternate */
+#if DEBUG_UART_TX_GPIO_PORT >= GPIO_ALT_LOWER_LIMIT
ldr r2, [r1, #GPIO_AFRH_OFFSET]
- bic r2, r2, #(GPIO_ALTERNATE_MASK << GPIO_TX_ALT_SHIFT)
- orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << GPIO_TX_ALT_SHIFT)
+ bic r2, r2, #(GPIO_ALTERNATE_MASK << \
+ ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2))
+ orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << \
+ ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2))
str r2, [r1, #GPIO_AFRH_OFFSET]
+#else
+ ldr r2, [r1, #GPIO_AFRL_OFFSET]
+ bic r2, r2, #(GPIO_ALTERNATE_MASK << (DEBUG_UART_TX_GPIO_PORT << 2))
+ orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << (DEBUG_UART_TX_GPIO_PORT << 2))
+ str r2, [r1, #GPIO_AFRL_OFFSET]
+#endif
/* Enable UART clock, with its source */
ldr r1, =(RCC_BASE + DEBUG_UART_TX_CLKSRC_REG)
mov r2, #DEBUG_UART_TX_CLKSRC
@@ -174,3 +223,34 @@
ldr r1, =STM32MP_DEBUG_USART_BASE
b console_stm32_core_putc
endfunc plat_crash_console_putc
+
+ /* ----------------------------------------------------------
+ * void plat_panic_handler(void) __dead2;
+ * Report exception + endless loop.
+ *
+ * r6 holds the address where the fault occurred.
+ * Filling lr with this value allows debuggers to reconstruct
+ * the backtrace.
+ * ----------------------------------------------------------
+ */
+func plat_panic_handler
+ mrs r0, cpsr
+ and r0, #MODE32_MASK
+ bl plat_report_exception
+ mov lr, r6
+ b .
+endfunc plat_panic_handler
+
+#if DEBUG
+.section .rodata.rev_err_str, "aS"
+abort_str:
+ .asciz "\nAbort at: 0x"
+undefined_str:
+ .asciz "\nUndefined instruction at: 0x"
+exception_start_str:
+ .asciz "\nException mode=0x"
+exception_end_str:
+ .asciz " at: 0x"
+end_error_str:
+ .asciz "\n\r"
+#endif