1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * linux/arch/unicore32/lib/backtrace.S
5 * Code specific to PKUnity SoC and UniCore ISA
7 * Copyright (C) 2001-2010 GUAN Xue-tao
9 #include <linux/linkage.h>
10 #include <asm/assembler.h>
13 @ fp is 0 or stack frame
25 #if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
30 stm.w (v4 - v8, lr), [sp-] @ Save an extra register
31 @ so we have a location...
32 mov.a frame, r0 @ if frame pointer is zero
33 beq no_frame @ we have no stack frames
35 1: stm.w (pc), [sp-] @ calculate offset of PC stored
36 ldw.w r0, [sp]+, #4 @ by stmfd for this CPU
42 * optionally saved caller registers (r4 - r10)
47 * optionally saved arguments (r0 - r3)
48 * saved sp => <next word>
50 * Functions start with the following code sequence:
52 * stm.w (r0 - r3), [sp-] (optional)
53 * corrected pc => stm.w sp, (..., fp, ip, lr, pc)
57 1001: ldw sv_pc, [frame+], #0 @ get saved pc
58 1002: ldw sv_fp, [frame+], #-12 @ get saved fp
60 sub sv_pc, sv_pc, offset @ Correct PC for prefetching
62 1003: ldw r2, [sv_pc+], #-4 @ if stmfd sp, {args} exists,
63 ldw r3, .Ldsi+4 @ adjust saved 'pc' back one
64 cxor.a r3, r2 >> #14 @ instruction
66 sub r0, sv_pc, #4 @ allow for mov
69 sub r0, sv_pc, #8 @ allow for mov + stmia
71 ldw r1, [frame+], #-4 @ get saved lr
73 b.l dump_backtrace_entry
75 ldw r1, [sv_pc+], #-4 @ if stmfd sp, {args} exists,
79 ldw r0, [frame+], #-8 @ get sp
80 sub r0, r0, #4 @ point at the last arg
81 b.l .Ldumpstm @ dump saved registers
83 1004: ldw r1, [sv_pc+], #0 @ if stmfd {, fp, ip, lr, pc}
84 ldw r3, .Ldsi @ instruction exists,
88 b.l .Ldumpstm @ dump saved registers
90 cxor.a sv_fp, #0 @ zero saved fp means
91 beq no_frame @ no further frames
93 csub.a sv_fp, frame @ next frame must be
94 mov frame, sv_fp @ above the current frame
100 no_frame: ldm.w (v4 - v8, pc), [sp]+
104 .pushsection __ex_table,"a"
116 .Ldumpstm: stm.w (instr, reg, stack, v7, lr), [sp-]
126 cand.a instr, r3 << reg
133 ldw.w r3, [stack]+, #-4
139 cand.a instr, #0x40 @ if H is 1, high 16 regs
141 add r2, r2, #0x10 @ so r2 need add 16
145 2: sub.a reg, reg, #1
151 201: ldm.w (instr, reg, stack, v7, pc), [sp]+
153 .Lfp: .asciz "%cr%d:%08x"
155 .Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n"
157 .Ldsi: .word 0x92eec000 >> 14 @ stm.w sp, (... fp, ip, lr, pc)
158 .word 0x92e10000 >> 14 @ stm.w sp, ()