mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-22 04:24:19 +00:00
allwinner: Introduce basic platform support
This platform supports Allwinner's SoCs with ARMv8 cores. So far they all sport a single cluster of Cortex-A53 cores. "sunxi" is the original code name used for this platform, and since it appears in the Linux kernel and in U-Boot as well, we use it here as a short file name prefix and for identifiers. This port includes BL31 support only. U-Boot's SPL takes the role of the primary loader, also doing the DRAM initialization. It then loads the rest of the firmware, namely ATF and U-Boot (BL33), then hands execution over to ATF. This commit includes the basic platform code shared across all SoCs. There is no platform.mk yet. [Andre: moved files into proper directories, supported RESET_TO_BL31, various clean ups and simplifications ] Signed-off-by: Samuel Holland <samuel@sholland.org> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
This commit is contained in:
parent
498161a504
commit
58032586f8
9 changed files with 372 additions and 0 deletions
27
plat/allwinner/common/include/plat_macros.S
Normal file
27
plat/allwinner/common/include/plat_macros.S
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PLAT_MACROS_S__
|
||||||
|
#define __PLAT_MACROS_S__
|
||||||
|
|
||||||
|
#include <arm_macros.S>
|
||||||
|
#include <sunxi_mmap.h>
|
||||||
|
|
||||||
|
/* ---------------------------------------------
|
||||||
|
* 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
|
||||||
|
mov_imm x17, SUNXI_GICC_BASE
|
||||||
|
mov_imm x16, SUNXI_GICD_BASE
|
||||||
|
arm_print_gic_regs
|
||||||
|
.endm
|
||||||
|
|
||||||
|
#endif /* __PLAT_MACROS_S__ */
|
45
plat/allwinner/common/include/platform_def.h
Normal file
45
plat/allwinner/common/include/platform_def.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PLATFORM_DEF_H__
|
||||||
|
#define __PLATFORM_DEF_H__
|
||||||
|
|
||||||
|
#include <common_def.h>
|
||||||
|
#include <sunxi_mmap.h>
|
||||||
|
#include <tbbr/tbbr_img_def.h>
|
||||||
|
|
||||||
|
#define BL31_BASE SUNXI_SRAM_A2_BASE
|
||||||
|
#define BL31_LIMIT (SUNXI_SRAM_A2_BASE + SUNXI_SRAM_A2_SIZE)
|
||||||
|
|
||||||
|
/* The traditional U-Boot load address is 160MB into DRAM, so at 0x4a000000 */
|
||||||
|
#define PLAT_SUNXI_NS_IMAGE_OFFSET (SUNXI_DRAM_BASE + (160U << 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 PLAT_MAX_PWR_LVL_STATES 2
|
||||||
|
#define PLAT_MAX_RET_STATE 1
|
||||||
|
#define PLAT_MAX_OFF_STATE 2
|
||||||
|
|
||||||
|
#define PLAT_MAX_PWR_LVL 2
|
||||||
|
#define PLAT_NUM_PWR_DOMAINS (1 + \
|
||||||
|
PLATFORM_CLUSTER_COUNT + \
|
||||||
|
PLATFORM_CORE_COUNT)
|
||||||
|
|
||||||
|
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
|
||||||
|
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
|
||||||
|
|
||||||
|
#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 4
|
||||||
|
#define PLATFORM_STACK_SIZE (0x1000 / PLATFORM_CORE_COUNT)
|
||||||
|
|
||||||
|
#endif /* __PLATFORM_DEF_H__ */
|
17
plat/allwinner/common/include/sunxi_def.h
Normal file
17
plat/allwinner/common/include/sunxi_def.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SUNXI_DEF_H__
|
||||||
|
#define __SUNXI_DEF_H__
|
||||||
|
|
||||||
|
/* Clock configuration */
|
||||||
|
#define SUNXI_OSC24M_CLK_IN_HZ 24000000
|
||||||
|
|
||||||
|
/* UART configuration */
|
||||||
|
#define SUNXI_UART0_BAUDRATE 115200
|
||||||
|
#define SUNXI_UART0_CLK_IN_HZ SUNXI_OSC24M_CLK_IN_HZ
|
||||||
|
|
||||||
|
#endif /* __SUNXI_DEF_H__ */
|
49
plat/allwinner/common/plat_helpers.S
Normal file
49
plat/allwinner/common/plat_helpers.S
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch.h>
|
||||||
|
#include <asm_macros.S>
|
||||||
|
#include <sunxi_def.h>
|
||||||
|
#include <sunxi_mmap.h>
|
||||||
|
|
||||||
|
.globl plat_crash_console_init
|
||||||
|
.globl plat_crash_console_putc
|
||||||
|
.globl plat_crash_console_flush
|
||||||
|
.globl plat_my_core_pos
|
||||||
|
.globl platform_mem_init
|
||||||
|
.globl plat_report_exception
|
||||||
|
|
||||||
|
func plat_crash_console_init
|
||||||
|
mov_imm x0, SUNXI_UART0_BASE
|
||||||
|
mov_imm x1, SUNXI_UART0_CLK_IN_HZ
|
||||||
|
mov_imm x2, SUNXI_UART0_BAUDRATE
|
||||||
|
b console_16550_core_init
|
||||||
|
endfunc plat_crash_console_init
|
||||||
|
|
||||||
|
func plat_crash_console_putc
|
||||||
|
mov_imm x1, SUNXI_UART0_BASE
|
||||||
|
b console_16550_core_putc
|
||||||
|
endfunc plat_crash_console_putc
|
||||||
|
|
||||||
|
func plat_crash_console_flush
|
||||||
|
ret
|
||||||
|
endfunc plat_crash_console_flush
|
||||||
|
|
||||||
|
func plat_my_core_pos
|
||||||
|
mrs x0, mpidr_el1
|
||||||
|
and x1, x0, #MPIDR_CLUSTER_MASK
|
||||||
|
and x0, x0, #MPIDR_CPU_MASK
|
||||||
|
add x0, x0, x1, LSR #6
|
||||||
|
ret
|
||||||
|
endfunc plat_my_core_pos
|
||||||
|
|
||||||
|
func platform_mem_init
|
||||||
|
ret
|
||||||
|
endfunc platform_mem_init
|
||||||
|
|
||||||
|
func plat_report_exception
|
||||||
|
ret
|
||||||
|
endfunc plat_report_exception
|
73
plat/allwinner/common/sunxi_bl31_setup.c
Normal file
73
plat/allwinner/common/sunxi_bl31_setup.c
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <console.h>
|
||||||
|
#include <debug.h>
|
||||||
|
#include <generic_delay_timer.h>
|
||||||
|
#include <gicv2.h>
|
||||||
|
#include <platform.h>
|
||||||
|
#include <platform_def.h>
|
||||||
|
#include <sunxi_def.h>
|
||||||
|
#include <sunxi_mmap.h>
|
||||||
|
#include <uart_16550.h>
|
||||||
|
|
||||||
|
#include "sunxi_private.h"
|
||||||
|
|
||||||
|
static entry_point_info_t bl33_image_ep_info;
|
||||||
|
|
||||||
|
static console_16550_t console;
|
||||||
|
|
||||||
|
static const gicv2_driver_data_t sunxi_gic_data = {
|
||||||
|
.gicd_base = SUNXI_GICD_BASE,
|
||||||
|
.gicc_base = SUNXI_GICC_BASE,
|
||||||
|
};
|
||||||
|
|
||||||
|
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
|
||||||
|
u_register_t arg2, u_register_t arg3)
|
||||||
|
{
|
||||||
|
/* Initialize the debug console as soon as possible */
|
||||||
|
console_16550_register(SUNXI_UART0_BASE, SUNXI_UART0_CLK_IN_HZ,
|
||||||
|
SUNXI_UART0_BAUDRATE, &console);
|
||||||
|
|
||||||
|
/* Populate entry point information for BL33 */
|
||||||
|
SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
|
||||||
|
/*
|
||||||
|
* Tell BL31 where the non-trusted software image
|
||||||
|
* is located and the entry state information
|
||||||
|
*/
|
||||||
|
bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
|
||||||
|
bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
|
||||||
|
DISABLE_ALL_EXCEPTIONS);
|
||||||
|
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bl31_plat_arch_setup(void)
|
||||||
|
{
|
||||||
|
sunxi_configure_mmu_el3(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bl31_platform_setup(void)
|
||||||
|
{
|
||||||
|
generic_delay_timer_init();
|
||||||
|
|
||||||
|
/* Configure the interrupt controller */
|
||||||
|
gicv2_driver_init(&sunxi_gic_data);
|
||||||
|
gicv2_distif_init();
|
||||||
|
gicv2_pcpu_distif_init();
|
||||||
|
gicv2_cpuif_enable();
|
||||||
|
|
||||||
|
INFO("BL31: Platform setup done\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
|
||||||
|
{
|
||||||
|
assert(sec_state_is_valid(type) != 0);
|
||||||
|
assert(type == NON_SECURE);
|
||||||
|
|
||||||
|
return &bl33_image_ep_info;
|
||||||
|
}
|
56
plat/allwinner/common/sunxi_common.c
Normal file
56
plat/allwinner/common/sunxi_common.c
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <platform.h>
|
||||||
|
#include <platform_def.h>
|
||||||
|
#include <sunxi_def.h>
|
||||||
|
#include <xlat_tables_v2.h>
|
||||||
|
|
||||||
|
static mmap_region_t sunxi_mmap[PLATFORM_MMAP_REGIONS + 1] = {
|
||||||
|
MAP_REGION_FLAT(SUNXI_ROM_BASE, SUNXI_ROM_SIZE,
|
||||||
|
MT_MEMORY | MT_RO | MT_SECURE),
|
||||||
|
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),
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int plat_get_syscnt_freq2(void)
|
||||||
|
{
|
||||||
|
return SUNXI_OSC24M_CLK_IN_HZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t plat_get_ns_image_entrypoint(void)
|
||||||
|
{
|
||||||
|
#ifdef PRELOADED_BL33_BASE
|
||||||
|
return PRELOADED_BL33_BASE;
|
||||||
|
#else
|
||||||
|
return PLAT_SUNXI_NS_IMAGE_OFFSET;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void sunxi_configure_mmu_el3(int flags)
|
||||||
|
{
|
||||||
|
mmap_add_region(BL31_BASE, BL31_BASE,
|
||||||
|
BL31_LIMIT - BL31_BASE,
|
||||||
|
MT_MEMORY | MT_RW | MT_SECURE);
|
||||||
|
mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
|
||||||
|
BL_CODE_END - BL_CODE_BASE,
|
||||||
|
MT_CODE | MT_SECURE);
|
||||||
|
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();
|
||||||
|
|
||||||
|
enable_mmu_el3(0);
|
||||||
|
}
|
55
plat/allwinner/common/sunxi_pm.c
Normal file
55
plat/allwinner/common/sunxi_pm.c
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch_helpers.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <debug.h>
|
||||||
|
#include <delay_timer.h>
|
||||||
|
#include <mmio.h>
|
||||||
|
#include <platform.h>
|
||||||
|
#include <platform_def.h>
|
||||||
|
#include <psci.h>
|
||||||
|
#include <sunxi_mmap.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)
|
||||||
|
|
||||||
|
static void __dead2 sunxi_system_off(void)
|
||||||
|
{
|
||||||
|
ERROR("PSCI: Full shutdown not implemented, halting\n");
|
||||||
|
wfi();
|
||||||
|
panic();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __dead2 sunxi_system_reset(void)
|
||||||
|
{
|
||||||
|
/* Reset the whole system when the watchdog times out */
|
||||||
|
mmio_write_32(SUNXI_WDOG0_CFG_REG, 1);
|
||||||
|
/* Enable the watchdog with the shortest timeout (0.5 seconds) */
|
||||||
|
mmio_write_32(SUNXI_WDOG0_MODE_REG, (0 << 4) | 1);
|
||||||
|
/* Wait for twice the watchdog timeout before panicking */
|
||||||
|
mdelay(1000);
|
||||||
|
|
||||||
|
ERROR("PSCI: System reset failed\n");
|
||||||
|
wfi();
|
||||||
|
panic();
|
||||||
|
}
|
||||||
|
|
||||||
|
static plat_psci_ops_t sunxi_psci_ops = {
|
||||||
|
.system_off = sunxi_system_off,
|
||||||
|
.system_reset = sunxi_system_reset,
|
||||||
|
};
|
||||||
|
|
||||||
|
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
|
||||||
|
const plat_psci_ops_t **psci_ops)
|
||||||
|
{
|
||||||
|
assert(psci_ops);
|
||||||
|
|
||||||
|
*psci_ops = &sunxi_psci_ops;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
12
plat/allwinner/common/sunxi_private.h
Normal file
12
plat/allwinner/common/sunxi_private.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SUNXI_PRIVATE_H__
|
||||||
|
#define __SUNXI_PRIVATE_H__
|
||||||
|
|
||||||
|
void sunxi_configure_mmu_el3(int flags);
|
||||||
|
|
||||||
|
#endif /* __SUNXI_PRIVATE_H__ */
|
38
plat/allwinner/common/sunxi_topology.c
Normal file
38
plat/allwinner/common/sunxi_topology.c
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch.h>
|
||||||
|
#include <platform.h>
|
||||||
|
#include <platform_def.h>
|
||||||
|
|
||||||
|
static unsigned char plat_power_domain_tree_desc[PLAT_MAX_PWR_LVL + 1] = {
|
||||||
|
/* One root node for the SoC */
|
||||||
|
1,
|
||||||
|
/* One node for each cluster */
|
||||||
|
PLATFORM_CLUSTER_COUNT,
|
||||||
|
/* One set of CPUs per cluster */
|
||||||
|
PLATFORM_MAX_CPUS_PER_CLUSTER,
|
||||||
|
};
|
||||||
|
|
||||||
|
int plat_core_pos_by_mpidr(u_register_t mpidr)
|
||||||
|
{
|
||||||
|
unsigned int cluster = MPIDR_AFFLVL1_VAL(mpidr);
|
||||||
|
unsigned int core = MPIDR_AFFLVL0_VAL(mpidr);
|
||||||
|
|
||||||
|
if (MPIDR_AFFLVL3_VAL(mpidr) > 0 ||
|
||||||
|
MPIDR_AFFLVL2_VAL(mpidr) > 0 ||
|
||||||
|
cluster >= PLATFORM_CLUSTER_COUNT ||
|
||||||
|
core >= PLATFORM_MAX_CPUS_PER_CLUSTER) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cluster * PLATFORM_MAX_CPUS_PER_CLUSTER + core;
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned char *plat_get_power_domain_tree_desc(void)
|
||||||
|
{
|
||||||
|
return plat_power_domain_tree_desc;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue