root/arch/unicore32/lib/backtrace.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /* SPDX-License-Identifier: GPL-2.0-only */
   2 /*
   3  * linux/arch/unicore32/lib/backtrace.S
   4  *
   5  * Code specific to PKUnity SoC and UniCore ISA
   6  *
   7  * Copyright (C) 2001-2010 GUAN Xue-tao
   8  */
   9 #include <linux/linkage.h>
  10 #include <asm/assembler.h>
  11                 .text
  12 
  13 @ fp is 0 or stack frame
  14 
  15 #define frame   v4
  16 #define sv_fp   v5
  17 #define sv_pc   v6
  18 #define offset  v8
  19 
  20 ENTRY(__backtrace)
  21                 mov     r0, fp
  22 
  23 ENTRY(c_backtrace)
  24 
  25 #if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
  26                 mov     pc, lr
  27 ENDPROC(__backtrace)
  28 ENDPROC(c_backtrace)
  29 #else
  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
  34 
  35 1:              stm.w   (pc), [sp-]             @ calculate offset of PC stored
  36                 ldw.w   r0, [sp]+, #4           @ by stmfd for this CPU
  37                 adr     r1, 1b
  38                 sub     offset, r0, r1
  39 
  40 /*
  41  * Stack frame layout:
  42  *             optionally saved caller registers (r4 - r10)
  43  *             saved fp
  44  *             saved sp
  45  *             saved lr
  46  *    frame => saved pc
  47  *             optionally saved arguments (r0 - r3)
  48  * saved sp => <next word>
  49  *
  50  * Functions start with the following code sequence:
  51  *                  mov   ip, sp
  52  *                  stm.w (r0 - r3), [sp-] (optional)
  53  * corrected pc =>  stm.w sp, (..., fp, ip, lr, pc)
  54  */
  55 for_each_frame:
  56 
  57 1001:           ldw     sv_pc, [frame+], #0     @ get saved pc
  58 1002:           ldw     sv_fp, [frame+], #-12   @ get saved fp
  59 
  60                 sub     sv_pc, sv_pc, offset    @ Correct PC for prefetching
  61 
  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
  65                 beq     201f
  66                 sub     r0, sv_pc, #4           @ allow for mov
  67                 b       202f
  68 201:
  69                 sub     r0, sv_pc, #8           @ allow for mov + stmia
  70 202:
  71                 ldw     r1, [frame+], #-4       @ get saved lr
  72                 mov     r2, frame
  73                 b.l     dump_backtrace_entry
  74 
  75                 ldw     r1, [sv_pc+], #-4       @ if stmfd sp, {args} exists,
  76                 ldw     r3, .Ldsi+4
  77                 cxor.a  r3, r1 >> #14
  78                 bne     1004f
  79                 ldw     r0, [frame+], #-8       @ get sp
  80                 sub     r0, r0, #4              @ point at the last arg
  81                 b.l     .Ldumpstm               @ dump saved registers
  82 
  83 1004:           ldw     r1, [sv_pc+], #0        @ if stmfd {, fp, ip, lr, pc}
  84                 ldw     r3, .Ldsi               @ instruction exists,
  85                 cxor.a  r3, r1 >> #14
  86                 bne     201f
  87                 sub     r0, frame, #16
  88                 b.l     .Ldumpstm               @ dump saved registers
  89 201:
  90                 cxor.a  sv_fp, #0               @ zero saved fp means
  91                 beq     no_frame                @ no further frames
  92 
  93                 csub.a  sv_fp, frame            @ next frame must be
  94                 mov     frame, sv_fp            @ above the current frame
  95                 bua     for_each_frame
  96 
  97 1006:           adr     r0, .Lbad
  98                 mov     r1, frame
  99                 b.l     printk
 100 no_frame:       ldm.w   (v4 - v8, pc), [sp]+
 101 ENDPROC(__backtrace)
 102 ENDPROC(c_backtrace)
 103 
 104                 .pushsection __ex_table,"a"
 105                 .align  3
 106                 .long   1001b, 1006b
 107                 .long   1002b, 1006b
 108                 .long   1003b, 1006b
 109                 .long   1004b, 1006b
 110                 .popsection
 111 
 112 #define instr v4
 113 #define reg   v5
 114 #define stack v6
 115 
 116 .Ldumpstm:      stm.w   (instr, reg, stack, v7, lr), [sp-]
 117                 mov     stack, r0
 118                 mov     instr, r1
 119                 mov     reg, #14
 120                 mov     v7, #0
 121 1:              mov     r3, #1
 122                 csub.a  reg, #8
 123                 bne     201f
 124                 sub     reg, reg, #3
 125 201:
 126                 cand.a  instr, r3 << reg
 127                 beq     2f
 128                 add     v7, v7, #1
 129                 cxor.a  v7, #6
 130                 cmoveq  v7, #1
 131                 cmoveq  r1, #'\n'
 132                 cmovne  r1, #' '
 133                 ldw.w   r3, [stack]+, #-4
 134                 mov     r2, reg
 135                 csub.a  r2, #8
 136                 bsl     201f
 137                 sub     r2, r2, #3
 138 201:
 139                 cand.a  instr, #0x40            @ if H is 1, high 16 regs
 140                 beq     201f
 141                 add     r2, r2, #0x10           @ so r2 need add 16
 142 201:
 143                 adr     r0, .Lfp
 144                 b.l     printk
 145 2:              sub.a   reg, reg, #1
 146                 bns     1b
 147                 cxor.a  v7, #0
 148                 beq     201f
 149                 adr     r0, .Lcr
 150                 b.l     printk
 151 201:            ldm.w   (instr, reg, stack, v7, pc), [sp]+
 152 
 153 .Lfp:           .asciz  "%cr%d:%08x"
 154 .Lcr:           .asciz  "\n"
 155 .Lbad:          .asciz  "Backtrace aborted due to bad frame pointer <%p>\n"
 156                 .align
 157 .Ldsi:          .word   0x92eec000 >> 14        @ stm.w sp, (... fp, ip, lr, pc)
 158                 .word   0x92e10000 >> 14        @ stm.w sp, ()
 159 
 160 #endif

/* [<][>][^][v][top][bottom][index][help] */