source: rtems/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_print.c @ 0c3edbf

4.115
Last change on this file since 0c3edbf was 0c3edbf, checked in by Sebastian Huber <sebastian.huber@…>, on 07/25/13 at 08:46:15

Include missing <rtems/score/threaddispatch.h>

  • Property mode set to 100644
File size: 5.9 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup ppc_exc
5 *
6 * @brief PowerPC Exceptions implementation.
7 */
8
9/*
10 * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
11 *                    Canon Centre Recherche France.
12 *
13 * Derived from file "libcpu/powerpc/new-exceptions/bspsupport/vectors_init.c".
14 *
15 * The license and distribution terms for this file may be
16 * found in the file LICENSE in this distribution or at
17 * http://www.rtems.com/license/LICENSE.
18 */
19
20#include <bsp/vectors.h>
21
22#include <rtems/score/threaddispatch.h>
23
24#ifndef __SPE__
25  #define GET_GPR(gpr) (gpr)
26#else
27  #define GET_GPR(gpr) ((int) ((gpr) >> 32))
28#endif
29
30/* T. Straumann: provide a stack trace
31 * <strauman@slac.stanford.edu>, 6/26/2001
32 */
33typedef struct LRFrameRec_ {
34  struct LRFrameRec_ *frameLink;
35  unsigned long *lr;
36} LRFrameRec, *LRFrame;
37
38#define STACK_CLAMP 50          /* in case we have a corrupted bottom */
39
40static uint32_t ppc_exc_get_DAR_dflt(void)
41{
42  if (ppc_cpu_is_60x())
43    return PPC_SPECIAL_PURPOSE_REGISTER(PPC_DAR);
44  else
45    switch (ppc_cpu_is_bookE()) {
46      default:
47        break;
48      case PPC_BOOKE_STD:
49      case PPC_BOOKE_E500:
50        return PPC_SPECIAL_PURPOSE_REGISTER(BOOKE_DEAR);
51      case PPC_BOOKE_405:
52        return PPC_SPECIAL_PURPOSE_REGISTER(PPC405_DEAR);
53    }
54  return 0xdeadbeef;
55}
56
57uint32_t (*ppc_exc_get_DAR)(void) = ppc_exc_get_DAR_dflt;
58
59void BSP_printStackTrace(const BSP_Exception_frame *excPtr)
60{
61  LRFrame f;
62  int i;
63  LRFrame sp;
64  void *lr;
65
66  printk("Stack Trace: \n  ");
67  if (excPtr) {
68    printk("IP: 0x%08x, ", excPtr->EXC_SRR0);
69    sp = (LRFrame) GET_GPR(excPtr->GPR1);
70    lr = (void *) excPtr->EXC_LR;
71  } else {
72    /* there's no macro for this */
73    __asm__ __volatile__("mr %0, 1":"=r"(sp));
74    lr = (LRFrame) ppc_link_register();
75  }
76  printk("LR: 0x%08x\n", lr);
77  for (f = (LRFrame) sp, i = 0; f->frameLink && i < STACK_CLAMP; f = f->frameLink) {
78    printk("--^ 0x%08x", (long) (f->frameLink->lr));
79    if (!(++i % 5))
80      printk("\n");
81  }
82  if (i >= STACK_CLAMP) {
83    printk("Too many stack frames (stack possibly corrupted), giving up...\n");
84  } else {
85    if (i % 5)
86      printk("\n");
87  }
88}
89
90void _BSP_Exception_frame_print(const CPU_Exception_frame *excPtr)
91{
92  const Thread_Control *executing = _Thread_Executing;
93  bool synch = (int) excPtr->_EXC_number >= 0;
94  unsigned n = excPtr->_EXC_number & 0x7fff;
95
96  printk("exception vector %d (0x%x)\n", n, n);
97  printk("  next PC or address of fault = 0x%08x\n", excPtr->EXC_SRR0);
98  printk("  saved MSR = 0x%08x\n", excPtr->EXC_SRR1);
99
100  /* Try to find out more about the context where this happened */
101  printk(
102    "  context = %s, ISR nest level = %u\n",
103    _ISR_Nest_level == 0 ? "task" : "interrupt",
104    _ISR_Nest_level
105  );
106  printk(
107    "  thread dispatch disable level = %u\n",
108    _Thread_Dispatch_disable_level
109  );
110
111  /* Dump registers */
112
113  printk("  R0  = 0x%08x", GET_GPR(excPtr->GPR0));
114  if (synch) {
115    printk(" R1  = 0x%08x", GET_GPR(excPtr->GPR1));
116    printk(" R2  = 0x%08x", GET_GPR(excPtr->GPR2));
117  } else {
118    printk("               ");
119    printk("               ");
120  }
121  printk(" R3  = 0x%08x\n", GET_GPR(excPtr->GPR3));
122  printk("  R4  = 0x%08x", GET_GPR(excPtr->GPR4));
123  printk(" R5  = 0x%08x", GET_GPR(excPtr->GPR5));
124  printk(" R6  = 0x%08x", GET_GPR(excPtr->GPR6));
125  printk(" R7  = 0x%08x\n", GET_GPR(excPtr->GPR7));
126  printk("  R8  = 0x%08x", GET_GPR(excPtr->GPR8));
127  printk(" R9  = 0x%08x", GET_GPR(excPtr->GPR9));
128  printk(" R10 = 0x%08x", GET_GPR(excPtr->GPR10));
129  printk(" R11 = 0x%08x\n", GET_GPR(excPtr->GPR11));
130  printk("  R12 = 0x%08x", GET_GPR(excPtr->GPR12));
131  if (synch) {
132    printk(" R13 = 0x%08x", GET_GPR(excPtr->GPR13));
133    printk(" R14 = 0x%08x", GET_GPR(excPtr->GPR14));
134    printk(" R15 = 0x%08x\n", GET_GPR(excPtr->GPR15));
135    printk("  R16 = 0x%08x", GET_GPR(excPtr->GPR16));
136    printk(" R17 = 0x%08x", GET_GPR(excPtr->GPR17));
137    printk(" R18 = 0x%08x", GET_GPR(excPtr->GPR18));
138    printk(" R19 = 0x%08x\n", GET_GPR(excPtr->GPR19));
139    printk("  R20 = 0x%08x", GET_GPR(excPtr->GPR20));
140    printk(" R21 = 0x%08x", GET_GPR(excPtr->GPR21));
141    printk(" R22 = 0x%08x", GET_GPR(excPtr->GPR22));
142    printk(" R23 = 0x%08x\n", GET_GPR(excPtr->GPR23));
143    printk("  R24 = 0x%08x", GET_GPR(excPtr->GPR24));
144    printk(" R25 = 0x%08x", GET_GPR(excPtr->GPR25));
145    printk(" R26 = 0x%08x", GET_GPR(excPtr->GPR26));
146    printk(" R27 = 0x%08x\n", GET_GPR(excPtr->GPR27));
147    printk("  R28 = 0x%08x", GET_GPR(excPtr->GPR28));
148    printk(" R29 = 0x%08x", GET_GPR(excPtr->GPR29));
149    printk(" R30 = 0x%08x", GET_GPR(excPtr->GPR30));
150    printk(" R31 = 0x%08x\n", GET_GPR(excPtr->GPR31));
151  } else {
152    printk("\n");
153  }
154  printk("  CR  = 0x%08x\n", excPtr->EXC_CR);
155  printk("  CTR = 0x%08x\n", excPtr->EXC_CTR);
156  printk("  XER = 0x%08x\n", excPtr->EXC_XER);
157  printk("  LR  = 0x%08x\n", excPtr->EXC_LR);
158
159  /* Would be great to print DAR but unfortunately,
160   * that is not portable across different CPUs.
161   * AFAIK on classic PPC DAR is SPR 19, on the
162   * 405 we have DEAR = SPR 0x3d5 and bookE says
163   * DEAR = SPR 61 :-(
164   */
165  if (ppc_exc_get_DAR != NULL) {
166    char* reg = ppc_cpu_is_60x() ? " DAR" : "DEAR";
167    printk(" %s = 0x%08x\n", reg, ppc_exc_get_DAR());
168  }
169  if (ppc_cpu_is_bookE()) {
170    unsigned esr, mcsr;
171    if (ppc_cpu_is_bookE() == PPC_BOOKE_405) {
172      esr  = PPC_SPECIAL_PURPOSE_REGISTER(PPC405_ESR);
173      mcsr = PPC_SPECIAL_PURPOSE_REGISTER(PPC405_MCSR);
174    } else {
175      esr  = PPC_SPECIAL_PURPOSE_REGISTER(BOOKE_ESR);
176      mcsr = PPC_SPECIAL_PURPOSE_REGISTER(BOOKE_MCSR);
177    }
178    printk("  ESR = 0x%08x\n", esr);
179    printk(" MCSR = 0x%08x\n", mcsr);
180  }
181
182  if (executing != NULL) {
183    const char *name = (const char *) &executing->Object.name;
184
185    printk(
186      "  executing thread ID = 0x%08x, name = %c%c%c%c\n",
187      executing->Object.id,
188      name [0],
189      name [1],
190      name [2],
191      name [3]
192    );
193  } else {
194    printk("  executing thread pointer is NULL");
195  }
196
197  BSP_printStackTrace(excPtr);
198}
Note: See TracBrowser for help on using the repository browser.