Merge changes I23f600b5,Icf9ffdf2,Iee7a51d1,I99afc312,I4bf8e8c0, ... into integration
* changes:
plat/marvell/armada: cleanup MSS SRAM if used for copy
plat/marvell: cn913x: allow CP1/CP2 mapping at BLE stage
plat/marvell/armada/common/mss: use MSS SRAM in secure mode
include/drivers/marvell/mochi: add detection of secure mode
plat/marvell: fix SPD handling in dram port
marvell: drivers: move XOR0/1 DIOB from WIN 0 to 1
drivers/marvell/mochi: add support for cn913x in PCIe EP mode
drivers/marvell/mochi: add missing stream IDs configurations
plat/marvell/armada/a8k: support HW RNG by SMC
drivers/rambus: add TRNG-IP-76 driver
diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk
index afd7ae1..8b5eddd 100644
--- a/bl32/sp_min/sp_min.mk
+++ b/bl32/sp_min/sp_min.mk
@@ -37,6 +37,11 @@
bl32/sp_min/wa_cve_2017_5715_icache_inv.S
endif
+ifeq (${TRNG_SUPPORT},1)
+BL32_SOURCES += services/std_svc/trng/trng_main.c \
+ services/std_svc/trng/trng_entropy_pool.c
+endif
+
BL32_LINKERFILE := bl32/sp_min/sp_min.ld.S
# Include the platform-specific SP_MIN Makefile
diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst
index f597460..0ef2923 100644
--- a/docs/plat/stm32mp1.rst
+++ b/docs/plat/stm32mp1.rst
@@ -95,6 +95,7 @@
------------------
Boot media(s) supported by BL2 must be specified in the build command.
Available storage medias are:
+
- ``STM32MP_SDMMC``
- ``STM32MP_EMMC``
- ``STM32MP_RAW_NAND``
@@ -112,6 +113,7 @@
make DEVICE_TREE=stm32mp157c-ev1 all
To build TF-A with OP-TEE support for all bootable devices:
+
.. code:: bash
make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=optee STM32MP_SDMMC=1 STM32MP_EMMC=1 STM32MP_RAW_NAND=1 STM32MP_SPI_NAND=1 STM32MP_SPI_NOR=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb
diff --git a/drivers/arm/tzc/tzc400.c b/drivers/arm/tzc/tzc400.c
index 95a5e7f..9798ed4 100644
--- a/drivers/arm/tzc/tzc400.c
+++ b/drivers/arm/tzc/tzc400.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -162,7 +162,9 @@
/*
* `tzc400_configure_region` is used to program regions into the TrustZone
* controller. A region can be associated with more than one filter. The
- * associated filters are passed in as a bitmap (bit0 = filter0).
+ * associated filters are passed in as a bitmap (bit0 = filter0), except that
+ * the value TZC_400_REGION_ATTR_FILTER_BIT_ALL selects all filters, based on
+ * the value of tzc400.num_filters.
* NOTE:
* Region 0 is special; it is preferable to use tzc400_configure_region0
* for this region (see comment for that function).
@@ -176,6 +178,11 @@
{
assert(tzc400.base != 0U);
+ /* Adjust filter mask by real filter number */
+ if (filters == TZC_400_REGION_ATTR_FILTER_BIT_ALL) {
+ filters = (1U << tzc400.num_filters) - 1U;
+ }
+
/* Do range checks on filters and regions. */
assert(((filters >> tzc400.num_filters) == 0U) &&
(region < tzc400.num_regions));
diff --git a/drivers/marvell/uart/a3700_console.S b/drivers/marvell/uart/a3700_console.S
index 58dad7a..b377321 100644
--- a/drivers/marvell/uart/a3700_console.S
+++ b/drivers/marvell/uart/a3700_console.S
@@ -60,10 +60,10 @@
str w3, [x0, #UART_POSSR_REG]
/*
- * Wait for the TX (THR and TSR) to be empty. If wait for 20ms, the TX FIFO is
+ * Wait for the TX (THR and TSR) to be empty. If wait for 3ms, the TX FIFO is
* still not empty, TX FIFO will reset by all means.
*/
- mov w1, #20 /* max time out 20ms */
+ mov w1, #30 /* max time out 30 * 100 us */
2:
/* Check whether TX (THR and TSR) is empty */
ldr w3, [x0, #UART_STATUS_REG]
@@ -72,13 +72,13 @@
b.ne 4f
/* Delay */
- mov w2, #30000
+ mov w2, #60000 /* 60000 cycles of below 3 instructions on 1200 MHz CPU ~~ 100 us */
3:
sub w2, w2, #1
cmp w2, #0
b.ne 3b
- /* Check whether 10ms is waited */
+ /* Check whether wait timeout expired */
sub w1, w1, #1
cmp w1, #0
b.ne 2b
diff --git a/drivers/st/fmc/stm32_fmc2_nand.c b/drivers/st/fmc/stm32_fmc2_nand.c
index a58a243..453069b 100644
--- a/drivers/st/fmc/stm32_fmc2_nand.c
+++ b/drivers/st/fmc/stm32_fmc2_nand.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/
@@ -200,9 +200,6 @@
if ((twait < NAND_TCS_MIN) && (tset_mem < (NAND_TCS_MIN - twait))) {
tset_mem = NAND_TCS_MIN - twait;
}
- if ((twait < NAND_TALS_MIN) && (tset_mem < (NAND_TALS_MIN - twait))) {
- tset_mem = NAND_TALS_MIN - twait;
- }
if ((twait > thiz) && ((twait - thiz) < NAND_TDS_MIN) &&
(tset_mem < (NAND_TDS_MIN - (twait - thiz)))) {
tset_mem = NAND_TDS_MIN - (twait - thiz);
@@ -244,12 +241,6 @@
if ((twait < NAND_TCS_MIN) && (tset_att < (NAND_TCS_MIN - twait))) {
tset_att = NAND_TCS_MIN - twait;
}
- if ((twait < NAND_TCLS_MIN) && (tset_att < (NAND_TCLS_MIN - twait))) {
- tset_att = NAND_TCLS_MIN - twait;
- }
- if ((twait < NAND_TALS_MIN) && (tset_att < (NAND_TALS_MIN - twait))) {
- tset_att = NAND_TALS_MIN - twait;
- }
if ((thold_mem < NAND_TRHW_MIN) &&
(tset_att < (NAND_TRHW_MIN - thold_mem))) {
tset_att = NAND_TRHW_MIN - thold_mem;
diff --git a/include/drivers/arm/tzc400.h b/include/drivers/arm/tzc400.h
index 32aeb03..cf2e82b 100644
--- a/include/drivers/arm/tzc400.h
+++ b/include/drivers/arm/tzc400.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -80,11 +80,8 @@
/* Filter enable bits in a TZC */
#define TZC_400_REGION_ATTR_F_EN_MASK U(0xf)
-#define TZC_400_REGION_ATTR_FILTER_BIT(x) \
- ((U(1) << (x)) << TZC_REGION_ATTR_F_EN_SHIFT)
-#define TZC_400_REGION_ATTR_FILTER_BIT_ALL \
- (TZC_400_REGION_ATTR_F_EN_MASK << \
- TZC_REGION_ATTR_F_EN_SHIFT)
+#define TZC_400_REGION_ATTR_FILTER_BIT(x) (U(1) << (x))
+#define TZC_400_REGION_ATTR_FILTER_BIT_ALL TZC_400_REGION_ATTR_F_EN_MASK
/*
* All TZC region configuration registers are placed one after another. It
diff --git a/include/lib/libc/stdlib.h b/include/lib/libc/stdlib.h
index 24e7bae..4641e56 100644
--- a/include/lib/libc/stdlib.h
+++ b/include/lib/libc/stdlib.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2017 Roberto E. Vargas Caballero
+ * Copyright (c) 2012-2021 Roberto E. Vargas Caballero
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,8 +18,15 @@
#define _ATEXIT_MAX 1
+#define isspace(x) (((x) == ' ') || ((x) == '\r') || ((x) == '\n') || \
+ ((x) == '\t') || ((x) == '\b'))
+
extern void abort(void);
extern int atexit(void (*func)(void));
extern void exit(int status);
+long strtol(const char *nptr, char **endptr, int base);
+unsigned long strtoul(const char *nptr, char **endptr, int base);
+long long strtoll(const char *nptr, char **endptr, int base);
+unsigned long long strtoull(const char *nptr, char **endptr, int base);
#endif /* STDLIB_H */
diff --git a/lib/cpus/aarch32/cpu_helpers.S b/lib/cpus/aarch32/cpu_helpers.S
index 9b5d787..6ed800c 100644
--- a/lib/cpus/aarch32/cpu_helpers.S
+++ b/lib/cpus/aarch32/cpu_helpers.S
@@ -78,6 +78,10 @@
mov r1, #CPU_PWR_DWN_OPS
add r1, r1, r2, lsl #2
ldr r1, [r0, r1]
+#if ENABLE_ASSERTIONS
+ cmp r1, #0
+ ASM_ASSERT(ne)
+#endif
bx r1
endfunc prepare_cpu_pwr_dwn
@@ -146,6 +150,10 @@
/* Subtract the increment and offset to get the cpu-ops pointer */
sub r0, r4, #(CPU_OPS_SIZE + CPU_MIDR)
+#if ENABLE_ASSERTIONS
+ cmp r0, #0
+ ASM_ASSERT(ne)
+#endif
error_exit:
bx lr
endfunc get_cpu_ops_ptr
@@ -224,7 +232,15 @@
* function. If it's non-NULL, jump to the function in turn.
*/
bl _cpu_data
+#if ENABLE_ASSERTIONS
+ cmp r0, #0
+ ASM_ASSERT(ne)
+#endif
ldr r1, [r0, #CPU_DATA_CPU_OPS_PTR]
+#if ENABLE_ASSERTIONS
+ cmp r1, #0
+ ASM_ASSERT(ne)
+#endif
ldr r0, [r1, #CPU_ERRATA_FUNC]
cmp r0, #0
beq 1f
diff --git a/lib/libc/libc.mk b/lib/libc/libc.mk
index 93d30d0..b75d09c 100644
--- a/lib/libc/libc.mk
+++ b/lib/libc/libc.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -20,11 +20,17 @@
snprintf.c \
strchr.c \
strcmp.c \
+ strlcat.c \
strlcpy.c \
strlen.c \
strncmp.c \
strnlen.c \
- strrchr.c)
+ strrchr.c \
+ strtok.c \
+ strtoul.c \
+ strtoll.c \
+ strtoull.c \
+ strtol.c)
ifeq (${ARCH},aarch64)
LIBC_SRCS += $(addprefix lib/libc/aarch64/, \
diff --git a/lib/libc/libc_asm.mk b/lib/libc/libc_asm.mk
index 6416a3c..2f27265 100644
--- a/lib/libc/libc_asm.mk
+++ b/lib/libc/libc_asm.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2020, Arm Limited. All rights reserved.
+# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -19,11 +19,17 @@
snprintf.c \
strchr.c \
strcmp.c \
+ strlcat.c \
strlcpy.c \
strlen.c \
strncmp.c \
strnlen.c \
- strrchr.c)
+ strrchr.c \
+ strtok.c \
+ strtoul.c \
+ strtoll.c \
+ strtoull.c \
+ strtol.c)
ifeq (${ARCH},aarch64)
LIBC_SRCS += $(addprefix lib/libc/aarch64/, \
diff --git a/lib/libc/memset.c b/lib/libc/memset.c
index f9dd4c5..17f798c 100644
--- a/lib/libc/memset.c
+++ b/lib/libc/memset.c
@@ -10,19 +10,20 @@
void *memset(void *dst, int val, size_t count)
{
- char *ptr = dst;
+ uint8_t *ptr = dst;
uint64_t *ptr64;
uint64_t fill = (unsigned char)val;
/* Simplify code below by making sure we write at least one byte. */
- if (count == 0) {
+ if (count == 0U) {
return dst;
}
/* Handle the first part, until the pointer becomes 64-bit aligned. */
- while (((uintptr_t)ptr & 7)) {
- *ptr++ = val;
- if (--count == 0) {
+ while (((uintptr_t)ptr & 7U) != 0U) {
+ *ptr = (uint8_t)val;
+ ptr++;
+ if (--count == 0U) {
return dst;
}
}
@@ -33,15 +34,17 @@
fill |= fill << 32;
/* Use 64-bit writes for as long as possible. */
- ptr64 = (void *)ptr;
- for (; count >= 8; count -= 8) {
- *ptr64++ = fill;
+ ptr64 = (uint64_t *)ptr;
+ for (; count >= 8U; count -= 8) {
+ *ptr64 = fill;
+ ptr64++;
}
/* Handle the remaining part byte-per-byte. */
- ptr = (void *)ptr64;
- while (count--) {
- *ptr++ = val;
+ ptr = (uint8_t *)ptr64;
+ while (count-- > 0U) {
+ *ptr = (uint8_t)val;
+ ptr++;
}
return dst;
diff --git a/lib/libc/strtol.c b/lib/libc/strtol.c
new file mode 100644
index 0000000..deb862c
--- /dev/null
+++ b/lib/libc/strtol.c
@@ -0,0 +1,133 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 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 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 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 <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+/*
+ * Convert a string to a long integer.
+ *
+ * Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+long strtol(const char *nptr, char **endptr, int base)
+{
+ const char *s;
+ unsigned long acc;
+ char c;
+ unsigned long cutoff;
+ int neg, any, cutlim;
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ s = nptr;
+ do {
+ c = *s++;
+ } while (isspace((unsigned char)c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X') &&
+ ((s[1] >= '0' && s[1] <= '9') ||
+ (s[1] >= 'A' && s[1] <= 'F') ||
+ (s[1] >= 'a' && s[1] <= 'f'))) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ acc = any = 0;
+
+ /*
+ * Compute the cutoff value between legal numbers and illegal
+ * numbers. That is the largest legal value, divided by the
+ * base. An input number that is greater than this value, if
+ * followed by a legal input character, is too big. One that
+ * is equal to this value may be valid or not; the limit
+ * between valid and invalid numbers is then based on the last
+ * digit. For instance, if the range for longs is
+ * [-2147483648..2147483647] and the input base is 10,
+ * cutoff will be set to 214748364 and cutlim to either
+ * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+ * a value > 214748364, or equal but the next digit is > 7 (or 8),
+ * the number is too big, and we will return a range error.
+ *
+ * Set 'any' if any `digits' consumed; make it negative to indicate
+ * overflow.
+ */
+ cutoff = neg ? (unsigned long)-(LONG_MIN + LONG_MAX) + LONG_MAX
+ : LONG_MAX;
+ cutlim = cutoff % base;
+ cutoff /= base;
+ for ( ; ; c = *s++) {
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'A' && c <= 'Z')
+ c -= 'A' - 10;
+ else if (c >= 'a' && c <= 'z')
+ c -= 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = neg ? LONG_MIN : LONG_MAX;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != NULL)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/lib/libc/strtoll.c b/lib/libc/strtoll.c
new file mode 100644
index 0000000..4e101e8
--- /dev/null
+++ b/lib/libc/strtoll.c
@@ -0,0 +1,134 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 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 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 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 <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+/*
+ * Convert a string to a long long integer.
+ *
+ * Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+long long strtoll(const char *nptr, char **endptr, int base)
+{
+ const char *s;
+ unsigned long long acc;
+ char c;
+ unsigned long long cutoff;
+ int neg, any, cutlim;
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ s = nptr;
+ do {
+ c = *s++;
+ } while (isspace((unsigned char)c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X') &&
+ ((s[1] >= '0' && s[1] <= '9') ||
+ (s[1] >= 'A' && s[1] <= 'F') ||
+ (s[1] >= 'a' && s[1] <= 'f'))) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ acc = any = 0;
+
+ /*
+ * Compute the cutoff value between legal numbers and illegal
+ * numbers. That is the largest legal value, divided by the
+ * base. An input number that is greater than this value, if
+ * followed by a legal input character, is too big. One that
+ * is equal to this value may be valid or not; the limit
+ * between valid and invalid numbers is then based on the last
+ * digit. For instance, if the range for quads is
+ * [-9223372036854775808..9223372036854775807] and the input base
+ * is 10, cutoff will be set to 922337203685477580 and cutlim to
+ * either 7 (neg==0) or 8 (neg==1), meaning that if we have
+ * accumulated a value > 922337203685477580, or equal but the
+ * next digit is > 7 (or 8), the number is too big, and we will
+ * return a range error.
+ *
+ * Set 'any' if any `digits' consumed; make it negative to indicate
+ * overflow.
+ */
+ cutoff = neg ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX
+ : LLONG_MAX;
+ cutlim = cutoff % base;
+ cutoff /= base;
+ for ( ; ; c = *s++) {
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'A' && c <= 'Z')
+ c -= 'A' - 10;
+ else if (c >= 'a' && c <= 'z')
+ c -= 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = neg ? LLONG_MIN : LLONG_MAX;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != NULL)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/lib/libc/strtoul.c b/lib/libc/strtoul.c
new file mode 100644
index 0000000..b42fb14
--- /dev/null
+++ b/lib/libc/strtoul.c
@@ -0,0 +1,112 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 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 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 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 <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+/*
+ * Convert a string to an unsigned long integer.
+ *
+ * Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+unsigned long strtoul(const char *nptr, char **endptr, int base)
+{
+ const char *s;
+ unsigned long acc;
+ char c;
+ unsigned long cutoff;
+ int neg, any, cutlim;
+
+ /*
+ * See strtol for comments as to the logic used.
+ */
+ s = nptr;
+ do {
+ c = *s++;
+ } while (isspace((unsigned char)c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X') &&
+ ((s[1] >= '0' && s[1] <= '9') ||
+ (s[1] >= 'A' && s[1] <= 'F') ||
+ (s[1] >= 'a' && s[1] <= 'f'))) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ acc = any = 0;
+
+ cutoff = ULONG_MAX / base;
+ cutlim = ULONG_MAX % base;
+ for ( ; ; c = *s++) {
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'A' && c <= 'Z')
+ c -= 'A' - 10;
+ else if (c >= 'a' && c <= 'z')
+ c -= 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = ULONG_MAX;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != NULL)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/lib/libc/strtoull.c b/lib/libc/strtoull.c
new file mode 100644
index 0000000..2e65a43
--- /dev/null
+++ b/lib/libc/strtoull.c
@@ -0,0 +1,112 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 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 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 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 <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+/*
+ * Convert a string to an unsigned long long integer.
+ *
+ * Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+unsigned long long strtoull(const char *nptr, char **endptr, int base)
+{
+ const char *s;
+ unsigned long long acc;
+ char c;
+ unsigned long long cutoff;
+ int neg, any, cutlim;
+
+ /*
+ * See strtoq for comments as to the logic used.
+ */
+ s = nptr;
+ do {
+ c = *s++;
+ } while (isspace((unsigned char)c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X') &&
+ ((s[1] >= '0' && s[1] <= '9') ||
+ (s[1] >= 'A' && s[1] <= 'F') ||
+ (s[1] >= 'a' && s[1] <= 'f'))) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ acc = any = 0;
+
+ cutoff = ULLONG_MAX / base;
+ cutlim = ULLONG_MAX % base;
+ for ( ; ; c = *s++) {
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'A' && c <= 'Z')
+ c -= 'A' - 10;
+ else if (c >= 'a' && c <= 'z')
+ c -= 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = ULLONG_MAX;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != NULL)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk
index 901d888..da83b5e 100644
--- a/plat/allwinner/common/allwinner-common.mk
+++ b/plat/allwinner/common/allwinner-common.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -20,8 +20,6 @@
${AW_PLAT}/common/sunxi_common.c
BL31_SOURCES += drivers/allwinner/axp/common.c \
- drivers/allwinner/sunxi_msgbox.c \
- drivers/arm/css/scpi/css_scpi.c \
${GICV2_SOURCES} \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
@@ -29,12 +27,40 @@
plat/common/plat_gicv2.c \
plat/common/plat_psci_common.c \
${AW_PLAT}/common/sunxi_bl31_setup.c \
- ${AW_PLAT}/common/sunxi_cpu_ops.c \
${AW_PLAT}/common/sunxi_pm.c \
${AW_PLAT}/${PLAT}/sunxi_power.c \
${AW_PLAT}/common/sunxi_security.c \
${AW_PLAT}/common/sunxi_topology.c
+# By default, attempt to use SCPI to the ARISC management processor. If SCPI
+# is not enabled or SCP firmware is not loaded, fall back to a simpler native
+# implementation that does not support CPU or system suspend.
+#
+# If SCP firmware will always be present (or absent), the unused implementation
+# can be compiled out.
+SUNXI_PSCI_USE_NATIVE ?= 1
+SUNXI_PSCI_USE_SCPI ?= 1
+
+$(eval $(call assert_boolean,SUNXI_PSCI_USE_NATIVE))
+$(eval $(call assert_boolean,SUNXI_PSCI_USE_SCPI))
+$(eval $(call add_define,SUNXI_PSCI_USE_NATIVE))
+$(eval $(call add_define,SUNXI_PSCI_USE_SCPI))
+
+ifeq (${SUNXI_PSCI_USE_NATIVE}${SUNXI_PSCI_USE_SCPI},00)
+$(error "At least one of SCPI or native PSCI ops must be enabled")
+endif
+
+ifeq (${SUNXI_PSCI_USE_NATIVE},1)
+BL31_SOURCES += ${AW_PLAT}/common/sunxi_cpu_ops.c \
+ ${AW_PLAT}/common/sunxi_native_pm.c
+endif
+
+ifeq (${SUNXI_PSCI_USE_SCPI},1)
+BL31_SOURCES += drivers/allwinner/sunxi_msgbox.c \
+ drivers/arm/css/scpi/css_scpi.c \
+ ${AW_PLAT}/common/sunxi_scpi_pm.c
+endif
+
# The bootloader is guaranteed to only run on CPU 0 by the boot ROM.
COLD_BOOT_SINGLE_CPU := 1
diff --git a/plat/allwinner/common/include/sunxi_private.h b/plat/allwinner/common/include/sunxi_private.h
index dcf3dc9..b68d23f 100644
--- a/plat/allwinner/common/include/sunxi_private.h
+++ b/plat/allwinner/common/include/sunxi_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,13 +7,32 @@
#ifndef SUNXI_PRIVATE_H
#define SUNXI_PRIVATE_H
+#include <lib/psci/psci.h>
+
void sunxi_configure_mmu_el3(int flags);
void sunxi_cpu_on(u_register_t mpidr);
-void sunxi_cpu_off(u_register_t mpidr);
-void sunxi_disable_secondary_cpus(u_register_t primary_mpidr);
+void sunxi_cpu_power_off_others(void);
+void sunxi_cpu_power_off_self(void);
void sunxi_power_down(void);
+#if SUNXI_PSCI_USE_NATIVE
+void sunxi_set_native_psci_ops(const plat_psci_ops_t **psci_ops);
+#else
+static inline void sunxi_set_native_psci_ops(const plat_psci_ops_t **psci_ops)
+{
+}
+#endif
+#if SUNXI_PSCI_USE_SCPI
+int sunxi_set_scpi_psci_ops(const plat_psci_ops_t **psci_ops);
+#else
+static inline int sunxi_set_scpi_psci_ops(const plat_psci_ops_t **psci_ops)
+{
+ return -1;
+}
+#endif
+int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint);
+
int sunxi_pmic_setup(uint16_t socid, const void *fdt);
void sunxi_security_setup(void);
diff --git a/plat/allwinner/common/sunxi_cpu_ops.c b/plat/allwinner/common/sunxi_cpu_ops.c
index 6e29b69..cbad720 100644
--- a/plat/allwinner/common/sunxi_cpu_ops.c
+++ b/plat/allwinner/common/sunxi_cpu_ops.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -45,7 +45,8 @@
mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0x00);
}
-void sunxi_cpu_off(u_register_t mpidr)
+/* We can't turn ourself off like this, but it works for other cores. */
+static void sunxi_cpu_off(u_register_t mpidr)
{
unsigned int cluster = MPIDR_AFFLVL1_VAL(mpidr);
unsigned int core = MPIDR_AFFLVL0_VAL(mpidr);
@@ -54,23 +55,22 @@
/* Deassert DBGPWRDUP */
mmio_clrbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
+ /* Activate the core output clamps, but not for core 0. */
+ if (core != 0)
+ mmio_setbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core));
+ /* Assert CPU power-on reset */
+ mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
+ /* Remove power from the CPU */
+ sunxi_cpu_disable_power(cluster, core);
+}
- /* We can't turn ourself off like this, but it works for other cores. */
- if (read_mpidr() != mpidr) {
- /* Activate the core output clamps, but not for core 0. */
- if (core != 0)
- mmio_setbits_32(SUNXI_POWEROFF_GATING_REG(cluster),
- BIT(core));
- /* Assert CPU power-on reset */
- mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
- /* Remove power from the CPU */
- sunxi_cpu_disable_power(cluster, core);
-
- return;
- }
+void sunxi_cpu_power_off_self(void)
+{
+ u_register_t mpidr = read_mpidr();
+ unsigned int core = MPIDR_AFFLVL0_VAL(mpidr);
/* Simplifies assembly, all SoCs so far are single cluster anyway. */
- assert(cluster == 0);
+ assert(MPIDR_AFFLVL1_VAL(mpidr) == 0);
/*
* If we are supposed to turn ourself off, tell the arisc SCP
@@ -106,8 +106,9 @@
mmio_setbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
}
-void sunxi_disable_secondary_cpus(u_register_t primary_mpidr)
+void sunxi_cpu_power_off_others(void)
{
+ u_register_t self = read_mpidr();
unsigned int cluster;
unsigned int core;
@@ -116,7 +117,7 @@
u_register_t mpidr = (cluster << MPIDR_AFF1_SHIFT) |
(core << MPIDR_AFF0_SHIFT) |
BIT(31);
- if (mpidr != primary_mpidr)
+ if (mpidr != self)
sunxi_cpu_off(mpidr);
}
}
diff --git a/plat/allwinner/common/sunxi_native_pm.c b/plat/allwinner/common/sunxi_native_pm.c
new file mode 100644
index 0000000..148f50e
--- /dev/null
+++ b/plat/allwinner/common/sunxi_native_pm.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/gicv2.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+
+#include <sunxi_mmap.h>
+#include <sunxi_private.h>
+
+#define SUNXI_WDOG0_CTRL_REG (SUNXI_R_WDOG_BASE + 0x0010)
+#define SUNXI_WDOG0_CFG_REG (SUNXI_R_WDOG_BASE + 0x0014)
+#define SUNXI_WDOG0_MODE_REG (SUNXI_R_WDOG_BASE + 0x0018)
+
+static int sunxi_pwr_domain_on(u_register_t mpidr)
+{
+ sunxi_cpu_on(mpidr);
+
+ return PSCI_E_SUCCESS;
+}
+
+static void sunxi_pwr_domain_off(const psci_power_state_t *target_state)
+{
+ gicv2_cpuif_disable();
+
+ sunxi_cpu_power_off_self();
+}
+
+static void sunxi_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+ gicv2_pcpu_distif_init();
+ gicv2_cpuif_enable();
+}
+
+static void __dead2 sunxi_system_off(void)
+{
+ gicv2_cpuif_disable();
+
+ /* Attempt to power down the board (may not return) */
+ sunxi_power_down();
+
+ /* Turn off all CPUs */
+ sunxi_cpu_power_off_others();
+ sunxi_cpu_power_off_self();
+ psci_power_down_wfi();
+}
+
+static void __dead2 sunxi_system_reset(void)
+{
+ gicv2_cpuif_disable();
+
+ /* Reset the whole system when the watchdog times out */
+ mmio_write_32(SUNXI_WDOG0_CFG_REG, 1);
+ /* Enable the watchdog with the shortest timeout (0.5 seconds) */
+ mmio_write_32(SUNXI_WDOG0_MODE_REG, (0 << 4) | 1);
+ /* Wait for twice the watchdog timeout before panicking */
+ mdelay(1000);
+
+ ERROR("PSCI: System reset failed\n");
+ panic();
+}
+
+static const plat_psci_ops_t sunxi_native_psci_ops = {
+ .pwr_domain_on = sunxi_pwr_domain_on,
+ .pwr_domain_off = sunxi_pwr_domain_off,
+ .pwr_domain_on_finish = sunxi_pwr_domain_on_finish,
+ .system_off = sunxi_system_off,
+ .system_reset = sunxi_system_reset,
+ .validate_ns_entrypoint = sunxi_validate_ns_entrypoint,
+};
+
+void sunxi_set_native_psci_ops(const plat_psci_ops_t **psci_ops)
+{
+ *psci_ops = &sunxi_native_psci_ops;
+}
diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c
index aa80c52..eb1b7e7 100644
--- a/plat/allwinner/common/sunxi_pm.c
+++ b/plat/allwinner/common/sunxi_pm.c
@@ -8,203 +8,14 @@
#include <platform_def.h>
-#include <arch_helpers.h>
#include <common/debug.h>
-#include <drivers/arm/css/css_scpi.h>
-#include <drivers/arm/gicv2.h>
-#include <drivers/delay_timer.h>
#include <lib/mmio.h>
#include <lib/psci/psci.h>
-#include <plat/common/platform.h>
#include <sunxi_cpucfg.h>
-#include <sunxi_def.h>
-#include <sunxi_mmap.h>
#include <sunxi_private.h>
-#define SUNXI_WDOG0_CTRL_REG (SUNXI_R_WDOG_BASE + 0x0010)
-#define SUNXI_WDOG0_CFG_REG (SUNXI_R_WDOG_BASE + 0x0014)
-#define SUNXI_WDOG0_MODE_REG (SUNXI_R_WDOG_BASE + 0x0018)
-
-#define CPU_PWR_LVL MPIDR_AFFLVL0
-#define CLUSTER_PWR_LVL MPIDR_AFFLVL1
-#define SYSTEM_PWR_LVL MPIDR_AFFLVL2
-
-#define CPU_PWR_STATE(state) \
- ((state)->pwr_domain_state[CPU_PWR_LVL])
-#define CLUSTER_PWR_STATE(state) \
- ((state)->pwr_domain_state[CLUSTER_PWR_LVL])
-#define SYSTEM_PWR_STATE(state) \
- ((state)->pwr_domain_state[SYSTEM_PWR_LVL])
-
-/*
- * The addresses for the SCP exception vectors are defined in the or1k
- * architecture specification.
- */
-#define OR1K_VEC_FIRST 0x01
-#define OR1K_VEC_LAST 0x0e
-#define OR1K_VEC_ADDR(n) (0x100 * (n))
-
-/*
- * This magic value is the little-endian representation of the or1k
- * instruction "l.mfspr r2, r0, 0x12", which is guaranteed to be the
- * first instruction in the SCP firmware.
- */
-#define SCP_FIRMWARE_MAGIC 0xb4400012
-
-static bool scpi_available;
-
-static inline scpi_power_state_t scpi_map_state(plat_local_state_t psci_state)
-{
- if (is_local_state_run(psci_state))
- return scpi_power_on;
- if (is_local_state_retn(psci_state))
- return scpi_power_retention;
- return scpi_power_off;
-}
-
-static void sunxi_cpu_standby(plat_local_state_t cpu_state)
-{
- u_register_t scr = read_scr_el3();
-
- assert(is_local_state_retn(cpu_state));
-
- write_scr_el3(scr | SCR_IRQ_BIT);
- wfi();
- write_scr_el3(scr);
-}
-
-static int sunxi_pwr_domain_on(u_register_t mpidr)
-{
- if (scpi_available) {
- scpi_set_css_power_state(mpidr,
- scpi_power_on,
- scpi_power_on,
- scpi_power_on);
- } else {
- sunxi_cpu_on(mpidr);
- }
-
- return PSCI_E_SUCCESS;
-}
-
-static void sunxi_pwr_domain_off(const psci_power_state_t *target_state)
-{
- plat_local_state_t cpu_pwr_state = CPU_PWR_STATE(target_state);
- plat_local_state_t cluster_pwr_state = CLUSTER_PWR_STATE(target_state);
- plat_local_state_t system_pwr_state = SYSTEM_PWR_STATE(target_state);
-
- if (is_local_state_off(cpu_pwr_state))
- gicv2_cpuif_disable();
-
- if (scpi_available) {
- scpi_set_css_power_state(read_mpidr(),
- scpi_map_state(cpu_pwr_state),
- scpi_map_state(cluster_pwr_state),
- scpi_map_state(system_pwr_state));
- }
-}
-
-static void __dead2 sunxi_pwr_down_wfi(const psci_power_state_t *target_state)
-{
- sunxi_cpu_off(read_mpidr());
-
- while (1)
- wfi();
-}
-
-static void sunxi_pwr_domain_on_finish(const psci_power_state_t *target_state)
-{
- if (is_local_state_off(SYSTEM_PWR_STATE(target_state)))
- gicv2_distif_init();
- if (is_local_state_off(CPU_PWR_STATE(target_state))) {
- gicv2_pcpu_distif_init();
- gicv2_cpuif_enable();
- }
-}
-
-static void __dead2 sunxi_system_off(void)
-{
- gicv2_cpuif_disable();
-
- if (scpi_available) {
- /* Send the power down request to the SCP */
- uint32_t ret = scpi_sys_power_state(scpi_system_shutdown);
-
- if (ret != SCP_OK)
- ERROR("PSCI: SCPI %s failed: %d\n", "shutdown", ret);
- }
-
- /* Turn off all secondary CPUs */
- sunxi_disable_secondary_cpus(read_mpidr());
-
- sunxi_power_down();
-
- udelay(1000);
- ERROR("PSCI: Cannot turn off system, halting\n");
- wfi();
- panic();
-}
-
-static void __dead2 sunxi_system_reset(void)
-{
- gicv2_cpuif_disable();
-
- if (scpi_available) {
- /* Send the system reset request to the SCP */
- uint32_t ret = scpi_sys_power_state(scpi_system_reboot);
-
- if (ret != SCP_OK)
- ERROR("PSCI: SCPI %s failed: %d\n", "reboot", ret);
- }
-
- /* Reset the whole system when the watchdog times out */
- mmio_write_32(SUNXI_WDOG0_CFG_REG, 1);
- /* Enable the watchdog with the shortest timeout (0.5 seconds) */
- mmio_write_32(SUNXI_WDOG0_MODE_REG, (0 << 4) | 1);
- /* Wait for twice the watchdog timeout before panicking */
- mdelay(1000);
-
- ERROR("PSCI: System reset failed\n");
- wfi();
- panic();
-}
-
-static int sunxi_validate_power_state(unsigned int power_state,
- psci_power_state_t *req_state)
-{
- unsigned int power_level = psci_get_pstate_pwrlvl(power_state);
- unsigned int type = psci_get_pstate_type(power_state);
-
- assert(req_state != NULL);
-
- if (power_level > PLAT_MAX_PWR_LVL)
- return PSCI_E_INVALID_PARAMS;
-
- if (type == PSTATE_TYPE_STANDBY) {
- /* Only one retention power state is supported. */
- if (psci_get_pstate_id(power_state) > 0)
- return PSCI_E_INVALID_PARAMS;
- /* The SoC cannot be suspended without losing state */
- if (power_level == SYSTEM_PWR_LVL)
- return PSCI_E_INVALID_PARAMS;
- for (unsigned int i = 0; i <= power_level; ++i)
- req_state->pwr_domain_state[i] = PLAT_MAX_RET_STATE;
- } else {
- /* Only one off power state is supported. */
- if (psci_get_pstate_id(power_state) > 0)
- return PSCI_E_INVALID_PARAMS;
- for (unsigned int i = 0; i <= power_level; ++i)
- req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
- }
- /* Higher power domain levels should all remain running */
- for (unsigned int i = power_level + 1; i <= PLAT_MAX_PWR_LVL; ++i)
- req_state->pwr_domain_state[i] = PSCI_LOCAL_STATE_RUN;
-
- return PSCI_E_SUCCESS;
-}
-
-static int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint)
+int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint)
{
/* The non-secure entry point must be in DRAM */
if (ns_entrypoint < SUNXI_DRAM_BASE) {
@@ -214,25 +25,6 @@
return PSCI_E_SUCCESS;
}
-static void sunxi_get_sys_suspend_power_state(psci_power_state_t *req_state)
-{
- assert(req_state);
-
- for (unsigned int i = 0; i <= PLAT_MAX_PWR_LVL; ++i)
- req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
-}
-
-static plat_psci_ops_t sunxi_psci_ops = {
- .cpu_standby = sunxi_cpu_standby,
- .pwr_domain_on = sunxi_pwr_domain_on,
- .pwr_domain_off = sunxi_pwr_domain_off,
- .pwr_domain_on_finish = sunxi_pwr_domain_on_finish,
- .system_off = sunxi_system_off,
- .system_reset = sunxi_system_reset,
- .validate_power_state = sunxi_validate_power_state,
- .validate_ns_entrypoint = sunxi_validate_ns_entrypoint,
-};
-
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
const plat_psci_ops_t **psci_ops)
{
@@ -246,36 +38,12 @@
sec_entrypoint >> 32);
}
- /* Check for a valid SCP firmware, and boot the SCP if found. */
- if (mmio_read_32(SUNXI_SCP_BASE) == SCP_FIRMWARE_MAGIC) {
- /* Program SCP exception vectors to the firmware entrypoint. */
- for (unsigned int i = OR1K_VEC_FIRST; i <= OR1K_VEC_LAST; ++i) {
- uint32_t vector = SUNXI_SRAM_A2_BASE + OR1K_VEC_ADDR(i);
- uint32_t offset = SUNXI_SCP_BASE - vector;
-
- mmio_write_32(vector, offset >> 2);
- clean_dcache_range(vector, sizeof(uint32_t));
- }
- /* Take the SCP out of reset. */
- mmio_setbits_32(SUNXI_R_CPUCFG_BASE, BIT(0));
- /* Wait for the SCP firmware to boot. */
- if (scpi_wait_ready() == 0)
- scpi_available = true;
- }
-
- NOTICE("PSCI: System suspend is %s\n",
- scpi_available ? "available via SCPI" : "unavailable");
- if (scpi_available) {
- /* Suspend is only available via SCPI. */
- sunxi_psci_ops.pwr_domain_suspend = sunxi_pwr_domain_off;
- sunxi_psci_ops.pwr_domain_suspend_finish = sunxi_pwr_domain_on_finish;
- sunxi_psci_ops.get_sys_suspend_power_state = sunxi_get_sys_suspend_power_state;
+ if (sunxi_set_scpi_psci_ops(psci_ops) == 0) {
+ INFO("PSCI: Suspend is available via SCPI\n");
} else {
- /* This is only needed when SCPI is unavailable. */
- sunxi_psci_ops.pwr_domain_pwr_down_wfi = sunxi_pwr_down_wfi;
+ INFO("PSCI: Suspend is unavailable\n");
+ sunxi_set_native_psci_ops(psci_ops);
}
- *psci_ops = &sunxi_psci_ops;
-
return 0;
}
diff --git a/plat/allwinner/common/sunxi_scpi_pm.c b/plat/allwinner/common/sunxi_scpi_pm.c
new file mode 100644
index 0000000..74763ef
--- /dev/null
+++ b/plat/allwinner/common/sunxi_scpi_pm.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <platform_def.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/css/css_scpi.h>
+#include <drivers/arm/gicv2.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+
+#include <sunxi_mmap.h>
+#include <sunxi_private.h>
+
+/*
+ * The addresses for the SCP exception vectors are defined in the or1k
+ * architecture specification.
+ */
+#define OR1K_VEC_FIRST 0x01
+#define OR1K_VEC_LAST 0x0e
+#define OR1K_VEC_ADDR(n) (0x100 * (n))
+
+/*
+ * This magic value is the little-endian representation of the or1k
+ * instruction "l.mfspr r2, r0, 0x12", which is guaranteed to be the
+ * first instruction in the SCP firmware.
+ */
+#define SCP_FIRMWARE_MAGIC 0xb4400012
+
+#define CPU_PWR_LVL MPIDR_AFFLVL0
+#define CLUSTER_PWR_LVL MPIDR_AFFLVL1
+#define SYSTEM_PWR_LVL MPIDR_AFFLVL2
+
+#define CPU_PWR_STATE(state) \
+ ((state)->pwr_domain_state[CPU_PWR_LVL])
+#define CLUSTER_PWR_STATE(state) \
+ ((state)->pwr_domain_state[CLUSTER_PWR_LVL])
+#define SYSTEM_PWR_STATE(state) \
+ ((state)->pwr_domain_state[SYSTEM_PWR_LVL])
+
+static inline scpi_power_state_t scpi_map_state(plat_local_state_t psci_state)
+{
+ if (is_local_state_run(psci_state)) {
+ return scpi_power_on;
+ }
+ if (is_local_state_retn(psci_state)) {
+ return scpi_power_retention;
+ }
+ return scpi_power_off;
+}
+
+static void sunxi_cpu_standby(plat_local_state_t cpu_state)
+{
+ u_register_t scr = read_scr_el3();
+
+ assert(is_local_state_retn(cpu_state));
+
+ write_scr_el3(scr | SCR_IRQ_BIT);
+ wfi();
+ write_scr_el3(scr);
+}
+
+static int sunxi_pwr_domain_on(u_register_t mpidr)
+{
+ scpi_set_css_power_state(mpidr,
+ scpi_power_on,
+ scpi_power_on,
+ scpi_power_on);
+
+ return PSCI_E_SUCCESS;
+}
+
+static void sunxi_pwr_domain_off(const psci_power_state_t *target_state)
+{
+ plat_local_state_t cpu_pwr_state = CPU_PWR_STATE(target_state);
+ plat_local_state_t cluster_pwr_state = CLUSTER_PWR_STATE(target_state);
+ plat_local_state_t system_pwr_state = SYSTEM_PWR_STATE(target_state);
+
+ if (is_local_state_off(cpu_pwr_state)) {
+ gicv2_cpuif_disable();
+ }
+
+ scpi_set_css_power_state(read_mpidr(),
+ scpi_map_state(cpu_pwr_state),
+ scpi_map_state(cluster_pwr_state),
+ scpi_map_state(system_pwr_state));
+}
+
+static void sunxi_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+ if (is_local_state_off(SYSTEM_PWR_STATE(target_state))) {
+ gicv2_distif_init();
+ }
+ if (is_local_state_off(CPU_PWR_STATE(target_state))) {
+ gicv2_pcpu_distif_init();
+ gicv2_cpuif_enable();
+ }
+}
+
+static void __dead2 sunxi_system_off(void)
+{
+ uint32_t ret;
+
+ gicv2_cpuif_disable();
+
+ /* Send the power down request to the SCP. */
+ ret = scpi_sys_power_state(scpi_system_shutdown);
+ if (ret != SCP_OK) {
+ ERROR("PSCI: SCPI %s failed: %d\n", "shutdown", ret);
+ }
+
+ psci_power_down_wfi();
+}
+
+static void __dead2 sunxi_system_reset(void)
+{
+ uint32_t ret;
+
+ gicv2_cpuif_disable();
+
+ /* Send the system reset request to the SCP. */
+ ret = scpi_sys_power_state(scpi_system_reboot);
+ if (ret != SCP_OK) {
+ ERROR("PSCI: SCPI %s failed: %d\n", "reboot", ret);
+ }
+
+ psci_power_down_wfi();
+}
+
+static int sunxi_validate_power_state(unsigned int power_state,
+ psci_power_state_t *req_state)
+{
+ unsigned int power_level = psci_get_pstate_pwrlvl(power_state);
+ unsigned int type = psci_get_pstate_type(power_state);
+
+ assert(req_state != NULL);
+
+ if (power_level > PLAT_MAX_PWR_LVL) {
+ return PSCI_E_INVALID_PARAMS;
+ }
+
+ if (type == PSTATE_TYPE_STANDBY) {
+ /* Only one retention power state is supported. */
+ if (psci_get_pstate_id(power_state) > 0) {
+ return PSCI_E_INVALID_PARAMS;
+ }
+ /* The SoC cannot be suspended without losing state */
+ if (power_level == SYSTEM_PWR_LVL) {
+ return PSCI_E_INVALID_PARAMS;
+ }
+ for (unsigned int i = 0; i <= power_level; ++i) {
+ req_state->pwr_domain_state[i] = PLAT_MAX_RET_STATE;
+ }
+ } else {
+ /* Only one off power state is supported. */
+ if (psci_get_pstate_id(power_state) > 0) {
+ return PSCI_E_INVALID_PARAMS;
+ }
+ for (unsigned int i = 0; i <= power_level; ++i) {
+ req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
+ }
+ }
+ /* Higher power domain levels should all remain running */
+ for (unsigned int i = power_level + 1; i <= PLAT_MAX_PWR_LVL; ++i) {
+ req_state->pwr_domain_state[i] = PSCI_LOCAL_STATE_RUN;
+ }
+
+ return PSCI_E_SUCCESS;
+}
+
+static void sunxi_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+ assert(req_state != NULL);
+
+ for (unsigned int i = 0; i <= PLAT_MAX_PWR_LVL; ++i) {
+ req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
+ }
+}
+
+static const plat_psci_ops_t sunxi_scpi_psci_ops = {
+ .cpu_standby = sunxi_cpu_standby,
+ .pwr_domain_on = sunxi_pwr_domain_on,
+ .pwr_domain_off = sunxi_pwr_domain_off,
+ .pwr_domain_suspend = sunxi_pwr_domain_off,
+ .pwr_domain_on_finish = sunxi_pwr_domain_on_finish,
+ .pwr_domain_suspend_finish = sunxi_pwr_domain_on_finish,
+ .system_off = sunxi_system_off,
+ .system_reset = sunxi_system_reset,
+ .validate_power_state = sunxi_validate_power_state,
+ .validate_ns_entrypoint = sunxi_validate_ns_entrypoint,
+ .get_sys_suspend_power_state = sunxi_get_sys_suspend_power_state,
+};
+
+int sunxi_set_scpi_psci_ops(const plat_psci_ops_t **psci_ops)
+{
+ *psci_ops = &sunxi_scpi_psci_ops;
+
+ /* Check for a valid SCP firmware. */
+ if (mmio_read_32(SUNXI_SCP_BASE) != SCP_FIRMWARE_MAGIC) {
+ return -1;
+ }
+
+ /* Program SCP exception vectors to the firmware entrypoint. */
+ for (unsigned int i = OR1K_VEC_FIRST; i <= OR1K_VEC_LAST; ++i) {
+ uint32_t vector = SUNXI_SRAM_A2_BASE + OR1K_VEC_ADDR(i);
+ uint32_t offset = SUNXI_SCP_BASE - vector;
+
+ mmio_write_32(vector, offset >> 2);
+ clean_dcache_range(vector, sizeof(uint32_t));
+ }
+
+ /* Take the SCP out of reset. */
+ mmio_setbits_32(SUNXI_R_CPUCFG_BASE, BIT(0));
+
+ /* Wait for the SCP firmware to boot. */
+ return scpi_wait_ready();
+}
diff --git a/plat/arm/board/juno/juno_decl.h b/plat/arm/board/juno/juno_decl.h
index cd87c3b..21e56c0 100644
--- a/plat/arm/board/juno/juno_decl.h
+++ b/plat/arm/board/juno/juno_decl.h
@@ -7,6 +7,6 @@
#ifndef JUNO_DECL_H
#define JUNO_DECL_H
-int juno_getentropy(void *buf, size_t len);
+bool juno_getentropy(uint64_t *buf);
#endif /* JUNO_DECL_H */
diff --git a/plat/arm/board/juno/juno_stack_protector.c b/plat/arm/board/juno/juno_stack_protector.c
index 236eb5b..8c51f57 100644
--- a/plat/arm/board/juno/juno_stack_protector.c
+++ b/plat/arm/board/juno/juno_stack_protector.c
@@ -13,20 +13,16 @@
u_register_t plat_get_stack_protector_canary(void)
{
- u_register_t c[TRNG_NBYTES / sizeof(u_register_t)];
- u_register_t ret = 0;
- size_t i;
+ uint64_t entropy;
- if (juno_getentropy(c, sizeof(c)) != 0) {
+ if (!juno_getentropy(&entropy)) {
ERROR("Not enough entropy to initialize canary value\n");
panic();
}
- /*
- * On Juno we get 128-bits of entropy in one round.
- * Fuse the values together to form the canary.
- */
- for (i = 0; i < ARRAY_SIZE(c); i++)
- ret ^= c[i];
- return ret;
+ if (sizeof(entropy) == sizeof(u_register_t)) {
+ return entropy;
+ }
+
+ return (entropy & 0xffffffffULL) ^ (entropy >> 32);
}
diff --git a/plat/arm/board/juno/juno_trng.c b/plat/arm/board/juno/juno_trng.c
index 7869d3e..b38e49f 100644
--- a/plat/arm/board/juno/juno_trng.c
+++ b/plat/arm/board/juno/juno_trng.c
@@ -5,6 +5,8 @@
*/
#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
#include <string.h>
#include <lib/mmio.h>
@@ -16,7 +18,10 @@
#define NSAMPLE_CLOCKS 1 /* min 1 cycle, max 231 cycles */
#define NRETRIES 5
-static inline int output_valid(void)
+/* initialised to false */
+static bool juno_trng_initialized;
+
+static bool output_valid(void)
{
int i;
@@ -25,59 +30,58 @@
val = mmio_read_32(TRNG_BASE + TRNG_STATUS);
if (val & 1U)
- break;
+ return true;
}
- if (i >= NRETRIES)
- return 0; /* No output data available. */
- return 1;
+ return false; /* No output data available. */
}
/*
- * This function fills `buf` with `len` bytes of entropy.
+ * This function fills `buf` with 8 bytes of entropy.
* It uses the Trusted Entropy Source peripheral on Juno.
- * Returns 0 when the buffer has been filled with entropy
- * successfully and -1 otherwise.
+ * Returns 'true' when the buffer has been filled with entropy
+ * successfully, or 'false' otherwise.
*/
-int juno_getentropy(void *buf, size_t len)
+bool juno_getentropy(uint64_t *buf)
{
- uint8_t *bp = buf;
+ uint64_t ret;
assert(buf);
- assert(len);
- assert(!check_uptr_overflow((uintptr_t)bp, len));
+ assert(!check_uptr_overflow((uintptr_t)buf, sizeof(*buf)));
- /* Disable interrupt mode. */
- mmio_write_32(TRNG_BASE + TRNG_INTMASK, 0);
- /* Program TRNG to sample for `NSAMPLE_CLOCKS`. */
- mmio_write_32(TRNG_BASE + TRNG_CONFIG, NSAMPLE_CLOCKS);
+ if (!juno_trng_initialized) {
+ /* Disable interrupt mode. */
+ mmio_write_32(TRNG_BASE + TRNG_INTMASK, 0);
+ /* Program TRNG to sample for `NSAMPLE_CLOCKS`. */
+ mmio_write_32(TRNG_BASE + TRNG_CONFIG, NSAMPLE_CLOCKS);
+ /* Abort any potentially pending sampling. */
+ mmio_write_32(TRNG_BASE + TRNG_CONTROL, 2);
+ /* Reset TRNG outputs. */
+ mmio_write_32(TRNG_BASE + TRNG_STATUS, 1);
- while (len > 0) {
- int i;
+ juno_trng_initialized = true;
+ }
+ if (!output_valid()) {
/* Start TRNG. */
mmio_write_32(TRNG_BASE + TRNG_CONTROL, 1);
- /* Check if output is valid. */
if (!output_valid())
- return -1;
-
- /* Fill entropy buffer. */
- for (i = 0; i < TRNG_NOUTPUTS; i++) {
- size_t n;
- uint32_t val;
-
- val = mmio_read_32(TRNG_BASE + i * sizeof(uint32_t));
- n = MIN(len, sizeof(uint32_t));
- memcpy(bp, &val, n);
- bp += n;
- len -= n;
- if (len == 0)
- break;
- }
-
- /* Reset TRNG outputs. */
- mmio_write_32(TRNG_BASE + TRNG_STATUS, 1);
+ return false;
}
- return 0;
+ /* XOR each two 32-bit registers together, combine the pairs */
+ ret = mmio_read_32(TRNG_BASE + 0);
+ ret ^= mmio_read_32(TRNG_BASE + 4);
+ ret <<= 32;
+
+ ret |= mmio_read_32(TRNG_BASE + 8);
+ ret ^= mmio_read_32(TRNG_BASE + 12);
+ *buf = ret;
+
+ /* Acknowledge current cycle, clear output registers. */
+ mmio_write_32(TRNG_BASE + TRNG_STATUS, 1);
+ /* Trigger next TRNG cycle. */
+ mmio_write_32(TRNG_BASE + TRNG_CONTROL, 1);
+
+ return true;
}
diff --git a/plat/arm/board/morello/morello_bl31_setup.c b/plat/arm/board/morello/morello_bl31_setup.c
index 5b91e87..59dd37b 100644
--- a/plat/arm/board/morello/morello_bl31_setup.c
+++ b/plat/arm/board/morello/morello_bl31_setup.c
@@ -8,6 +8,7 @@
#include <drivers/arm/css/css_mhu_doorbell.h>
#include <drivers/arm/css/scmi.h>
#include <drivers/arm/css/sds.h>
+#include <lib/cassert.h>
#include <plat/arm/common/plat_arm.h>
#include "morello_def.h"
@@ -17,18 +18,21 @@
* 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
+ * - Local DDR size in bytes, DDR memory in master board
+ * - Remote DDR size in bytes, DDR memory in slave board
+ * - slave_count
+ * - multichip mode
*/
struct morello_plat_info {
- bool multichip_mode;
+ uint64_t local_ddr_size;
+ uint64_t remote_ddr_size;
uint8_t slave_count;
- uint8_t local_ddr_size;
- uint8_t remote_ddr_size;
+ bool multichip_mode;
} __packed;
+/* Compile time assertion to ensure the size of structure is 18 bytes */
+CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE,
+ assert_invalid_plat_info_size);
/*
* BL33 image information structure stored in SDS.
* This structure holds the source & destination addresses and
@@ -80,6 +84,7 @@
int ret;
struct morello_plat_info plat_info;
struct morello_bl33_info bl33_info;
+ struct morello_plat_info *copy_dest;
ret = sds_init();
if (ret != SDS_OK) {
@@ -99,8 +104,8 @@
/* 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.local_ddr_size > MORELLO_MAX_DDR_CAPACITY)
+ || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY)
|| (plat_info.slave_count > MORELLO_MAX_SLAVE_COUNT)) {
ERROR("platform info SDS is corrupted\n");
panic();
@@ -127,5 +132,6 @@
* 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);
+ copy_dest = (struct morello_plat_info *)MORELLO_PLATFORM_INFO_BASE;
+ *copy_dest = plat_info;
}
diff --git a/plat/arm/board/morello/morello_def.h b/plat/arm/board/morello/morello_def.h
index 09db303..793729b 100644
--- a/plat/arm/board/morello/morello_def.h
+++ b/plat/arm/board/morello/morello_def.h
@@ -18,8 +18,8 @@
/* 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_SDS_PLATFORM_INFO_SIZE U(18)
+#define MORELLO_MAX_DDR_CAPACITY U(0x1000000000)
#define MORELLO_MAX_SLAVE_COUNT U(16)
/* SDS BL33 image information defines */
@@ -28,6 +28,6 @@
#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)
+#define MORELLO_PLATFORM_INFO_BASE UL(0x06000000)
#endif /* MORELLO_DEF_H */
diff --git a/plat/arm/board/rdn2/include/platform_def.h b/plat/arm/board/rdn2/include/platform_def.h
index 5561f8c..3f753f7 100644
--- a/plat/arm/board/rdn2/include/platform_def.h
+++ b/plat/arm/board/rdn2/include/platform_def.h
@@ -22,7 +22,7 @@
#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1
/* TZC Related Constants */
-#define PLAT_ARM_TZC_BASE UL(0x10820000)
+#define PLAT_ARM_TZC_BASE UL(0x10720000)
#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT(0)
#define TZC400_OFFSET UL(0x1000000)
diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c
index 36c3fbb..e8238ba 100644
--- a/plat/arm/css/sgi/sgi_bl31_setup.c
+++ b/plat/arm/css/sgi/sgi_bl31_setup.c
@@ -28,7 +28,7 @@
.ring_doorbell = &mhu_ring_doorbell,
};
-static scmi_channel_plat_info_t rd_n1e1_edge_scmi_plat_info[] = {
+static scmi_channel_plat_info_t plat_rd_scmi_info[] = {
{
.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
.db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
@@ -76,9 +76,9 @@
if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM ||
sgi_plat_info.platform_id == RD_V1_SID_VER_PART_NUM ||
sgi_plat_info.platform_id == RD_N2_SID_VER_PART_NUM) {
- if (channel_id >= ARRAY_SIZE(rd_n1e1_edge_scmi_plat_info))
+ if (channel_id >= ARRAY_SIZE(plat_rd_scmi_info))
panic();
- return &rd_n1e1_edge_scmi_plat_info[channel_id];
+ return &plat_rd_scmi_info[channel_id];
}
else if (sgi_plat_info.platform_id == SGI575_SSC_VER_PART_NUM)
return &sgi575_scmi_plat_info;
diff --git a/plat/nxp/common/plat_make_helper/plat_build_macros.mk b/plat/nxp/common/plat_make_helper/plat_build_macros.mk
new file mode 100644
index 0000000..bba5e36
--- /dev/null
+++ b/plat/nxp/common/plat_make_helper/plat_build_macros.mk
@@ -0,0 +1,11 @@
+#
+# Copyright (c) 2020, NXP.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+
+define SET_NXP_MAKE_FLAG
+$1 := yes
+$2_$1 := yes
+endef
diff --git a/plat/qti/common/src/spmi_arb.c b/plat/qti/common/src/spmi_arb.c
index 16e85a6..4213ed1 100644
--- a/plat/qti/common/src/spmi_arb.c
+++ b/plat/qti/common/src/spmi_arb.c
@@ -10,8 +10,8 @@
#include <spmi_arb.h>
-#define REG_APID_MAP(apid) (0x0C440900U + 4U * i)
-#define NUM_APID 0x80
+#define REG_APID_MAP(apid) (0x0C440900U + sizeof(uint32_t) * apid)
+#define NUM_APID ((0x1100U - 0x900U) / sizeof(uint32_t))
#define PPID_MASK (0xfffU << 8)
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S b/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S
index 7eab337..d8439f7 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S
@@ -12,9 +12,6 @@
.globl plat_is_my_cpu_primary
.globl zynqmp_calc_core_pos
.globl plat_my_core_pos
- .globl plat_crash_console_init
- .globl plat_crash_console_putc
- .globl plat_crash_console_flush
.globl platform_mem_init
/* -----------------------------------------------------
@@ -79,45 +76,6 @@
ret
endfunc zynqmp_calc_core_pos
- /* ---------------------------------------------
- * int plat_crash_console_init(void)
- * Function to initialize the crash console
- * without a C Runtime to print crash report.
- * Clobber list : x0 - x4
- * ---------------------------------------------
- */
-func plat_crash_console_init
- mov_imm x0, ZYNQMP_CRASH_UART_BASE
- mov_imm x1, ZYNQMP_CRASH_UART_CLK_IN_HZ
- mov_imm x2, ZYNQMP_UART_BAUDRATE
- b console_cdns_core_init
-endfunc plat_crash_console_init
-
- /* ---------------------------------------------
- * int plat_crash_console_putc(int c)
- * Function to print a character on the crash
- * console without a C Runtime.
- * Clobber list : x1, x2
- * ---------------------------------------------
- */
-func plat_crash_console_putc
- mov_imm x1, ZYNQMP_CRASH_UART_BASE
- b console_cdns_core_putc
-endfunc plat_crash_console_putc
-
- /* ---------------------------------------------
- * void plat_crash_console_flush()
- * Function to force a write of all buffered
- * data that hasn't been output.
- * Out : void.
- * Clobber list : r0
- * ---------------------------------------------
- */
-func plat_crash_console_flush
- mov_imm x0, ZYNQMP_CRASH_UART_BASE
- b console_cdns_core_flush
-endfunc plat_crash_console_flush
-
/* ---------------------------------------------------------------------
* We don't need to carry out any memory initialization on ARM
* platforms. The Secure RAM is accessible straight away.
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 1cd168f..6e700b9 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -73,7 +73,8 @@
plat/arm/common/arm_gicv2.c \
plat/common/plat_gicv2.c \
plat/xilinx/common/ipi.c \
- plat/xilinx/zynqmp/zynqmp_ipi.c \
+ plat/xilinx/zynqmp/zynqmp_ipi.c \
+ plat/common/aarch64/crash_console_helpers.S \
plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S \
plat/xilinx/zynqmp/aarch64/zynqmp_common.c