1/* 2 * Copyright (c) 2021-2023, Stephan Gerhold <stephan@gerhold.net> 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7#include <arch.h> 8#include <asm_macros.S> 9#include <platform_def.h> 10 11#include <msm8916_mmap.h> 12 13#define APCS_TCM_START_ADDR 0x10 14#define APCS_TCM_REDIRECT_EN_0 BIT_32(0) 15 16 .globl plat_crash_console_init 17 .globl plat_crash_console_putc 18 .globl plat_crash_console_flush 19 .globl plat_panic_handler 20 .globl plat_my_core_pos 21 .globl plat_get_my_entrypoint 22 .globl plat_reset_handler 23 .globl platform_mem_init 24 .globl msm8916_entry_point 25 26 /* ------------------------------------------------- 27 * int plat_crash_console_init(void) 28 * Initialize the crash console. 29 * Out: x0 - 1 on success, 0 on error 30 * Clobber list : x0 - x4 31 * ------------------------------------------------- 32 */ 33func plat_crash_console_init 34 mov_imm x1, BLSP_UART_BASE 35 mov x0, #1 36 b console_uartdm_core_init 37endfunc plat_crash_console_init 38 39 /* ------------------------------------------------- 40 * int plat_crash_console_putc(int c) 41 * Print a character on the crash console. 42 * In : w0 - character to be printed 43 * Out: w0 - printed character on success 44 * Clobber list : x1, x2 45 * ------------------------------------------------- 46 */ 47func plat_crash_console_putc 48 mov_imm x1, BLSP_UART_BASE 49 b console_uartdm_core_putc 50endfunc plat_crash_console_putc 51 52 /* ------------------------------------------------- 53 * void plat_crash_console_flush(void) 54 * Force a write of all buffered data that has not 55 * been output. 56 * Clobber list : x1, x2 57 * ------------------------------------------------- 58 */ 59func plat_crash_console_flush 60 mov_imm x1, BLSP_UART_BASE 61 b console_uartdm_core_flush 62endfunc plat_crash_console_flush 63 64 /* ------------------------------------------------- 65 * void plat_panic_handler(void) __dead 66 * Called when an unrecoverable error occurs. 67 * ------------------------------------------------- 68 */ 69func plat_panic_handler 70 /* Try to shutdown/reset */ 71 mov_imm x0, MPM_PS_HOLD 72 str wzr, [x0] 731: b 1b 74endfunc plat_panic_handler 75 76 /* ------------------------------------------------- 77 * unsigned int plat_my_core_pos(void) 78 * Out: x0 - index of the calling CPU 79 * ------------------------------------------------- 80 */ 81func plat_my_core_pos 82 mrs x1, mpidr_el1 83 and x0, x1, #MPIDR_CPU_MASK 84 .if PLATFORM_CLUSTER_COUNT > 1 85 and x1, x1, #MPIDR_CLUSTER_MASK 86 orr x0, x0, x1, LSR #(MPIDR_AFFINITY_BITS - \ 87 PLATFORM_CPU_PER_CLUSTER_SHIFT) 88 .endif 89 ret 90endfunc plat_my_core_pos 91 92 /* ------------------------------------------------- 93 * uintptr_t plat_get_my_entrypoint(void) 94 * Distinguish cold and warm boot and return warm boot 95 * entry address if available. 96 * Out: x0 - warm boot entry point or 0 on cold boot 97 * ------------------------------------------------- 98 */ 99func plat_get_my_entrypoint 100 ldr x0, msm8916_entry_point 101 cbz x0, 1f 102 ret 1031: 104 /* 105 * Cold boot: Disable TCM redirect to L2 cache as early as 106 * possible to avoid crashes when making use of the cache. 107 */ 108 mov_imm x1, APCS_CFG(0) 109 ldr w2, [x1, #APCS_TCM_START_ADDR] 110 and w2, w2, #~APCS_TCM_REDIRECT_EN_0 111 str w2, [x1, #APCS_TCM_START_ADDR] 112 113 /* 114 * After reset the CPU always starts executing at the fixed reset 115 * address (0x0), which does not match the link address of BL31. 116 * The "boot remapper" redirects all memory accesses to the real 117 * physical address in DRAM. 118 * 119 * For warm boots, this is already handled by loading the real 120 * entry point address above. 121 * 122 * For cold boots, check if the CPU is using the boot remapper, 123 * i.e. if bl31_entrypoint appears to be at the reset address (0x0). 124 */ 125 adr x1, bl31_entrypoint 126 cbnz x1, 2f 127 128 /* 129 * Add the real BL31_BASE offset to the return address in the link 130 * register so the CPU will continue at the real address after return. 131 */ 132 mov_imm x1, BL31_BASE 133 add lr, lr, x1 1342: 135 ret 136endfunc plat_get_my_entrypoint 137 138 /* ------------------------------------------------- 139 * void platform_mem_init(void) 140 * Performs additional memory initialization early 141 * in the boot process. 142 * ------------------------------------------------- 143 */ 144func platform_mem_init 145 /* Nothing to do here, all memory is already initialized */ 146 ret 147endfunc platform_mem_init 148 149 .data 150 .align 3 151 152 /* ------------------------------------------------- 153 * Warm boot entry point for CPU. Set by PSCI code. 154 * ------------------------------------------------- 155 */ 156msm8916_entry_point: 157 .quad 0 158