1/* SPDX-License-Identifier: BSD-3-Clause */ 2/* 3 * Copyright (C) 2024, Charleye <wangkart@aliyun.com> 4 * All rights reserved. 5 */ 6 7#include <arch.h> 8#include <asm_macros.S> 9#include <assert_macros.S> 10#include <platform_def.h> 11 12 .global lua_calc_core_pos 13 .global plat_my_core_pos 14 .global platform_mem_init 15 .global plat_is_my_cpu_primary 16 .global plat_secondary_cold_boot_setup 17 .global plat_get_my_entrypoint 18 .global plat_crash_console_init 19 .global plat_crash_console_putc 20 .global plat_crash_console_flush 21 .global plat_report_exception 22 .global plat_panic_handler 23 24.section .rodata.plat_prints, "aS" 25panic_handler_msg: 26 .asciz "[PANIC HANDLER] Loop in EL3.\n" 27 28func plat_crash_console_init 29 mov_imm x0, PLAT_LUA_BOOT_UART_BASE 30 mov_imm x1, PLAT_LUA_BOOT_UART_CLK_IN_HZ 31 mov_imm x2, PLAT_LUA_CONSOLE_BAUDRATE 32 b console_16550_core_init 33endfunc plat_crash_console_init 34 35func plat_crash_console_putc 36 mov_imm x1, PLAT_LUA_BOOT_UART_BASE 37 b console_16550_core_putc 38endfunc plat_crash_console_putc 39 40func plat_crash_console_flush 41 ret 42endfunc plat_crash_console_flush 43 44func plat_report_exception 45 ret 46endfunc plat_report_exception 47 48func plat_panic_handler 49 adr x4, panic_handler_msg 50 bl asm_print_str 51 wfi 52 b plat_panic_handler 53endfunc plat_panic_handler 54 55/* 56 * unsigned int lua_calc_core_pos(u_register_t mpidr) 57 * core_pos = (cluster_id * max_cpus_per_cluster) + core_id 58 */ 59func lua_calc_core_pos 60 and x1, x0, #MPIDR_CPU_MASK 61 and x0, x0, #MPIDR_CLUSTER_MASK 62 add x0, x1, x0, lsr #6 63 ret 64endfunc lua_calc_core_pos 65 66func plat_my_core_pos 67 mrs x0, mpidr_el1 68 lsr x0, x0, #8 69 b lua_calc_core_pos 70endfunc plat_my_core_pos 71 72func platform_mem_init 73 ret 74endfunc platform_mem_init 75 76/* 77 * Secondary CPUs are placed in a holding pen, waiting for their mailbox 78 * to be populated. Note that all CPUs share the same mailbox ; therefore, 79 * populating it will release all CPUs from their holding pen. If 80 * finer-grained control is needed then this should be handled in the 81 * code that secondary CPUs jump to. 82 */ 83func plat_secondary_cold_boot_setup 84 /* Calculate address of our hold entry */ 85 bl plat_my_core_pos 86 lsl x0, x0, #PLAT_LUA_HOLD_ENTRY_SHIFT 87 mov_imm x2, PLAT_LUA_HOLD_BASE 88 89 /* Wait until we have a go */ 90poll_mailbox: 91 ldr x1, [x2, x0] 92 cbz x1, 1f 93 94 /* Clear the mailbox again ready for next time. */ 95 mov x1, #PLAT_LUA_HOLD_STATE_WAIT 96 str x1, [x2, x0] 97 98 /* Jump to the provided entrypoint. */ 99 mov_imm x0, PLAT_LUA_TRUSTED_MAILBOX_BASE 100 ldr x1, [x0] 101 br x1 1021: 103 wfe 104 b poll_mailbox 105endfunc plat_secondary_cold_boot_setup 106 107func plat_get_my_entrypoint 108 /* TODO support warm boot */ 109 mov x0, #0 110 ret 111endfunc plat_get_my_entrypoint 112 113/* 114 * Find out whether the current cpu is the primary 115 * cpu (applicable only after a cold boot) 116 */ 117func plat_is_my_cpu_primary 118 mrs x0, mpidr_el1 119 and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) 120 cmp x0, #PLAT_LUA_PRIMARY_CPU 121 cset w0, eq 122 ret 123endfunc plat_is_my_cpu_primary 124