aboutsummaryrefslogtreecommitdiffstats
path: root/plat
diff options
context:
space:
mode:
Diffstat (limited to 'plat')
-rw-r--r--plat/allwinner/common/allwinner-common.mk59
-rw-r--r--plat/allwinner/common/arisc_off.S115
-rw-r--r--plat/allwinner/common/include/platform_def.h14
-rw-r--r--plat/allwinner/common/include/sunxi_def.h4
-rw-r--r--plat/allwinner/common/include/sunxi_private.h (renamed from plat/allwinner/common/sunxi_private.h)20
-rw-r--r--plat/allwinner/common/sunxi_bl31_setup.c65
-rw-r--r--plat/allwinner/common/sunxi_common.c151
-rw-r--r--plat/allwinner/common/sunxi_cpu_ops.c43
-rw-r--r--plat/allwinner/common/sunxi_pm.c16
-rw-r--r--plat/allwinner/common/sunxi_security.c1
-rw-r--r--plat/allwinner/sun50i_a64/include/core_off_arisc.h39
-rw-r--r--plat/allwinner/sun50i_a64/include/sunxi_mmap.h2
-rw-r--r--plat/allwinner/sun50i_a64/platform.mk50
-rw-r--r--plat/allwinner/sun50i_a64/sunxi_power.c338
-rw-r--r--plat/allwinner/sun50i_h6/include/core_off_arisc.h39
-rw-r--r--plat/allwinner/sun50i_h6/include/sunxi_mmap.h4
-rw-r--r--plat/allwinner/sun50i_h6/platform.mk52
-rw-r--r--plat/allwinner/sun50i_h6/sunxi_power.c43
-rw-r--r--plat/arm/board/fvp/aarch64/fvp_helpers.S12
-rw-r--r--plat/arm/board/fvp/fvp_common.c7
-rw-r--r--plat/arm/board/fvp/platform.mk2
-rw-r--r--plat/arm/board/juno/include/platform_def.h2
-rw-r--r--plat/arm/board/juno/juno_common.c4
-rw-r--r--plat/arm/board/juno/juno_topology.c15
-rw-r--r--plat/arm/board/n1sdp/aarch64/n1sdp_helper.S74
-rw-r--r--plat/arm/board/n1sdp/include/plat_macros.S23
-rw-r--r--plat/arm/board/n1sdp/include/platform_def.h71
-rw-r--r--plat/arm/board/n1sdp/n1sdp_bl31_setup.c22
-rw-r--r--plat/arm/board/n1sdp/n1sdp_interconnect.c33
-rw-r--r--plat/arm/board/n1sdp/n1sdp_plat.c25
-rw-r--r--plat/arm/board/n1sdp/n1sdp_security.c (renamed from plat/arm/css/sgi/fdts/sgi575.dts)11
-rw-r--r--plat/arm/board/n1sdp/n1sdp_topology.c55
-rw-r--r--plat/arm/board/n1sdp/platform.mk67
-rw-r--r--plat/arm/board/sgi575/fdts/sgi575.dts21
-rw-r--r--plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts (renamed from plat/arm/css/sgi/fdts/sgi575_tb_fw_config.dts)0
-rw-r--r--plat/arm/board/sgi575/include/platform_def.h18
-rw-r--r--plat/arm/board/sgi575/platform.mk24
-rw-r--r--plat/arm/board/sgiclarka/fdts/sgiclarka.dts21
-rw-r--r--plat/arm/board/sgiclarka/fdts/sgiclarka_tb_fw_config.dts25
-rw-r--r--plat/arm/board/sgiclarka/include/platform_def.h18
-rw-r--r--plat/arm/board/sgiclarka/platform.mk38
-rw-r--r--plat/arm/common/aarch64/arm_helpers.S6
-rw-r--r--plat/arm/common/arm_bl1_setup.c5
-rw-r--r--plat/arm/common/arm_bl2_el3_setup.c2
-rw-r--r--plat/arm/common/arm_bl2_setup.c2
-rw-r--r--plat/arm/common/arm_bl2u_setup.c2
-rw-r--r--plat/arm/common/arm_bl31_setup.c10
-rw-r--r--plat/arm/common/arm_common.c38
-rw-r--r--plat/arm/common/arm_common.mk5
-rw-r--r--plat/arm/common/arm_gicv3.c30
-rw-r--r--plat/arm/common/arm_sip_svc.c2
-rw-r--r--plat/arm/common/arm_tzc400.c4
-rw-r--r--plat/arm/common/arm_tzc_dmc500.c4
-rw-r--r--plat/arm/common/sp_min/arm_sp_min_setup.c2
-rw-r--r--plat/arm/common/tsp/arm_tsp_setup.c2
-rw-r--r--plat/arm/css/common/aarch64/css_helpers.S2
-rw-r--r--plat/arm/css/drivers/scmi/scmi.h3
-rw-r--r--plat/arm/css/drivers/scp/css_pm_scmi.c11
-rw-r--r--plat/arm/css/sgi/aarch64/sgi_helper.S9
-rw-r--r--plat/arm/css/sgi/include/sgi_base_platform_def.h (renamed from plat/arm/css/sgi/include/platform_def.h)13
-rw-r--r--plat/arm/css/sgi/include/sgi_plat_config.h43
-rw-r--r--plat/arm/css/sgi/include/sgi_variant.h17
-rw-r--r--plat/arm/css/sgi/sgi-common.mk26
-rw-r--r--plat/arm/css/sgi/sgi_bl1_setup.c19
-rw-r--r--plat/arm/css/sgi/sgi_bl31_setup.c80
-rw-r--r--plat/arm/css/sgi/sgi_image_load.c33
-rw-r--r--plat/arm/css/sgi/sgi_interconnect.c1
-rw-r--r--plat/arm/css/sgi/sgi_plat_config.c55
-rw-r--r--plat/arm/css/sgi/sgi_topology.c11
-rw-r--r--plat/arm/css/sgm/sgm_bl31_setup.c15
-rw-r--r--plat/common/aarch32/crash_console_helpers.S92
-rw-r--r--plat/common/aarch32/platform_helpers.S4
-rw-r--r--plat/common/aarch64/crash_console_helpers.S92
-rw-r--r--plat/common/aarch64/platform_helpers.S4
-rw-r--r--plat/common/plat_bl_common.c38
-rw-r--r--plat/hisilicon/hikey/aarch64/hikey_helpers.S14
-rw-r--r--plat/hisilicon/hikey960/aarch64/hikey960_helpers.S16
-rw-r--r--plat/hisilicon/poplar/aarch64/poplar_helpers.S87
-rw-r--r--plat/hisilicon/poplar/bl31_plat_setup.c9
-rw-r--r--plat/hisilicon/poplar/include/plat_private.h9
-rw-r--r--plat/hisilicon/poplar/include/platform_def.h14
-rw-r--r--plat/hisilicon/poplar/plat_pm.c9
-rw-r--r--plat/hisilicon/poplar/plat_topology.c6
-rw-r--r--plat/hisilicon/poplar/platform.mk9
-rw-r--r--plat/hisilicon/poplar/poplar_gicv2.c62
-rw-r--r--plat/imx/common/imx8_helpers.S7
-rw-r--r--plat/imx/common/lpuart_console.S3
-rw-r--r--plat/imx/imx7/warp7/aarch32/warp7_helpers.S7
-rw-r--r--plat/imx/imx7/warp7/platform.mk1
-rw-r--r--plat/layerscape/board/ls1043/platform.mk1
-rw-r--r--plat/layerscape/common/aarch64/ls_console.S3
-rw-r--r--plat/marvell/common/aarch64/marvell_helpers.S14
-rw-r--r--plat/meson/gxbb/aarch64/gxbb_helpers.S97
-rw-r--r--plat/meson/gxbb/gxbb_bl31_setup.c144
-rw-r--r--plat/meson/gxbb/gxbb_common.c143
-rw-r--r--plat/meson/gxbb/gxbb_def.h118
-rw-r--r--plat/meson/gxbb/gxbb_efuse.c25
-rw-r--r--plat/meson/gxbb/gxbb_mhu.c52
-rw-r--r--plat/meson/gxbb/gxbb_pm.c191
-rw-r--r--plat/meson/gxbb/gxbb_private.h38
-rw-r--r--plat/meson/gxbb/gxbb_scpi.c137
-rw-r--r--plat/meson/gxbb/gxbb_sip_svc.c66
-rw-r--r--plat/meson/gxbb/gxbb_thermal.c27
-rw-r--r--plat/meson/gxbb/gxbb_topology.c53
-rw-r--r--plat/meson/gxbb/include/plat_macros.S71
-rw-r--r--plat/meson/gxbb/include/platform_def.h66
-rw-r--r--plat/meson/gxbb/platform.mk78
-rw-r--r--plat/nvidia/tegra/common/aarch64/tegra_helpers.S17
-rw-r--r--plat/qemu/include/platform_def.h2
-rw-r--r--plat/qemu/platform.mk12
-rw-r--r--plat/qemu/qemu_common.c5
-rw-r--r--plat/rockchip/rk3328/platform.mk1
-rw-r--r--plat/rockchip/rk3368/platform.mk1
-rw-r--r--plat/rockchip/rk3399/platform.mk1
-rw-r--r--plat/rpi3/platform.mk14
-rw-r--r--plat/rpi3/rpi3_bl31_setup.c71
-rw-r--r--plat/rpi3/rpi3_common.c10
-rw-r--r--plat/st/stm32mp1/bl2_io_storage.c167
-rw-r--r--plat/st/stm32mp1/include/boot_api.h7
-rw-r--r--plat/st/stm32mp1/include/platform_def.h2
-rw-r--r--plat/st/stm32mp1/platform.mk17
-rw-r--r--plat/st/stm32mp1/stm32mp1_def.h3
-rw-r--r--plat/ti/k3/common/k3_bl31_setup.c2
-rw-r--r--plat/ti/k3/common/k3_helpers.S21
-rw-r--r--plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S81
-rw-r--r--plat/xilinx/zynqmp/bl31_zynqmp_setup.c4
-rw-r--r--plat/xilinx/zynqmp/plat_zynqmp.c7
-rw-r--r--plat/xilinx/zynqmp/platform.mk5
-rw-r--r--plat/xilinx/zynqmp/tsp/tsp_plat_setup.c4
-rw-r--r--plat/xilinx/zynqmp/zynqmp_def.h8
-rw-r--r--plat/xilinx/zynqmp/zynqmp_private.h5
131 files changed, 3840 insertions, 529 deletions
diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk
new file mode 100644
index 000000000..2dc058f54
--- /dev/null
+++ b/plat/allwinner/common/allwinner-common.mk
@@ -0,0 +1,59 @@
+#
+# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include lib/xlat_tables_v2/xlat_tables.mk
+
+AW_PLAT := plat/allwinner
+
+PLAT_INCLUDES := -Iinclude/plat/arm/common \
+ -Iinclude/plat/arm/common/aarch64 \
+ -I${AW_PLAT}/common/include \
+ -I${AW_PLAT}/${PLAT}/include
+
+include lib/libfdt/libfdt.mk
+
+PLAT_BL_COMMON_SOURCES := drivers/console/${ARCH}/console.S \
+ drivers/ti/uart/${ARCH}/16550_console.S \
+ ${XLAT_TABLES_LIB_SRCS} \
+ ${AW_PLAT}/common/plat_helpers.S \
+ ${AW_PLAT}/common/sunxi_common.c
+
+BL31_SOURCES += drivers/arm/gic/common/gic_common.c \
+ drivers/arm/gic/v2/gicv2_helpers.c \
+ drivers/arm/gic/v2/gicv2_main.c \
+ drivers/delay_timer/delay_timer.c \
+ drivers/delay_timer/generic_delay_timer.c \
+ lib/cpus/${ARCH}/cortex_a53.S \
+ 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
+
+# The bootloader is guaranteed to only run on CPU 0 by the boot ROM.
+COLD_BOOT_SINGLE_CPU := 1
+
+# Enable workarounds for Cortex-A53 errata. Allwinner uses at least r0p4.
+ERRATA_A53_835769 := 1
+ERRATA_A53_843419 := 1
+ERRATA_A53_855873 := 1
+
+MULTI_CONSOLE_API := 1
+
+# The reset vector can be changed for each CPU.
+PROGRAMMABLE_RESET_ADDRESS := 1
+
+# Allow mapping read-only data as execute-never.
+SEPARATE_CODE_AND_RODATA := 1
+
+# BL31 gets loaded alongside BL33 (U-Boot) by U-Boot's SPL
+RESET_TO_BL31 := 1
+
+# We are short on memory, so save 3.5KB by not having an extra coherent page.
+USE_COHERENT_MEM := 0
diff --git a/plat/allwinner/common/arisc_off.S b/plat/allwinner/common/arisc_off.S
new file mode 100644
index 000000000..ed10832c9
--- /dev/null
+++ b/plat/allwinner/common/arisc_off.S
@@ -0,0 +1,115 @@
+# turn_off_core.S
+#
+# Copyright (c) 2018, Andre Przywara <osp@andrep.de>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# OpenRISC assembly to turn off an ARM core on an Allwinner SoC from
+# the arisc management controller.
+# Generate a binary representation with:
+# $ or1k-elf-as -c -o turn_off_core.o turn_off_core.S
+# $ or1k-elf-objcopy -O binary --reverse-bytes=4 turn_off_core.o \
+# turn_off_core.bin
+# The encoded instructions go into an array defined in
+# plat/allwinner/sun50i_*/include/core_off_arisc.h, to be handed off to
+# the arisc processor.
+#
+# This routine is meant to be called directly from arisc reset (put the
+# start address in the reset vector), to be actually triggered by that
+# very ARM core to be turned off.
+# It expects the core number presented as a mask in the upper half of
+# r3, so to be patched in the lower 16 bits of the first instruction,
+# overwriting the 0 in this code here.
+# The code will do the following:
+# - Read the C_CPU_STATUS register, which contains the status of the WFI
+# lines of each of the four A53 cores.
+# - Loop until the core in question reaches WFI.
+# - Using that mask, activate the core output clamps by setting the
+# respective core bit in CPUX_PWROFF_GATING_REG (0x1f01500).
+# Note that the clamp for core 0 covers more than just the core, activating
+# it hangs the whole system. So we skip this step for core 0.
+# - Using the negated mask, assert the core's reset line by clearing the
+# respective bit in C_RST_CTRL (0x1f01c30).
+# - Finally turn off the core's power switch by writing 0xff to the
+# respective CPUx_PWR_SWITCH_REG (0x1f01540 ff.)
+# - Assert the arisc's own reset to end execution.
+# This also signals other arisc users that the chip is free again.
+# So in C this would look like:
+# while (!(readl(0x1700030) & (1U << core_nr)))
+# ;
+# if (core_nr != 0)
+# writel(readl(0x1f01500) | (1U << core_nr), 0x1f01500);
+# writel(readl(0x1f01c30) & ~(1U << core_nr), 0x1f01c30);
+# writel(0xff, 0x1f01540 + (core_nr * 4));
+# (using A64/H5 addresses)
+
+.text
+_start:
+ l.movhi r3, 0 # FIXUP! with core mask
+ l.movhi r0, 0 # clear r0
+ l.movhi r13, 0x170 # r13: CPU_CFG_BASE=0x01700000
+wait_wfi:
+ l.lwz r5, 0x30(r13) # load C_CPU_STATUS
+ l.and r5, r5, r3 # mask requested core
+ l.sfeq r5, r0 # is it not yet in WFI?
+ l.bf wait_wfi # try again
+
+ l.srli r6, r3, 16 # move mask to lower 16 bits
+ l.sfeqi r6, 1 # core 0 is special
+ l.bf 1f # don't touch the bit for core 0
+ l.movhi r13, 0x1f0 # address of R_CPUCFG (delay)
+ l.lwz r5, 0x1500(r13) # core output clamps
+ l.or r5, r5, r6 # set bit to ...
+ l.sw 0x1500(r13), r5 # ... activate for our core
+
+1: l.lwz r5, 0x1c30(r13) # CPU power-on reset
+ l.xori r6, r6, -1 # negate core mask
+ l.and r5, r5, r6 # clear bit to ...
+ l.sw 0x1c30(r13), r5 # ... assert for our core
+
+ l.ff1 r6, r3 # get core number from high mask
+ l.addi r6, r6, -17 # convert to 0-3
+ l.slli r6, r6, 2 # r5: core number*4 (0-12)
+ l.add r6, r6, r13 # add to base address
+ l.ori r5, r0, 0xff # 0xff means all switches off
+ l.sw 0x1540(r6), r5 # core power switch registers
+
+reset: l.sw 0x1c00(r13),r0 # pull down our own reset line
+
+ l.j reset # just in case ....
+ l.nop 0x0 # (delay slot)
+
+# same as above, but with the MMIO addresses matching the H6 SoC
+_start_h6:
+ l.movhi r3, 0 # FIXUP! with core mask
+ l.movhi r0, 0 # clear r0
+ l.movhi r13, 0x901 # r13: CPU_CFG_BASE=0x09010000
+1:
+ l.lwz r5, 0x80(r13) # load C_CPU_STATUS
+ l.and r5, r5, r3 # mask requested core
+ l.sfeq r5, r0 # is it not yet in WFI?
+ l.bf 1b # try again
+
+ l.srli r6, r3, 16 # move mask to lower 16 bits(ds)
+ l.sfeqi r6, 1 # core 0 is special
+ l.bf 1f # don't touch the bit for core 0
+ l.movhi r13, 0x700 # address of R_CPUCFG (ds)
+ l.lwz r5, 0x0444(r13) # core output clamps
+ l.or r5, r5, r6 # set bit to ...
+ l.sw 0x0444(r13), r5 # ... activate for our core
+
+1: l.lwz r5, 0x0440(r13) # CPU power-on reset
+ l.xori r6, r6, -1 # negate core mask
+ l.and r5, r5, r6 # clear bit to ...
+ l.sw 0x0440(r13), r5 # ... assert for our core
+
+ l.ff1 r6, r3 # get core number from high mask
+ l.addi r6, r6, -17 # convert to 0-3
+ l.slli r6, r6, 2 # r5: core number*4 (0-12)
+ l.add r6, r6, r13 # add to base address
+ l.ori r5, r0, 0xff # 0xff means all switches off
+ l.sw 0x0450(r6), r5 # core power switch registers
+
+1: l.sw 0x0400(r13),r0 # pull down our own reset line
+
+ l.j 1b # just in case ...
+ l.nop 0x0 # (delay slot)
diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h
index b46d41016..08eb5cf2b 100644
--- a/plat/allwinner/common/include/platform_def.h
+++ b/plat/allwinner/common/include/platform_def.h
@@ -18,11 +18,17 @@
/* The traditional U-Boot load address is 160MB into DRAM, so at 0x4a000000 */
#define PLAT_SUNXI_NS_IMAGE_OFFSET (SUNXI_DRAM_BASE + (160U << 20))
+/* How much memory to reserve as secure for BL32, if configured */
+#define SUNXI_DRAM_SEC_SIZE (32U << 20)
+
+/* How much DRAM to map (to map BL33, for fetching the DTB from U-Boot) */
+#define SUNXI_DRAM_MAP_SIZE (64U << 20)
+
#define CACHE_WRITEBACK_SHIFT 6
#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
-#define MAX_MMAP_REGIONS (4 + PLATFORM_MMAP_REGIONS)
-#define MAX_XLAT_TABLES 2
+#define MAX_MMAP_REGIONS (3 + PLATFORM_MMAP_REGIONS)
+#define MAX_XLAT_TABLES 1
#define PLAT_MAX_PWR_LVL_STATES U(2)
#define PLAT_MAX_RET_STATE U(1)
@@ -34,13 +40,13 @@
PLATFORM_CORE_COUNT)
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 28)
#define PLATFORM_CLUSTER_COUNT 1
#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER_COUNT * \
PLATFORM_MAX_CPUS_PER_CLUSTER)
#define PLATFORM_MAX_CPUS_PER_CLUSTER 4
-#define PLATFORM_MMAP_REGIONS 3
+#define PLATFORM_MMAP_REGIONS 4
#define PLATFORM_STACK_SIZE (0x1000 / PLATFORM_CORE_COUNT)
#ifndef SPD_none
diff --git a/plat/allwinner/common/include/sunxi_def.h b/plat/allwinner/common/include/sunxi_def.h
index e68fbe463..da87b2389 100644
--- a/plat/allwinner/common/include/sunxi_def.h
+++ b/plat/allwinner/common/include/sunxi_def.h
@@ -14,4 +14,8 @@
#define SUNXI_UART0_BAUDRATE 115200
#define SUNXI_UART0_CLK_IN_HZ SUNXI_OSC24M_CLK_IN_HZ
+#define SUNXI_SOC_A64 0x1689
+#define SUNXI_SOC_H5 0x1718
+#define SUNXI_SOC_H6 0x1728
+
#endif /* __SUNXI_DEF_H__ */
diff --git a/plat/allwinner/common/sunxi_private.h b/plat/allwinner/common/include/sunxi_private.h
index 20fa23e62..1e1b0a4d1 100644
--- a/plat/allwinner/common/sunxi_private.h
+++ b/plat/allwinner/common/include/sunxi_private.h
@@ -4,19 +4,23 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __SUNXI_PRIVATE_H__
-#define __SUNXI_PRIVATE_H__
+#ifndef SUNXI_PRIVATE_H
+#define SUNXI_PRIVATE_H
void sunxi_configure_mmu_el3(int flags);
-void sunxi_cpu_off(unsigned int cluster, unsigned int core);
+
void sunxi_cpu_on(unsigned int cluster, unsigned int core);
+void sunxi_cpu_off(unsigned int cluster, unsigned int core);
void sunxi_disable_secondary_cpus(unsigned int primary_cpu);
+void __dead2 sunxi_power_down(void);
-uint16_t sunxi_read_soc_id(void);
-
-void sunxi_pmic_setup(void);
+int sunxi_pmic_setup(uint16_t socid, const void *fdt);
void sunxi_security_setup(void);
-void __dead2 sunxi_power_down(void);
+uint16_t sunxi_read_soc_id(void);
+void sunxi_set_gpio_out(char port, int pin, bool level_high);
+int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb);
+void sunxi_execute_arisc_code(uint32_t *code, size_t size,
+ int patch_offset, uint16_t param);
-#endif /* __SUNXI_PRIVATE_H__ */
+#endif /* SUNXI_PRIVATE_H */
diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c
index 7e11cecf5..8f597c39e 100644
--- a/plat/allwinner/common/sunxi_bl31_setup.c
+++ b/plat/allwinner/common/sunxi_bl31_setup.c
@@ -10,13 +10,14 @@
#include <debug.h>
#include <generic_delay_timer.h>
#include <gicv2.h>
+#include <libfdt.h>
#include <platform.h>
#include <platform_def.h>
#include <sunxi_def.h>
#include <sunxi_mmap.h>
+#include <sunxi_private.h>
#include <uart_16550.h>
-#include "sunxi_private.h"
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
@@ -28,6 +29,47 @@ static const gicv2_driver_data_t sunxi_gic_data = {
.gicc_base = SUNXI_GICC_BASE,
};
+/*
+ * Try to find a DTB loaded in memory by previous stages.
+ *
+ * At the moment we implement a heuristic to find the DTB attached to U-Boot:
+ * U-Boot appends its DTB to the end of the image. Assuming that BL33 is
+ * U-Boot, try to find the size of the U-Boot image to learn the DTB address.
+ * The generic ARMv8 U-Boot image contains the load address and its size
+ * as u64 variables at the beginning of the image. There might be padding
+ * or other headers before that data, so scan the first 2KB after the BL33
+ * entry point to find the load address, which should be followed by the
+ * size. Adding those together gives us the address of the DTB.
+ */
+static void *sunxi_find_dtb(void)
+{
+ uint64_t *u_boot_base;
+ int i;
+
+ u_boot_base = (void *)(SUNXI_DRAM_VIRT_BASE + SUNXI_DRAM_SEC_SIZE);
+
+ for (i = 0; i < 2048 / sizeof(uint64_t); i++) {
+ uint32_t *dtb_base;
+
+ if (u_boot_base[i] != PLAT_SUNXI_NS_IMAGE_OFFSET)
+ continue;
+
+ /* Does the suspected U-Boot size look anyhow reasonable? */
+ if (u_boot_base[i + 1] >= 256 * 1024 * 1024)
+ continue;
+
+ /* end of the image: base address + size */
+ dtb_base = (void *)((char *)u_boot_base + u_boot_base[i + 1]);
+
+ if (fdt_check_header(dtb_base) != 0)
+ continue;
+
+ return dtb_base;
+ }
+
+ return NULL;
+}
+
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
@@ -66,15 +108,16 @@ void bl31_platform_setup(void)
{
const char *soc_name;
uint16_t soc_id = sunxi_read_soc_id();
+ void *fdt;
switch (soc_id) {
- case 0x1689:
+ case SUNXI_SOC_A64:
soc_name = "A64/H64/R18";
break;
- case 0x1718:
+ case SUNXI_SOC_H5:
soc_name = "H5";
break;
- case 0x1728:
+ case SUNXI_SOC_H6:
soc_name = "H6";
break;
default:
@@ -85,6 +128,18 @@ void bl31_platform_setup(void)
generic_delay_timer_init();
+ fdt = sunxi_find_dtb();
+ if (fdt) {
+ const char *model;
+ int length;
+
+ model = fdt_getprop(fdt, 0, "model", &length);
+ NOTICE("BL31: Found U-Boot DTB at %p, model: %s\n", fdt,
+ model ?: "unknown");
+ } else {
+ NOTICE("BL31: No DTB found.\n");
+ }
+
/* Configure the interrupt controller */
gicv2_driver_init(&sunxi_gic_data);
gicv2_distif_init();
@@ -93,7 +148,7 @@ void bl31_platform_setup(void)
sunxi_security_setup();
- sunxi_pmic_setup();
+ sunxi_pmic_setup(soc_id, fdt);
INFO("BL31: Platform setup done\n");
}
diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c
index fc9bf2097..2eb26a91b 100644
--- a/plat/allwinner/common/sunxi_common.c
+++ b/plat/allwinner/common/sunxi_common.c
@@ -4,21 +4,28 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <arch_helpers.h>
+#include <debug.h>
+#include <errno.h>
#include <mmio.h>
#include <platform.h>
#include <platform_def.h>
#include <sunxi_def.h>
+#include <sunxi_mmap.h>
+#include <sunxi_private.h>
#include <xlat_tables_v2.h>
-#include "sunxi_private.h"
-
static mmap_region_t sunxi_mmap[PLATFORM_MMAP_REGIONS + 1] = {
MAP_REGION_FLAT(SUNXI_SRAM_BASE, SUNXI_SRAM_SIZE,
MT_MEMORY | MT_RW | MT_SECURE),
MAP_REGION_FLAT(SUNXI_DEV_BASE, SUNXI_DEV_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(SUNXI_DRAM_BASE, SUNXI_DRAM_SIZE,
- MT_MEMORY | MT_RW | MT_NS),
+ MAP_REGION(SUNXI_DRAM_BASE, SUNXI_DRAM_VIRT_BASE, SUNXI_DRAM_SEC_SIZE,
+ MT_MEMORY | MT_RW | MT_SECURE),
+ MAP_REGION(PLAT_SUNXI_NS_IMAGE_OFFSET,
+ SUNXI_DRAM_VIRT_BASE + SUNXI_DRAM_SEC_SIZE,
+ SUNXI_DRAM_MAP_SIZE,
+ MT_MEMORY | MT_RO | MT_NS),
{},
};
@@ -47,9 +54,6 @@ void sunxi_configure_mmu_el3(int flags)
mmap_add_region(BL_RO_DATA_BASE, BL_RO_DATA_BASE,
BL_RO_DATA_END - BL_RO_DATA_BASE,
MT_RO_DATA | MT_SECURE);
- mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
- BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
- MT_DEVICE | MT_RW | MT_SECURE);
mmap_add(sunxi_mmap);
init_xlat_tables();
@@ -71,3 +75,136 @@ uint16_t sunxi_read_soc_id(void)
return reg >> 16;
}
+
+/*
+ * Configure a given pin to the GPIO-OUT function and sets its level.
+ * The port is given as a capital letter, the pin is the number within
+ * this port group.
+ * So to set pin PC7 to high, use: sunxi_set_gpio_out('C', 7, true);
+ */
+void sunxi_set_gpio_out(char port, int pin, bool level_high)
+{
+ uintptr_t port_base;
+
+ if (port < 'A' || port > 'L')
+ return;
+ if (port == 'L')
+ port_base = SUNXI_R_PIO_BASE;
+ else
+ port_base = SUNXI_PIO_BASE + (port - 'A') * 0x24;
+
+ /* Set the new level first before configuring the pin. */
+ if (level_high)
+ mmio_setbits_32(port_base + 0x10, BIT(pin));
+ else
+ mmio_clrbits_32(port_base + 0x10, BIT(pin));
+
+ /* configure pin as GPIO out (4(3) bits per pin, 1: GPIO out */
+ mmio_clrsetbits_32(port_base + (pin / 8) * 4,
+ 0x7 << ((pin % 8) * 4),
+ 0x1 << ((pin % 8) * 4));
+}
+
+int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb)
+{
+ uint32_t pin_func = 0x77;
+ uint32_t device_bit;
+ unsigned int reset_offset = 0xb0;
+
+ switch (socid) {
+ case SUNXI_SOC_H5:
+ if (use_rsb)
+ return -ENODEV;
+ pin_func = 0x22;
+ device_bit = BIT(6);
+ break;
+ case SUNXI_SOC_H6:
+ if (use_rsb)
+ return -ENODEV;
+ pin_func = 0x33;
+ device_bit = BIT(16);
+ reset_offset = 0x19c;
+ break;
+ case SUNXI_SOC_A64:
+ pin_func = use_rsb ? 0x22 : 0x33;
+ device_bit = use_rsb ? BIT(3) : BIT(6);
+ break;
+ default:
+ INFO("R_I2C/RSB on Allwinner 0x%x SoC not supported\n", socid);
+ return -ENODEV;
+ }
+
+ /* un-gate R_PIO clock */
+ if (socid != SUNXI_SOC_H6)
+ mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x28, BIT(0));
+
+ /* switch pins PL0 and PL1 to the desired function */
+ mmio_clrsetbits_32(SUNXI_R_PIO_BASE + 0x00, 0xffU, pin_func);
+
+ /* level 2 drive strength */
+ mmio_clrsetbits_32(SUNXI_R_PIO_BASE + 0x14, 0x0fU, 0xaU);
+
+ /* set both pins to pull-up */
+ mmio_clrsetbits_32(SUNXI_R_PIO_BASE + 0x1c, 0x0fU, 0x5U);
+
+ /* assert, then de-assert reset of I2C/RSB controller */
+ mmio_clrbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit);
+ mmio_setbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit);
+
+ /* un-gate clock */
+ if (socid != SUNXI_SOC_H6)
+ mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x28, device_bit);
+ else
+ mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x19c, device_bit | BIT(0));
+
+ return 0;
+}
+
+/* This lock synchronises access to the arisc management processor. */
+DEFINE_BAKERY_LOCK(arisc_lock);
+
+/*
+ * Tell the "arisc" SCP core (an OpenRISC core) to execute some code.
+ * We don't have any service running there, so we place some OpenRISC code
+ * in SRAM, put the address of that into the reset vector and release the
+ * arisc reset line. The SCP will execute that code and pull the line up again.
+ */
+void sunxi_execute_arisc_code(uint32_t *code, size_t size,
+ int patch_offset, uint16_t param)
+{
+ uintptr_t arisc_reset_vec = SUNXI_SRAM_A2_BASE - 0x4000 + 0x100;
+
+ do {
+ bakery_lock_get(&arisc_lock);
+ /* Wait until the arisc is in reset state. */
+ if (!(mmio_read_32(SUNXI_R_CPUCFG_BASE) & BIT(0)))
+ break;
+
+ bakery_lock_release(&arisc_lock);
+ } while (1);
+
+ /* Patch up the code to feed in an input parameter. */
+ if (patch_offset >= 0 && patch_offset <= (size - 4))
+ code[patch_offset] = (code[patch_offset] & ~0xffff) | param;
+ clean_dcache_range((uintptr_t)code, size);
+
+ /*
+ * The OpenRISC unconditional branch has opcode 0, the branch offset
+ * is in the lower 26 bits, containing the distance to the target,
+ * in instruction granularity (32 bits).
+ */
+ mmio_write_32(arisc_reset_vec, ((uintptr_t)code - arisc_reset_vec) / 4);
+ clean_dcache_range(arisc_reset_vec, 4);
+
+ /* De-assert the arisc reset line to let it run. */
+ mmio_setbits_32(SUNXI_R_CPUCFG_BASE, BIT(0));
+
+ /*
+ * We release the lock here, although the arisc is still busy.
+ * But as long as it runs, the reset line is high, so other users
+ * won't leave the loop above.
+ * Once it has finished, the code is supposed to clear the reset line,
+ * to signal this to other users.
+ */
+ bakery_lock_release(&arisc_lock);
+}
diff --git a/plat/allwinner/common/sunxi_cpu_ops.c b/plat/allwinner/common/sunxi_cpu_ops.c
index aaee65c66..3b732b5d1 100644
--- a/plat/allwinner/common/sunxi_cpu_ops.c
+++ b/plat/allwinner/common/sunxi_cpu_ops.c
@@ -4,15 +4,19 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <arch_helpers.h>
+#include <assert.h>
+#include <core_off_arisc.h>
#include <debug.h>
+#include <delay_timer.h>
#include <mmio.h>
+#include <platform.h>
#include <platform_def.h>
-#include <sunxi_mmap.h>
#include <sunxi_cpucfg.h>
+#include <sunxi_mmap.h>
+#include <sunxi_private.h>
#include <utils_def.h>
-#include "sunxi_private.h"
-
static void sunxi_cpu_disable_power(unsigned int cluster, unsigned int core)
{
if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0xff)
@@ -40,16 +44,37 @@ static void sunxi_cpu_enable_power(unsigned int cluster, unsigned int core)
void sunxi_cpu_off(unsigned int cluster, unsigned int core)
{
+ int corenr = cluster * PLATFORM_MAX_CPUS_PER_CLUSTER + core;
+
VERBOSE("PSCI: Powering off cluster %d core %d\n", cluster, core);
/* Deassert DBGPWRDUP */
mmio_clrbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
- /* Activate the core output clamps */
- 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 (plat_my_core_pos() != corenr) {
+ /* Activate the core output clamps, but not for core 0. */
+ if (corenr != 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;
+ }
+
+ /* Simplifies assembly, all SoCs so far are single cluster anyway. */
+ assert(cluster == 0);
+
+ /*
+ * If we are supposed to turn ourself off, tell the arisc SCP
+ * to do that work for us. The code expects the core mask to be
+ * patched into the first instruction.
+ */
+ sunxi_execute_arisc_code(arisc_core_off, sizeof(arisc_core_off),
+ 0, BIT_32(core));
}
void sunxi_cpu_on(unsigned int cluster, unsigned int core)
diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c
index e4bb58229..7d13cdad1 100644
--- a/plat/allwinner/common/sunxi_pm.c
+++ b/plat/allwinner/common/sunxi_pm.c
@@ -13,15 +13,14 @@
#include <platform.h>
#include <platform_def.h>
#include <psci.h>
-#include <sunxi_mmap.h>
#include <sunxi_cpucfg.h>
+#include <sunxi_mmap.h>
+#include <sunxi_private.h>
#define SUNXI_WDOG0_CTRL_REG (SUNXI_WDOG_BASE + 0x0010)
#define SUNXI_WDOG0_CFG_REG (SUNXI_WDOG_BASE + 0x0014)
#define SUNXI_WDOG0_MODE_REG (SUNXI_WDOG_BASE + 0x0018)
-#include "sunxi_private.h"
-
#define mpidr_is_valid(mpidr) ( \
MPIDR_AFFLVL3_VAL(mpidr) == 0 && \
MPIDR_AFFLVL2_VAL(mpidr) == 0 && \
@@ -43,6 +42,16 @@ static void sunxi_pwr_domain_off(const psci_power_state_t *target_state)
gicv2_cpuif_disable();
}
+static void __dead2 sunxi_pwr_down_wfi(const psci_power_state_t *target_state)
+{
+ u_register_t mpidr = read_mpidr();
+
+ sunxi_cpu_off(MPIDR_AFFLVL1_VAL(mpidr), MPIDR_AFFLVL0_VAL(mpidr));
+
+ while (1)
+ wfi();
+}
+
static void sunxi_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
gicv2_pcpu_distif_init();
@@ -83,6 +92,7 @@ static int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint)
static plat_psci_ops_t sunxi_psci_ops = {
.pwr_domain_on = sunxi_pwr_domain_on,
.pwr_domain_off = sunxi_pwr_domain_off,
+ .pwr_domain_pwr_down_wfi = sunxi_pwr_down_wfi,
.pwr_domain_on_finish = sunxi_pwr_domain_on_finish,
.system_off = sunxi_system_off,
.system_reset = sunxi_system_reset,
diff --git a/plat/allwinner/common/sunxi_security.c b/plat/allwinner/common/sunxi_security.c
index 80fed6ad0..905372887 100644
--- a/plat/allwinner/common/sunxi_security.c
+++ b/plat/allwinner/common/sunxi_security.c
@@ -7,6 +7,7 @@
#include <debug.h>
#include <mmio.h>
#include <sunxi_mmap.h>
+#include <sunxi_private.h>
#ifdef SUNXI_SPC_BASE
#define SPC_DECPORT_STA_REG(p) (SUNXI_SPC_BASE + ((p) * 0x0c) + 0x4)
diff --git a/plat/allwinner/sun50i_a64/include/core_off_arisc.h b/plat/allwinner/sun50i_a64/include/core_off_arisc.h
new file mode 100644
index 000000000..ae436ca1b
--- /dev/null
+++ b/plat/allwinner/sun50i_a64/include/core_off_arisc.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+static uint32_t arisc_core_off[] = {
+ 0x18600000, /* l.movhi r3, <corenr> */
+ 0x18000000, /* l.movhi r0, 0x0 */
+ 0x19a00170, /* l.movhi r13, 0x170 */
+ 0x84ad0030, /* l.lwz r5, 0x30(r13) */
+ 0xe0a51803, /* l.and r5, r5, r3 */
+ 0xe4050000, /* l.sfeq r5, r0 */
+ 0x13fffffd, /* l.bf -12 */
+
+ 0xb8c30050, /* l.srli r6, r3, 16 */
+ 0xbc060001, /* l.sfeqi r6, 1 */
+ 0x10000005, /* l.bf +20 */
+ 0x19a001f0, /* l.movhi r13, 0x1f0 */
+ 0x84ad1500, /* l.lwz r5, 0x1500(r13) */
+ 0xe0a53004, /* l.or r5, r5, r6 */
+ 0xd44d2d00, /* l.sw 0x1500(r13), r5 */
+
+ 0x84ad1c30, /* l.lwz r5, 0x1c30(r13) */
+ 0xacc6ffff, /* l.xori r6, r6, -1 */
+ 0xe0a53003, /* l.and r5, r5, r6 */
+ 0xd46d2c30, /* l.sw 0x1c30(r13), r5 */
+
+ 0xe0c3000f, /* l.ff1 r6, r3 */
+ 0x9cc6ffef, /* l.addi r6, r6, -17 */
+ 0xb8c60002, /* l.slli r6, r6, 2 */
+ 0xe0c66800, /* l.add r6, r6, r13 */
+ 0xa8a000ff, /* l.ori r5, r0, 0xff */
+ 0xd4462d40, /* l.sw 0x1540(r6), r5 */
+
+ 0xd46d0400, /* l.sw 0x1c00(r13), r0 */
+ 0x03ffffff, /* l.j -1 */
+ 0x15000000, /* l.nop */
+};
diff --git a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
index 7d46487dc..28b1dd3b8 100644
--- a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
+++ b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
@@ -21,7 +21,7 @@
#define SUNXI_DEV_BASE 0x01000000
#define SUNXI_DEV_SIZE 0x01000000
#define SUNXI_DRAM_BASE 0x40000000
-#define SUNXI_DRAM_SIZE 0x80000000
+#define SUNXI_DRAM_VIRT_BASE 0x02000000
/* Memory-mapped devices */
#define SUNXI_CPU_MBIST_BASE 0x01502000
diff --git a/plat/allwinner/sun50i_a64/platform.mk b/plat/allwinner/sun50i_a64/platform.mk
index 221665471..b46fbc2d1 100644
--- a/plat/allwinner/sun50i_a64/platform.mk
+++ b/plat/allwinner/sun50i_a64/platform.mk
@@ -4,51 +4,7 @@
# SPDX-License-Identifier: BSD-3-Clause
#
-include lib/xlat_tables_v2/xlat_tables.mk
+# The differences between the platform are covered by the include files.
+include plat/allwinner/common/allwinner-common.mk
-AW_PLAT := plat/allwinner
-
-PLAT_INCLUDES := -Iinclude/plat/arm/common/ \
- -Iinclude/plat/arm/common/aarch64 \
- -I${AW_PLAT}/common/include \
- -I${AW_PLAT}/${PLAT}/include
-
-PLAT_BL_COMMON_SOURCES := drivers/console/${ARCH}/console.S \
- drivers/ti/uart/${ARCH}/16550_console.S \
- ${XLAT_TABLES_LIB_SRCS} \
- ${AW_PLAT}/common/plat_helpers.S \
- ${AW_PLAT}/common/sunxi_common.c
-
-BL31_SOURCES += drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v2/gicv2_helpers.c \
- drivers/arm/gic/v2/gicv2_main.c \
- drivers/delay_timer/delay_timer.c \
- drivers/delay_timer/generic_delay_timer.c \
- lib/cpus/${ARCH}/cortex_a53.S \
- 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}/sun50i_a64/sunxi_power.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.
-COLD_BOOT_SINGLE_CPU := 1
-
-# Enable workarounds for Cortex-A53 errata. Allwinner uses at least r0p4.
-ERRATA_A53_835769 := 1
-ERRATA_A53_843419 := 1
-ERRATA_A53_855873 := 1
-
-MULTI_CONSOLE_API := 1
-
-# The reset vector can be changed for each CPU.
-PROGRAMMABLE_RESET_ADDRESS := 1
-
-# Allow mapping read-only data as execute-never.
-SEPARATE_CODE_AND_RODATA := 1
-
-# BL31 gets loaded alongside BL33 (U-Boot) by U-Boot's SPL
-RESET_TO_BL31 := 1
+PLAT_BL_COMMON_SOURCES += drivers/allwinner/sunxi_rsb.c
diff --git a/plat/allwinner/sun50i_a64/sunxi_power.c b/plat/allwinner/sun50i_a64/sunxi_power.c
index c1907d6d2..af3047731 100644
--- a/plat/allwinner/sun50i_a64/sunxi_power.c
+++ b/plat/allwinner/sun50i_a64/sunxi_power.c
@@ -5,20 +5,350 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <allwinner/sunxi_rsb.h>
#include <arch_helpers.h>
#include <debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <sunxi_def.h>
+#include <sunxi_mmap.h>
+#include <sunxi_private.h>
-int sunxi_pmic_setup(void)
+static enum pmic_type {
+ GENERIC_H5,
+ GENERIC_A64,
+ REF_DESIGN_H5, /* regulators controlled by GPIO pins on port L */
+ AXP803_RSB, /* PMIC connected via RSB on most A64 boards */
+} pmic;
+
+#define AXP803_HW_ADDR 0x3a3
+#define AXP803_RT_ADDR 0x2d
+
+/*
+ * On boards without a proper PMIC we struggle to turn off the system properly.
+ * Try to turn off as much off the system as we can, to reduce power
+ * consumption. This should be entered with only one core running and SMP
+ * disabled.
+ * This function only cares about peripherals.
+ */
+void sunxi_turn_off_soc(uint16_t socid)
+{
+ int i;
+
+ /** Turn off most peripherals, most importantly DRAM users. **/
+ /* Keep DRAM controller running for now. */
+ mmio_clrbits_32(SUNXI_CCU_BASE + 0x2c0, ~BIT_32(14));
+ mmio_clrbits_32(SUNXI_CCU_BASE + 0x60, ~BIT_32(14));
+ /* Contains msgbox (bit 21) and spinlock (bit 22) */
+ mmio_write_32(SUNXI_CCU_BASE + 0x2c4, 0);
+ mmio_write_32(SUNXI_CCU_BASE + 0x64, 0);
+ mmio_write_32(SUNXI_CCU_BASE + 0x2c8, 0);
+ /* Keep PIO controller running for now. */
+ mmio_clrbits_32(SUNXI_CCU_BASE + 0x68, ~(BIT_32(5)));
+ mmio_write_32(SUNXI_CCU_BASE + 0x2d0, 0);
+ /* Contains UART0 (bit 16) */
+ mmio_write_32(SUNXI_CCU_BASE + 0x2d8, 0);
+ mmio_write_32(SUNXI_CCU_BASE + 0x6c, 0);
+ mmio_write_32(SUNXI_CCU_BASE + 0x70, 0);
+
+ /** Turn off DRAM controller. **/
+ mmio_clrbits_32(SUNXI_CCU_BASE + 0x2c0, BIT_32(14));
+ mmio_clrbits_32(SUNXI_CCU_BASE + 0x60, BIT_32(14));
+
+ /** Migrate CPU and bus clocks away from the PLLs. **/
+ /* AHB1: use OSC24M/1, APB1 = AHB1 / 2 */
+ mmio_write_32(SUNXI_CCU_BASE + 0x54, 0x1000);
+ /* APB2: use OSC24M */
+ mmio_write_32(SUNXI_CCU_BASE + 0x58, 0x1000000);
+ /* AHB2: use AHB1 clock */
+ mmio_write_32(SUNXI_CCU_BASE + 0x5c, 0);
+ /* CPU: use OSC24M */
+ mmio_write_32(SUNXI_CCU_BASE + 0x50, 0x10000);
+
+ /** Turn off PLLs. **/
+ for (i = 0; i < 6; i++)
+ mmio_clrbits_32(SUNXI_CCU_BASE + i * 8, BIT(31));
+ switch (socid) {
+ case SUNXI_SOC_H5:
+ mmio_clrbits_32(SUNXI_CCU_BASE + 0x44, BIT(31));
+ break;
+ case SUNXI_SOC_A64:
+ mmio_clrbits_32(SUNXI_CCU_BASE + 0x2c, BIT(31));
+ mmio_clrbits_32(SUNXI_CCU_BASE + 0x4c, BIT(31));
+ break;
+ }
+}
+
+static int rsb_init(void)
+{
+ int ret;
+
+ ret = rsb_init_controller();
+ if (ret)
+ return ret;
+
+ /* Start with 400 KHz to issue the I2C->RSB switch command. */
+ ret = rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ, 400000);
+ if (ret)
+ return ret;
+
+ /*
+ * Initiate an I2C transaction to write 0x7c into register 0x3e,
+ * switching the PMIC to RSB mode.
+ */
+ ret = rsb_set_device_mode(0x7c3e00);
+ if (ret)
+ return ret;
+
+ /* Now in RSB mode, switch to the recommended 3 MHz. */
+ ret = rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ, 3000000);
+ if (ret)
+ return ret;
+
+ /* Associate the 8-bit runtime address with the 12-bit bus address. */
+ return rsb_assign_runtime_address(AXP803_HW_ADDR,
+ AXP803_RT_ADDR);
+}
+
+static int axp_write(uint8_t reg, uint8_t val)
+{
+ return rsb_write(AXP803_RT_ADDR, reg, val);
+}
+
+static int axp_setbits(uint8_t reg, uint8_t set_mask)
+{
+ uint8_t regval;
+ int ret;
+
+ ret = rsb_read(AXP803_RT_ADDR, reg);
+ if (ret < 0)
+ return ret;
+
+ regval = ret | set_mask;
+
+ return rsb_write(AXP803_RT_ADDR, reg, regval);
+}
+
+static bool should_enable_regulator(const void *fdt, int node)
{
- /* STUB */
- NOTICE("BL31: STUB PMIC setup code called\n");
+ if (fdt_getprop(fdt, node, "phandle", NULL) != NULL)
+ return true;
+ if (fdt_getprop(fdt, node, "regulator-always-on", NULL) != NULL)
+ return true;
+ return false;
+}
+
+/*
+ * Retrieve the voltage from a given regulator DTB node.
+ * Both the regulator-{min,max}-microvolt properties must be present and
+ * have the same value. Return that value in millivolts.
+ */
+static int fdt_get_regulator_millivolt(const void *fdt, int node)
+{
+ const fdt32_t *prop;
+ uint32_t min_volt;
+
+ prop = fdt_getprop(fdt, node, "regulator-min-microvolt", NULL);
+ if (prop == NULL)
+ return -EINVAL;
+ min_volt = fdt32_to_cpu(*prop);
+
+ prop = fdt_getprop(fdt, node, "regulator-max-microvolt", NULL);
+ if (prop == NULL)
+ return -EINVAL;
+
+ if (fdt32_to_cpu(*prop) != min_volt)
+ return -EINVAL;
+
+ return min_volt / 1000;
+}
+
+#define NO_SPLIT 0xff
+
+struct axp_regulator {
+ char *dt_name;
+ uint16_t min_volt;
+ uint16_t max_volt;
+ uint16_t step;
+ unsigned char split;
+ unsigned char volt_reg;
+ unsigned char switch_reg;
+ unsigned char switch_bit;
+} regulators[] = {
+ {"dcdc1", 1600, 3400, 100, NO_SPLIT, 0x20, 0xff, 9},
+ {"dcdc5", 800, 1840, 10, 32, 0x24, 0xff, 9},
+ {"dldo1", 700, 3300, 100, NO_SPLIT, 0x15, 0x12, 3},
+ {"dldo2", 700, 4200, 100, 27, 0x16, 0x12, 4},
+ {"dldo3", 700, 3300, 100, NO_SPLIT, 0x17, 0x12, 5},
+ {"fldo1", 700, 1450, 50, NO_SPLIT, 0x1c, 0x13, 2},
+ {}
+};
+
+static int setup_regulator(const void *fdt, int node,
+ const struct axp_regulator *reg)
+{
+ int mvolt;
+ uint8_t regval;
+
+ if (!should_enable_regulator(fdt, node))
+ return -ENOENT;
+
+ mvolt = fdt_get_regulator_millivolt(fdt, node);
+ if (mvolt < reg->min_volt || mvolt > reg->max_volt)
+ return -EINVAL;
+
+ regval = (mvolt / reg->step) - (reg->min_volt / reg->step);
+ if (regval > reg->split)
+ regval = ((regval - reg->split) / 2) + reg->split;
+
+ axp_write(reg->volt_reg, regval);
+ if (reg->switch_reg < 0xff)
+ axp_setbits(reg->switch_reg, BIT(reg->switch_bit));
+
+ INFO("PMIC: AXP803: %s voltage: %d.%03dV\n", reg->dt_name,
+ mvolt / 1000, mvolt % 1000);
return 0;
}
+static void setup_axp803_rails(const void *fdt)
+{
+ int node;
+ bool dc1sw = false;
+
+ /* locate the PMIC DT node, bail out if not found */
+ node = fdt_node_offset_by_compatible(fdt, -1, "x-powers,axp803");
+ if (node == -FDT_ERR_NOTFOUND) {
+ WARN("BL31: PMIC: No AXP803 DT node, skipping initial setup.\n");
+ return;
+ }
+
+ if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL))
+ axp_setbits(0x8f, BIT(4));
+
+ /* descend into the "regulators" subnode */
+ node = fdt_first_subnode(fdt, node);
+
+ /* iterate over all regulators to find used ones */
+ for (node = fdt_first_subnode(fdt, node);
+ node != -FDT_ERR_NOTFOUND;
+ node = fdt_next_subnode(fdt, node)) {
+ struct axp_regulator *reg;
+ const char *name;
+ int length;
+
+ /* We only care if it's always on or referenced. */
+ if (!should_enable_regulator(fdt, node))
+ continue;
+
+ name = fdt_get_name(fdt, node, &length);
+ for (reg = regulators; reg->dt_name; reg++) {
+ if (!strncmp(name, reg->dt_name, length)) {
+ setup_regulator(fdt, node, reg);
+ break;
+ }
+ }
+
+ if (!strncmp(name, "dc1sw", length)) {
+ /* Delay DC1SW enablement to avoid overheating. */
+ dc1sw = true;
+ continue;
+ }
+ }
+ /*
+ * If DLDO2 is enabled after DC1SW, the PMIC overheats and shuts
+ * down. So always enable DC1SW as the very last regulator.
+ */
+ if (dc1sw) {
+ INFO("PMIC: AXP803: Enabling DC1SW\n");
+ axp_setbits(0x12, BIT(7));
+ }
+}
+
+int sunxi_pmic_setup(uint16_t socid, const void *fdt)
+{
+ int ret;
+
+ switch (socid) {
+ case SUNXI_SOC_H5:
+ pmic = REF_DESIGN_H5;
+ NOTICE("BL31: PMIC: Defaulting to PortL GPIO according to H5 reference design.\n");
+ break;
+ case SUNXI_SOC_A64:
+ pmic = GENERIC_A64;
+ ret = sunxi_init_platform_r_twi(socid, true);
+ if (ret)
+ return ret;
+
+ ret = rsb_init();
+ if (ret)
+ return ret;
+
+ pmic = AXP803_RSB;
+ NOTICE("BL31: PMIC: Detected AXP803 on RSB.\n");
+
+ if (fdt)
+ setup_axp803_rails(fdt);
+
+ break;
+ default:
+ NOTICE("BL31: PMIC: No support for Allwinner %x SoC.\n", socid);
+ return -ENODEV;
+ }
+ return 0;
+}
+
void __dead2 sunxi_power_down(void)
{
- ERROR("PSCI: Full shutdown not implemented, halting\n");
+ switch (pmic) {
+ case GENERIC_H5:
+ /* Turn off as many peripherals and clocks as we can. */
+ sunxi_turn_off_soc(SUNXI_SOC_H5);
+ /* Turn off the pin controller now. */
+ mmio_write_32(SUNXI_CCU_BASE + 0x68, 0);
+ break;
+ case GENERIC_A64:
+ /* Turn off as many peripherals and clocks as we can. */
+ sunxi_turn_off_soc(SUNXI_SOC_A64);
+ /* Turn off the pin controller now. */
+ mmio_write_32(SUNXI_CCU_BASE + 0x68, 0);
+ break;
+ case REF_DESIGN_H5:
+ sunxi_turn_off_soc(SUNXI_SOC_H5);
+
+ /*
+ * Switch PL pins to power off the board:
+ * - PL5 (VCC_IO) -> high
+ * - PL8 (PWR-STB = CPU power supply) -> low
+ * - PL9 (PWR-DRAM) ->low
+ * - PL10 (power LED) -> low
+ * Note: Clearing PL8 will reset the board, so keep it up.
+ */
+ sunxi_set_gpio_out('L', 5, 1);
+ sunxi_set_gpio_out('L', 9, 0);
+ sunxi_set_gpio_out('L', 10, 0);
+
+ /* Turn off pin controller now. */
+ mmio_write_32(SUNXI_CCU_BASE + 0x68, 0);
+
+ break;
+ case AXP803_RSB:
+ /* (Re-)init RSB in case the rich OS has disabled it. */
+ sunxi_init_platform_r_twi(SUNXI_SOC_A64, true);
+ rsb_init();
+
+ /* Set "power disable control" bit */
+ axp_setbits(0x32, BIT(7));
+ break;
+ default:
+ break;
+ }
+
+ udelay(1000);
+ ERROR("PSCI: Cannot turn off system, halting.\n");
wfi();
panic();
}
diff --git a/plat/allwinner/sun50i_h6/include/core_off_arisc.h b/plat/allwinner/sun50i_h6/include/core_off_arisc.h
new file mode 100644
index 000000000..63a5d8d96
--- /dev/null
+++ b/plat/allwinner/sun50i_h6/include/core_off_arisc.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+static uint32_t arisc_core_off[] = {
+ 0x18600000, /* l.movhi r3, <corenr> */
+ 0x18000000, /* l.movhi r0, 0x0 */
+ 0x19a00901, /* l.movhi r13, 0x901 */
+ 0x84ad0080, /* l.lwz r5, 0x80(r13) */
+ 0xe0a51803, /* l.and r5, r5, r3 */
+ 0xe4050000, /* l.sfeq r5, r0 */
+ 0x13fffffd, /* l.bf -12 */
+ 0xb8c30050, /* l.srli r6, r3, 16 */
+
+ 0xbc060001, /* l.sfeqi r6, 1 */
+ 0x10000005, /* l.bf +20 */
+ 0x19a00700, /* l.movhi r13, 0x700 */
+ 0x84ad0444, /* l.lwz r5, 0x0444(r13) */
+ 0xe0a53004, /* l.or r5, r5, r6 */
+ 0xd40d2c44, /* l.sw 0x0444(r13), r5 */
+
+ 0x84ad0440, /* l.lwz r5, 0x0440(r13) */
+ 0xacc6ffff, /* l.xori r6, r6, -1 */
+ 0xe0a53003, /* l.and r5, r5, r6 */
+ 0xd40d2c40, /* l.sw 0x0440(r13), r5 */
+
+ 0xe0c3000f, /* l.ff1 r6, r3 */
+ 0x9cc6ffef, /* l.addi r6, r6, -17 */
+ 0xb8c60002, /* l.slli r6, r6, 2 */
+ 0xe0c66800, /* l.add r6, r6, r13 */
+ 0xa8a000ff, /* l.ori r5, r0, 0xff */
+ 0xd4062c50, /* l.sw 0x0450(r6), r5 */
+
+ 0xd40d0400, /* l.sw 0x0400(r13), r0 */
+ 0x03ffffff, /* l.j -1 */
+ 0x15000000, /* l.nop */
+};
diff --git a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
index f2d5aed6b..ff1eb61e9 100644
--- a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
+++ b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
@@ -11,7 +11,7 @@
#define SUNXI_ROM_BASE 0x00000000
#define SUNXI_ROM_SIZE 0x00010000
#define SUNXI_SRAM_BASE 0x00020000
-#define SUNXI_SRAM_SIZE 0x00098000
+#define SUNXI_SRAM_SIZE 0x000f8000
#define SUNXI_SRAM_A1_BASE 0x00020000
#define SUNXI_SRAM_A1_SIZE 0x00008000
#define SUNXI_SRAM_A2_BASE 0x00104000
@@ -21,7 +21,7 @@
#define SUNXI_DEV_BASE 0x01000000
#define SUNXI_DEV_SIZE 0x09000000
#define SUNXI_DRAM_BASE 0x40000000
-#define SUNXI_DRAM_SIZE 0xc0000000
+#define SUNXI_DRAM_VIRT_BASE 0x0a000000
/* Memory-mapped devices */
#define SUNXI_SYSCON_BASE 0x03000000
diff --git a/plat/allwinner/sun50i_h6/platform.mk b/plat/allwinner/sun50i_h6/platform.mk
index 4fb8986d6..5c21eadb2 100644
--- a/plat/allwinner/sun50i_h6/platform.mk
+++ b/plat/allwinner/sun50i_h6/platform.mk
@@ -4,53 +4,7 @@
# SPDX-License-Identifier: BSD-3-Clause
#
-include lib/xlat_tables_v2/xlat_tables.mk
+# The differences between the platform are covered by the include files.
+include plat/allwinner/common/allwinner-common.mk
-AW_PLAT := plat/allwinner
-AW_DRIVERS := drivers/allwinner
-
-PLAT_INCLUDES := -Iinclude/plat/arm/common \
- -Iinclude/plat/arm/common/aarch64 \
- -I${AW_PLAT}/common/include \
- -I${AW_PLAT}/${PLAT}/include
-
-PLAT_BL_COMMON_SOURCES := drivers/console/${ARCH}/console.S \
- drivers/mentor/i2c/mi2cv.c \
- drivers/ti/uart/${ARCH}/16550_console.S \
- ${XLAT_TABLES_LIB_SRCS} \
- ${AW_PLAT}/common/plat_helpers.S \
- ${AW_PLAT}/common/sunxi_common.c
-
-BL31_SOURCES += drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v2/gicv2_helpers.c \
- drivers/arm/gic/v2/gicv2_main.c \
- drivers/delay_timer/delay_timer.c \
- drivers/delay_timer/generic_delay_timer.c \
- lib/cpus/${ARCH}/cortex_a53.S \
- 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}/sun50i_h6/sunxi_power.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.
-COLD_BOOT_SINGLE_CPU := 1
-
-# Enable workarounds for Cortex-A53 errata. Allwinner uses at least r0p4.
-ERRATA_A53_835769 := 1
-ERRATA_A53_843419 := 1
-ERRATA_A53_855873 := 1
-
-MULTI_CONSOLE_API := 1
-
-# The reset vector can be changed for each CPU.
-PROGRAMMABLE_RESET_ADDRESS := 1
-
-# Allow mapping read-only data as execute-never.
-SEPARATE_CODE_AND_RODATA := 1
-
-# BL31 gets loaded alongside BL33 (U-Boot) by U-Boot's SPL
-RESET_TO_BL31 := 1
+PLAT_BL_COMMON_SOURCES += drivers/mentor/i2c/mi2cv.c
diff --git a/plat/allwinner/sun50i_h6/sunxi_power.c b/plat/allwinner/sun50i_h6/sunxi_power.c
index 12438b339..7bdac8ab0 100644
--- a/plat/allwinner/sun50i_h6/sunxi_power.c
+++ b/plat/allwinner/sun50i_h6/sunxi_power.c
@@ -12,7 +12,9 @@
#include <mmio.h>
#include <mentor/mi2cv.h>
#include <string.h>
+#include <sunxi_def.h>
#include <sunxi_mmap.h>
+#include <sunxi_private.h>
#define AXP805_ADDR 0x36
#define AXP805_ID 0x03
@@ -24,36 +26,6 @@ enum pmic_type {
enum pmic_type pmic;
-static int sunxi_init_r_i2c(void)
-{
- uint32_t reg;
-
- /* switch pins PL0 and PL1 to I2C */
- reg = mmio_read_32(SUNXI_R_PIO_BASE + 0x00);
- mmio_write_32(SUNXI_R_PIO_BASE + 0x00, (reg & ~0xff) | 0x33);
-
- /* level 2 drive strength */
- reg = mmio_read_32(SUNXI_R_PIO_BASE + 0x14);
- mmio_write_32(SUNXI_R_PIO_BASE + 0x14, (reg & ~0x0f) | 0xa);
-
- /* set both ports to pull-up */
- reg = mmio_read_32(SUNXI_R_PIO_BASE + 0x1c);
- mmio_write_32(SUNXI_R_PIO_BASE + 0x1c, (reg & ~0x0f) | 0x5);
-
- /* assert & de-assert reset of R_I2C */
- reg = mmio_read_32(SUNXI_R_PRCM_BASE + 0x19c);
- mmio_write_32(SUNXI_R_PRCM_BASE + 0x19c, reg & ~BIT(16));
- mmio_write_32(SUNXI_R_PRCM_BASE + 0x19c, reg | BIT(16));
-
- /* un-gate R_I2C clock */
- mmio_write_32(SUNXI_R_PRCM_BASE + 0x19c, reg | BIT(16) | BIT(0));
-
- /* call mi2cv driver */
- i2c_init((void *)SUNXI_R_I2C_BASE);
-
- return 0;
-}
-
int axp_i2c_read(uint8_t chip, uint8_t reg, uint8_t *val)
{
int ret;
@@ -96,11 +68,13 @@ static int axp805_probe(void)
return 0;
}
-int sunxi_pmic_setup(void)
+int sunxi_pmic_setup(uint16_t socid, const void *fdt)
{
int ret;
- sunxi_init_r_i2c();
+ sunxi_init_platform_r_twi(SUNXI_SOC_H6, false);
+ /* initialise mi2cv driver */
+ i2c_init((void *)SUNXI_R_I2C_BASE);
NOTICE("PMIC: Probing AXP805\n");
pmic = AXP805;
@@ -120,7 +94,10 @@ void __dead2 sunxi_power_down(void)
switch (pmic) {
case AXP805:
- sunxi_init_r_i2c();
+ /* Re-initialise after rich OS might have used it. */
+ sunxi_init_platform_r_twi(SUNXI_SOC_H6, false);
+ /* initialise mi2cv driver */
+ i2c_init((void *)SUNXI_R_I2C_BASE);
axp_i2c_read(AXP805_ADDR, 0x32, &val);
axp_i2c_write(AXP805_ADDR, 0x32, val | 0x80);
break;
diff --git a/plat/arm/board/fvp/aarch64/fvp_helpers.S b/plat/arm/board/fvp/aarch64/fvp_helpers.S
index 88fcdb1b0..abc3ceb00 100644
--- a/plat/arm/board/fvp/aarch64/fvp_helpers.S
+++ b/plat/arm/board/fvp/aarch64/fvp_helpers.S
@@ -19,7 +19,7 @@
.globl plat_arm_calc_core_pos
.macro fvp_choose_gicmmap param1, param2, x_tmp, w_tmp, res
- ldr \x_tmp, =V2M_SYSREGS_BASE + V2M_SYS_ID
+ mov_imm \x_tmp, V2M_SYSREGS_BASE + V2M_SYS_ID
ldr \w_tmp, [\x_tmp]
ubfx \w_tmp, \w_tmp, #V2M_SYS_ID_BLD_SHIFT, #V2M_SYS_ID_BLD_LENGTH
cmp \w_tmp, #BLD_GIC_VE_MMAP
@@ -48,7 +48,7 @@ func plat_secondary_cold_boot_setup
* ---------------------------------------------
*/
mrs x0, mpidr_el1
- ldr x1, =PWRC_BASE
+ mov_imm x1, PWRC_BASE
str w0, [x1, #PPOFFR_OFF]
/* ---------------------------------------------
@@ -72,8 +72,8 @@ func plat_secondary_cold_boot_setup
b secondary_cold_boot_wait
gicv2_bypass_disable:
- ldr x0, =VE_GICC_BASE
- ldr x1, =BASE_GICC_BASE
+ mov_imm x0, VE_GICC_BASE
+ mov_imm x1, BASE_GICC_BASE
fvp_choose_gicmmap x0, x1, x2, w2, x1
mov w0, #(IRQ_BYP_DIS_GRP1 | FIQ_BYP_DIS_GRP1)
orr w0, w0, #(IRQ_BYP_DIS_GRP0 | FIQ_BYP_DIS_GRP0)
@@ -128,7 +128,7 @@ func plat_get_my_entrypoint
* ---------------------------------------------------------------------
*/
mrs x2, mpidr_el1
- ldr x1, =PWRC_BASE
+ mov_imm x1, PWRC_BASE
str w2, [x1, #PSYSR_OFF]
ldr w2, [x1, #PSYSR_OFF]
ubfx w2, w2, #PSYSR_WK_SHIFT, #PSYSR_WK_WIDTH
@@ -171,7 +171,7 @@ endfunc plat_get_my_entrypoint
*/
func plat_is_my_cpu_primary
mrs x0, mpidr_el1
- ldr x1, =MPIDR_AFFINITY_MASK
+ mov_imm x1, MPIDR_AFFINITY_MASK
and x0, x0, x1
cmp x0, #FVP_PRIMARY_CPU
cset w0, eq
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index aa4f8398d..f5198f686 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -7,7 +7,6 @@
#include <arm_config.h>
#include <arm_def.h>
#include <arm_spm_def.h>
-#include <arm_xlat_tables.h>
#include <assert.h>
#include <cci.h>
#include <ccn.h>
@@ -18,6 +17,8 @@
#include <platform.h>
#include <secure_partition.h>
#include <v2m_def.h>
+#include <xlat_tables_compat.h>
+
#include "../fvp_def.h"
#include "fvp_private.h"
@@ -52,8 +53,8 @@ arm_config_t arm_config;
/*
* Table of memory regions for various BL stages to map using the MMU.
- * This doesn't include Trusted SRAM as arm_setup_page_tables() already
- * takes care of mapping it.
+ * This doesn't include Trusted SRAM as setup_page_tables() already takes care
+ * of mapping it.
*
* The flash needs to be mapped as writable in order to erase the FIP's Table of
* Contents in case of unrecoverable error (see plat_error_handler()).
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 332df4d44..3d858c20e 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -202,7 +202,9 @@ ENABLE_AMU := 1
DYNAMIC_WORKAROUND_CVE_2018_3639 := 1
# Enable reclaiming of BL31 initialisation code for secondary cores stacks for FVP
+ifneq (${RESET_TO_BL31},1)
RECLAIM_INIT_CODE := 1
+endif
ifeq (${ENABLE_AMU},1)
BL31_SOURCES += lib/cpus/aarch64/cortex_a75_pubsub.c \
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index 0e5c6d9ac..d4a77f027 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -142,7 +142,7 @@
# define PLAT_ARM_MAX_BL2_SIZE 0x1C000
#endif
#else
-# define PLAT_ARM_MAX_BL2_SIZE 0xE000
+# define PLAT_ARM_MAX_BL2_SIZE 0xF000
#endif
/*
diff --git a/plat/arm/board/juno/juno_common.c b/plat/arm/board/juno/juno_common.c
index 40b1a275a..2e6b01134 100644
--- a/plat/arm/board/juno/juno_common.c
+++ b/plat/arm/board/juno/juno_common.c
@@ -8,8 +8,8 @@
/*
* Table of memory regions for different BL stages to map using the MMU.
- * This doesn't include Trusted SRAM as arm_setup_page_tables() already
- * takes care of mapping it.
+ * This doesn't include Trusted SRAM as setup_page_tables() already takes care
+ * of mapping it.
*/
#ifdef IMAGE_BL1
const mmap_region_t plat_arm_mmap[] = {
diff --git a/plat/arm/board/juno/juno_topology.c b/plat/arm/board/juno/juno_topology.c
index 72bb92e00..6d8fc05ce 100644
--- a/plat/arm/board/juno/juno_topology.c
+++ b/plat/arm/board/juno/juno_topology.c
@@ -9,6 +9,21 @@
#include <plat_arm.h>
#include <platform.h>
#include "juno_def.h"
+#include "../../css/drivers/scmi/scmi.h"
+#include "../../css/drivers/mhu/css_mhu_doorbell.h"
+
+static scmi_channel_plat_info_t juno_scmi_plat_info = {
+ .scmi_mbx_mem = CSS_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 &juno_scmi_plat_info;
+}
/*
* On Juno, the system power level is the highest power level.
diff --git a/plat/arm/board/n1sdp/aarch64/n1sdp_helper.S b/plat/arm/board/n1sdp/aarch64/n1sdp_helper.S
new file mode 100644
index 000000000..6eb01aa57
--- /dev/null
+++ b/plat/arm/board/n1sdp/aarch64/n1sdp_helper.S
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <cortex_ares.h>
+#include <cpu_macros.S>
+#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.
+ * (ClusterId * N1SDP_MAX_CPUS_PER_CLUSTER * N1SDP_MAX_PE_PER_CPU) +
+ * (CPUId * N1SDP_MAX_PE_PER_CPU) +
+ * ThreadId
+ *
+ * which can be simplified as:
+ *
+ * ((ClusterId * N1SDP_MAX_CPUS_PER_CLUSTER + CPUId) *
+ * N1SDP_MAX_PE_PER_CPU) + ThreadId
+ * ------------------------------------------------------
+ */
+
+func plat_arm_calc_core_pos
+ mov x3, x0
+
+ /*
+ * The MT bit in MPIDR is always set for n1sdp and the
+ * affinity level 0 corresponds to thread affinity level.
+ */
+
+ /* Extract individual affinity fields from MPIDR */
+ ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+
+ /* Compute linear position */
+ mov x4, #N1SDP_MAX_CPUS_PER_CLUSTER
+ madd x1, x2, x4, x1
+ mov x5, #N1SDP_MAX_PE_PER_CPU
+ madd x0, x1, x5, x0
+ ret
+endfunc plat_arm_calc_core_pos
+
+ /* -----------------------------------------------------
+ * void plat_reset_handler(void);
+ *
+ * Determine the CPU MIDR and disable power down bit for
+ * that CPU.
+ * -----------------------------------------------------
+ */
+
+func plat_reset_handler
+ jump_if_cpu_midr CORTEX_ARES_MIDR, ARES
+ ret
+
+ /* -----------------------------------------------------
+ * Disable CPU power down bit in power control register
+ * -----------------------------------------------------
+ */
+ARES:
+ mrs x0, CORTEX_ARES_CPUPWRCTLR_EL1
+ bic x0, x0, #CORTEX_ARES_CORE_PWRDN_EN_MASK
+ msr CORTEX_ARES_CPUPWRCTLR_EL1, x0
+ isb
+ ret
+endfunc plat_reset_handler
diff --git a/plat/arm/board/n1sdp/include/plat_macros.S b/plat/arm/board/n1sdp/include/plat_macros.S
new file mode 100644
index 000000000..fe9a66c3d
--- /dev/null
+++ b/plat/arm/board/n1sdp/include/plat_macros.S
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. 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/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h
new file mode 100644
index 000000000..d26f55921
--- /dev/null
+++ b/plat/arm/board/n1sdp/include/platform_def.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <arm_def.h>
+#include <board_css_def.h>
+#include <css_def.h>
+
+#if CSS_USE_SCMI_SDS_DRIVER
+#define N1SDP_SCMI_PAYLOAD_BASE 0x45400000
+#else
+#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE 0x45400000
+#endif
+
+#define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00080000 /* 512 KB */
+#define PLAT_ARM_MAX_BL31_SIZE 0X20000
+
+
+/*******************************************************************************
+ * N1SDP topology related constants
+ ******************************************************************************/
+#define N1SDP_MAX_CPUS_PER_CLUSTER 2
+#define PLAT_ARM_CLUSTER_COUNT 2
+#define N1SDP_MAX_PE_PER_CPU 1
+
+#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \
+ N1SDP_MAX_CPUS_PER_CLUSTER * \
+ N1SDP_MAX_PE_PER_CPU)
+
+
+/*
+ * 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 3
+#define MAX_XLAT_TABLES 4
+
+#define PLATFORM_STACK_SIZE 0x400
+
+#define PLAT_ARM_NSTIMER_FRAME_ID 0
+#define PLAT_CSS_MHU_BASE 0x45000000
+#define PLAT_MAX_PWR_LVL 1
+
+#define PLAT_ARM_G1S_IRQS ARM_G1S_IRQS, \
+ CSS_IRQ_MHU
+#define PLAT_ARM_G0_IRQS ARM_G0_IRQS
+
+#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 N1SDP_DEVICE_BASE (0x20000000)
+#define N1SDP_DEVICE_SIZE (0x20000000)
+#define N1SDP_MAP_DEVICE MAP_REGION_FLAT( \
+ N1SDP_DEVICE_BASE, \
+ N1SDP_DEVICE_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE 0x30000000
+#define PLAT_ARM_GICC_BASE 0x2C000000
+#define PLAT_ARM_GICR_BASE 0x300C0000
+
+/* Platform ID address */
+#define SSC_VERSION (SSC_REG_BASE + SSC_VERSION_OFFSET)
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
new file mode 100644
index 000000000..65aad9cf2
--- /dev/null
+++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "../../css/drivers/scmi/scmi.h"
+#include "../../css/drivers/mhu/css_mhu_doorbell.h"
+#include <platform_def.h>
+
+static scmi_channel_plat_info_t n1sdp_scmi_plat_info = {
+ .scmi_mbx_mem = N1SDP_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 &n1sdp_scmi_plat_info;
+}
diff --git a/plat/arm/board/n1sdp/n1sdp_interconnect.c b/plat/arm/board/n1sdp/n1sdp_interconnect.c
new file mode 100644
index 000000000..908f41c39
--- /dev/null
+++ b/plat/arm/board/n1sdp/n1sdp_interconnect.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/*
+ * For N1SDP which support 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/n1sdp/n1sdp_plat.c b/plat/arm/board/n1sdp/n1sdp_plat.c
new file mode 100644
index 000000000..8c057c55e
--- /dev/null
+++ b/plat/arm/board/n1sdp/n1sdp_plat.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arm_def.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <plat_arm.h>
+#include <platform.h>
+#include <platform_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,
+ N1SDP_MAP_DEVICE,
+ SOC_CSS_MAP_DEVICE,
+ {0}
+};
+
diff --git a/plat/arm/css/sgi/fdts/sgi575.dts b/plat/arm/board/n1sdp/n1sdp_security.c
index be9920cbc..d2a187ba1 100644
--- a/plat/arm/css/sgi/fdts/sgi575.dts
+++ b/plat/arm/board/n1sdp/n1sdp_security.c
@@ -4,8 +4,9 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-/dts-v1/;
-/ {
- /* compatible string */
- compatible = "arm,sgi575";
-};
+/*
+ * TZC programming is currently not done.
+ */
+void plat_arm_security_setup(void)
+{
+}
diff --git a/plat/arm/board/n1sdp/n1sdp_topology.c b/plat/arm/board/n1sdp/n1sdp_topology.c
new file mode 100644
index 000000000..c3b4550d0
--- /dev/null
+++ b/plat/arm/board/n1sdp/n1sdp_topology.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat_arm.h>
+
+/* Topology */
+typedef struct n1sdp_topology {
+ const unsigned char *power_tree;
+ unsigned int plat_cluster_core_count;
+} n1sdp_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 n1sdp_pd_tree_desc[] = {
+ PLAT_ARM_CLUSTER_COUNT,
+ N1SDP_MAX_CPUS_PER_CLUSTER,
+ N1SDP_MAX_CPUS_PER_CLUSTER
+};
+
+/* Topology configuration for n1sdp */
+const n1sdp_topology_t n1sdp_topology = {
+ .power_tree = n1sdp_pd_tree_desc,
+ .plat_cluster_core_count = N1SDP_MAX_CPUS_PER_CLUSTER
+};
+
+/*******************************************************************************
+ * This function returns the topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ return n1sdp_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 n1sdp_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/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk
new file mode 100644
index 000000000..c9acb4911
--- /dev/null
+++ b/plat/arm/board/n1sdp/platform.mk
@@ -0,0 +1,67 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+N1SDP_BASE := plat/arm/board/n1sdp
+
+INTERCONNECT_SOURCES := ${N1SDP_BASE}/n1sdp_interconnect.c
+
+PLAT_INCLUDES := -I${N1SDP_BASE}/include
+
+
+N1SDP_CPU_SOURCES := lib/cpus/aarch64/cortex_ares.S
+
+
+N1SDP_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 := ${N1SDP_BASE}/n1sdp_plat.c \
+ ${N1SDP_BASE}/aarch64/n1sdp_helper.S
+
+
+BL31_SOURCES := ${N1SDP_CPU_SOURCES} \
+ ${INTERCONNECT_SOURCES} \
+ ${N1SDP_GIC_SOURCES} \
+ ${N1SDP_BASE}/n1sdp_bl31_setup.c \
+ ${N1SDP_BASE}/n1sdp_topology.c \
+ ${N1SDP_BASE}/n1sdp_security.c
+
+
+# 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 n1sdp
+override NEED_BL1 := no
+override NEED_BL2 := no
+override NEED_BL2U := no
+
+#TFA for n1sdp 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/soc/common/soc_css.mk
+include plat/arm/board/common/board_common.mk
+
diff --git a/plat/arm/board/sgi575/fdts/sgi575.dts b/plat/arm/board/sgi575/fdts/sgi575.dts
new file mode 100644
index 000000000..1e1ea14b0
--- /dev/null
+++ b/plat/arm/board/sgi575/fdts/sgi575.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+/ {
+ /* compatible string */
+ compatible = "arm,sgi575";
+
+ /*
+ * Place holder for system-id node with default values. The
+ * value of platform-id and config-id will be set to the
+ * correct values during the BL2 stage of boot.
+ */
+ system-id {
+ platform-id = <0x0>;
+ config-id = <0x0>;
+ };
+};
diff --git a/plat/arm/css/sgi/fdts/sgi575_tb_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts
index 315fa6999..315fa6999 100644
--- a/plat/arm/css/sgi/fdts/sgi575_tb_fw_config.dts
+++ b/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts
diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h
new file mode 100644
index 000000000..1870fc78a
--- /dev/null
+++ b/plat/arm/board/sgi575/include/platform_def.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <sgi_base_platform_def.h>
+
+#define PLAT_ARM_CLUSTER_COUNT 2
+#define CSS_SGI_MAX_CPUS_PER_CLUSTER 4
+#define CSS_SGI_MAX_PE_PER_CPU 1
+
+#define PLAT_CSS_MHU_BASE 0x45000000
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk
index 078f393c9..8df8b1292 100644
--- a/plat/arm/board/sgi575/platform.mk
+++ b/plat/arm/board/sgi575/platform.mk
@@ -6,9 +6,31 @@
include plat/arm/css/sgi/sgi-common.mk
+SGI575_BASE = plat/arm/board/sgi575
+
+PLAT_INCLUDES += -I${SGI575_BASE}/include/
+
+SGI_CPU_SOURCES := lib/cpus/aarch64/cortex_a75.S
+
+BL1_SOURCES += ${SGI_CPU_SOURCES}
+
BL2_SOURCES += lib/utils/mem_region.c \
plat/arm/common/arm_nor_psci_mem_protect.c
-BL31_SOURCES += drivers/cfi/v2m/v2m_flash.c \
+BL31_SOURCES += ${SGI_CPU_SOURCES} \
+ drivers/cfi/v2m/v2m_flash.c \
lib/utils/mem_region.c \
plat/arm/common/arm_nor_psci_mem_protect.c
+
+# Add the FDT_SOURCES and options for Dynamic Config
+FDT_SOURCES += ${SGI575_BASE}/fdts/${PLAT}_tb_fw_config.dts
+TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+
+# Add the TB_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
+
+FDT_SOURCES += ${SGI575_BASE}/fdts/${PLAT}.dts
+HW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}.dtb
+
+# Add the HW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${HW_CONFIG},--hw-config))
diff --git a/plat/arm/board/sgiclarka/fdts/sgiclarka.dts b/plat/arm/board/sgiclarka/fdts/sgiclarka.dts
new file mode 100644
index 000000000..43bd85692
--- /dev/null
+++ b/plat/arm/board/sgiclarka/fdts/sgiclarka.dts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+/ {
+ /* compatible string */
+ compatible = "arm,sgi-clark";
+
+ /*
+ * Place holder for system-id node with default values. The
+ * value of platform-id and config-id will be set to the
+ * correct values during the BL2 stage of boot.
+ */
+ system-id {
+ platform-id = <0x0>;
+ config-id = <0x0>;
+ };
+};
diff --git a/plat/arm/board/sgiclarka/fdts/sgiclarka_tb_fw_config.dts b/plat/arm/board/sgiclarka/fdts/sgiclarka_tb_fw_config.dts
new file mode 100644
index 000000000..315fa6999
--- /dev/null
+++ b/plat/arm/board/sgiclarka/fdts/sgiclarka_tb_fw_config.dts
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+ /* Platform Config */
+ compatible = "arm,tb_fw";
+ hw_config_addr = <0x0 0xFEF00000>;
+ hw_config_max_size = <0x0100000>;
+ /*
+ * The following two entries are placeholders for Mbed TLS
+ * heap information. The default values don't matter since
+ * they will be overwritten by BL1.
+ * In case of having shared Mbed TLS heap between BL1 and BL2,
+ * BL1 will populate these two properties with the respective
+ * info about the shared heap. This info will be available for
+ * BL2 in order to locate and re-use the heap.
+ */
+ mbedtls_heap_addr = <0x0 0x0>;
+ mbedtls_heap_size = <0x0>;
+};
diff --git a/plat/arm/board/sgiclarka/include/platform_def.h b/plat/arm/board/sgiclarka/include/platform_def.h
new file mode 100644
index 000000000..abc48d84c
--- /dev/null
+++ b/plat/arm/board/sgiclarka/include/platform_def.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <sgi_base_platform_def.h>
+
+#define PLAT_ARM_CLUSTER_COUNT 2
+#define CSS_SGI_MAX_CPUS_PER_CLUSTER 4
+#define CSS_SGI_MAX_PE_PER_CPU 1
+
+#define PLAT_CSS_MHU_BASE 0x45400000
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/sgiclarka/platform.mk b/plat/arm/board/sgiclarka/platform.mk
new file mode 100644
index 000000000..fc2f76670
--- /dev/null
+++ b/plat/arm/board/sgiclarka/platform.mk
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include plat/arm/css/sgi/sgi-common.mk
+
+SGICLARKA_BASE = plat/arm/board/sgiclarka
+
+PLAT_INCLUDES += -I${SGICLARKA_BASE}/include/
+
+SGI_CPU_SOURCES := lib/cpus/aarch64/cortex_ares.S
+
+BL1_SOURCES += ${SGI_CPU_SOURCES}
+
+BL2_SOURCES += lib/utils/mem_region.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c
+
+BL31_SOURCES += ${SGI_CPU_SOURCES} \
+ drivers/cfi/v2m/v2m_flash.c \
+ lib/utils/mem_region.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c
+
+# Add the FDT_SOURCES and options for Dynamic Config
+FDT_SOURCES += ${SGICLARKA_BASE}/fdts/${PLAT}_tb_fw_config.dts
+TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+
+# Add the TB_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
+
+FDT_SOURCES += ${SGICLARKA_BASE}/fdts/${PLAT}.dts
+HW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}.dtb
+
+# Add the HW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${HW_CONFIG},--hw-config))
+
+override CTX_INCLUDE_AARCH32_REGS := 0
diff --git a/plat/arm/common/aarch64/arm_helpers.S b/plat/arm/common/aarch64/arm_helpers.S
index 752929db5..06720589a 100644
--- a/plat/arm/common/aarch64/arm_helpers.S
+++ b/plat/arm/common/aarch64/arm_helpers.S
@@ -8,9 +8,9 @@
.weak plat_arm_calc_core_pos
.weak plat_my_core_pos
- .weak plat_crash_console_init
- .weak plat_crash_console_putc
- .weak plat_crash_console_flush
+ .globl plat_crash_console_init
+ .globl plat_crash_console_putc
+ .globl plat_crash_console_flush
.globl platform_mem_init
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index 717e96f85..f760e18dc 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -6,7 +6,6 @@
#include <arch.h>
#include <arm_def.h>
-#include <arm_xlat_tables.h>
#include <assert.h>
#include <bl1.h>
#include <bl_common.h>
@@ -15,6 +14,8 @@
#include <platform_def.h>
#include <sp805.h>
#include <utils.h>
+#include <xlat_tables_compat.h>
+
#include "../../../bl1/bl1_private.h"
/* Weak definitions may be overridden in specific ARM standard platform */
@@ -122,7 +123,7 @@ void arm_bl1_plat_arch_setup(void)
{0}
};
- arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+ setup_page_tables(bl_regions, plat_arm_get_mmap());
#ifdef AARCH32
enable_mmu_svc_mon(0);
#else
diff --git a/plat/arm/common/arm_bl2_el3_setup.c b/plat/arm/common/arm_bl2_el3_setup.c
index c67ab4914..4f5e6a9e6 100644
--- a/plat/arm/common/arm_bl2_el3_setup.c
+++ b/plat/arm/common/arm_bl2_el3_setup.c
@@ -79,7 +79,7 @@ void arm_bl2_el3_plat_arch_setup(void)
{0}
};
- arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+ setup_page_tables(bl_regions, plat_arm_get_mmap());
#ifdef AARCH32
enable_mmu_svc_mon(0);
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index d31f6dc3c..628a50def 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -125,7 +125,7 @@ void arm_bl2_plat_arch_setup(void)
{0}
};
- arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+ setup_page_tables(bl_regions, plat_arm_get_mmap());
#ifdef AARCH32
enable_mmu_svc_mon(0);
diff --git a/plat/arm/common/arm_bl2u_setup.c b/plat/arm/common/arm_bl2u_setup.c
index b518f0f62..3848aa065 100644
--- a/plat/arm/common/arm_bl2u_setup.c
+++ b/plat/arm/common/arm_bl2u_setup.c
@@ -80,7 +80,7 @@ void arm_bl2u_plat_arch_setup(void)
{0}
};
- arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+ setup_page_tables(bl_regions, plat_arm_get_mmap());
#ifdef AARCH32
enable_mmu_svc_mon(0);
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index e218c2f05..1b05f46e9 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -16,7 +16,7 @@
#include <platform.h>
#include <ras.h>
#include <utils.h>
-#include <arm_xlat_tables.h>
+#include <xlat_tables_compat.h>
/*
* Placeholder variables for copying the arguments that have been passed to
@@ -25,11 +25,13 @@
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
+#if !RESET_TO_BL31
/*
* Check that BL31_BASE is above ARM_TB_FW_CONFIG_LIMIT. The reserved page
* is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2.
*/
CASSERT(BL31_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl31_base_overflows);
+#endif
/* Weak definitions may be overridden in specific ARM standard platform */
#pragma weak bl31_early_platform_setup2
@@ -38,8 +40,8 @@ CASSERT(BL31_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl31_base_overflows);
#pragma weak bl31_plat_get_next_image_ep_info
#define MAP_BL31_TOTAL MAP_REGION_FLAT( \
- BL31_BASE, \
- BL31_END - BL31_BASE, \
+ BL31_START, \
+ BL31_END - BL31_START, \
MT_MEMORY | MT_RW | MT_SECURE)
#if RECLAIM_INIT_CODE
IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE);
@@ -302,7 +304,7 @@ void __init arm_bl31_plat_arch_setup(void)
{0}
};
- arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+ setup_page_tables(bl_regions, plat_arm_get_mmap());
enable_mmu_el3(0);
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index a21d189e9..6b1478545 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -5,7 +5,6 @@
*/
#include <arch.h>
#include <arch_helpers.h>
-#include <arm_xlat_tables.h>
#include <assert.h>
#include <debug.h>
#include <mmio.h>
@@ -14,6 +13,7 @@
#include <platform_def.h>
#include <romlib.h>
#include <secure_partition.h>
+#include <xlat_tables_compat.h>
/* Weak definitions may be overridden in specific ARM standard platform */
#pragma weak plat_get_ns_image_entrypoint
@@ -32,42 +32,6 @@ void arm_setup_romlib(void)
#endif
}
-/*
- * Set up the page tables for the generic and platform-specific memory regions.
- * The size of the Trusted SRAM seen by the BL image must be specified as well
- * as an array specifying the generic memory regions which can be;
- * - Code section;
- * - Read-only data section;
- * - Init code section, if applicable
- * - Coherent memory region, if applicable.
- */
-
-void __init arm_setup_page_tables(const mmap_region_t bl_regions[],
- const mmap_region_t plat_regions[])
-{
-#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
- const mmap_region_t *regions = bl_regions;
-
- while (regions->size != 0U) {
- VERBOSE("Region: 0x%lx - 0x%lx has attributes 0x%x\n",
- regions->base_va,
- (regions->base_va + regions->size),
- regions->attr);
- regions++;
- }
-#endif
- /*
- * Map the Trusted SRAM with appropriate memory attributes.
- * Subsequent mappings will adjust the attributes for specific regions.
- */
- mmap_add(bl_regions);
- /* Now (re-)map the platform-specific memory regions */
- mmap_add(plat_regions);
-
- /* Create the page tables to reflect the above mappings */
- init_xlat_tables();
-}
-
uintptr_t plat_get_ns_image_entrypoint(void)
{
#ifdef PRELOADED_BL33_BASE
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 3fb1eff2d..23777fb7b 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -130,6 +130,11 @@ ARM_CRYPTOCELL_INTEG := 0
$(eval $(call assert_boolean,ARM_CRYPTOCELL_INTEG))
$(eval $(call add_define,ARM_CRYPTOCELL_INTEG))
+# Enable PIE support for RESET_TO_BL31 case
+ifeq (${RESET_TO_BL31},1)
+ ENABLE_PIE := 1
+endif
+
# CryptoCell integration relies on coherent buffers for passing data from
# the AP CPU to the CryptoCell
ifeq (${ARM_CRYPTOCELL_INTEG},1)
diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c
index e9e8a74d9..a43bff3d4 100644
--- a/plat/arm/common/arm_gicv3.c
+++ b/plat/arm/common/arm_gicv3.c
@@ -10,6 +10,7 @@
#include <plat_arm.h>
#include <platform.h>
#include <platform_def.h>
+#include <utils.h>
/******************************************************************************
* The following functions are defined as weak to allow a platform to override
@@ -33,10 +34,16 @@ static const interrupt_prop_t arm_interrupt_props[] = {
/*
* We save and restore the GICv3 context on system suspend. Allocate the
- * data in the designated EL3 Secure carve-out memory
+ * data in the designated EL3 Secure carve-out memory. The `volatile`
+ * is used to prevent the compiler from removing the gicv3 contexts even
+ * though the DEFINE_LOAD_SYM_ADDR creates a dummy reference to it.
*/
-static gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram");
-static gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram");
+static volatile gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram");
+static volatile gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram");
+
+/* Define accessor function to get reference to the GICv3 context */
+DEFINE_LOAD_SYM_ADDR(rdist_ctx)
+DEFINE_LOAD_SYM_ADDR(dist_ctx)
/*
* MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
@@ -134,6 +141,10 @@ void plat_arm_gic_redistif_off(void)
*****************************************************************************/
void plat_arm_gic_save(void)
{
+ gicv3_redist_ctx_t * const rdist_context =
+ (gicv3_redist_ctx_t *)LOAD_ADDR_OF(rdist_ctx);
+ gicv3_dist_ctx_t * const dist_context =
+ (gicv3_dist_ctx_t *)LOAD_ADDR_OF(dist_ctx);
/*
* If an ITS is available, save its context before
@@ -149,10 +160,10 @@ void plat_arm_gic_save(void)
* we only need to save the context of the CPU that is issuing
* the SYSTEM SUSPEND call, i.e. the current CPU.
*/
- gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx);
+ gicv3_rdistif_save(plat_my_core_pos(), rdist_context);
/* Save the GIC Distributor context */
- gicv3_distif_save(&dist_ctx);
+ gicv3_distif_save(dist_context);
/*
* From here, all the components of the GIC can be safely powered down
@@ -163,8 +174,13 @@ void plat_arm_gic_save(void)
void plat_arm_gic_resume(void)
{
+ const gicv3_redist_ctx_t *rdist_context =
+ (gicv3_redist_ctx_t *)LOAD_ADDR_OF(rdist_ctx);
+ const gicv3_dist_ctx_t *dist_context =
+ (gicv3_dist_ctx_t *)LOAD_ADDR_OF(dist_ctx);
+
/* Restore the GIC Distributor context */
- gicv3_distif_init_restore(&dist_ctx);
+ gicv3_distif_init_restore(dist_context);
/*
* Restore the GIC Redistributor and ITS contexts after the
@@ -172,7 +188,7 @@ void plat_arm_gic_resume(void)
* we only need to restore the context of the CPU that issued
* the SYSTEM SUSPEND call.
*/
- gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx);
+ gicv3_rdistif_init_restore(plat_my_core_pos(), rdist_context);
/*
* If an ITS is available, restore its context after
diff --git a/plat/arm/common/arm_sip_svc.c b/plat/arm/common/arm_sip_svc.c
index e450c6f94..e482a8945 100644
--- a/plat/arm/common/arm_sip_svc.c
+++ b/plat/arm/common/arm_sip_svc.c
@@ -58,7 +58,7 @@ static uintptr_t arm_sip_handler(unsigned int smc_fid,
/* Validate supplied entry point */
pc = (u_register_t) ((x1 << 32) | (uint32_t) x2);
- if (arm_validate_ns_entrypoint(pc))
+ if (arm_validate_ns_entrypoint(pc) != 0)
SMC_RET1(handle, STATE_SW_E_PARAM);
/*
diff --git a/plat/arm/common/arm_tzc400.c b/plat/arm/common/arm_tzc400.c
index a32736c3a..2ae084c7b 100644
--- a/plat/arm/common/arm_tzc400.c
+++ b/plat/arm/common/arm_tzc400.c
@@ -24,7 +24,7 @@
void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions)
{
#ifndef EL3_PAYLOAD_BASE
- int region_index = 1;
+ unsigned int region_index = 1U;
const arm_tzc_regions_info_t *p;
const arm_tzc_regions_info_t init_tzc_regions[] = {
ARM_TZC_REGIONS_DEF,
@@ -55,7 +55,7 @@ void arm_tzc400_setup(const arm_tzc_regions_info_t *tzc_regions)
region_index++;
}
- INFO("Total %d regions set.\n", region_index);
+ INFO("Total %u regions set.\n", region_index);
#else /* if defined(EL3_PAYLOAD_BASE) */
diff --git a/plat/arm/common/arm_tzc_dmc500.c b/plat/arm/common/arm_tzc_dmc500.c
index 8cb81e7ae..6bd771b0e 100644
--- a/plat/arm/common/arm_tzc_dmc500.c
+++ b/plat/arm/common/arm_tzc_dmc500.c
@@ -20,7 +20,7 @@ void arm_tzc_dmc500_setup(tzc_dmc500_driver_data_t *plat_driver_data,
const arm_tzc_regions_info_t *tzc_regions)
{
#ifndef EL3_PAYLOAD_BASE
- int region_index = 1;
+ unsigned int region_index = 1U;
const arm_tzc_regions_info_t *p;
const arm_tzc_regions_info_t init_tzc_regions[] = {
ARM_TZC_REGIONS_DEF,
@@ -50,7 +50,7 @@ void arm_tzc_dmc500_setup(tzc_dmc500_driver_data_t *plat_driver_data,
region_index++;
}
- INFO("Total %d regions set.\n", region_index);
+ INFO("Total %u regions set.\n", region_index);
#else
/* Allow secure access only to DRAM for EL3 payloads */
diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c
index b8234c186..e151073f7 100644
--- a/plat/arm/common/sp_min/arm_sp_min_setup.c
+++ b/plat/arm/common/sp_min/arm_sp_min_setup.c
@@ -208,7 +208,7 @@ void sp_min_plat_arch_setup(void)
{0}
};
- arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+ setup_page_tables(bl_regions, plat_arm_get_mmap());
enable_mmu_svc_mon(0);
}
diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c
index 2d42d8e00..3cf88251f 100644
--- a/plat/arm/common/tsp/arm_tsp_setup.c
+++ b/plat/arm/common/tsp/arm_tsp_setup.c
@@ -85,6 +85,6 @@ void tsp_plat_arch_setup(void)
{0}
};
- arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+ setup_page_tables(bl_regions, plat_arm_get_mmap());
enable_mmu_el1(0);
}
diff --git a/plat/arm/css/common/aarch64/css_helpers.S b/plat/arm/css/common/aarch64/css_helpers.S
index 59d920650..5096d8d95 100644
--- a/plat/arm/css/common/aarch64/css_helpers.S
+++ b/plat/arm/css/common/aarch64/css_helpers.S
@@ -108,7 +108,7 @@ endfunc plat_is_my_cpu_primary
func plat_is_my_cpu_primary
mov x9, x30
bl plat_my_core_pos
- ldr x1, =SCP_BOOT_CFG_ADDR
+ mov_imm x1, SCP_BOOT_CFG_ADDR
ldr x1, [x1]
ubfx x1, x1, #PLAT_CSS_PRIMARY_CPU_SHIFT, \
#PLAT_CSS_PRIMARY_CPU_BIT_WIDTH
diff --git a/plat/arm/css/drivers/scmi/scmi.h b/plat/arm/css/drivers/scmi/scmi.h
index 71a8c2d02..7f8922910 100644
--- a/plat/arm/css/drivers/scmi/scmi.h
+++ b/plat/arm/css/drivers/scmi/scmi.h
@@ -159,4 +159,7 @@ int scmi_sys_pwr_state_get(void *p, uint32_t *system_state);
int scmi_ap_core_set_reset_addr(void *p, uint64_t reset_addr, uint32_t attr);
int scmi_ap_core_get_reset_addr(void *p, uint64_t *reset_addr, uint32_t *attr);
+/* API to get the platform specific SCMI channel information. */
+scmi_channel_plat_info_t *plat_css_get_scmi_info();
+
#endif /* __CSS_SCMI_H__ */
diff --git a/plat/arm/css/drivers/scp/css_pm_scmi.c b/plat/arm/css/drivers/scp/css_pm_scmi.c
index 9297e9fe4..956f583c0 100644
--- a/plat/arm/css/drivers/scp/css_pm_scmi.c
+++ b/plat/arm/css/drivers/scp/css_pm_scmi.c
@@ -13,7 +13,6 @@
#include <platform.h>
#include <string.h>
#include "../scmi/scmi.h"
-#include "../mhu/css_mhu_doorbell.h"
#include "css_scp.h"
/*
@@ -298,14 +297,6 @@ void __dead2 css_scp_sys_reboot(void)
css_scp_system_off(SCMI_SYS_PWR_COLD_RESET);
}
-static scmi_channel_plat_info_t plat_css_scmi_plat_info = {
- .scmi_mbx_mem = CSS_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,
-};
-
static int scmi_ap_core_init(scmi_channel_t *ch)
{
#if PROGRAMMABLE_RESET_ADDRESS
@@ -330,7 +321,7 @@ static int scmi_ap_core_init(scmi_channel_t *ch)
void __init plat_arm_pwrc_setup(void)
{
- channel.info = &plat_css_scmi_plat_info;
+ channel.info = plat_css_get_scmi_info();
channel.lock = ARM_SCMI_LOCK_GET_INSTANCE;
scmi_handle = scmi_init(&channel);
if (scmi_handle == NULL) {
diff --git a/plat/arm/css/sgi/aarch64/sgi_helper.S b/plat/arm/css/sgi/aarch64/sgi_helper.S
index 27bae43cf..d79f1aa21 100644
--- a/plat/arm/css/sgi/aarch64/sgi_helper.S
+++ b/plat/arm/css/sgi/aarch64/sgi_helper.S
@@ -8,6 +8,7 @@
#include <asm_macros.S>
#include <platform_def.h>
#include <cortex_a75.h>
+#include <cortex_ares.h>
#include <cpu_macros.S>
.globl plat_arm_calc_core_pos
@@ -58,6 +59,7 @@ endfunc plat_arm_calc_core_pos
*/
func plat_reset_handler
jump_if_cpu_midr CORTEX_A75_MIDR, A75
+ jump_if_cpu_midr CORTEX_ARES_MIDR, ARES
ret
/* -----------------------------------------------------
@@ -70,4 +72,11 @@ A75:
msr CORTEX_A75_CPUPWRCTLR_EL1, x0
isb
ret
+
+ARES:
+ mrs x0, CORTEX_ARES_CPUPWRCTLR_EL1
+ bic x0, x0, #CORTEX_ARES_CORE_PWRDN_EN_MASK
+ msr CORTEX_ARES_CPUPWRCTLR_EL1, x0
+ isb
+ ret
endfunc plat_reset_handler
diff --git a/plat/arm/css/sgi/include/platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index 629749056..90eb3360b 100644
--- a/plat/arm/css/sgi/include/platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef PLATFORM_DEF_H
-#define PLATFORM_DEF_H
+#ifndef SGI_BASE_PLATFORM_DEF_H
+#define SGI_BASE_PLATFORM_DEF_H
#include <arm_def.h>
#include <arm_spm_def.h>
@@ -17,11 +17,6 @@
#include <v2m_def.h>
#include <xlat_tables_defs.h>
-#define CSS_SGI_MAX_CPUS_PER_CLUSTER 4
-
-/* CPU topology */
-#define PLAT_ARM_CLUSTER_COUNT 2
-#define CSS_SGI_MAX_PE_PER_CPU 1
#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \
CSS_SGI_MAX_CPUS_PER_CLUSTER * \
CSS_SGI_MAX_PE_PER_CPU)
@@ -118,8 +113,6 @@
#define PLAT_ARM_NSTIMER_FRAME_ID 0
-#define PLAT_CSS_MHU_BASE 0x45000000
-
#define PLAT_ARM_TRUSTED_ROM_BASE 0x0
#define PLAT_ARM_TRUSTED_ROM_SIZE 0x00080000 /* 512KB */
@@ -216,4 +209,4 @@
V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
-#endif /* PLATFORM_DEF_H */
+#endif /* SGI_BASE_PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgi/include/sgi_plat_config.h b/plat/arm/css/sgi/include/sgi_plat_config.h
deleted file mode 100644
index 9b29d74e4..000000000
--- a/plat/arm/css/sgi/include/sgi_plat_config.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __SGI_PLAT_CONFIG_H__
-#define __SGI_PLAT_CONFIG_H__
-
-#include <ccn.h>
-#include <gicv3.h>
-
-/* The type of interconnect */
-typedef enum {
- ARM_CCI = 0,
- ARM_CCN,
- ARM_CMN
-} css_inteconn_type_t;
-
-typedef ccn_desc_t inteconn_desc_t;
-
-/* Interconnect configurations */
-typedef struct css_inteconn_config {
- css_inteconn_type_t ip_type;
- const inteconn_desc_t *plat_inteconn_desc;
-} css_inteconn_config_t;
-
-/* Topology configurations */
-typedef struct css_topology {
- const unsigned char *power_tree;
- unsigned int plat_cluster_core_count;
-} css_topology_t;
-
-typedef struct css_plat_config {
- const gicv3_driver_data_t *gic_data;
- const css_inteconn_config_t *inteconn;
- const css_topology_t *topology;
-} css_plat_config_t;
-
-void plat_config_init(void);
-css_plat_config_t *get_plat_config(void);
-
-#endif /* __SGI_PLAT_CONFIG_H__ */
diff --git a/plat/arm/css/sgi/include/sgi_variant.h b/plat/arm/css/sgi/include/sgi_variant.h
index 5698d0abd..dea580be2 100644
--- a/plat/arm/css/sgi/include/sgi_variant.h
+++ b/plat/arm/css/sgi/include/sgi_variant.h
@@ -4,10 +4,21 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __SGI_VARIANT_H__
-#define __SGI_VARIANT_H__
+#ifndef SGI_VARIANT_H
+#define SGI_VARIANT_H
/* SSC_VERSION values for SGI575 */
#define SGI575_SSC_VER_PART_NUM 0x0783
-#endif /* __SGI_VARIANT_H__ */
+/* SID Version values for SGI-Clark */
+#define SGI_CLARK_SID_VER_PART_NUM 0x0786
+
+/* Structure containing SGI platform variant information */
+typedef struct sgi_platform_info {
+ unsigned int platform_id; /* Part Number of the platform */
+ unsigned int config_id; /* Config Id of the platform */
+} sgi_platform_info_t;
+
+extern sgi_platform_info_t sgi_plat_info;
+
+#endif /* SGI_VARIANT_H */
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index 24f03dd4b..d6e5448de 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -22,8 +22,6 @@ INTERCONNECT_SOURCES := ${CSS_ENT_BASE}/sgi_interconnect.c
PLAT_INCLUDES += -I${CSS_ENT_BASE}/include
-ENT_CPU_SOURCES := lib/cpus/aarch64/cortex_a75.S
-
ENT_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
drivers/arm/gic/v3/gicv3_main.c \
drivers/arm/gic/v3/gicv3_helpers.c \
@@ -35,38 +33,20 @@ ENT_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c \
${CSS_ENT_BASE}/aarch64/sgi_helper.S
-BL1_SOURCES += ${INTERCONNECT_SOURCES} \
- ${ENT_CPU_SOURCES} \
- ${CSS_ENT_BASE}/sgi_bl1_setup.c \
- ${CSS_ENT_BASE}/sgi_plat_config.c
+BL1_SOURCES += ${INTERCONNECT_SOURCES}
BL2_SOURCES += ${CSS_ENT_BASE}/sgi_security.c \
${CSS_ENT_BASE}/sgi_image_load.c
-BL31_SOURCES += ${ENT_CPU_SOURCES} \
- ${INTERCONNECT_SOURCES} \
+BL31_SOURCES += ${INTERCONNECT_SOURCES} \
${ENT_GIC_SOURCES} \
${CSS_ENT_BASE}/sgi_bl31_setup.c \
- ${CSS_ENT_BASE}/sgi_topology.c \
- ${CSS_ENT_BASE}/sgi_plat_config.c
+ ${CSS_ENT_BASE}/sgi_topology.c
ifeq (${RAS_EXTENSION},1)
BL31_SOURCES += ${CSS_ENT_BASE}/sgi_ras.c
endif
-# Add the FDT_SOURCES and options for Dynamic Config
-FDT_SOURCES += ${CSS_ENT_BASE}/fdts/${PLAT}_tb_fw_config.dts
-TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
-
-# Add the TB_FW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
-
-FDT_SOURCES += ${CSS_ENT_BASE}/fdts/${PLAT}.dts
-HW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}.dtb
-
-# Add the HW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${HW_CONFIG},--hw-config))
-
ifneq (${RESET_TO_BL31},0)
$(error "Using BL31 as the reset vector is not supported on ${PLATFORM} platform. \
Please set RESET_TO_BL31 to 0.")
diff --git a/plat/arm/css/sgi/sgi_bl1_setup.c b/plat/arm/css/sgi/sgi_bl1_setup.c
deleted file mode 100644
index d3d98d92a..000000000
--- a/plat/arm/css/sgi/sgi_bl1_setup.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <bl_common.h>
-#include <debug.h>
-#include <plat_arm.h>
-#include <sgi_plat_config.h>
-#include <soc_css.h>
-
-void bl1_early_platform_setup(void)
-{
- /* Initialize the platform configuration structure */
- plat_config_init();
-
- arm_bl1_early_platform_setup();
-}
diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c
index 09f493edd..ce8502699 100644
--- a/plat/arm/css/sgi/sgi_bl31_setup.c
+++ b/plat/arm/css/sgi/sgi_bl31_setup.c
@@ -4,17 +4,91 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
#include <bl_common.h>
#include <debug.h>
+#include <libfdt.h>
#include <plat_arm.h>
-#include <sgi_plat_config.h>
#include <sgi_ras.h>
+#include <sgi_variant.h>
+#include "../../css/drivers/scmi/scmi.h"
+#include "../../css/drivers/mhu/css_mhu_doorbell.h"
+
+sgi_platform_info_t sgi_plat_info;
+
+static scmi_channel_plat_info_t sgi575_scmi_plat_info = {
+ .scmi_mbx_mem = CSS_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,
+};
+
+static scmi_channel_plat_info_t sgi_clark_scmi_plat_info = {
+ .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
+ .db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
+ .db_preserve_mask = 0xfffffffe,
+ .db_modify_mask = 0x1,
+ .ring_doorbell = &mhuv2_ring_doorbell,
+};
+
+scmi_channel_plat_info_t *plat_css_get_scmi_info()
+{
+ if (sgi_plat_info.platform_id == SGI_CLARK_SID_VER_PART_NUM)
+ return &sgi_clark_scmi_plat_info;
+ else if (sgi_plat_info.platform_id == SGI575_SSC_VER_PART_NUM)
+ return &sgi575_scmi_plat_info;
+ else
+ panic();
+};
+
+/*******************************************************************************
+ * This function sets the sgi_platform_id and sgi_config_id
+ ******************************************************************************/
+int sgi_identify_platform(unsigned long hw_config)
+{
+ void *fdt;
+ int nodeoffset;
+ const unsigned int *property;
+
+ fdt = (void *)hw_config;
+
+ /* Check the validity of the fdt */
+ assert(fdt_check_header(fdt) == 0);
+
+ nodeoffset = fdt_subnode_offset(fdt, 0, "system-id");
+ if (nodeoffset < 0) {
+ ERROR("Failed to get system-id node offset\n");
+ return -1;
+ }
+
+ property = fdt_getprop(fdt, nodeoffset, "platform-id", NULL);
+ if (property == NULL) {
+ ERROR("Failed to get platform-id property\n");
+ return -1;
+ }
+
+ sgi_plat_info.platform_id = fdt32_to_cpu(*property);
+
+ property = fdt_getprop(fdt, nodeoffset, "config-id", NULL);
+ if (property == NULL) {
+ ERROR("Failed to get config-id property\n");
+ return -1;
+ }
+
+ sgi_plat_info.config_id = fdt32_to_cpu(*property);
+
+ return 0;
+}
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
- /* Initialize the platform configuration structure */
- plat_config_init();
+ int ret;
+
+ ret = sgi_identify_platform(arg2);
+ if (ret == -1)
+ panic();
arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
}
diff --git a/plat/arm/css/sgi/sgi_image_load.c b/plat/arm/css/sgi/sgi_image_load.c
index 09403f884..d97583ef9 100644
--- a/plat/arm/css/sgi/sgi_image_load.c
+++ b/plat/arm/css/sgi/sgi_image_load.c
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <arch_helpers.h>
#include <debug.h>
#include <desc_image_load.h>
#include <libfdt.h>
@@ -13,6 +14,7 @@
* This function inserts Platform information via device tree nodes as,
* system-id {
* platform-id = <0>;
+ * config-id = <0>;
* }
******************************************************************************/
static int plat_sgi_append_config_node(void)
@@ -20,7 +22,7 @@ static int plat_sgi_append_config_node(void)
bl_mem_params_node_t *mem_params;
void *fdt;
int nodeoffset, err;
- unsigned int platid = 0;
+ unsigned int platid = 0, platcfg = 0;
char *platform_name;
mem_params = get_bl_mem_params_node(HW_CONFIG_ID);
@@ -45,31 +47,38 @@ static int plat_sgi_append_config_node(void)
}
if (strcmp(platform_name, "arm,sgi575") == 0) {
- platid = mmio_read_32(SSC_VERSION);
+ platid = mmio_read_32(SSC_VERSION) & SSC_VERSION_PART_NUM_MASK;
+ platcfg = (mmio_read_32(SSC_VERSION) >> SSC_VERSION_CONFIG_SHIFT)
+ & SSC_VERSION_CONFIG_MASK;
+ } else if (strcmp(platform_name, "arm,sgi-clark") == 0) {
+ platid = mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
+ & SID_SYSTEM_ID_PART_NUM_MASK;
+ platcfg = mmio_read_32(SID_REG_BASE + SID_SYSTEM_CFG_OFFSET);
} else {
WARN("Invalid platform\n");
return -1;
}
- /* Increase DTB blob by 512 byte */
- err = fdt_open_into(fdt, fdt, mem_params->image_info.image_size + 512);
- if (err < 0) {
- ERROR("Failed to open HW_CONFIG DTB\n");
+ nodeoffset = fdt_subnode_offset(fdt, 0, "system-id");
+ if (nodeoffset < 0) {
+ ERROR("Failed to get system-id node offset\n");
return -1;
}
- /* Create "/system-id" node */
- nodeoffset = fdt_add_subnode(fdt, 0, "system-id");
- if (nodeoffset < 0) {
- ERROR("Failed to add node system-id\n");
+ err = fdt_setprop_u32(fdt, nodeoffset, "platform-id", platid);
+ if (err < 0) {
+ ERROR("Failed to set platform-id\n");
return -1;
}
- err = fdt_setprop_u32(fdt, nodeoffset, "platform-id", platid);
+ err = fdt_setprop_u32(fdt, nodeoffset, "config-id", platcfg);
if (err < 0) {
- ERROR("Failed to add node platform-id\n");
+ ERROR("Failed to set config-id\n");
return -1;
}
+
+ flush_dcache_range((uintptr_t)fdt, mem_params->image_info.image_size);
+
return 0;
}
diff --git a/plat/arm/css/sgi/sgi_interconnect.c b/plat/arm/css/sgi/sgi_interconnect.c
index 325b5b152..074f8a274 100644
--- a/plat/arm/css/sgi/sgi_interconnect.c
+++ b/plat/arm/css/sgi/sgi_interconnect.c
@@ -6,7 +6,6 @@
#include <arch_helpers.h>
#include <debug.h>
-#include <sgi_plat_config.h>
/*
* For SGI575 which support FCM (with automatic interconnect enter/exit),
diff --git a/plat/arm/css/sgi/sgi_plat_config.c b/plat/arm/css/sgi/sgi_plat_config.c
deleted file mode 100644
index 29b99a3c2..000000000
--- a/plat/arm/css/sgi/sgi_plat_config.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <debug.h>
-#include <plat_arm.h>
-#include <platform_def.h>
-#include <sgi_variant.h>
-#include <sgi_plat_config.h>
-#include <string.h>
-
-static css_plat_config_t *css_plat_info;
-
-/* GIC */
-/* The GICv3 driver only needs to be initialized in EL3 */
-uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
-
-/* Interconnect configuration for SGI575 */
-const css_inteconn_config_t sgi575_inteconn = {
- .ip_type = ARM_CMN,
- .plat_inteconn_desc = NULL
-};
-
-/* Configuration structure for SGI575 */
-css_plat_config_t sgi575_config = {
- .inteconn = &sgi575_inteconn,
-};
-
-/*******************************************************************************
- * This function initializes the platform sturcture.
- ******************************************************************************/
-void plat_config_init(void)
-{
- /* Get the platform configurations */
- switch (GET_SGI_PART_NUM) {
- case SGI575_SSC_VER_PART_NUM:
- css_plat_info = &sgi575_config;
- break;
- default:
- ERROR("Not a valid sgi variant!\n");
- panic();
- }
-}
-
-/*******************************************************************************
- * This function returns the platform structure pointer.
- ******************************************************************************/
-css_plat_config_t *get_plat_config(void)
-{
- assert(css_plat_info != NULL);
- return css_plat_info;
-}
diff --git a/plat/arm/css/sgi/sgi_topology.c b/plat/arm/css/sgi/sgi_topology.c
index 3f6357bd1..3b7a57ad2 100644
--- a/plat/arm/css/sgi/sgi_topology.c
+++ b/plat/arm/css/sgi/sgi_topology.c
@@ -5,7 +5,6 @@
*/
#include <plat_arm.h>
-#include <sgi_plat_config.h>
/* Topology */
/*
@@ -20,18 +19,12 @@ const unsigned char sgi_pd_tree_desc[] = {
CSS_SGI_MAX_CPUS_PER_CLUSTER
};
-/* Topology configuration for sgi platform */
-const css_topology_t sgi_topology = {
- .power_tree = sgi_pd_tree_desc,
- .plat_cluster_core_count = CSS_SGI_MAX_CPUS_PER_CLUSTER
-};
-
/*******************************************************************************
* This function returns the topology tree information.
******************************************************************************/
const unsigned char *plat_get_power_domain_tree_desc(void)
{
- return sgi_topology.power_tree;
+ return sgi_pd_tree_desc;
}
/*******************************************************************************
@@ -40,7 +33,7 @@ const unsigned char *plat_get_power_domain_tree_desc(void)
******************************************************************************/
unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
{
- return sgi_topology.plat_cluster_core_count;
+ return CSS_SGI_MAX_CPUS_PER_CLUSTER;
}
/*******************************************************************************
diff --git a/plat/arm/css/sgm/sgm_bl31_setup.c b/plat/arm/css/sgm/sgm_bl31_setup.c
index a55176a74..29c32e7cf 100644
--- a/plat/arm/css/sgm/sgm_bl31_setup.c
+++ b/plat/arm/css/sgm/sgm_bl31_setup.c
@@ -8,6 +8,21 @@
#include <debug.h>
#include <plat_arm.h>
#include <sgm_plat_config.h>
+#include "../../css/drivers/scmi/scmi.h"
+#include "../../css/drivers/mhu/css_mhu_doorbell.h"
+
+static scmi_channel_plat_info_t sgm775_scmi_plat_info = {
+ .scmi_mbx_mem = CSS_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 &sgm775_scmi_plat_info;
+}
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
diff --git a/plat/common/aarch32/crash_console_helpers.S b/plat/common/aarch32/crash_console_helpers.S
new file mode 100644
index 000000000..fc37c08fa
--- /dev/null
+++ b/plat/common/aarch32/crash_console_helpers.S
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * If a platform wishes to use the functions in this file it has to be added to
+ * the Makefile of the platform. It is not included in the common Makefile.
+ */
+
+#include <asm_macros.S>
+#include <console.h>
+
+ .globl plat_crash_console_init
+ .globl plat_crash_console_putc
+ .globl plat_crash_console_flush
+
+#if MULTI_CONSOLE_API
+
+ /* -----------------------------------------------------
+ * int plat_crash_console_init(void)
+ * Use normal console by default. Switch it to crash
+ * mode so serial consoles become active again.
+ * NOTE: This default implementation will only work for
+ * crashes that occur after a normal console (marked
+ * valid for the crash state) has been registered with
+ * the console framework. To debug crashes that occur
+ * earlier, the platform has to override these functions
+ * with an implementation that initializes a console
+ * driver with hardcoded parameters. See
+ * docs/porting-guide.rst for more information.
+ * -----------------------------------------------------
+ */
+func plat_crash_console_init
+#if defined(IMAGE_BL1)
+ /*
+ * BL1 code can possibly crash so early that the data segment is not yet
+ * accessible. Don't risk undefined behavior by trying to run the normal
+ * console framework. Platforms that want to debug BL1 will need to
+ * override this with custom functions that can run from registers only.
+ */
+ mov r0, #0
+ bx lr
+#else /* IMAGE_BL1 */
+ mov r3, lr
+ mov r0, #CONSOLE_FLAG_CRASH
+ bl console_switch_state
+ mov r0, #1
+ bx r3
+#endif
+endfunc plat_crash_console_init
+
+ /* -----------------------------------------------------
+ * void plat_crash_console_putc(int character)
+ * Output through the normal console by default.
+ * -----------------------------------------------------
+ */
+func plat_crash_console_putc
+ b console_putc
+endfunc plat_crash_console_putc
+
+ /* -----------------------------------------------------
+ * void plat_crash_console_flush(void)
+ * Flush normal console by default.
+ * -----------------------------------------------------
+ */
+func plat_crash_console_flush
+ b console_flush
+endfunc plat_crash_console_flush
+
+#else /* MULTI_CONSOLE_API */
+
+ /* -----------------------------------------------------
+ * In the old API these are all no-op stubs that need to
+ * be overridden by the platform to be useful.
+ * -----------------------------------------------------
+ */
+func plat_crash_console_init
+ mov r0, #0
+ bx lr
+endfunc plat_crash_console_init
+
+func plat_crash_console_putc
+ bx lr
+endfunc plat_crash_console_putc
+
+func plat_crash_console_flush
+ bx lr
+endfunc plat_crash_console_flush
+
+#endif
diff --git a/plat/common/aarch32/platform_helpers.S b/plat/common/aarch32/platform_helpers.S
index d61853942..e1e2a6f58 100644
--- a/plat/common/aarch32/platform_helpers.S
+++ b/plat/common/aarch32/platform_helpers.S
@@ -8,9 +8,11 @@
#include <asm_macros.S>
.weak plat_report_exception
+#if !ERROR_DEPRECATED
.weak plat_crash_console_init
.weak plat_crash_console_putc
.weak plat_crash_console_flush
+#endif
.weak plat_reset_handler
.weak plat_disable_acp
.weak bl1_plat_prepare_exit
@@ -26,6 +28,7 @@ func plat_report_exception
bx lr
endfunc plat_report_exception
+#if !ERROR_DEPRECATED
/* -----------------------------------------------------
* Placeholder function which should be redefined by
* each platform.
@@ -54,6 +57,7 @@ func plat_crash_console_flush
mov r0, #0
bx lr
endfunc plat_crash_console_flush
+#endif
/* -----------------------------------------------------
* Placeholder function which should be redefined by
diff --git a/plat/common/aarch64/crash_console_helpers.S b/plat/common/aarch64/crash_console_helpers.S
new file mode 100644
index 000000000..5af8db252
--- /dev/null
+++ b/plat/common/aarch64/crash_console_helpers.S
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * If a platform wishes to use the functions in this file it has to be added to
+ * the Makefile of the platform. It is not included in the common Makefile.
+ */
+
+#include <asm_macros.S>
+#include <console.h>
+
+ .globl plat_crash_console_init
+ .globl plat_crash_console_putc
+ .globl plat_crash_console_flush
+
+#if MULTI_CONSOLE_API
+
+ /* -----------------------------------------------------
+ * int plat_crash_console_init(void)
+ * Use normal console by default. Switch it to crash
+ * mode so serial consoles become active again.
+ * NOTE: This default implementation will only work for
+ * crashes that occur after a normal console (marked
+ * valid for the crash state) has been registered with
+ * the console framework. To debug crashes that occur
+ * earlier, the platform has to override these functions
+ * with an implementation that initializes a console
+ * driver with hardcoded parameters. See
+ * docs/porting-guide.rst for more information.
+ * -----------------------------------------------------
+ */
+func plat_crash_console_init
+#if defined(IMAGE_BL1)
+ /*
+ * BL1 code can possibly crash so early that the data segment is not yet
+ * accessible. Don't risk undefined behavior by trying to run the normal
+ * console framework. Platforms that want to debug BL1 will need to
+ * override this with custom functions that can run from registers only.
+ */
+ mov x0, #0
+ ret
+#else /* IMAGE_BL1 */
+ mov x3, x30
+ mov x0, #CONSOLE_FLAG_CRASH
+ bl console_switch_state
+ mov x0, #1
+ ret x3
+#endif
+endfunc plat_crash_console_init
+
+ /* -----------------------------------------------------
+ * void plat_crash_console_putc(int character)
+ * Output through the normal console by default.
+ * -----------------------------------------------------
+ */
+func plat_crash_console_putc
+ b console_putc
+endfunc plat_crash_console_putc
+
+ /* -----------------------------------------------------
+ * void plat_crash_console_flush(void)
+ * Flush normal console by default.
+ * -----------------------------------------------------
+ */
+func plat_crash_console_flush
+ b console_flush
+endfunc plat_crash_console_flush
+
+#else /* MULTI_CONSOLE_API */
+
+ /* -----------------------------------------------------
+ * In the old API these are all no-op stubs that need to
+ * be overridden by the platform to be useful.
+ * -----------------------------------------------------
+ */
+func plat_crash_console_init
+ mov x0, #0
+ ret
+endfunc plat_crash_console_init
+
+func plat_crash_console_putc
+ ret
+endfunc plat_crash_console_putc
+
+func plat_crash_console_flush
+ ret
+endfunc plat_crash_console_flush
+
+#endif
diff --git a/plat/common/aarch64/platform_helpers.S b/plat/common/aarch64/platform_helpers.S
index 7214588a6..d3ffcaf19 100644
--- a/plat/common/aarch64/platform_helpers.S
+++ b/plat/common/aarch64/platform_helpers.S
@@ -10,9 +10,11 @@
#include <platform_def.h>
.weak plat_report_exception
+#if !ERROR_DEPRECATED
.weak plat_crash_console_init
.weak plat_crash_console_putc
.weak plat_crash_console_flush
+#endif
.weak plat_reset_handler
.weak plat_disable_acp
.weak bl1_plat_prepare_exit
@@ -37,6 +39,7 @@ func plat_report_exception
ret
endfunc plat_report_exception
+#if !ERROR_DEPRECATED
#if MULTI_CONSOLE_API
/* -----------------------------------------------------
* int plat_crash_console_init(void)
@@ -109,6 +112,7 @@ func plat_crash_console_flush
ret
endfunc plat_crash_console_flush
#endif
+#endif /* ERROR_DEPRECATED */
/* -----------------------------------------------------
* Placeholder function which should be redefined by
diff --git a/plat/common/plat_bl_common.c b/plat/common/plat_bl_common.c
index 264d5180d..4cf1cc573 100644
--- a/plat/common/plat_bl_common.c
+++ b/plat/common/plat_bl_common.c
@@ -13,6 +13,7 @@
#include <mbedtls_config.h>
#endif
#include <platform.h>
+#include <xlat_tables_compat.h>
/*
* The following platform functions are weakly defined. The Platforms
@@ -72,3 +73,40 @@ int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
return 0;
}
#endif /* TRUSTED_BOARD_BOOT */
+
+/*
+ * Set up the page tables for the generic and platform-specific memory regions.
+ * The size of the Trusted SRAM seen by the BL image must be specified as well
+ * as an array specifying the generic memory regions which can be;
+ * - Code section;
+ * - Read-only data section;
+ * - Init code section, if applicable
+ * - Coherent memory region, if applicable.
+ */
+
+void __init setup_page_tables(const mmap_region_t *bl_regions,
+ const mmap_region_t *plat_regions)
+{
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+ const mmap_region_t *regions = bl_regions;
+
+ while (regions->size != 0U) {
+ VERBOSE("Region: 0x%lx - 0x%lx has attributes 0x%x\n",
+ regions->base_va,
+ regions->base_va + regions->size,
+ regions->attr);
+ regions++;
+ }
+#endif
+ /*
+ * Map the Trusted SRAM with appropriate memory attributes.
+ * Subsequent mappings will adjust the attributes for specific regions.
+ */
+ mmap_add(bl_regions);
+
+ /* Now (re-)map the platform-specific memory regions */
+ mmap_add(plat_regions);
+
+ /* Create the page tables to reflect the above mappings */
+ init_xlat_tables();
+}
diff --git a/plat/hisilicon/hikey/aarch64/hikey_helpers.S b/plat/hisilicon/hikey/aarch64/hikey_helpers.S
index 32ff8b40c..9dfdae49c 100644
--- a/plat/hisilicon/hikey/aarch64/hikey_helpers.S
+++ b/plat/hisilicon/hikey/aarch64/hikey_helpers.S
@@ -12,6 +12,7 @@
.globl platform_mem_init
.globl plat_crash_console_init
.globl plat_crash_console_putc
+ .globl plat_crash_console_flush
.globl plat_report_exception
.globl plat_reset_handler
@@ -61,6 +62,19 @@ func plat_crash_console_putc
endfunc plat_crash_console_putc
/* ---------------------------------------------
+ * int plat_crash_console_flush()
+ * Function to force a write of all buffered
+ * data that hasn't been output.
+ * Out : return -1 on error else return 0.
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func plat_crash_console_flush
+ mov_imm x0, CRASH_CONSOLE_BASE
+ b console_core_flush
+endfunc plat_crash_console_flush
+
+ /* ---------------------------------------------
* void plat_report_exception(unsigned int type)
* Function to report an unhandled exception
* with platform-specific means.
diff --git a/plat/hisilicon/hikey960/aarch64/hikey960_helpers.S b/plat/hisilicon/hikey960/aarch64/hikey960_helpers.S
index d18399fbf..550c5604b 100644
--- a/plat/hisilicon/hikey960/aarch64/hikey960_helpers.S
+++ b/plat/hisilicon/hikey960/aarch64/hikey960_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,6 +14,7 @@
.globl platform_mem_init
.globl plat_crash_console_init
.globl plat_crash_console_putc
+ .globl plat_crash_console_flush
.globl plat_report_exception
.globl plat_reset_handler
.globl clr_ex
@@ -65,6 +66,19 @@ func plat_crash_console_putc
endfunc plat_crash_console_putc
/* ---------------------------------------------
+ * int plat_crash_console_flush()
+ * Function to force a write of all buffered
+ * data that hasn't been output.
+ * Out : return -1 on error else return 0.
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func plat_crash_console_flush
+ mov_imm x0, CRASH_CONSOLE_BASE
+ b console_core_flush
+endfunc plat_crash_console_flush
+
+ /* ---------------------------------------------
* void plat_report_exception(unsigned int type)
* Function to report an unhandled exception
* with platform-specific means.
diff --git a/plat/hisilicon/poplar/aarch64/poplar_helpers.S b/plat/hisilicon/poplar/aarch64/poplar_helpers.S
new file mode 100644
index 000000000..928dbefcc
--- /dev/null
+++ b/plat/hisilicon/poplar/aarch64/poplar_helpers.S
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <asm_macros.S>
+#include <platform_def.h>
+
+ .globl plat_my_core_pos
+ .globl poplar_calc_core_pos
+ .globl plat_crash_console_init
+ .globl plat_crash_console_putc
+ .globl plat_crash_console_flush
+ .globl platform_mem_init
+
+ /* -----------------------------------------------------
+ * unsigned int plat_my_core_pos(void)
+ * This function uses poplar_calc_core_pos()
+ * definition to get the index of the calling CPU.
+ * -----------------------------------------------------
+ */
+func plat_my_core_pos
+ mrs x0, mpidr_el1
+ b poplar_calc_core_pos
+endfunc plat_my_core_pos
+
+ /* -----------------------------------------------------
+ * unsigned int poplar_calc_core_pos(u_register_t mpidr)
+ * Helper function to calculate the core position.
+ * With this function: CorePos = (ClusterId * 4) +
+ * CoreId
+ * -----------------------------------------------------
+ */
+func poplar_calc_core_pos
+ and x1, x0, #MPIDR_CPU_MASK
+ and x0, x0, #MPIDR_CLUSTER_MASK
+ add x0, x1, x0, LSR #6
+ ret
+endfunc poplar_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, POPLAR_CRASH_UART_BASE
+ mov_imm x1, POPLAR_CRASH_UART_CLK_IN_HZ
+ mov_imm x2, POPLAR_CONSOLE_BAUDRATE
+ b console_pl011_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, POPLAR_CRASH_UART_BASE
+ b console_pl011_core_putc
+endfunc plat_crash_console_putc
+
+ /* ---------------------------------------------
+ * int plat_crash_console_flush()
+ * Function to force a write of all buffered
+ * data that hasn't been output.
+ * Out : return -1 on error else return 0.
+ * Clobber list : r0
+ * ---------------------------------------------
+ */
+func plat_crash_console_flush
+ mov_imm x0, POPLAR_CRASH_UART_BASE
+ b console_pl011_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.
+ * ---------------------------------------------------------------------
+ */
+func platform_mem_init
+ ret
+endfunc platform_mem_init
diff --git a/plat/hisilicon/poplar/bl31_plat_setup.c b/plat/hisilicon/poplar/bl31_plat_setup.c
index 83803a66a..20a613d5f 100644
--- a/plat/hisilicon/poplar/bl31_plat_setup.c
+++ b/plat/hisilicon/poplar/bl31_plat_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -15,13 +15,12 @@
#include <errno.h>
#include <generic_delay_timer.h>
#include <mmio.h>
-#include <plat_arm.h>
#include <platform.h>
+#include <platform_def.h>
#include <stddef.h>
#include <string.h>
#include "hi3798cv200.h"
#include "plat_private.h"
-#include "platform_def.h"
/* Memory ranges for code and RO data sections */
#define BL31_RO_BASE (unsigned long)(&__RO_START__)
@@ -113,8 +112,8 @@ void bl31_platform_setup(void)
generic_delay_timer_init();
/* Init GIC distributor and CPU interface */
- plat_arm_gic_driver_init();
- plat_arm_gic_init();
+ poplar_gic_driver_init();
+ poplar_gic_init();
/* Init security properties of IP blocks */
hisi_tzpc_sec_init();
diff --git a/plat/hisilicon/poplar/include/plat_private.h b/plat/hisilicon/poplar/include/plat_private.h
index 845b1bd79..63b7d766f 100644
--- a/plat/hisilicon/poplar/include/plat_private.h
+++ b/plat/hisilicon/poplar/include/plat_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -26,4 +26,11 @@ void plat_configure_mmu_el1(unsigned long total_base,
void plat_io_setup(void);
+unsigned int poplar_calc_core_pos(u_register_t mpidr);
+
+void poplar_gic_driver_init(void);
+void poplar_gic_init(void);
+void poplar_gic_cpuif_enable(void);
+void poplar_gic_pcpu_init(void);
+
#endif /* __PLAT_PRIVATE_H__ */
diff --git a/plat/hisilicon/poplar/include/platform_def.h b/plat/hisilicon/poplar/include/platform_def.h
index 99fd99637..6287a76aa 100644
--- a/plat/hisilicon/poplar/include/platform_def.h
+++ b/plat/hisilicon/poplar/include/platform_def.h
@@ -22,9 +22,9 @@
#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
#define PLATFORM_LINKER_ARCH aarch64
-#define PLAT_ARM_CRASH_UART_BASE PL011_UART0_BASE
-#define PLAT_ARM_CRASH_UART_CLK_IN_HZ PL011_UART0_CLK_IN_HZ
-#define ARM_CONSOLE_BAUDRATE PL011_BAUDRATE
+#define POPLAR_CRASH_UART_BASE PL011_UART0_BASE
+#define POPLAR_CRASH_UART_CLK_IN_HZ PL011_UART0_CLK_IN_HZ
+#define POPLAR_CONSOLE_BAUDRATE PL011_BAUDRATE
/* Generic platform constants */
#define PLATFORM_STACK_SIZE (0x800)
@@ -134,10 +134,10 @@
#define PLAT_MAX_RET_STATE U(1)
/* Interrupt controller */
-#define PLAT_ARM_GICD_BASE GICD_BASE
-#define PLAT_ARM_GICC_BASE GICC_BASE
+#define POPLAR_GICD_BASE GICD_BASE
+#define POPLAR_GICC_BASE GICC_BASE
-#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
+#define POPLAR_G1S_IRQ_PROPS(grp) \
INTR_PROP_DESC(HISI_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \
GIC_INTR_CFG_LEVEL), \
INTR_PROP_DESC(HISI_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \
@@ -165,6 +165,6 @@
INTR_PROP_DESC(HISI_IRQ_SEC_AXI, GIC_HIGHEST_SEC_PRIORITY, grp, \
GIC_INTR_CFG_LEVEL)
-#define PLAT_ARM_G0_IRQ_PROPS(grp)
+#define POPLAR_G0_IRQ_PROPS(grp)
#endif /* PLATFORM_DEF_H */
diff --git a/plat/hisilicon/poplar/plat_pm.c b/plat/hisilicon/poplar/plat_pm.c
index e59cac94c..dcbcec4a1 100644
--- a/plat/hisilicon/poplar/plat_pm.c
+++ b/plat/hisilicon/poplar/plat_pm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,12 +12,11 @@
#include <context_mgmt.h>
#include <debug.h>
#include <mmio.h>
-#include <plat_arm.h>
#include <platform.h>
+#include <platform_def.h>
#include <psci.h>
#include "hi3798cv200.h"
#include "plat_private.h"
-#include "platform_def.h"
#define REG_PERI_CPU_RVBARADDR 0xF8A80034
#define REG_PERI_CPU_AARCH_MODE 0xF8A80030
@@ -76,10 +75,10 @@ static void poplar_pwr_domain_on_finish(const psci_power_state_t *target_state)
PLAT_MAX_OFF_STATE);
/* Enable the gic cpu interface */
- plat_arm_gic_pcpu_init();
+ poplar_gic_pcpu_init();
/* Program the gic per-cpu distributor or re-distributor interface */
- plat_arm_gic_cpuif_enable();
+ poplar_gic_cpuif_enable();
}
static void poplar_pwr_domain_suspend_finish(
diff --git a/plat/hisilicon/poplar/plat_topology.c b/plat/hisilicon/poplar/plat_topology.c
index 3dd818e03..bb53c6b1f 100644
--- a/plat/hisilicon/poplar/plat_topology.c
+++ b/plat/hisilicon/poplar/plat_topology.c
@@ -1,13 +1,13 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
-#include <plat_arm.h>
#include <psci.h>
#include "platform_def.h"
+#include "plat_private.h"
const unsigned char hisi_power_domain_tree_desc[] = {
PLATFORM_CLUSTER_COUNT,
@@ -27,5 +27,5 @@ int plat_core_pos_by_mpidr(u_register_t mpidr)
if ((mpidr & MPIDR_CPU_MASK) >= PLATFORM_CORE_COUNT)
return -1;
- return plat_arm_calc_core_pos(mpidr);
+ return poplar_calc_core_pos(mpidr);
}
diff --git a/plat/hisilicon/poplar/platform.mk b/plat/hisilicon/poplar/platform.mk
index 9d2b61700..de262adca 100644
--- a/plat/hisilicon/poplar/platform.mk
+++ b/plat/hisilicon/poplar/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -53,7 +53,6 @@ PLAT_PL061_MAX_GPIOS := 104
$(eval $(call add_define,PLAT_PL061_MAX_GPIOS))
PLAT_INCLUDES := -Iplat/hisilicon/poplar/include \
- -Iinclude/plat/arm/common/ \
-Iplat/hisilicon/poplar \
-Iinclude/common/tbbr \
-Iinclude/drivers/synopsys \
@@ -68,10 +67,10 @@ PLAT_BL_COMMON_SOURCES := \
drivers/delay_timer/delay_timer.c \
drivers/arm/pl011/aarch64/pl011_console.S \
drivers/arm/gic/v2/gicv2_main.c \
- plat/arm/common/aarch64/arm_helpers.S \
- plat/arm/common/arm_gicv2.c \
plat/common/plat_gicv2.c \
- plat/hisilicon/poplar/aarch64/platform_common.c
+ plat/hisilicon/poplar/aarch64/platform_common.c \
+ plat/hisilicon/poplar/aarch64/poplar_helpers.S \
+ plat/hisilicon/poplar/poplar_gicv2.c
BL1_SOURCES += \
lib/cpus/aarch64/cortex_a53.S \
diff --git a/plat/hisilicon/poplar/poplar_gicv2.c b/plat/hisilicon/poplar/poplar_gicv2.c
new file mode 100644
index 000000000..1c1be47fb
--- /dev/null
+++ b/plat/hisilicon/poplar/poplar_gicv2.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <gicv2.h>
+#include <platform.h>
+#include <platform_def.h>
+
+/******************************************************************************
+ * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
+ * interrupts.
+ *****************************************************************************/
+static const interrupt_prop_t poplar_interrupt_props[] = {
+ POPLAR_G1S_IRQ_PROPS(GICV2_INTR_GROUP0),
+ POPLAR_G0_IRQ_PROPS(GICV2_INTR_GROUP0)
+};
+
+static unsigned int target_mask_array[PLATFORM_CORE_COUNT];
+
+static const gicv2_driver_data_t poplar_gic_data = {
+ .gicd_base = POPLAR_GICD_BASE,
+ .gicc_base = POPLAR_GICC_BASE,
+ .interrupt_props = poplar_interrupt_props,
+ .interrupt_props_num = ARRAY_SIZE(poplar_interrupt_props),
+ .target_masks = target_mask_array,
+ .target_masks_num = ARRAY_SIZE(target_mask_array),
+};
+
+/******************************************************************************
+ * Helper to initialize the GICv2 only driver.
+ *****************************************************************************/
+void poplar_gic_driver_init(void)
+{
+ gicv2_driver_init(&poplar_gic_data);
+}
+
+void poplar_gic_init(void)
+{
+ gicv2_distif_init();
+ gicv2_pcpu_distif_init();
+ gicv2_set_pe_target_mask(plat_my_core_pos());
+ gicv2_cpuif_enable();
+}
+
+/******************************************************************************
+ * Helper to enable the GICv2 CPU interface
+ *****************************************************************************/
+void poplar_gic_cpuif_enable(void)
+{
+ gicv2_cpuif_enable();
+}
+
+/******************************************************************************
+ * Helper to initialize the per cpu distributor interface in GICv2
+ *****************************************************************************/
+void poplar_gic_pcpu_init(void)
+{
+ gicv2_pcpu_distif_init();
+ gicv2_set_pe_target_mask(plat_my_core_pos());
+}
diff --git a/plat/imx/common/imx8_helpers.S b/plat/imx/common/imx8_helpers.S
index b89d346c6..19293bfe7 100644
--- a/plat/imx/common/imx8_helpers.S
+++ b/plat/imx/common/imx8_helpers.S
@@ -16,6 +16,7 @@
.globl plat_secondary_cold_boot_setup
.globl plat_crash_console_init
.globl plat_crash_console_putc
+ .globl plat_crash_console_flush
.globl platform_mem_init
.globl imx_mailbox_init
@@ -106,6 +107,7 @@ func plat_secondary_cold_boot_setup
endfunc plat_secondary_cold_boot_setup
func plat_crash_console_init
+ mov x0, #1
ret
endfunc plat_crash_console_init
@@ -113,6 +115,11 @@ func plat_crash_console_putc
ret
endfunc plat_crash_console_putc
+func plat_crash_console_flush
+ mov x0, #0
+ ret
+endfunc plat_crash_console_flush
+
func platform_mem_init
ret
endfunc platform_mem_init
diff --git a/plat/imx/common/lpuart_console.S b/plat/imx/common/lpuart_console.S
index ad71b89f2..668fd6249 100644
--- a/plat/imx/common/lpuart_console.S
+++ b/plat/imx/common/lpuart_console.S
@@ -6,6 +6,7 @@
#include <arch.h>
#include <asm_macros.S>
+#define USE_FINISH_CONSOLE_REG_2
#include <console_macros.S>
#include <assert_macros.S>
#include "imx8_lpuart.h"
@@ -26,7 +27,7 @@ func console_lpuart_register
mov x0, x6
mov x30, x7
- finish_console_register lpuart
+ finish_console_register lpuart putc=1, getc=1
register_fail:
ret x7
diff --git a/plat/imx/imx7/warp7/aarch32/warp7_helpers.S b/plat/imx/imx7/warp7/aarch32/warp7_helpers.S
index b1921cc38..3695b32db 100644
--- a/plat/imx/imx7/warp7/aarch32/warp7_helpers.S
+++ b/plat/imx/imx7/warp7/aarch32/warp7_helpers.S
@@ -14,6 +14,7 @@
.globl plat_get_my_entrypoint
.globl plat_crash_console_init
.globl plat_crash_console_putc
+ .globl plat_crash_console_flush
.globl plat_panic_handler
/* ---------------------------------------------
@@ -45,6 +46,12 @@ func plat_crash_console_putc
b imx_crash_uart_putc
endfunc plat_crash_console_putc
+func plat_crash_console_flush
+ /* Placeholder */
+ mov r0, #0
+ bx lr
+endfunc plat_crash_console_flush
+
func plat_panic_handler
mov r3, #HAB_ROM_VECTOR_TABLE_FAILSAFE
ldr r3, [r3, #0]
diff --git a/plat/imx/imx7/warp7/platform.mk b/plat/imx/imx7/warp7/platform.mk
index deb4c4115..a77186582 100644
--- a/plat/imx/imx7/warp7/platform.mk
+++ b/plat/imx/imx7/warp7/platform.mk
@@ -22,7 +22,6 @@ endif
# Platform
PLAT_INCLUDES := -Idrivers/imx/uart \
-Iinclude/common/tbbr \
- -Iinclude/plat/arm/common/ \
-Iplat/imx/common/include/ \
-Iplat/imx/imx7/warp7/include \
-Idrivers/imx/timer \
diff --git a/plat/layerscape/board/ls1043/platform.mk b/plat/layerscape/board/ls1043/platform.mk
index c554ac30d..678205cd3 100644
--- a/plat/layerscape/board/ls1043/platform.mk
+++ b/plat/layerscape/board/ls1043/platform.mk
@@ -22,7 +22,6 @@ LS1043_SECURITY_SOURCES := plat/layerscape/common/ls_tzc380.c \
plat/layerscape/board/ls1043/ls1043_security.c
PLAT_INCLUDES := -Iplat/layerscape/board/ls1043/include \
- -Iinclude/plat/arm/common \
-Iplat/layerscape/common/include \
-Iinclude/drivers/arm \
-Iinclude/lib \
diff --git a/plat/layerscape/common/aarch64/ls_console.S b/plat/layerscape/common/aarch64/ls_console.S
index 5c87465eb..ec4390a69 100644
--- a/plat/layerscape/common/aarch64/ls_console.S
+++ b/plat/layerscape/common/aarch64/ls_console.S
@@ -6,6 +6,7 @@
#include <arch.h>
#include <asm_macros.S>
+#define USE_FINISH_CONSOLE_REG_2
#include <console_macros.S>
#include <assert_macros.S>
#include "ls_16550.h"
@@ -106,7 +107,7 @@ func console_ls_16550_register
mov x0, x6
mov x30, x7
- finish_console_register ls_16550
+ finish_console_register ls_16550 putc=1, getc=1, flush=1
register_fail:
ret x7
diff --git a/plat/marvell/common/aarch64/marvell_helpers.S b/plat/marvell/common/aarch64/marvell_helpers.S
index a3dc917c6..128c3ab69 100644
--- a/plat/marvell/common/aarch64/marvell_helpers.S
+++ b/plat/marvell/common/aarch64/marvell_helpers.S
@@ -18,6 +18,7 @@
.weak plat_my_core_pos
.globl plat_crash_console_init
.globl plat_crash_console_putc
+ .globl plat_crash_console_flush
.globl platform_mem_init
.globl disable_mmu_dcache
.globl invalidate_tlb_all
@@ -79,6 +80,19 @@ func plat_crash_console_putc
b console_core_putc
endfunc plat_crash_console_putc
+ /* ---------------------------------------------
+ * int plat_crash_console_flush()
+ * Function to force a write of all buffered
+ * data that hasn't been output.
+ * Out : return -1 on error else return 0.
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func plat_crash_console_flush
+ mov_imm x0, PLAT_MARVELL_CRASH_UART_BASE
+ b console_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/meson/gxbb/aarch64/gxbb_helpers.S b/plat/meson/gxbb/aarch64/gxbb_helpers.S
new file mode 100644
index 000000000..760d6c46d
--- /dev/null
+++ b/plat/meson/gxbb/aarch64/gxbb_helpers.S
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <platform_def.h>
+
+ .globl plat_crash_console_flush
+ .globl plat_crash_console_init
+ .globl plat_crash_console_putc
+ .globl platform_mem_init
+ .globl plat_is_my_cpu_primary
+ .globl plat_my_core_pos
+ .globl plat_reset_handler
+ .globl plat_gxbb_calc_core_pos
+
+ /* -----------------------------------------------------
+ * unsigned int plat_my_core_pos(void);
+ * -----------------------------------------------------
+ */
+func plat_my_core_pos
+ mrs x0, mpidr_el1
+ b plat_gxbb_calc_core_pos
+endfunc plat_my_core_pos
+
+ /* -----------------------------------------------------
+ * unsigned int plat_gxbb_calc_core_pos(u_register_t mpidr);
+ * -----------------------------------------------------
+ */
+func plat_gxbb_calc_core_pos
+ and x0, x0, #MPIDR_CPU_MASK
+ ret
+endfunc plat_gxbb_calc_core_pos
+
+ /* -----------------------------------------------------
+ * unsigned int plat_is_my_cpu_primary(void);
+ * -----------------------------------------------------
+ */
+func plat_is_my_cpu_primary
+ mrs x0, mpidr_el1
+ and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+ cmp x0, #GXBB_PRIMARY_CPU
+ cset w0, eq
+ ret
+endfunc plat_is_my_cpu_primary
+
+ /* ---------------------------------------------
+ * void platform_mem_init(void);
+ * ---------------------------------------------
+ */
+func platform_mem_init
+ ret
+endfunc platform_mem_init
+
+ /* ---------------------------------------------
+ * int plat_crash_console_init(void)
+ * ---------------------------------------------
+ */
+func plat_crash_console_init
+ mov_imm x0, GXBB_UART0_AO_BASE
+ mov_imm x1, GXBB_UART0_AO_CLK_IN_HZ
+ mov_imm x2, GXBB_UART_BAUDRATE
+ b console_meson_init
+endfunc plat_crash_console_init
+
+ /* ---------------------------------------------
+ * int plat_crash_console_putc(int c)
+ * Clobber list : x1, x2
+ * ---------------------------------------------
+ */
+func plat_crash_console_putc
+ mov_imm x1, GXBB_UART0_AO_BASE
+ b console_meson_core_putc
+endfunc plat_crash_console_putc
+
+ /* ---------------------------------------------
+ * int plat_crash_console_flush()
+ * Out : return -1 on error else return 0.
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func plat_crash_console_flush
+ mov_imm x0, GXBB_UART0_AO_BASE
+ b console_meson_core_flush
+endfunc plat_crash_console_flush
+
+ /* ---------------------------------------------
+ * void plat_reset_handler(void);
+ * ---------------------------------------------
+ */
+func plat_reset_handler
+ ret
+endfunc plat_reset_handler
diff --git a/plat/meson/gxbb/gxbb_bl31_setup.c b/plat/meson/gxbb/gxbb_bl31_setup.c
new file mode 100644
index 000000000..3e176f9a0
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_bl31_setup.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <bl_common.h>
+#include <gicv2.h>
+#include <interrupt_props.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <xlat_mmu_helpers.h>
+
+#include "gxbb_private.h"
+
+/*
+ * Placeholder variables for copying the arguments that have been passed to
+ * BL31 from BL2.
+ */
+static entry_point_info_t bl33_image_ep_info;
+
+/*******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for
+ * the security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ ******************************************************************************/
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+ entry_point_info_t *next_image_info;
+
+ assert(type == NON_SECURE);
+
+ next_image_info = &bl33_image_ep_info;
+
+ /* None of the images can have 0x0 as the entrypoint. */
+ if (next_image_info->pc != 0U) {
+ return next_image_info;
+ } else {
+ return NULL;
+ }
+}
+
+/*******************************************************************************
+ * Perform any BL31 early platform setup. Here is an opportunity to copy
+ * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before
+ * they are lost (potentially). This needs to be done before the MMU is
+ * initialized so that the memory layout can be used while creating page
+ * tables. BL2 has flushed this information to memory, so we are guaranteed
+ * to pick up good data.
+ ******************************************************************************/
+struct gxbb_bl31_param {
+ param_header_t h;
+ image_info_t *bl31_image_info;
+ entry_point_info_t *bl32_ep_info;
+ image_info_t *bl32_image_info;
+ entry_point_info_t *bl33_ep_info;
+ image_info_t *bl33_image_info;
+};
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+ struct gxbb_bl31_param *from_bl2;
+
+ /* Initialize the console to provide early debug support */
+ gxbb_console_init();
+
+ /*
+ * In debug builds, we pass a special value in 'arg1' to verify platform
+ * parameters from BL2 to BL31. In release builds it's not used.
+ */
+ assert(arg1 == GXBB_BL31_PLAT_PARAM_VAL);
+
+ /* Check that params passed from BL2 are not NULL. */
+ from_bl2 = (struct gxbb_bl31_param *) arg0;
+
+ /* Check params passed from BL2 are not NULL. */
+ assert(from_bl2 != NULL);
+ assert(from_bl2->h.type == PARAM_BL31);
+ assert(from_bl2->h.version >= VERSION_1);
+
+ /*
+ * Copy BL33 entry point information. It is stored in Secure RAM, in
+ * BL2's address space.
+ */
+ bl33_image_ep_info = *from_bl2->bl33_ep_info;
+
+ if (bl33_image_ep_info.pc == 0U) {
+ ERROR("BL31: BL33 entrypoint not obtained from BL2\n");
+ panic();
+ }
+}
+
+void bl31_plat_arch_setup(void)
+{
+ gxbb_setup_page_tables();
+
+ enable_mmu_el3(0);
+}
+
+/*******************************************************************************
+ * GICv2 driver setup information
+ ******************************************************************************/
+static const interrupt_prop_t gxbb_interrupt_props[] = {
+ INTR_PROP_DESC(IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY,
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+};
+
+static const gicv2_driver_data_t gxbb_gic_data = {
+ .gicd_base = GXBB_GICD_BASE,
+ .gicc_base = GXBB_GICC_BASE,
+ .interrupt_props = gxbb_interrupt_props,
+ .interrupt_props_num = ARRAY_SIZE(gxbb_interrupt_props),
+};
+
+void bl31_platform_setup(void)
+{
+ mhu_secure_init();
+
+ gicv2_driver_init(&gxbb_gic_data);
+ gicv2_distif_init();
+ gicv2_pcpu_distif_init();
+ gicv2_cpuif_enable();
+
+ gxbb_thermal_unknown();
+}
diff --git a/plat/meson/gxbb/gxbb_common.c b/plat/meson/gxbb/gxbb_common.c
new file mode 100644
index 000000000..349d02f9e
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_common.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <ep_info.h>
+#include <interrupt_mgmt.h>
+#include <meson_console.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <stdint.h>
+#include <xlat_tables_v2.h>
+
+/*******************************************************************************
+ * Platform memory map regions
+ ******************************************************************************/
+#define MAP_NSDRAM0 MAP_REGION_FLAT(GXBB_NSDRAM0_BASE, \
+ GXBB_NSDRAM0_SIZE, \
+ MT_MEMORY | MT_RW | MT_NS)
+
+#define MAP_NSDRAM1 MAP_REGION_FLAT(GXBB_NSDRAM1_BASE, \
+ GXBB_NSDRAM1_SIZE, \
+ MT_MEMORY | MT_RW | MT_NS)
+
+#define MAP_SEC_DEVICE0 MAP_REGION_FLAT(GXBB_SEC_DEVICE0_BASE, \
+ GXBB_SEC_DEVICE0_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_SEC_DEVICE1 MAP_REGION_FLAT(GXBB_SEC_DEVICE1_BASE, \
+ GXBB_SEC_DEVICE1_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_TZRAM MAP_REGION_FLAT(GXBB_TZRAM_BASE, \
+ GXBB_TZRAM_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_SEC_DEVICE2 MAP_REGION_FLAT(GXBB_SEC_DEVICE2_BASE, \
+ GXBB_SEC_DEVICE2_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_SEC_DEVICE3 MAP_REGION_FLAT(GXBB_SEC_DEVICE3_BASE, \
+ GXBB_SEC_DEVICE3_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+static const mmap_region_t gxbb_mmap[] = {
+ MAP_NSDRAM0,
+ MAP_NSDRAM1,
+ MAP_SEC_DEVICE0,
+ MAP_SEC_DEVICE1,
+ MAP_TZRAM,
+ MAP_SEC_DEVICE2,
+ MAP_SEC_DEVICE3,
+ {0}
+};
+
+/*******************************************************************************
+ * Per-image regions
+ ******************************************************************************/
+#define MAP_BL31 MAP_REGION_FLAT(BL31_BASE, \
+ BL31_END - BL31_BASE, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+
+#define MAP_BL_CODE MAP_REGION_FLAT(BL_CODE_BASE, \
+ BL_CODE_END - BL_CODE_BASE, \
+ MT_CODE | MT_SECURE)
+
+#define MAP_BL_RO_DATA MAP_REGION_FLAT(BL_RO_DATA_BASE, \
+ BL_RO_DATA_END - BL_RO_DATA_BASE, \
+ MT_RO_DATA | MT_SECURE)
+
+#define MAP_BL_COHERENT MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, \
+ BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+/*******************************************************************************
+ * Function that sets up the translation tables.
+ ******************************************************************************/
+void gxbb_setup_page_tables(void)
+{
+#if IMAGE_BL31
+ const mmap_region_t gxbb_bl_mmap[] = {
+ MAP_BL31,
+ MAP_BL_CODE,
+ MAP_BL_RO_DATA,
+#if USE_COHERENT_MEM
+ MAP_BL_COHERENT,
+#endif
+ {0}
+ };
+#endif
+
+ mmap_add(gxbb_bl_mmap);
+
+ mmap_add(gxbb_mmap);
+
+ init_xlat_tables();
+}
+
+/*******************************************************************************
+ * Function that sets up the console
+ ******************************************************************************/
+static console_meson_t gxbb_console;
+
+void gxbb_console_init(void)
+{
+ int rc = console_meson_register(GXBB_UART0_AO_BASE,
+ GXBB_UART0_AO_CLK_IN_HZ,
+ GXBB_UART_BAUDRATE,
+ &gxbb_console);
+ if (rc == 0) {
+ /*
+ * The crash console doesn't use the multi console API, it uses
+ * the core console functions directly. It is safe to call panic
+ * and let it print debug information.
+ */
+ panic();
+ }
+
+ console_set_scope(&gxbb_console.console,
+ CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
+}
+
+/*******************************************************************************
+ * Function that returns the system counter frequency
+ ******************************************************************************/
+unsigned int plat_get_syscnt_freq2(void)
+{
+ uint32_t val;
+
+ val = mmio_read_32(GXBB_SYS_CPU_CFG7);
+ val &= 0xFDFFFFFF;
+ mmio_write_32(GXBB_SYS_CPU_CFG7, val);
+
+ val = mmio_read_32(GXBB_AO_TIMESTAMP_CNTL);
+ val &= 0xFFFFFE00;
+ mmio_write_32(GXBB_AO_TIMESTAMP_CNTL, val);
+
+ return GXBB_OSC24M_CLK_IN_HZ;
+}
diff --git a/plat/meson/gxbb/gxbb_def.h b/plat/meson/gxbb/gxbb_def.h
new file mode 100644
index 000000000..0c73ac082
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_def.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef GXBB_DEF_H
+#define GXBB_DEF_H
+
+#include <utils_def.h>
+
+/*******************************************************************************
+ * System oscillator
+ ******************************************************************************/
+#define GXBB_OSC24M_CLK_IN_HZ ULL(24000000) /* 24 MHz */
+
+/*******************************************************************************
+ * Memory regions
+ ******************************************************************************/
+#define GXBB_NSDRAM0_BASE UL(0x01000000)
+#define GXBB_NSDRAM0_SIZE UL(0x0F000000)
+
+#define GXBB_NSDRAM1_BASE UL(0x10000000)
+#define GXBB_NSDRAM1_SIZE UL(0x00100000)
+
+#define BL31_BASE UL(0x10100000)
+#define BL31_SIZE UL(0x000C0000)
+#define BL31_LIMIT (BL31_BASE + BL31_SIZE)
+
+/* Shared memory used for SMC services */
+#define GXBB_SHARE_MEM_INPUT_BASE UL(0x100FE000)
+#define GXBB_SHARE_MEM_OUTPUT_BASE UL(0x100FF000)
+
+#define GXBB_SEC_DEVICE0_BASE UL(0xC0000000)
+#define GXBB_SEC_DEVICE0_SIZE UL(0x09000000)
+
+#define GXBB_SEC_DEVICE1_BASE UL(0xD0040000)
+#define GXBB_SEC_DEVICE1_SIZE UL(0x00008000)
+
+#define GXBB_TZRAM_BASE UL(0xD9000000)
+#define GXBB_TZRAM_SIZE UL(0x00014000)
+/* Top 0xC000 bytes (up to 0xD9020000) used by BL2 */
+
+/* Mailboxes */
+#define GXBB_MHU_SECURE_SCP_TO_AP_PAYLOAD UL(0xD9013800)
+#define GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD UL(0xD9013A00)
+#define GXBB_PSCI_MAILBOX_BASE UL(0xD9013F00)
+
+#define GXBB_TZROM_BASE UL(0xD9040000)
+#define GXBB_TZROM_SIZE UL(0x00010000)
+
+#define GXBB_SEC_DEVICE2_BASE UL(0xDA000000)
+#define GXBB_SEC_DEVICE2_SIZE UL(0x00200000)
+
+#define GXBB_SEC_DEVICE3_BASE UL(0xDA800000)
+#define GXBB_SEC_DEVICE3_SIZE UL(0x00200000)
+
+/*******************************************************************************
+ * GIC-400 and interrupt handling related constants
+ ******************************************************************************/
+#define GXBB_GICD_BASE UL(0xC4301000)
+#define GXBB_GICC_BASE UL(0xC4302000)
+
+#define IRQ_SEC_PHY_TIMER 29
+
+#define IRQ_SEC_SGI_0 8
+#define IRQ_SEC_SGI_1 9
+#define IRQ_SEC_SGI_2 10
+#define IRQ_SEC_SGI_3 11
+#define IRQ_SEC_SGI_4 12
+#define IRQ_SEC_SGI_5 13
+#define IRQ_SEC_SGI_6 14
+#define IRQ_SEC_SGI_7 15
+
+/*******************************************************************************
+ * UART definitions
+ ******************************************************************************/
+#define GXBB_UART0_AO_BASE UL(0xC81004C0)
+#define GXBB_UART0_AO_CLK_IN_HZ GXBB_OSC24M_CLK_IN_HZ
+#define GXBB_UART_BAUDRATE U(115200)
+
+/*******************************************************************************
+ * Memory-mapped I/O Registers
+ ******************************************************************************/
+#define GXBB_AO_TIMESTAMP_CNTL UL(0xC81000B4)
+
+#define GXBB_SYS_CPU_CFG7 UL(0xC8834664)
+
+#define GXBB_AO_RTI_STATUS_REG3 UL(0xDA10001C)
+
+#define GXBB_HIU_MAILBOX_SET_0 UL(0xDA83C404)
+#define GXBB_HIU_MAILBOX_STAT_0 UL(0xDA83C408)
+#define GXBB_HIU_MAILBOX_CLR_0 UL(0xDA83C40C)
+#define GXBB_HIU_MAILBOX_SET_3 UL(0xDA83C428)
+#define GXBB_HIU_MAILBOX_STAT_3 UL(0xDA83C42C)
+#define GXBB_HIU_MAILBOX_CLR_3 UL(0xDA83C430)
+
+/*******************************************************************************
+ * System Monitor Call IDs and arguments
+ ******************************************************************************/
+#define GXBB_SM_GET_SHARE_MEM_INPUT_BASE U(0x82000020)
+#define GXBB_SM_GET_SHARE_MEM_OUTPUT_BASE U(0x82000021)
+
+#define GXBB_SM_EFUSE_READ U(0x82000030)
+#define GXBB_SM_EFUSE_USER_MAX U(0x82000033)
+
+#define GXBB_SM_JTAG_ON U(0x82000040)
+#define GXBB_SM_JTAG_OFF U(0x82000041)
+
+#define GXBB_JTAG_STATE_ON U(0)
+#define GXBB_JTAG_STATE_OFF U(1)
+
+#define GXBB_JTAG_M3_AO U(0)
+#define GXBB_JTAG_M3_EE U(1)
+#define GXBB_JTAG_A53_AO U(2)
+#define GXBB_JTAG_A53_EE U(3)
+
+#endif /* GXBB_DEF_H */
diff --git a/plat/meson/gxbb/gxbb_efuse.c b/plat/meson/gxbb/gxbb_efuse.c
new file mode 100644
index 000000000..edea5426c
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_efuse.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include "gxbb_private.h"
+
+#define EFUSE_BASE 0x140
+#define EFUSE_SIZE 0xC0
+
+uint64_t gxbb_efuse_read(void *dst, uint32_t offset, uint32_t size)
+{
+ if ((uint64_t)(offset + size) > (uint64_t)EFUSE_SIZE)
+ return 0;
+
+ return scpi_efuse_read(dst, offset + EFUSE_BASE, size);
+}
+
+uint64_t gxbb_efuse_user_max(void)
+{
+ return EFUSE_SIZE;
+}
diff --git a/plat/meson/gxbb/gxbb_mhu.c b/plat/meson/gxbb/gxbb_mhu.c
new file mode 100644
index 000000000..78b895c52
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_mhu.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bakery_lock.h>
+#include <mmio.h>
+#include <platform_def.h>
+
+static DEFINE_BAKERY_LOCK(mhu_lock);
+
+void mhu_secure_message_start(void)
+{
+ bakery_lock_get(&mhu_lock);
+
+ while (mmio_read_32(GXBB_HIU_MAILBOX_STAT_3) != 0)
+ ;
+}
+
+void mhu_secure_message_send(uint32_t msg)
+{
+ mmio_write_32(GXBB_HIU_MAILBOX_SET_3, msg);
+
+ while (mmio_read_32(GXBB_HIU_MAILBOX_STAT_3) != 0)
+ ;
+}
+
+uint32_t mhu_secure_message_wait(void)
+{
+ uint32_t val;
+
+ do {
+ val = mmio_read_32(GXBB_HIU_MAILBOX_STAT_0);
+ } while (val == 0);
+
+ return val;
+}
+
+void mhu_secure_message_end(void)
+{
+ mmio_write_32(GXBB_HIU_MAILBOX_CLR_0, 0xFFFFFFFF);
+
+ bakery_lock_release(&mhu_lock);
+}
+
+void mhu_secure_init(void)
+{
+ bakery_lock_init(&mhu_lock);
+
+ mmio_write_32(GXBB_HIU_MAILBOX_CLR_3, 0xFFFFFFFF);
+}
diff --git a/plat/meson/gxbb/gxbb_pm.c b/plat/meson/gxbb/gxbb_pm.c
new file mode 100644
index 000000000..930b5e168
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_pm.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <console.h>
+#include <debug.h>
+#include <errno.h>
+#include <gicv2.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <psci.h>
+
+#include "gxbb_private.h"
+
+#define SCPI_POWER_ON 0
+#define SCPI_POWER_RETENTION 1
+#define SCPI_POWER_OFF 3
+
+#define SCPI_SYSTEM_SHUTDOWN 0
+#define SCPI_SYSTEM_REBOOT 1
+
+static uintptr_t gxbb_sec_entrypoint;
+static volatile uint32_t gxbb_cpu0_go;
+
+static void gxbb_program_mailbox(u_register_t mpidr, uint64_t value)
+{
+ unsigned int core = plat_gxbb_calc_core_pos(mpidr);
+ uintptr_t cpu_mailbox_addr = GXBB_PSCI_MAILBOX_BASE + (core << 4);
+
+ mmio_write_64(cpu_mailbox_addr, value);
+ flush_dcache_range(cpu_mailbox_addr, sizeof(uint64_t));
+}
+
+static void __dead2 gxbb_system_reset(void)
+{
+ INFO("BL31: PSCI_SYSTEM_RESET\n");
+
+ uint32_t status = mmio_read_32(GXBB_AO_RTI_STATUS_REG3);
+
+ NOTICE("BL31: Reboot reason: 0x%x\n", status);
+
+ status &= 0xFFFF0FF0;
+
+ console_flush();
+
+ mmio_write_32(GXBB_AO_RTI_STATUS_REG3, status);
+
+ int ret = scpi_sys_power_state(SCPI_SYSTEM_REBOOT);
+
+ if (ret != 0) {
+ ERROR("BL31: PSCI_SYSTEM_RESET: SCP error: %u\n", ret);
+ panic();
+ }
+
+ wfi();
+
+ ERROR("BL31: PSCI_SYSTEM_RESET: Operation not handled\n");
+ panic();
+}
+
+static void __dead2 gxbb_system_off(void)
+{
+ INFO("BL31: PSCI_SYSTEM_OFF\n");
+
+ unsigned int ret = scpi_sys_power_state(SCPI_SYSTEM_SHUTDOWN);
+
+ if (ret != 0) {
+ ERROR("BL31: PSCI_SYSTEM_OFF: SCP error %u\n", ret);
+ panic();
+ }
+
+ gxbb_program_mailbox(read_mpidr_el1(), 0);
+
+ wfi();
+
+ ERROR("BL31: PSCI_SYSTEM_OFF: Operation not handled\n");
+ panic();
+}
+
+static int32_t gxbb_pwr_domain_on(u_register_t mpidr)
+{
+ unsigned int core = plat_gxbb_calc_core_pos(mpidr);
+
+ /* CPU0 can't be turned OFF, emulate it with a WFE loop */
+ if (core == GXBB_PRIMARY_CPU) {
+ VERBOSE("BL31: Releasing CPU0 from wait loop...\n");
+
+ gxbb_cpu0_go = 1;
+ flush_dcache_range((uintptr_t)&gxbb_cpu0_go, sizeof(gxbb_cpu0_go));
+ dsb();
+ isb();
+
+ sev();
+
+ return PSCI_E_SUCCESS;
+ }
+
+ gxbb_program_mailbox(mpidr, gxbb_sec_entrypoint);
+ scpi_set_css_power_state(mpidr,
+ SCPI_POWER_ON, SCPI_POWER_ON, SCPI_POWER_ON);
+ dmbsy();
+ sev();
+
+ return PSCI_E_SUCCESS;
+}
+
+static void gxbb_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+ unsigned int core = plat_gxbb_calc_core_pos(read_mpidr_el1());
+
+ assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
+ PLAT_LOCAL_STATE_OFF);
+
+ if (core == GXBB_PRIMARY_CPU) {
+ gxbb_cpu0_go = 0;
+ flush_dcache_range((uintptr_t)&gxbb_cpu0_go, sizeof(gxbb_cpu0_go));
+ dsb();
+ isb();
+ }
+
+ gicv2_pcpu_distif_init();
+ gicv2_cpuif_enable();
+}
+
+static void gxbb_pwr_domain_off(const psci_power_state_t *target_state)
+{
+ u_register_t mpidr = read_mpidr_el1();
+ unsigned int core = plat_gxbb_calc_core_pos(mpidr);
+ uintptr_t addr = GXBB_PSCI_MAILBOX_BASE + 8 + (core << 4);
+
+ mmio_write_32(addr, 0xFFFFFFFF);
+ flush_dcache_range(addr, sizeof(uint32_t));
+
+ gicv2_cpuif_disable();
+
+ /* CPU0 can't be turned OFF, emulate it with a WFE loop */
+ if (core == GXBB_PRIMARY_CPU)
+ return;
+
+ scpi_set_css_power_state(mpidr,
+ SCPI_POWER_OFF, SCPI_POWER_ON, SCPI_POWER_ON);
+}
+
+static void __dead2 gxbb_pwr_domain_pwr_down_wfi(const psci_power_state_t
+ *target_state)
+{
+ unsigned int core = plat_gxbb_calc_core_pos(read_mpidr_el1());
+
+ /* CPU0 can't be turned OFF, emulate it with a WFE loop */
+ if (core == GXBB_PRIMARY_CPU) {
+ VERBOSE("BL31: CPU0 entering wait loop...\n");
+
+ while (gxbb_cpu0_go == 0)
+ wfe();
+
+ VERBOSE("BL31: CPU0 resumed.\n");
+
+ write_rmr_el3(RMR_EL3_RR_BIT | RMR_EL3_AA64_BIT);
+ }
+
+ dsbsy();
+
+ for (;;)
+ wfi();
+}
+
+/*******************************************************************************
+ * Platform handlers and setup function.
+ ******************************************************************************/
+static const plat_psci_ops_t gxbb_ops = {
+ .pwr_domain_on = gxbb_pwr_domain_on,
+ .pwr_domain_on_finish = gxbb_pwr_domain_on_finish,
+ .pwr_domain_off = gxbb_pwr_domain_off,
+ .pwr_domain_pwr_down_wfi = gxbb_pwr_domain_pwr_down_wfi,
+ .system_off = gxbb_system_off,
+ .system_reset = gxbb_system_reset,
+};
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+ const plat_psci_ops_t **psci_ops)
+{
+ gxbb_sec_entrypoint = sec_entrypoint;
+ *psci_ops = &gxbb_ops;
+ gxbb_cpu0_go = 0;
+ return 0;
+}
diff --git a/plat/meson/gxbb/gxbb_private.h b/plat/meson/gxbb/gxbb_private.h
new file mode 100644
index 000000000..910a42c1c
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_private.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef GXBB_PRIVATE_H
+#define GXBB_PRIVATE_H
+
+#include <stdint.h>
+
+/* Utility functions */
+unsigned int plat_gxbb_calc_core_pos(u_register_t mpidr);
+void gxbb_console_init(void);
+void gxbb_setup_page_tables(void);
+
+/* MHU functions */
+void mhu_secure_message_start(void);
+void mhu_secure_message_send(uint32_t msg);
+uint32_t mhu_secure_message_wait(void);
+void mhu_secure_message_end(void);
+void mhu_secure_init(void);
+
+/* SCPI functions */
+void scpi_set_css_power_state(u_register_t mpidr, uint32_t cpu_state,
+ uint32_t cluster_state, uint32_t css_state);
+uint32_t scpi_sys_power_state(uint64_t system_state);
+void scpi_jtag_set_state(uint32_t state, uint8_t select);
+uint32_t scpi_efuse_read(void *dst, uint32_t base, uint32_t size);
+void scpi_unknown_thermal(uint32_t arg0, uint32_t arg1,
+ uint32_t arg2, uint32_t arg3);
+
+/* Peripherals */
+void gxbb_thermal_unknown(void);
+uint64_t gxbb_efuse_read(void *dst, uint32_t offset, uint32_t size);
+uint64_t gxbb_efuse_user_max(void);
+
+#endif /* GXBB_PRIVATE_H */
diff --git a/plat/meson/gxbb/gxbb_scpi.c b/plat/meson/gxbb/gxbb_scpi.c
new file mode 100644
index 000000000..2390bcad8
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_scpi.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <string.h>
+
+#include "gxbb_private.h"
+
+#define SIZE_SHIFT 20
+#define SIZE_MASK 0x1FF
+
+/*
+ * Note: The Amlogic SCP firmware uses the legacy SCPI protocol.
+ */
+#define SCPI_CMD_SET_CSS_POWER_STATE 0x04
+#define SCPI_CMD_SET_SYS_POWER_STATE 0x08
+
+#define SCPI_CMD_JTAG_SET_STATE 0xC0
+#define SCPI_CMD_EFUSE_READ 0xC2
+
+static inline uint32_t scpi_cmd(uint32_t command, uint32_t size)
+{
+ return command | (size << SIZE_SHIFT);
+}
+
+void scpi_secure_message_send(uint32_t command, uint32_t size)
+{
+ mhu_secure_message_send(scpi_cmd(command, size));
+}
+
+uint32_t scpi_secure_message_receive(void **message_out, size_t *size_out)
+{
+ uint32_t response = mhu_secure_message_wait();
+
+ size_t size = (response >> SIZE_SHIFT) & SIZE_MASK;
+
+ response &= ~(SIZE_MASK << SIZE_SHIFT);
+
+ if (size_out != NULL)
+ *size_out = size;
+
+ if (message_out != NULL)
+ *message_out = (void *)GXBB_MHU_SECURE_SCP_TO_AP_PAYLOAD;
+
+ return response;
+}
+
+void scpi_set_css_power_state(u_register_t mpidr, uint32_t cpu_state,
+ uint32_t cluster_state, uint32_t css_state)
+{
+ uint32_t state = (mpidr & 0x0F) | /* CPU ID */
+ ((mpidr & 0xF00) >> 4) | /* Cluster ID */
+ (cpu_state << 8) |
+ (cluster_state << 12) |
+ (css_state << 16);
+
+ mhu_secure_message_start();
+ mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD, state);
+ mhu_secure_message_send(scpi_cmd(SCPI_CMD_SET_CSS_POWER_STATE, 4));
+ mhu_secure_message_wait();
+ mhu_secure_message_end();
+}
+
+uint32_t scpi_sys_power_state(uint64_t system_state)
+{
+ uint32_t *response;
+ size_t size;
+
+ mhu_secure_message_start();
+ mmio_write_8(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD, system_state);
+ mhu_secure_message_send(scpi_cmd(SCPI_CMD_SET_SYS_POWER_STATE, 1));
+ scpi_secure_message_receive((void *)&response, &size);
+ mhu_secure_message_end();
+
+ return *response;
+}
+
+void scpi_jtag_set_state(uint32_t state, uint8_t select)
+{
+ assert(state <= GXBB_JTAG_STATE_OFF);
+
+ if (select > GXBB_JTAG_A53_EE) {
+ WARN("BL31: Invalid JTAG select (0x%x).\n", select);
+ return;
+ }
+
+ mhu_secure_message_start();
+ mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD,
+ (state << 8) | (uint32_t)select);
+ mhu_secure_message_send(scpi_cmd(SCPI_CMD_JTAG_SET_STATE, 4));
+ mhu_secure_message_wait();
+ mhu_secure_message_end();
+}
+
+uint32_t scpi_efuse_read(void *dst, uint32_t base, uint32_t size)
+{
+ uint32_t *response;
+ size_t resp_size;
+
+ if (size > 0x1FC)
+ return 0;
+
+ mhu_secure_message_start();
+ mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD, base);
+ mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD + 4, size);
+ mhu_secure_message_send(scpi_cmd(SCPI_CMD_EFUSE_READ, 8));
+ scpi_secure_message_receive((void *)&response, &resp_size);
+ mhu_secure_message_end();
+
+ /*
+ * response[0] is the size of the response message.
+ * response[1 ... N] are the contents.
+ */
+ if (*response != 0)
+ memcpy(dst, response + 1, *response);
+
+ return *response;
+}
+
+void scpi_unknown_thermal(uint32_t arg0, uint32_t arg1,
+ uint32_t arg2, uint32_t arg3)
+{
+ mhu_secure_message_start();
+ mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x0, arg0);
+ mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x4, arg1);
+ mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x8, arg2);
+ mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0xC, arg3);
+ mhu_secure_message_send(scpi_cmd(0xC3, 16));
+ mhu_secure_message_wait();
+ mhu_secure_message_end();
+}
diff --git a/plat/meson/gxbb/gxbb_sip_svc.c b/plat/meson/gxbb/gxbb_sip_svc.c
new file mode 100644
index 000000000..82ed44935
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_sip_svc.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <runtime_svc.h>
+#include <stdint.h>
+
+#include "gxbb_private.h"
+
+/*******************************************************************************
+ * This function is responsible for handling all SiP calls
+ ******************************************************************************/
+static uintptr_t gxbb_sip_handler(uint32_t smc_fid,
+ u_register_t x1, u_register_t x2,
+ u_register_t x3, u_register_t x4,
+ void *cookie, void *handle,
+ u_register_t flags)
+{
+ switch (smc_fid) {
+
+ case GXBB_SM_GET_SHARE_MEM_INPUT_BASE:
+ SMC_RET1(handle, GXBB_SHARE_MEM_INPUT_BASE);
+
+ case GXBB_SM_GET_SHARE_MEM_OUTPUT_BASE:
+ SMC_RET1(handle, GXBB_SHARE_MEM_OUTPUT_BASE);
+
+ case GXBB_SM_EFUSE_READ:
+ {
+ void *dst = (void *)GXBB_SHARE_MEM_OUTPUT_BASE;
+ uint64_t ret = gxbb_efuse_read(dst, (uint32_t)x1, x2);
+
+ SMC_RET1(handle, ret);
+ }
+ case GXBB_SM_EFUSE_USER_MAX:
+ SMC_RET1(handle, gxbb_efuse_user_max());
+
+ case GXBB_SM_JTAG_ON:
+ scpi_jtag_set_state(GXBB_JTAG_STATE_ON, x1);
+ SMC_RET1(handle, 0);
+
+ case GXBB_SM_JTAG_OFF:
+ scpi_jtag_set_state(GXBB_JTAG_STATE_OFF, x1);
+ SMC_RET1(handle, 0);
+
+ default:
+ ERROR("BL31: Unhandled SIP SMC: 0x%08x\n", smc_fid);
+ break;
+ }
+
+ SMC_RET1(handle, SMC_UNK);
+}
+
+DECLARE_RT_SVC(
+ gxbb_sip_handler,
+
+ OEN_SIP_START,
+ OEN_SIP_END,
+ SMC_TYPE_FAST,
+ NULL,
+ gxbb_sip_handler
+);
diff --git a/plat/meson/gxbb/gxbb_thermal.c b/plat/meson/gxbb/gxbb_thermal.c
new file mode 100644
index 000000000..b6048eee4
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_thermal.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include "gxbb_private.h"
+
+static int32_t modules_initialized = -1;
+
+/*******************************************************************************
+ * Unknown commands related to something thermal-related
+ ******************************************************************************/
+void gxbb_thermal_unknown(void)
+{
+ uint16_t ret;
+
+ if (modules_initialized == -1) {
+ scpi_efuse_read(&ret, 0, 2);
+ modules_initialized = ret;
+ }
+
+ scpi_unknown_thermal(10, 2, /* thermal */
+ 13, 1); /* thermalver */
+}
diff --git a/plat/meson/gxbb/gxbb_topology.c b/plat/meson/gxbb/gxbb_topology.c
new file mode 100644
index 000000000..49bb2dcad
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_topology.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <platform_def.h>
+#include <stdint.h>
+
+#include "gxbb_private.h"
+
+/* The power domain tree descriptor */
+static unsigned char power_domain_tree_desc[] = {
+ /* Number of root nodes */
+ PLATFORM_CLUSTER_COUNT,
+ /* Number of children for the first node */
+ PLATFORM_CLUSTER0_CORE_COUNT
+};
+
+/*******************************************************************************
+ * This function returns the ARM default topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ return power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ ******************************************************************************/
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+ unsigned int cluster_id, cpu_id;
+
+ mpidr &= MPIDR_AFFINITY_MASK;
+ if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK))
+ return -1;
+
+ cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+ cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+
+ if (cluster_id >= PLATFORM_CLUSTER_COUNT)
+ return -1;
+
+ if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER)
+ return -1;
+
+ return plat_gxbb_calc_core_pos(mpidr);
+}
diff --git a/plat/meson/gxbb/include/plat_macros.S b/plat/meson/gxbb/include/plat_macros.S
new file mode 100644
index 000000000..948b5f98f
--- /dev/null
+++ b/plat/meson/gxbb/include/plat_macros.S
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+#include <gicv2.h>
+#include <platform_def.h>
+
+.section .rodata.gic_reg_name, "aS"
+
+gicc_regs:
+ .asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
+gicd_pend_reg:
+ .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n Offset:\t\t\tvalue\n"
+newline:
+ .asciz "\n"
+spacer:
+ .asciz ":\t\t0x"
+
+ /* ---------------------------------------------
+ * The below required platform porting macro
+ * prints out relevant GIC and CCI registers
+ * whenever an unhandled exception is taken in
+ * BL31.
+ * Clobbers: x0 - x10, x16, x17, sp
+ * ---------------------------------------------
+ */
+ .macro plat_crash_print_regs
+
+ /* GICC registers */
+
+ mov_imm x17, GXBB_GICC_BASE
+
+ adr x6, gicc_regs
+ ldr w8, [x17, #GICC_HPPIR]
+ ldr w9, [x17, #GICC_AHPPIR]
+ ldr w10, [x17, #GICC_CTLR]
+ bl str_in_crash_buf_print
+
+ /* GICD registers */
+
+ mov_imm x16, GXBB_GICD_BASE
+
+ add x7, x16, #GICD_ISPENDR
+ adr x4, gicd_pend_reg
+ bl asm_print_str
+
+gicd_ispendr_loop:
+ sub x4, x7, x16
+ cmp x4, #0x280
+ b.eq exit_print_gic_regs
+ bl asm_print_hex
+
+ adr x4, spacer
+ bl asm_print_str
+
+ ldr x4, [x7], #8
+ bl asm_print_hex
+
+ adr x4, newline
+ bl asm_print_str
+ b gicd_ispendr_loop
+exit_print_gic_regs:
+
+ .endm
+
+#endif /* PLAT_MACROS_S */
diff --git a/plat/meson/gxbb/include/platform_def.h b/plat/meson/gxbb/include/platform_def.h
new file mode 100644
index 000000000..a85637fe2
--- /dev/null
+++ b/plat/meson/gxbb/include/platform_def.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include <utils_def.h>
+
+#include "../gxbb_def.h"
+
+#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH aarch64
+
+/* Special value used to verify platform parameters from BL2 to BL31 */
+#define GXBB_BL31_PLAT_PARAM_VAL ULL(0x0F1E2D3C4B5A6978)
+
+#define PLATFORM_STACK_SIZE UL(0x1000)
+
+#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4)
+#define PLATFORM_CLUSTER_COUNT U(1)
+#define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER
+#define PLATFORM_CORE_COUNT PLATFORM_CLUSTER0_CORE_COUNT
+
+#define GXBB_PRIMARY_CPU U(0)
+
+#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1
+#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \
+ PLATFORM_CORE_COUNT)
+
+#define PLAT_MAX_RET_STATE U(1)
+#define PLAT_MAX_OFF_STATE U(2)
+
+/* Local power state for power domains in Run state. */
+#define PLAT_LOCAL_STATE_RUN U(0)
+/* Local power state for retention. Valid only for CPU power domains */
+#define PLAT_LOCAL_STATE_RET U(1)
+/* Local power state for power-down. Valid for CPU and cluster power domains. */
+#define PLAT_LOCAL_STATE_OFF U(2)
+
+/*
+ * Macros used to parse state information from State-ID if it is using the
+ * recommended encoding for State-ID.
+ */
+#define PLAT_LOCAL_PSTATE_WIDTH U(4)
+#define PLAT_LOCAL_PSTATE_MASK ((U(1) << PLAT_LOCAL_PSTATE_WIDTH) - 1)
+
+/*
+ * Some data must be aligned on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches.
+ */
+#define CACHE_WRITEBACK_SHIFT U(6)
+#define CACHE_WRITEBACK_GRANULE (U(1) << CACHE_WRITEBACK_SHIFT)
+
+/* Memory-related defines */
+#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32)
+
+#define MAX_MMAP_REGIONS 12
+#define MAX_XLAT_TABLES 5
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/meson/gxbb/platform.mk b/plat/meson/gxbb/platform.mk
new file mode 100644
index 000000000..e6f5ae489
--- /dev/null
+++ b/plat/meson/gxbb/platform.mk
@@ -0,0 +1,78 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include lib/xlat_tables_v2/xlat_tables.mk
+
+PLAT_INCLUDES := -Iinclude/drivers/meson/ \
+ -Iplat/meson/gxbb/include
+
+GXBB_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
+ drivers/arm/gic/v2/gicv2_main.c \
+ drivers/arm/gic/v2/gicv2_helpers.c \
+ plat/common/plat_gicv2.c
+
+PLAT_BL_COMMON_SOURCES := drivers/console/aarch64/multi_console.S \
+ drivers/meson/console/aarch64/meson_console.S \
+ plat/meson/gxbb/gxbb_common.c \
+ plat/meson/gxbb/gxbb_topology.c \
+ ${XLAT_TABLES_LIB_SRCS}
+
+BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \
+ plat/common/plat_psci_common.c \
+ plat/meson/gxbb/aarch64/gxbb_helpers.S \
+ plat/meson/gxbb/gxbb_bl31_setup.c \
+ plat/meson/gxbb/gxbb_efuse.c \
+ plat/meson/gxbb/gxbb_mhu.c \
+ plat/meson/gxbb/gxbb_pm.c \
+ plat/meson/gxbb/gxbb_scpi.c \
+ plat/meson/gxbb/gxbb_sip_svc.c \
+ plat/meson/gxbb/gxbb_thermal.c \
+ ${GXBB_GIC_SOURCES}
+
+# Tune compiler for Cortex-A53
+ifeq ($(notdir $(CC)),armclang)
+ TF_CFLAGS_aarch64 += -mcpu=cortex-a53
+else ifneq ($(findstring clang,$(notdir $(CC))),)
+ TF_CFLAGS_aarch64 += -mcpu=cortex-a53
+else
+ TF_CFLAGS_aarch64 += -mtune=cortex-a53
+endif
+
+# Build config flags
+# ------------------
+
+# Enable all errata workarounds for Cortex-A53
+ERRATA_A53_826319 := 1
+ERRATA_A53_835769 := 1
+ERRATA_A53_836870 := 1
+ERRATA_A53_843419 := 1
+ERRATA_A53_855873 := 1
+
+WORKAROUND_CVE_2017_5715 := 0
+
+# Have different sections for code and rodata
+SEPARATE_CODE_AND_RODATA := 1
+
+# Use Coherent memory
+USE_COHERENT_MEM := 1
+
+# Use multi console API
+MULTI_CONSOLE_API := 1
+
+# Verify build config
+# -------------------
+
+ifneq (${MULTI_CONSOLE_API}, 1)
+ $(error Error: gxbb needs MULTI_CONSOLE_API=1)
+endif
+
+ifneq (${RESET_TO_BL31}, 0)
+ $(error Error: gxbb needs RESET_TO_BL31=0)
+endif
+
+ifeq (${ARCH},aarch32)
+ $(error Error: AArch32 not supported on gxbb)
+endif
diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
index 3c490d078..0476ba826 100644
--- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
+++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -36,6 +36,7 @@
.globl platform_mem_init
.globl plat_crash_console_init
.globl plat_crash_console_putc
+ .globl plat_crash_console_flush
.globl tegra_secure_entrypoint
.globl plat_reset_handler
@@ -240,6 +241,20 @@ func plat_crash_console_putc
b console_core_putc
endfunc plat_crash_console_putc
+ /* ---------------------------------------------
+ * int plat_crash_console_flush()
+ * Function to force a write of all buffered
+ * data that hasn't been output.
+ * Out : return -1 on error else return 0.
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func plat_crash_console_flush
+ adr x0, tegra_console_base
+ ldr x0, [x0]
+ b console_core_flush
+endfunc plat_crash_console_flush
+
/* ---------------------------------------------------
* Function to handle a platform reset and store
* input parameters passed by BL2.
diff --git a/plat/qemu/include/platform_def.h b/plat/qemu/include/platform_def.h
index 55252c380..c2289bc56 100644
--- a/plat/qemu/include/platform_def.h
+++ b/plat/qemu/include/platform_def.h
@@ -223,7 +223,7 @@
* DT related constants
*/
#define PLAT_QEMU_DT_BASE NS_DRAM0_BASE
-#define PLAT_QEMU_DT_MAX_SIZE 0x10000
+#define PLAT_QEMU_DT_MAX_SIZE 0x100000
/*
* System counter
diff --git a/plat/qemu/platform.mk b/plat/qemu/platform.mk
index 9167c9fcf..982886a93 100644
--- a/plat/qemu/platform.mk
+++ b/plat/qemu/platform.mk
@@ -38,24 +38,12 @@ ifeq (${ARM_ARCH_MAJOR},8)
PLAT_INCLUDES += -Iinclude/plat/arm/common/${ARCH}
endif
-# Use translation tables library v2 by default
-ARM_XLAT_TABLES_LIB_V1 := 0
-$(eval $(call assert_boolean,ARM_XLAT_TABLES_LIB_V1))
-$(eval $(call add_define,ARM_XLAT_TABLES_LIB_V1))
-
-
PLAT_BL_COMMON_SOURCES := plat/qemu/qemu_common.c \
plat/qemu/qemu_console.c \
drivers/arm/pl011/${ARCH}/pl011_console.S \
-ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
-PLAT_BL_COMMON_SOURCES += lib/xlat_tables/xlat_tables_common.c \
- lib/xlat_tables/${ARCH}/xlat_tables.c
-else
include lib/xlat_tables_v2/xlat_tables.mk
-
PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
-endif
ifneq (${TRUSTED_BOARD_BOOT},0)
diff --git a/plat/qemu/qemu_common.c b/plat/qemu/qemu_common.c
index 376ff2f11..43a3f7012 100644
--- a/plat/qemu/qemu_common.c
+++ b/plat/qemu/qemu_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,7 +7,8 @@
#include <arch_helpers.h>
#include <bl_common.h>
#include <platform_def.h>
-#include <arm_xlat_tables.h>
+#include <xlat_tables_v2.h>
+
#include "qemu_private.h"
#define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \
diff --git a/plat/rockchip/rk3328/platform.mk b/plat/rockchip/rk3328/platform.mk
index 560cccae6..785f64036 100644
--- a/plat/rockchip/rk3328/platform.mk
+++ b/plat/rockchip/rk3328/platform.mk
@@ -29,6 +29,7 @@ RK_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
PLAT_BL_COMMON_SOURCES := lib/xlat_tables/aarch64/xlat_tables.c \
lib/xlat_tables/xlat_tables_common.c \
+ plat/common/aarch64/crash_console_helpers.S \
plat/common/plat_psci_common.c
BL31_SOURCES += ${RK_GIC_SOURCES} \
diff --git a/plat/rockchip/rk3368/platform.mk b/plat/rockchip/rk3368/platform.mk
index 050a2c423..a3e593e60 100644
--- a/plat/rockchip/rk3368/platform.mk
+++ b/plat/rockchip/rk3368/platform.mk
@@ -26,6 +26,7 @@ RK_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \
lib/xlat_tables/aarch64/xlat_tables.c \
+ plat/common/aarch64/crash_console_helpers.S \
plat/common/plat_psci_common.c
BL31_SOURCES += ${RK_GIC_SOURCES} \
diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk
index 912041928..eccf1cc85 100644
--- a/plat/rockchip/rk3399/platform.mk
+++ b/plat/rockchip/rk3399/platform.mk
@@ -32,6 +32,7 @@ RK_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \
lib/xlat_tables/aarch64/xlat_tables.c \
+ plat/common/aarch64/crash_console_helpers.S \
plat/common/plat_psci_common.c
BL31_SOURCES += ${RK_GIC_SOURCES} \
diff --git a/plat/rpi3/platform.mk b/plat/rpi3/platform.mk
index a7b0991fb..36c1ee2b4 100644
--- a/plat/rpi3/platform.mk
+++ b/plat/rpi3/platform.mk
@@ -4,12 +4,16 @@
# SPDX-License-Identifier: BSD-3-Clause
#
+include lib/libfdt/libfdt.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+
PLAT_INCLUDES := -Iinclude/common/tbbr \
-Iplat/rpi3/include
PLAT_BL_COMMON_SOURCES := drivers/console/aarch64/console.S \
drivers/ti/uart/aarch64/16550_console.S \
- plat/rpi3/rpi3_common.c
+ plat/rpi3/rpi3_common.c \
+ ${XLAT_TABLES_LIB_SRCS}
BL1_SOURCES += drivers/io/io_fip.c \
drivers/io/io_memmap.c \
@@ -37,12 +41,8 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \
plat/rpi3/aarch64/plat_helpers.S \
plat/rpi3/rpi3_bl31_setup.c \
plat/rpi3/rpi3_pm.c \
- plat/rpi3/rpi3_topology.c
-
-# Translation tables library
-include lib/xlat_tables_v2/xlat_tables.mk
-
-PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
+ plat/rpi3/rpi3_topology.c \
+ ${LIBFDT_SRCS}
# Tune compiler for Cortex-A53
ifeq ($(notdir $(CC)),armclang)
diff --git a/plat/rpi3/rpi3_bl31_setup.c b/plat/rpi3/rpi3_bl31_setup.c
index 0ae783e12..483d150f0 100644
--- a/plat/rpi3/rpi3_bl31_setup.c
+++ b/plat/rpi3/rpi3_bl31_setup.c
@@ -6,6 +6,7 @@
#include <assert.h>
#include <bl_common.h>
+#include <libfdt.h>
#include <platform.h>
#include <platform_def.h>
#include <xlat_mmu_helpers.h>
@@ -137,12 +138,74 @@ void bl31_plat_arch_setup(void)
enable_mmu_el3(0);
}
-void bl31_platform_setup(void)
+/*
+ * Add information to the device tree (if any) about the reserved DRAM used by
+ * the Trusted Firmware.
+ */
+static void rpi3_dtb_add_mem_rsv(void)
{
+ int i, regions, rc;
+ uint64_t addr, size;
+ void *dtb = (void *)RPI3_PRELOADED_DTB_BASE;
+
+ INFO("rpi3: Checking DTB...\n");
+
+ /* Return if no device tree is detected */
+ if (fdt_check_header(dtb) != 0)
+ return;
+
+ regions = fdt_num_mem_rsv(dtb);
+
+ VERBOSE("rpi3: Found %d mem reserve region(s)\n", regions);
+
+ /* We expect to find one reserved region that we can modify */
+ if (regions < 1)
+ return;
+
+ /*
+ * Look for the region that corresponds to the default boot firmware. It
+ * starts at address 0, and it is not needed when the default firmware
+ * is replaced by this port of the Trusted Firmware.
+ */
+ for (i = 0; i < regions; i++) {
+ if (fdt_get_mem_rsv(dtb, i, &addr, &size) != 0)
+ continue;
+
+ if (addr != 0x0)
+ continue;
+
+ VERBOSE("rpi3: Firmware mem reserve region found\n");
+
+ rc = fdt_del_mem_rsv(dtb, i);
+ if (rc != 0) {
+ INFO("rpi3: Can't remove mem reserve region (%d)\n", rc);
+ }
+
+ break;
+ }
+
+ if (i == regions) {
+ VERBOSE("rpi3: Firmware mem reserve region not found\n");
+ }
+
/*
- * Do initial security configuration to allow DRAM/device access
- * (if earlier BL has not already done so).
+ * Reserve all SRAM. As said in the documentation, this isn't actually
+ * secure memory, so it is needed to tell BL33 that this is a reserved
+ * memory region. It doesn't guarantee it won't use it, though.
*/
+ rc = fdt_add_mem_rsv(dtb, SEC_SRAM_BASE, SEC_SRAM_SIZE);
+ if (rc != 0) {
+ WARN("rpi3: Can't add mem reserve region (%d)\n", rc);
+ }
+
+ INFO("rpi3: Reserved 0x%llx - 0x%llx in DTB\n", SEC_SRAM_BASE,
+ SEC_SRAM_BASE + SEC_SRAM_SIZE);
+}
- return;
+void bl31_platform_setup(void)
+{
+#ifdef RPI3_PRELOADED_DTB_BASE
+ /* Only modify a DTB if we know where to look for it */
+ rpi3_dtb_add_mem_rsv();
+#endif
}
diff --git a/plat/rpi3/rpi3_common.c b/plat/rpi3/rpi3_common.c
index 98cf534c7..18ff1c82e 100644
--- a/plat/rpi3/rpi3_common.c
+++ b/plat/rpi3/rpi3_common.c
@@ -23,7 +23,12 @@
#define MAP_SHARED_RAM MAP_REGION_FLAT(SHARED_RAM_BASE, \
SHARED_RAM_SIZE, \
- MT_DEVICE | MT_RW | MT_SECURE)
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#ifdef RPI3_PRELOADED_DTB_BASE
+#define MAP_NS_DTB MAP_REGION_FLAT(RPI3_PRELOADED_DTB_BASE, 0x10000, \
+ MT_MEMORY | MT_RW | MT_NS)
+#endif
#define MAP_NS_DRAM0 MAP_REGION_FLAT(NS_DRAM0_BASE, NS_DRAM0_SIZE, \
MT_MEMORY | MT_RW | MT_NS)
@@ -74,6 +79,9 @@ static const mmap_region_t plat_rpi3_mmap[] = {
static const mmap_region_t plat_rpi3_mmap[] = {
MAP_SHARED_RAM,
MAP_DEVICE0,
+#ifdef RPI3_PRELOADED_DTB_BASE
+ MAP_NS_DTB,
+#endif
#ifdef BL32_BASE
MAP_BL32_MEM,
#endif
diff --git a/plat/st/stm32mp1/bl2_io_storage.c b/plat/st/stm32mp1/bl2_io_storage.c
index 7346c0cf3..9a023124c 100644
--- a/plat/st/stm32mp1/bl2_io_storage.c
+++ b/plat/st/stm32mp1/bl2_io_storage.c
@@ -8,12 +8,18 @@
#include <assert.h>
#include <boot_api.h>
#include <debug.h>
+#include <io_block.h>
#include <io_driver.h>
#include <io_dummy.h>
+#include <io_mmc.h>
+#include <io_stm32image.h>
#include <io_storage.h>
+#include <mmc.h>
#include <mmio.h>
+#include <partition.h>
#include <platform.h>
#include <platform_def.h>
+#include <stm32_sdmmc2.h>
#include <stm32mp1_private.h>
#include <stm32mp1_rcc.h>
#include <string.h>
@@ -24,6 +30,50 @@ static const io_dev_connector_t *dummy_dev_con;
static uintptr_t dummy_dev_handle;
static uintptr_t dummy_dev_spec;
+static uintptr_t image_dev_handle;
+
+static io_block_spec_t gpt_block_spec = {
+ .offset = 0,
+ .length = 34 * MMC_BLOCK_SIZE, /* Size of GPT table */
+};
+
+uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE);
+
+static const io_block_dev_spec_t mmc_block_dev_spec = {
+ /* It's used as temp buffer in block driver */
+ .buffer = {
+ .offset = (size_t)&block_buffer,
+ .length = MMC_BLOCK_SIZE,
+ },
+ .ops = {
+ .read = mmc_read_blocks,
+ .write = NULL,
+ },
+ .block_size = MMC_BLOCK_SIZE,
+};
+
+static uintptr_t storage_dev_handle;
+static const io_dev_connector_t *mmc_dev_con;
+
+#define IMG_IDX_BL33 0
+
+static const struct stm32image_part_info bl33_partition_spec = {
+ .name = BL33_IMAGE_NAME,
+ .binary_type = BL33_BINARY_TYPE,
+};
+
+static struct stm32image_device_info stm32image_dev_info_spec = {
+ .lba_size = MMC_BLOCK_SIZE,
+ .part_info[IMG_IDX_BL33] = {
+ .name = BL33_IMAGE_NAME,
+ .binary_type = BL33_BINARY_TYPE,
+ },
+};
+
+static io_block_spec_t stm32image_block_spec;
+
+static const io_dev_connector_t *stm32image_dev_con;
+
static const io_block_spec_t bl32_block_spec = {
.offset = BL32_BASE,
.length = STM32MP1_BL32_SIZE
@@ -35,6 +85,8 @@ static const io_block_spec_t bl2_block_spec = {
};
static int open_dummy(const uintptr_t spec);
+static int open_image(const uintptr_t spec);
+static int open_storage(const uintptr_t spec);
struct plat_io_policy {
uintptr_t *dev_handle;
@@ -53,6 +105,21 @@ static const struct plat_io_policy policies[] = {
.image_spec = (uintptr_t)&bl32_block_spec,
.check = open_dummy
},
+ [BL33_IMAGE_ID] = {
+ .dev_handle = &image_dev_handle,
+ .image_spec = (uintptr_t)&bl33_partition_spec,
+ .check = open_image
+ },
+ [GPT_IMAGE_ID] = {
+ .dev_handle = &storage_dev_handle,
+ .image_spec = (uintptr_t)&gpt_block_spec,
+ .check = open_storage
+ },
+ [STM32_IMAGE_ID] = {
+ .dev_handle = &storage_dev_handle,
+ .image_spec = (uintptr_t)&stm32image_block_spec,
+ .check = open_storage
+ }
};
static int open_dummy(const uintptr_t spec)
@@ -60,6 +127,16 @@ static int open_dummy(const uintptr_t spec)
return io_dev_init(dummy_dev_handle, 0);
}
+static int open_image(const uintptr_t spec)
+{
+ return io_dev_init(image_dev_handle, 0);
+}
+
+static int open_storage(const uintptr_t spec)
+{
+ return io_dev_init(storage_dev_handle, 0);
+}
+
static void print_boot_device(boot_api_context_t *boot_context)
{
switch (boot_context->boot_interface_selected) {
@@ -149,6 +226,9 @@ static void print_reset_reason(void)
void stm32mp1_io_setup(void)
{
int io_result __unused;
+ struct stm32_sdmmc2_params params;
+ struct mmc_device_info device_info;
+ uintptr_t mmc_default_instance;
boot_api_context_t *boot_context =
(boot_api_context_t *)stm32mp1_get_boot_ctx_address();
@@ -168,6 +248,93 @@ void stm32mp1_io_setup(void)
io_result = io_dev_open(dummy_dev_con, dummy_dev_spec,
&dummy_dev_handle);
assert(io_result == 0);
+
+ switch (boot_context->boot_interface_selected) {
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
+ dmb();
+
+ memset(&params, 0, sizeof(struct stm32_sdmmc2_params));
+
+ if (boot_context->boot_interface_selected ==
+ BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC) {
+ device_info.mmc_dev_type = MMC_IS_EMMC;
+ mmc_default_instance = STM32MP1_SDMMC2_BASE;
+ } else {
+ device_info.mmc_dev_type = MMC_IS_SD;
+ mmc_default_instance = STM32MP1_SDMMC1_BASE;
+ }
+
+ switch (boot_context->boot_interface_instance) {
+ case 1:
+ params.reg_base = STM32MP1_SDMMC1_BASE;
+ break;
+ case 2:
+ params.reg_base = STM32MP1_SDMMC2_BASE;
+ break;
+ case 3:
+ params.reg_base = STM32MP1_SDMMC3_BASE;
+ break;
+ default:
+ WARN("SDMMC instance not found, using default\n");
+ params.reg_base = mmc_default_instance;
+ break;
+ }
+
+ params.device_info = &device_info;
+ stm32_sdmmc2_mmc_init(&params);
+
+ /* Open MMC as a block device to read GPT table */
+ io_result = register_io_dev_block(&mmc_dev_con);
+ if (io_result != 0) {
+ panic();
+ }
+
+ io_result = io_dev_open(mmc_dev_con,
+ (uintptr_t)&mmc_block_dev_spec,
+ &storage_dev_handle);
+ assert(io_result == 0);
+
+ partition_init(GPT_IMAGE_ID);
+
+ io_result = io_dev_close(storage_dev_handle);
+ assert(io_result == 0);
+
+ stm32image_dev_info_spec.device_size =
+ stm32_sdmmc2_mmc_get_device_size();
+ stm32image_dev_info_spec.part_info[IMG_IDX_BL33].part_offset =
+ get_partition_entry(BL33_IMAGE_NAME)->start;
+ stm32image_dev_info_spec.part_info[IMG_IDX_BL33].bkp_offset =
+ get_partition_entry(BL33_IMAGE_NAME)->length;
+
+ stm32image_block_spec.offset = 0;
+ stm32image_block_spec.length =
+ get_partition_entry(BL33_IMAGE_NAME)->length;
+
+ /*
+ * Re-open MMC with io_mmc, for better perfs compared to
+ * io_block.
+ */
+ io_result = register_io_dev_mmc(&mmc_dev_con);
+ assert(io_result == 0);
+
+ io_result = io_dev_open(mmc_dev_con, 0, &storage_dev_handle);
+ assert(io_result == 0);
+
+ io_result = register_io_dev_stm32image(&stm32image_dev_con);
+ assert(io_result == 0);
+
+ io_result = io_dev_open(stm32image_dev_con,
+ (uintptr_t)&stm32image_dev_info_spec,
+ &image_dev_handle);
+ assert(io_result == 0);
+ break;
+
+ default:
+ ERROR("Boot interface %d not supported\n",
+ boot_context->boot_interface_selected);
+ break;
+ }
}
/*
diff --git a/plat/st/stm32mp1/include/boot_api.h b/plat/st/stm32mp1/include/boot_api.h
index 71c359347..e019cffcc 100644
--- a/plat/st/stm32mp1/include/boot_api.h
+++ b/plat/st/stm32mp1/include/boot_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,6 +8,7 @@
#define __BOOT_API_H
#include <stdint.h>
+#include <stdio.h>
/*
* Possible value of boot context field 'boot_interface_sel'
@@ -229,7 +230,9 @@ typedef struct {
*/
uint8_t ecc_pubk[BOOT_API_ECDSA_PUB_KEY_LEN_IN_BYTES];
/* Pad up to 256 byte total size */
- uint8_t pad[84];
+ uint8_t pad[83];
+ /* Add binary type information */
+ uint8_t binary_type;
} __packed boot_api_image_header_t;
#endif /* __BOOT_API_H */
diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h
index 47e1ffcf5..2ba6cc64a 100644
--- a/plat/st/stm32mp1/include/platform_def.h
+++ b/plat/st/stm32mp1/include/platform_def.h
@@ -26,6 +26,7 @@
/* SSBL = second stage boot loader */
#define BL33_IMAGE_NAME "ssbl"
+#define BL33_BINARY_TYPE U(0x0)
#define STM32MP1_PRIMARY_CPU U(0x0)
@@ -39,6 +40,7 @@
#define MAX_IO_DEVICES 4
#define MAX_IO_HANDLES 4
+#define MAX_IO_BLOCK_DEVICES 1
/*******************************************************************************
* BL2 specific defines.
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 30b293296..678a8528e 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -14,8 +14,15 @@ STM32_TF_VERSION ?= 0
# Not needed for Cortex-A7
WORKAROUND_CVE_2017_5715:= 0
+# Number of TF-A copies in the device
+STM32_TF_A_COPIES := 2
+$(eval $(call add_define,STM32_TF_A_COPIES))
+PLAT_PARTITION_MAX_ENTRIES := $(shell echo $$(($(STM32_TF_A_COPIES) + 1)))
+$(eval $(call add_define,PLAT_PARTITION_MAX_ENTRIES))
+
PLAT_INCLUDES := -Iplat/st/stm32mp1/include/
PLAT_INCLUDES += -Iinclude/common/tbbr
+PLAT_INCLUDES += -Iinclude/drivers/partition
PLAT_INCLUDES += -Iinclude/drivers/st
# Device tree
@@ -56,11 +63,19 @@ PLAT_BL_COMMON_SOURCES += ${LIBFDT_SRCS} \
plat/st/stm32mp1/stm32mp1_helper.S \
plat/st/stm32mp1/stm32mp1_security.c
-BL2_SOURCES += drivers/io/io_dummy.c \
+BL2_SOURCES += drivers/io/io_block.c \
+ drivers/io/io_dummy.c \
drivers/io/io_storage.c \
+ drivers/st/io/io_stm32image.c \
plat/st/stm32mp1/bl2_io_storage.c \
plat/st/stm32mp1/bl2_plat_setup.c
+BL2_SOURCES += drivers/mmc/mmc.c \
+ drivers/partition/gpt.c \
+ drivers/partition/partition.c \
+ drivers/st/io/io_mmc.c \
+ drivers/st/mmc/stm32_sdmmc2.c
+
BL2_SOURCES += drivers/st/ddr/stm32mp1_ddr.c \
drivers/st/ddr/stm32mp1_ram.c
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index bb3fecf6d..222449837 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -155,10 +155,9 @@ enum ddr_type {
#define STM32MP1_SDMMC2_BASE U(0x58007000)
#define STM32MP1_SDMMC3_BASE U(0x48004000)
-#define STM32MP1_SD_INIT_FREQ 400000 /*400 KHz*/
+#define STM32MP1_MMC_INIT_FREQ 400000 /*400 KHz*/
#define STM32MP1_SD_NORMAL_SPEED_MAX_FREQ 25000000 /*25 MHz*/
#define STM32MP1_SD_HIGH_SPEED_MAX_FREQ 50000000 /*50 MHz*/
-#define STM32MP1_EMMC_INIT_FREQ STM32MP1_SD_INIT_FREQ
#define STM32MP1_EMMC_NORMAL_SPEED_MAX_FREQ 26000000 /*26 MHz*/
#define STM32MP1_EMMC_HIGH_SPEED_MAX_FREQ 52000000 /*52 MHz*/
diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c
index f84b9d449..e438dc36c 100644
--- a/plat/ti/k3/common/k3_bl31_setup.c
+++ b/plat/ti/k3/common/k3_bl31_setup.c
@@ -108,7 +108,7 @@ void bl31_plat_arch_setup(void)
{0}
};
- arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+ setup_page_tables(bl_regions, plat_arm_get_mmap());
enable_mmu_el3(0);
}
diff --git a/plat/ti/k3/common/k3_helpers.S b/plat/ti/k3/common/k3_helpers.S
index c95e9c367..3dfdda4bd 100644
--- a/plat/ti/k3/common/k3_helpers.S
+++ b/plat/ti/k3/common/k3_helpers.S
@@ -100,13 +100,13 @@ endfunc plat_my_core_pos
* Clobber list : x0 - x4
* ---------------------------------------------
*/
+ .globl plat_crash_console_init
func plat_crash_console_init
mov_imm x0, CRASH_CONSOLE_BASE
mov_imm x1, CRASH_CONSOLE_CLK
mov_imm x2, CRASH_CONSOLE_BAUD_RATE
mov w3, #0x0
- b console_core_init
-
+ b console_16550_core_init
endfunc plat_crash_console_init
/* ---------------------------------------------
@@ -116,7 +116,22 @@ endfunc plat_crash_console_init
* Clobber list : x1, x2
* ---------------------------------------------
*/
+ .globl plat_crash_console_putc
func plat_crash_console_putc
mov_imm x1, CRASH_CONSOLE_BASE
- b console_core_putc
+ b console_16550_core_putc
endfunc plat_crash_console_putc
+
+ /* ---------------------------------------------
+ * int plat_crash_console_flush()
+ * Function to force a write of all buffered
+ * data that hasn't been output.
+ * Out : return -1 on error else return 0.
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+ .globl plat_crash_console_flush
+func plat_crash_console_flush
+ mov_imm x0, CRASH_CONSOLE_BASE
+ b console_16550_core_flush
+endfunc plat_crash_console_flush
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S b/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S
index ad960f493..969d8faa1 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,6 +10,12 @@
.globl plat_secondary_cold_boot_setup
.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
/* -----------------------------------------------------
* void plat_secondary_cold_boot_setup (void);
@@ -47,3 +53,76 @@ func plat_is_my_cpu_primary
cset x0, eq
ret x9
endfunc plat_is_my_cpu_primary
+
+ /* -----------------------------------------------------
+ * unsigned int plat_my_core_pos(void)
+ * This function uses the zynqmp_calc_core_pos()
+ * definition to get the index of the calling CPU.
+ * -----------------------------------------------------
+ */
+func plat_my_core_pos
+ mrs x0, mpidr_el1
+ b zynqmp_calc_core_pos
+endfunc plat_my_core_pos
+
+ /* -----------------------------------------------------
+ * unsigned int zynqmp_calc_core_pos(u_register_t mpidr)
+ * Helper function to calculate the core position.
+ * With this function: CorePos = (ClusterId * 4) +
+ * CoreId
+ * -----------------------------------------------------
+ */
+func zynqmp_calc_core_pos
+ and x1, x0, #MPIDR_CPU_MASK
+ and x0, x0, #MPIDR_CLUSTER_MASK
+ add x0, x1, x0, LSR #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_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_core_putc
+endfunc plat_crash_console_putc
+
+ /* ---------------------------------------------
+ * int plat_crash_console_flush()
+ * Function to force a write of all buffered
+ * data that hasn't been output.
+ * Out : return -1 on error else return 0.
+ * Clobber list : r0
+ * ---------------------------------------------
+ */
+func plat_crash_console_flush
+ mov_imm x0, ZYNQMP_CRASH_UART_BASE
+ b console_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.
+ * ---------------------------------------------------------------------
+ */
+func platform_mem_init
+ ret
+endfunc platform_mem_init
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index a14388f56..01634500a 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -193,6 +193,6 @@ void bl31_plat_arch_setup(void)
{0}
};
- arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+ setup_page_tables(bl_regions, plat_arm_get_mmap());
enable_mmu_el3(0);
}
diff --git a/plat/xilinx/zynqmp/plat_zynqmp.c b/plat/xilinx/zynqmp/plat_zynqmp.c
index cbfa935c2..2441630bd 100644
--- a/plat/xilinx/zynqmp/plat_zynqmp.c
+++ b/plat/xilinx/zynqmp/plat_zynqmp.c
@@ -1,10 +1,11 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <plat_arm.h>
+#include <platform.h>
+#include "zynqmp_private.h"
int plat_core_pos_by_mpidr(u_register_t mpidr)
{
@@ -14,5 +15,5 @@ int plat_core_pos_by_mpidr(u_register_t mpidr)
if ((mpidr & MPIDR_CPU_MASK) >= PLATFORM_CORE_COUNT)
return -1;
- return plat_arm_calc_core_pos(mpidr);
+ return zynqmp_calc_core_pos(mpidr);
}
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 53d93c326..35c8983cd 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -16,10 +16,6 @@ ENABLE_SVE_FOR_NS := 0
WORKAROUND_CVE_2017_5715 := 0
-ARM_XLAT_TABLES_LIB_V1 := 1
-$(eval $(call assert_boolean,ARM_XLAT_TABLES_LIB_V1))
-$(eval $(call add_define,ARM_XLAT_TABLES_LIB_V1))
-
ifdef ZYNQMP_ATF_MEM_BASE
$(eval $(call add_define,ZYNQMP_ATF_MEM_BASE))
@@ -64,7 +60,6 @@ PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \
drivers/arm/gic/v2/gicv2_helpers.c \
drivers/cadence/uart/aarch64/cdns_console.S \
drivers/console/aarch64/console.S \
- plat/arm/common/aarch64/arm_helpers.S \
plat/arm/common/arm_cci.c \
plat/arm/common/arm_common.c \
plat/arm/common/arm_gicv2.c \
diff --git a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
index 52d4bf8cc..a27f34b45 100644
--- a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
+++ b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -57,6 +57,6 @@ void tsp_plat_arch_setup(void)
{0}
};
- arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+ setup_page_tables(bl_regions, plat_arm_get_mmap());
enable_mmu_el1(0);
}
diff --git a/plat/xilinx/zynqmp/zynqmp_def.h b/plat/xilinx/zynqmp/zynqmp_def.h
index 50a733176..9d19b1bbd 100644
--- a/plat/xilinx/zynqmp/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/zynqmp_def.h
@@ -145,13 +145,11 @@
# error "invalid ZYNQMP_CONSOLE"
#endif
-#define PLAT_ARM_CRASH_UART_BASE ZYNQMP_UART_BASE
+#define ZYNQMP_CRASH_UART_BASE ZYNQMP_UART_BASE
/* impossible to call C routine how it is done now - hardcode any value */
-#define PLAT_ARM_CRASH_UART_CLK_IN_HZ 100000000 /* FIXME */
-
+#define ZYNQMP_CRASH_UART_CLK_IN_HZ 100000000 /* FIXME */
/* Must be non zero */
-#define ZYNQMP_UART_BAUDRATE 115200
-#define ARM_CONSOLE_BAUDRATE ZYNQMP_UART_BAUDRATE
+#define ZYNQMP_UART_BAUDRATE 115200
/* Silicon version detection */
#define ZYNQMP_SILICON_VER_MASK 0xF000
diff --git a/plat/xilinx/zynqmp/zynqmp_private.h b/plat/xilinx/zynqmp/zynqmp_private.h
index 08a54107a..d5024c3ec 100644
--- a/plat/xilinx/zynqmp/zynqmp_private.h
+++ b/plat/xilinx/zynqmp/zynqmp_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,9 +9,12 @@
#include <bl_common.h>
#include <interrupt_mgmt.h>
+#include <stdint.h>
void zynqmp_config_setup(void);
+unsigned int zynqmp_calc_core_pos(u_register_t mpidr);
+
/* ZynqMP specific functions */
unsigned int zynqmp_get_uart_clk(void);
unsigned int zynqmp_get_bootmode(void);