linux/arch/unicore32/lib/backtrace.S
<<
>>
Prefs
   1/*
   2 * linux/arch/unicore32/lib/backtrace.S
   3 *
   4 * Code specific to PKUnity SoC and UniCore ISA
   5 *
   6 * Copyright (C) 2001-2010 GUAN Xue-tao
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12#include <linux/linkage.h>
  13#include <asm/assembler.h>
  14                .text
  15
  16@ fp is 0 or stack frame
  17
  18#define frame   v4
  19#define sv_fp   v5
  20#define sv_pc   v6
  21#define offset  v8
  22
  23ENTRY(__backtrace)
  24                mov     r0, fp
  25
  26ENTRY(c_backtrace)
  27
  28#if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
  29                mov     pc, lr
  30ENDPROC(__backtrace)
  31ENDPROC(c_backtrace)
  32#else
  33                stm.w   (v4 - v8, lr), [sp-]    @ Save an extra register
  34                                                @ so we have a location...
  35                mov.a   frame, r0               @ if frame pointer is zero
  36                beq     no_frame                @ we have no stack frames
  37
  381:              stm.w   (pc), [sp-]             @ calculate offset of PC stored
  39                ldw.w   r0, [sp]+, #4           @ by stmfd for this CPU
  40                adr     r1, 1b
  41                sub     offset, r0, r1
  42
  43/*
  44 * Stack frame layout:
  45 *             optionally saved caller registers (r4 - r10)
  46 *             saved fp
  47 *             saved sp
  48 *             saved lr
  49 *    frame => saved pc
  50 *             optionally saved arguments (r0 - r3)
  51 * saved sp => <next word>
  52 *
  53 * Functions start with the following code sequence:
  54 *                  mov   ip, sp
  55 *                  stm.w (r0 - r3), [sp-] (optional)
  56 * corrected pc =>  stm.w sp, (..., fp, ip, lr, pc)
  57 */
  58for_each_frame:
  59
  601001:           ldw     sv_pc, [frame+], #0     @ get saved pc
  611002:           ldw     sv_fp, [frame+], #-12   @ get saved fp
  62
  63                sub     sv_pc, sv_pc, offset    @ Correct PC for prefetching
  64
  651003:           ldw     r2, [sv_pc+], #-4       @ if stmfd sp, {args} exists,
  66                ldw     r3, .Ldsi+4             @ adjust saved 'pc' back one
  67                cxor.a  r3, r2 >> #14           @ instruction
  68                beq     201f
  69                sub     r0, sv_pc, #4           @ allow for mov
  70                b       202f
  71201:
  72                sub     r0, sv_pc, #8           @ allow for mov + stmia
  73202:
  74                ldw     r1, [frame+], #-4       @ get saved lr
  75                mov     r2, frame
  76                b.l     dump_backtrace_entry
  77
  78                ldw     r1, [sv_pc+], #-4       @ if stmfd sp, {args} exists,
  79                ldw     r3, .Ldsi+4
  80                cxor.a  r3, r1 >> #14
  81                bne     1004f
  82                ldw     r0, [frame+], #-8       @ get sp
  83                sub     r0, r0, #4              @ point at the last arg
  84                b.l     .Ldumpstm               @ dump saved registers
  85
  861004:           ldw     r1, [sv_pc+], #0        @ if stmfd {, fp, ip, lr, pc}
  87                ldw     r3, .Ldsi               @ instruction exists,
  88                cxor.a  r3, r1 >> #14
  89                bne     201f
  90                sub     r0, frame, #16
  91                b.l     .Ldumpstm               @ dump saved registers
  92201:
  93                cxor.a  sv_fp, #0               @ zero saved fp means
  94                beq     no_frame                @ no further frames
  95
  96                csub.a  sv_fp, frame            @ next frame must be
  97                mov     frame, sv_fp            @ above the current frame
  98                bua     for_each_frame
  99
 1001006:           adr     r0, .Lbad
 101                mov     r1, frame
 102                b.l     printk
 103no_frame:       ldm.w   (v4 - v8, pc), [sp]+
 104ENDPROC(__backtrace)
 105ENDPROC(c_backtrace)
 106
 107                .pushsection __ex_table,"a"
 108                .align  3
 109                .long   1001b, 1006b
 110                .long   1002b, 1006b
 111                .long   1003b, 1006b
 112                .long   1004b, 1006b
 113                .popsection
 114
 115#define instr v4
 116#define reg   v5
 117#define stack v6
 118
 119.Ldumpstm:      stm.w   (instr, reg, stack, v7, lr), [sp-]
 120                mov     stack, r0
 121                mov     instr, r1
 122                mov     reg, #14
 123                mov     v7, #0
 1241:              mov     r3, #1
 125                csub.a  reg, #8
 126                bne     201f
 127                sub     reg, reg, #3
 128201:
 129                cand.a  instr, r3 << reg
 130                beq     2f
 131                add     v7, v7, #1
 132                cxor.a  v7, #6
 133                cmoveq  v7, #1
 134                cmoveq  r1, #'\n'
 135                cmovne  r1, #' '
 136                ldw.w   r3, [stack]+, #-4
 137                mov     r2, reg
 138                csub.a  r2, #8
 139                bsl     201f
 140                sub     r2, r2, #3
 141201:
 142                cand.a  instr, #0x40            @ if H is 1, high 16 regs
 143                beq     201f
 144                add     r2, r2, #0x10           @ so r2 need add 16
 145201:
 146                adr     r0, .Lfp
 147                b.l     printk
 1482:              sub.a   reg, reg, #1
 149                bns     1b
 150                cxor.a  v7, #0
 151                beq     201f
 152                adr     r0, .Lcr
 153                b.l     printk
 154201:            ldm.w   (instr, reg, stack, v7, pc), [sp]+
 155
 156.Lfp:           .asciz  "%cr%d:%08x"
 157.Lcr:           .asciz  "\n"
 158.Lbad:          .asciz  "Backtrace aborted due to bad frame pointer <%p>\n"
 159                .align
 160.Ldsi:          .word   0x92eec000 >> 14        @ stm.w sp, (... fp, ip, lr, pc)
 161                .word   0x92e10000 >> 14        @ stm.w sp, ()
 162
 163#endif
 164