GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
+187
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019, 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 <drivers/console.h>
|
||||
|
||||
.globl plat_crash_console_init
|
||||
.globl plat_crash_console_putc
|
||||
.globl plat_crash_console_flush
|
||||
|
||||
/*
|
||||
* Spinlock to syncronize access to crash_console_triggered. We cannot
|
||||
* acquire spinlocks when the cache is disabled, so in some cases (like
|
||||
* late during CPU suspend) some risk remains.
|
||||
*/
|
||||
.section .data.crash_console_spinlock
|
||||
define_asm_spinlock crash_console_spinlock
|
||||
|
||||
/*
|
||||
* Flag to make sure that only one CPU can write a crash dump even if
|
||||
* multiple crash at the same time. Interleaving crash dumps on the same
|
||||
* console would just make the output unreadable, so it's better to only
|
||||
* get a single but uncorrupted dump. This also means that we don't have
|
||||
* to duplicate the reg_stash below for each CPU.
|
||||
*/
|
||||
.section .data.crash_console_triggered
|
||||
crash_console_triggered: .byte 0
|
||||
|
||||
/*
|
||||
* Space to stash away some register values while we're calling into
|
||||
* console drivers and don't have a real stack available. We need x14,
|
||||
* x15 and x30 for bookkeeping within the plat_crash_console functions
|
||||
* themselves, and some console drivers use x16 and x17 as additional
|
||||
* scratch space that is not preserved by the main crash reporting
|
||||
* framework. (Note that x16 and x17 should really never be expected to
|
||||
* retain their values across any function call, even between carefully
|
||||
* designed assembly functions, since the linker is always free to
|
||||
* insert a function call veneer that uses these registers as scratch
|
||||
* space at any time. The current crash reporting framework doesn't
|
||||
* really respect that, but since TF is usually linked as a single
|
||||
* contiguous binary of less than 128MB, it seems to work in practice.)
|
||||
*/
|
||||
.section .data.crash_console_reg_stash
|
||||
.align 3
|
||||
crash_console_reg_stash: .quad 0, 0, 0, 0, 0
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* int plat_crash_console_init(void)
|
||||
* Takes the crash console spinlock (if possible) and checks the trigger
|
||||
* flag to make sure we're the first CPU to dump. If not, return an
|
||||
* error (so crash dumping will fail but the CPU will still call
|
||||
* plat_panic_handler() which may do important platform-specific tasks
|
||||
* that may be needed on all crashing CPUs). In either case, the lock
|
||||
* will be released so other CPUs can make forward progress on this.
|
||||
* Clobbers: x0 - x4, x30
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
func plat_crash_console_init
|
||||
#if defined(IMAGE_BL31)
|
||||
mov x4, x30 /* x3 and x4 are not clobbered by spin_lock() */
|
||||
mov x3, #0 /* return value */
|
||||
|
||||
adrp x0, crash_console_spinlock
|
||||
add x0, x0, :lo12:crash_console_spinlock
|
||||
|
||||
mrs x1, sctlr_el3
|
||||
tst x1, #SCTLR_C_BIT
|
||||
beq skip_spinlock /* can't synchronize when cache disabled */
|
||||
bl spin_lock
|
||||
|
||||
skip_spinlock:
|
||||
adrp x1, crash_console_triggered
|
||||
add x1, x1, :lo12:crash_console_triggered
|
||||
ldarb w2, [x1]
|
||||
cmp w2, #0
|
||||
bne init_error
|
||||
|
||||
mov x3, #1 /* set return value to success */
|
||||
stlrb w3, [x1]
|
||||
|
||||
init_error:
|
||||
bl spin_unlock /* harmless if we didn't acquire the lock */
|
||||
mov x0, x3
|
||||
ret x4
|
||||
#else /* Only one CPU in BL1/BL2, no need to synchronize anything */
|
||||
mov x0, #1
|
||||
ret
|
||||
#endif
|
||||
endfunc plat_crash_console_init
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* int plat_crash_console_putc(char c)
|
||||
* Prints the character on all consoles registered with the console
|
||||
* framework that have CONSOLE_FLAG_CRASH set. Note that this is only
|
||||
* helpful for crashes that occur after the platform intialization code
|
||||
* has registered a console. Platforms using this implementation need to
|
||||
* ensure that all console drivers they use that have the CRASH flag set
|
||||
* support this (i.e. are written in assembly and comply to the register
|
||||
* clobber requirements of plat_crash_console_putc().
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
func plat_crash_console_putc
|
||||
adrp x1, crash_console_reg_stash
|
||||
add x1, x1, :lo12:crash_console_reg_stash
|
||||
stp x14, x15, [x1]
|
||||
stp x16, x17, [x1, #16]
|
||||
str x30, [x1, #32]
|
||||
|
||||
mov w14, w0 /* W14 = character to print */
|
||||
adrp x15, console_list
|
||||
ldr x15, [x15, :lo12:console_list] /* X15 = first console struct */
|
||||
|
||||
putc_loop:
|
||||
cbz x15, putc_done
|
||||
ldr w1, [x15, #CONSOLE_T_FLAGS]
|
||||
tst w1, #CONSOLE_FLAG_CRASH
|
||||
b.eq putc_continue
|
||||
ldr x2, [x15, #CONSOLE_T_PUTC]
|
||||
cbz x2, putc_continue
|
||||
cmp w14, #'\n'
|
||||
b.ne putc
|
||||
tst w1, #CONSOLE_FLAG_TRANSLATE_CRLF
|
||||
b.eq putc
|
||||
mov x1, x15
|
||||
mov w0, #'\r'
|
||||
blr x2
|
||||
ldr x2, [x15, #CONSOLE_T_PUTC]
|
||||
putc:
|
||||
mov x1, x15
|
||||
mov w0, w14
|
||||
blr x2
|
||||
putc_continue:
|
||||
ldr x15, [x15] /* X15 = next struct */
|
||||
b putc_loop
|
||||
|
||||
putc_done:
|
||||
adrp x1, crash_console_reg_stash
|
||||
add x1, x1, :lo12:crash_console_reg_stash
|
||||
ldp x14, x15, [x1]
|
||||
ldp x16, x17, [x1, #16]
|
||||
ldr x30, [x1, #32]
|
||||
ret
|
||||
endfunc plat_crash_console_putc
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* int plat_crash_console_flush(char c)
|
||||
* Flushes all consoles registered with the console framework that have
|
||||
* CONSOLE_FLAG_CRASH set. Same requirements as putc().
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
func plat_crash_console_flush
|
||||
adrp x1, crash_console_reg_stash
|
||||
add x1, x1, :lo12:crash_console_reg_stash
|
||||
stp x30, x15, [x1]
|
||||
stp x16, x17, [x1, #16]
|
||||
|
||||
adrp x15, console_list
|
||||
ldr x15, [x15, :lo12:console_list] /* X15 = first console struct */
|
||||
|
||||
flush_loop:
|
||||
cbz x15, flush_done
|
||||
ldr w1, [x15, #CONSOLE_T_FLAGS]
|
||||
tst w1, #CONSOLE_FLAG_CRASH
|
||||
b.eq flush_continue
|
||||
ldr x2, [x15, #CONSOLE_T_FLUSH]
|
||||
cbz x2, flush_continue
|
||||
mov x0, x15
|
||||
blr x2
|
||||
flush_continue:
|
||||
ldr x15, [x15] /* X15 = next struct */
|
||||
b flush_loop
|
||||
|
||||
flush_done:
|
||||
adrp x1, crash_console_reg_stash
|
||||
add x1, x1, :lo12:crash_console_reg_stash
|
||||
ldp x30, x15, [x1]
|
||||
ldp x16, x17, [x1, #16]
|
||||
ret
|
||||
endfunc plat_crash_console_flush
|
||||
Reference in New Issue
Block a user