summaryrefslogtreecommitdiff
path: root/plat/allwinner
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2018-06-01 02:01:39 +0100
committerAndre Przywara <andre.przywara@arm.com>2018-06-15 11:45:24 +0100
commitacb8b3cabbb412fac3e48f63bd212b12de632dee (patch)
tree2b899bfd2231f298207553d8a24f4eb50ba703a6 /plat/allwinner
parent560581ecebfa16e8b728317abf8c0f01c7ed2139 (diff)
allwinner: Add security setup
Some peripherals are TrustZone aware, so they need to be configured to be accessible from non-secure world, as we don't need any of them being exclusive to the secure world. This affects some clocks, DMA channels and the Secure Peripheral Controller (SPC). The latter controls access to most devices, but is not active unless booting with the secure boot fuse burnt. Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Diffstat (limited to 'plat/allwinner')
-rw-r--r--plat/allwinner/common/sunxi_bl31_setup.c2
-rw-r--r--plat/allwinner/common/sunxi_private.h2
-rw-r--r--plat/allwinner/common/sunxi_security.c45
-rw-r--r--plat/allwinner/sun50i_a64/include/sunxi_mmap.h3
-rw-r--r--plat/allwinner/sun50i_a64/platform.mk1
5 files changed, 53 insertions, 0 deletions
diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c
index 22abafe9..d1f1aa15 100644
--- a/plat/allwinner/common/sunxi_bl31_setup.c
+++ b/plat/allwinner/common/sunxi_bl31_setup.c
@@ -64,6 +64,8 @@ void bl31_platform_setup(void)
gicv2_pcpu_distif_init();
gicv2_cpuif_enable();
+ sunxi_security_setup();
+
INFO("BL31: Platform setup done\n");
}
diff --git a/plat/allwinner/common/sunxi_private.h b/plat/allwinner/common/sunxi_private.h
index bd923f40..b9f0fb41 100644
--- a/plat/allwinner/common/sunxi_private.h
+++ b/plat/allwinner/common/sunxi_private.h
@@ -12,4 +12,6 @@ void sunxi_cpu_off(unsigned int cluster, unsigned int core);
void sunxi_cpu_on(unsigned int cluster, unsigned int core);
void sunxi_disable_secondary_cpus(unsigned int primary_cpu);
+void sunxi_security_setup(void);
+
#endif /* __SUNXI_PRIVATE_H__ */
diff --git a/plat/allwinner/common/sunxi_security.c b/plat/allwinner/common/sunxi_security.c
new file mode 100644
index 00000000..e7600728
--- /dev/null
+++ b/plat/allwinner/common/sunxi_security.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <mmio.h>
+#include <sunxi_mmap.h>
+
+#ifdef SUNXI_SPC_BASE
+#define SPC_DECPORT_STA_REG(p) (SUNXI_SPC_BASE + ((p) * 0x0c) + 0x4)
+#define SPC_DECPORT_SET_REG(p) (SUNXI_SPC_BASE + ((p) * 0x0c) + 0x8)
+#define SPC_DECPORT_CLR_REG(p) (SUNXI_SPC_BASE + ((p) * 0x0c) + 0xc)
+#endif
+
+#define R_PRCM_SEC_SWITCH_REG 0x1d0
+#define DMA_SEC_REG 0x20
+
+/*
+ * Setup the peripherals to be accessible by non-secure world.
+ * This will not work for the Secure Peripherals Controller (SPC) unless
+ * a fuse it burnt (seems to be an erratum), but we do it nevertheless,
+ * to allow booting on boards using secure boot.
+ */
+void sunxi_security_setup(void)
+{
+ int i;
+
+#ifdef SUNXI_SPC_BASE
+ INFO("Configuring SPC Controller\n");
+ /* SPC setup: set all devices to non-secure */
+ for (i = 0; i < 6; i++)
+ mmio_write_32(SPC_DECPORT_SET_REG(i), 0xff);
+#endif
+
+ /* set MBUS clocks, bus clocks (AXI/AHB/APB) and PLLs to non-secure */
+ mmio_write_32(SUNXI_CCU_SEC_SWITCH_REG, 0x7);
+
+ /* set R_PRCM clocks to non-secure */
+ mmio_write_32(SUNXI_R_PRCM_BASE + R_PRCM_SEC_SWITCH_REG, 0x7);
+
+ /* Set all DMA channels (16 max.) to non-secure */
+ mmio_write_32(SUNXI_DMA_BASE + DMA_SEC_REG, 0xffff);
+}
diff --git a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
index f68a6869..cb202a83 100644
--- a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
+++ b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
@@ -28,6 +28,7 @@
#define SUNXI_CPUCFG_BASE 0x01700000
#define SUNXI_SYSCON_BASE 0x01c00000
#define SUNXI_SRAM_VER_REG (SUNXI_SYSCON_BASE + 0x24)
+#define SUNXI_DMA_BASE 0x01c02000
#define SUNXI_KEYMEM_BASE 0x01c0b000
#define SUNXI_SMHC0_BASE 0x01c0f000
#define SUNXI_SMHC1_BASE 0x01c10000
@@ -36,9 +37,11 @@
#define SUNXI_MSGBOX_BASE 0x01c17000
#define SUNXI_SPINLOCK_BASE 0x01c18000
#define SUNXI_CCU_BASE 0x01c20000
+#define SUNXI_CCU_SEC_SWITCH_REG (SUNXI_CCU_BASE + 0x2f0)
#define SUNXI_PIO_BASE 0x01c20800
#define SUNXI_TIMER_BASE 0x01c20c00
#define SUNXI_WDOG_BASE 0x01c20ca0
+#define SUNXI_SPC_BASE 0x01c23400
#define SUNXI_THS_BASE 0x01c25000
#define SUNXI_UART0_BASE 0x01c28000
#define SUNXI_UART1_BASE 0x01c28400
diff --git a/plat/allwinner/sun50i_a64/platform.mk b/plat/allwinner/sun50i_a64/platform.mk
index 49764e09..236464fe 100644
--- a/plat/allwinner/sun50i_a64/platform.mk
+++ b/plat/allwinner/sun50i_a64/platform.mk
@@ -30,6 +30,7 @@ BL31_SOURCES += drivers/arm/gic/common/gic_common.c \
${AW_PLAT}/common/sunxi_bl31_setup.c \
${AW_PLAT}/common/sunxi_cpu_ops.c \
${AW_PLAT}/common/sunxi_pm.c \
+ ${AW_PLAT}/common/sunxi_security.c \
${AW_PLAT}/common/sunxi_topology.c
# The bootloader is guaranteed to only run on CPU 0 by the boot ROM.