diff --git a/plat/rockchip/common/aarch32/plat_helpers.S b/plat/rockchip/common/aarch32/plat_helpers.S new file mode 100644 index 0000000..475c297 --- /dev/null +++ b/plat/rockchip/common/aarch32/plat_helpers.S @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include + + .globl cpuson_entry_point + .globl cpuson_flags + .globl platform_cpu_warmboot + .globl plat_secondary_cold_boot_setup + .globl plat_report_exception + .globl plat_is_my_cpu_primary + .globl plat_my_core_pos + .globl plat_reset_handler + .globl plat_panic_handler + + /* + * void plat_reset_handler(void); + * + * Determine the SOC type and call the appropriate reset + * handler. + * + */ +func plat_reset_handler + bx lr +endfunc plat_reset_handler + +func plat_my_core_pos + ldcopr r0, MPIDR + and r1, r0, #MPIDR_CPU_MASK +#ifdef PLAT_RK_MPIDR_CLUSTER_MASK + and r0, r0, #PLAT_RK_MPIDR_CLUSTER_MASK +#else + and r0, r0, #MPIDR_CLUSTER_MASK +#endif + add r0, r1, r0, LSR #PLAT_RK_CLST_TO_CPUID_SHIFT + bx lr +endfunc plat_my_core_pos + + /* -------------------------------------------------------------------- + * void plat_secondary_cold_boot_setup (void); + * + * This function performs any platform specific actions + * needed for a secondary cpu after a cold reset e.g + * mark the cpu's presence, mechanism to place it in a + * holding pen etc. + * -------------------------------------------------------------------- + */ +func plat_secondary_cold_boot_setup + /* rk3288 does not do cold boot for secondary CPU */ +cb_panic: + b cb_panic +endfunc plat_secondary_cold_boot_setup + +func plat_is_my_cpu_primary + ldcopr r0, MPIDR +#ifdef PLAT_RK_MPIDR_CLUSTER_MASK + ldr r1, =(PLAT_RK_MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) +#else + ldr r1, =(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) +#endif + and r0, r1 + cmp r0, #PLAT_RK_PRIMARY_CPU + moveq r0, #1 + movne r0, #0 + bx lr +endfunc plat_is_my_cpu_primary + + /* -------------------------------------------------------------------- + * void plat_panic_handler(void) + * Call system reset function on panic. Set up an emergency stack so we + * can run C functions (it only needs to last for a few calls until we + * reboot anyway). + * -------------------------------------------------------------------- + */ +func plat_panic_handler + bl plat_set_my_stack + b rockchip_soc_soft_reset +endfunc plat_panic_handler + + /* -------------------------------------------------------------------- + * void platform_cpu_warmboot (void); + * cpus online or resume entrypoint + * -------------------------------------------------------------------- + */ +func platform_cpu_warmboot _align=16 + push { r4 - r7, lr } + ldcopr r0, MPIDR + and r5, r0, #MPIDR_CPU_MASK +#ifdef PLAT_RK_MPIDR_CLUSTER_MASK + and r6, r0, #PLAT_RK_MPIDR_CLUSTER_MASK +#else + and r6, r0, #MPIDR_CLUSTER_MASK +#endif + mov r0, r6 + + func_rockchip_clst_warmboot + /* -------------------------------------------------------------------- + * big cluster id is 1 + * big cores id is from 0-3, little cores id 4-7 + * -------------------------------------------------------------------- + */ + add r7, r5, r6, LSR #PLAT_RK_CLST_TO_CPUID_SHIFT + /* -------------------------------------------------------------------- + * get per cpuup flag + * -------------------------------------------------------------------- + */ + ldr r4, =cpuson_flags + add r4, r4, r7, lsl #2 + ldr r1, [r4] + /* -------------------------------------------------------------------- + * check cpuon reason + * -------------------------------------------------------------------- + */ + cmp r1, #PMU_CPU_AUTO_PWRDN + beq boot_entry + cmp r1, #PMU_CPU_HOTPLUG + beq boot_entry + /* -------------------------------------------------------------------- + * If the boot core cpuson_flags or cpuson_entry_point is not + * expection. force the core into wfe. + * -------------------------------------------------------------------- + */ +wfe_loop: + wfe + b wfe_loop +boot_entry: + mov r1, #0 + str r1, [r4] + /* -------------------------------------------------------------------- + * get per cpuup boot addr + * -------------------------------------------------------------------- + */ + ldr r5, =cpuson_entry_point + ldr r2, [r5, r7, lsl #2] /* ehem. #3 */ + pop { r4 - r7, lr } + + bx r2 +endfunc platform_cpu_warmboot + + /* -------------------------------------------------------------------- + * Per-CPU Secure entry point - resume or power up + * -------------------------------------------------------------------- + */ + .section tzfw_coherent_mem, "a" + .align 3 +cpuson_entry_point: + .rept PLATFORM_CORE_COUNT + .quad 0 + .endr +cpuson_flags: + .rept PLATFORM_CORE_COUNT + .word 0 + .endr +rockchip_clst_warmboot_data diff --git a/plat/rockchip/common/aarch32/platform_common.c b/plat/rockchip/common/aarch32/platform_common.c new file mode 100644 index 0000000..9030951 --- /dev/null +++ b/plat/rockchip/common/aarch32/platform_common.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +void plat_configure_mmu_svc_mon(unsigned long total_base, + unsigned long total_size, + unsigned long ro_start, + unsigned long ro_limit, + unsigned long coh_start, + unsigned long coh_limit) +{ + mmap_add_region(total_base, total_base, total_size, + MT_MEMORY | MT_RW | MT_SECURE); + mmap_add_region(ro_start, ro_start, ro_limit - ro_start, + MT_MEMORY | MT_RO | MT_SECURE); + mmap_add_region(coh_start, coh_start, coh_limit - coh_start, + MT_DEVICE | MT_RW | MT_SECURE); + mmap_add(plat_rk_mmap); + rockchip_plat_mmu_svc_mon(); + init_xlat_tables(); + enable_mmu_svc_mon(0); +} + +unsigned int plat_get_syscnt_freq2(void) +{ + return SYS_COUNTER_FREQ_IN_TICKS; +} + +/* + * generic pm code does cci handling, but rockchip arm32 platforms + * have ever only 1 cluster, so nothing to do. + */ +void plat_cci_init(void) +{ +} + +void plat_cci_enable(void) +{ +} + +void plat_cci_disable(void) +{ +} diff --git a/plat/rockchip/common/aarch32/pmu_sram_cpus_on.S b/plat/rockchip/common/aarch32/pmu_sram_cpus_on.S new file mode 100644 index 0000000..a05ae54 --- /dev/null +++ b/plat/rockchip/common/aarch32/pmu_sram_cpus_on.S @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + + .globl pmu_cpuson_entrypoint + .macro pmusram_entry_func _name + .section .pmusram.entry, "ax" + .type \_name, %function + .cfi_startproc + \_name: + .endm + +pmusram_entry_func pmu_cpuson_entrypoint + +#if PSRAM_CHECK_WAKEUP_CPU +check_wake_cpus: + ldcopr r0, MPIDR + and r1, r0, #MPIDR_CPU_MASK +#ifdef PLAT_RK_MPIDR_CLUSTER_MASK + and r0, r0, #PLAT_RK_MPIDR_CLUSTER_MASK +#else + and r0, r0, #MPIDR_CLUSTER_MASK +#endif + orr r0, r0, r1 + + /* primary_cpu */ + ldr r1, boot_mpidr + cmp r0, r1 + beq sys_wakeup + + /* + * If the core is not the primary cpu, + * force the core into wfe. + */ +wfe_loop: + wfe + b wfe_loop +sys_wakeup: +#endif + +#if PSRAM_DO_DDR_RESUME +ddr_resume: + ldr r2, =__bl32_sram_stack_end + mov sp, r2 + bl dmc_resume +#endif + bl sram_restore +sys_resume: + bl sp_min_warm_entrypoint +endfunc pmu_cpuson_entrypoint diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h index e8750a5..f9470e5 100644 --- a/plat/rockchip/common/include/plat_private.h +++ b/plat/rockchip/common/include/plat_private.h @@ -68,6 +68,16 @@ /****************************************************************************** * Function and variable prototypes *****************************************************************************/ +#ifdef AARCH32 +void plat_configure_mmu_svc_mon(unsigned long total_base, + unsigned long total_size, + unsigned long, + unsigned long, + unsigned long, + unsigned long); + +void rockchip_plat_mmu_svc_mon(void); +#else void plat_configure_mmu_el3(unsigned long total_base, unsigned long total_size, unsigned long, @@ -75,6 +85,9 @@ unsigned long, unsigned long); +void rockchip_plat_mmu_el3(void); +#endif + void plat_cci_init(void); void plat_cci_enable(void); void plat_cci_disable(void); @@ -128,13 +141,11 @@ extern const unsigned char rockchip_power_domain_tree_desc[]; extern void *pmu_cpuson_entrypoint; -extern uint64_t cpuson_entry_point[PLATFORM_CORE_COUNT]; +extern u_register_t cpuson_entry_point[PLATFORM_CORE_COUNT]; extern uint32_t cpuson_flags[PLATFORM_CORE_COUNT]; extern const mmap_region_t plat_rk_mmap[]; -void rockchip_plat_mmu_el3(void); - #endif /* __ASSEMBLY__ */ /****************************************************************************** diff --git a/plat/rockchip/common/plat_topology.c b/plat/rockchip/common/plat_topology.c index a31e410..4987eeb 100644 --- a/plat/rockchip/common/plat_topology.c +++ b/plat/rockchip/common/plat_topology.c @@ -24,7 +24,11 @@ unsigned int cluster_id, cpu_id; cpu_id = mpidr & MPIDR_AFFLVL_MASK; +#ifdef PLAT_RK_MPIDR_CLUSTER_MASK + cluster_id = mpidr & PLAT_RK_MPIDR_CLUSTER_MASK; +#else cluster_id = mpidr & MPIDR_CLUSTER_MASK; +#endif cpu_id += (cluster_id >> PLAT_RK_CLST_TO_CPUID_SHIFT); diff --git a/plat/rockchip/common/sp_min_plat_setup.c b/plat/rockchip/common/sp_min_plat_setup.c new file mode 100644 index 0000000..7250919 --- /dev/null +++ b/plat/rockchip/common/sp_min_plat_setup.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static entry_point_info_t bl33_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. + * A NULL pointer is returned if the image does not exist. + ******************************************************************************/ +entry_point_info_t *sp_min_plat_get_bl33_ep_info(void) +{ + entry_point_info_t *next_image_info; + + next_image_info = &bl33_ep_info; + + if (next_image_info->pc == 0U) { + return NULL; + } + + return next_image_info; +} + +#pragma weak params_early_setup +void params_early_setup(void *plat_param_from_bl2) +{ +} + +unsigned int plat_is_my_cpu_primary(void); + +/******************************************************************************* + * Perform any BL32 specific platform actions. + ******************************************************************************/ +void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + static console_16550_t console; + struct rockchip_bl31_params *arg_from_bl2 = (struct rockchip_bl31_params *) arg0; + void *plat_params_from_bl2 = (void *) arg1; + + params_early_setup(plat_params_from_bl2); + +#if COREBOOT + if (coreboot_serial.type) + console_16550_register(coreboot_serial.baseaddr, + coreboot_serial.input_hertz, + coreboot_serial.baud, + &console); +#else + console_16550_register(PLAT_RK_UART_BASE, PLAT_RK_UART_CLOCK, + PLAT_RK_UART_BAUDRATE, &console); +#endif + VERBOSE("sp_min_setup\n"); + + /* Passing a NULL context is a critical programming error */ + assert(arg_from_bl2); + + assert(arg_from_bl2->h.type == PARAM_BL31); + assert(arg_from_bl2->h.version >= VERSION_1); + + bl33_ep_info = *arg_from_bl2->bl33_ep_info; +} + +/******************************************************************************* + * Perform any sp_min platform setup code + ******************************************************************************/ +void sp_min_platform_setup(void) +{ + generic_delay_timer_init(); + plat_rockchip_soc_init(); + + /* Initialize the gic cpu and distributor interfaces */ + plat_rockchip_gic_driver_init(); + plat_rockchip_gic_init(); + plat_rockchip_pmu_init(); +} + +/******************************************************************************* + * Perform the very early platform specific architectural setup here. At the + * moment this is only intializes the mmu in a quick and dirty way. + ******************************************************************************/ +void sp_min_plat_arch_setup(void) +{ + plat_cci_init(); + plat_cci_enable(); + + plat_configure_mmu_svc_mon(BL_CODE_BASE, + BL_COHERENT_RAM_END - BL_CODE_BASE, + BL_CODE_BASE, + BL_CODE_END, + BL_COHERENT_RAM_BASE, + BL_COHERENT_RAM_END); +} + +void sp_min_plat_fiq_handler(uint32_t id) +{ + VERBOSE("[sp_min] interrupt #%d\n", id); +}