source: rtems/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_global_handler.c @ e71a3a84

4.115
Last change on this file since e71a3a84 was e71a3a84, checked in by Joel Sherrill <joel.sherrill@…>, on 01/28/11 at 20:38:13

2011-01-28 Joel Sherrill <joel.sherrilL@…>

  • mpc5xx/exceptions/raw_exception.c, mpc5xx/exceptions/raw_exception.h, mpc5xx/include/console.h, mpc5xx/include/mpc5xx.h, mpc5xx/irq/irq.c, mpc5xx/irq/irq.h, mpc5xx/irq/irq_asm.S, mpc5xx/vectors/vectors.h, mpc5xx/vectors/vectors_init.c, mpc6xx/mmu/bat.c, mpc6xx/mmu/bat.h, mpc6xx/mmu/mmuAsm.S, new-exceptions/bspsupport/irq.c, new-exceptions/bspsupport/irq_supp.h, new-exceptions/bspsupport/nested_irq_test.c, new-exceptions/bspsupport/ppc_exc_address.c, new-exceptions/bspsupport/ppc_exc_categories.c, new-exceptions/bspsupport/ppc_exc_global_handler.c, new-exceptions/bspsupport/ppc_exc_hdl.c, new-exceptions/bspsupport/ppc_exc_initialize.c, new-exceptions/bspsupport/ppc_exc_prologue.c, new-exceptions/bspsupport/ppc_exc_test.c, new-exceptions/bspsupport/vectors.h, shared/include/byteorder.h, shared/include/cpuIdent.c, shared/include/cpuIdent.h, shared/include/io.h, shared/include/mmu.h, shared/include/page.h, shared/include/pgtable.h, shared/include/spr.h: Fix typo where license said found in found in.
  • Property mode set to 100644
File size: 5.7 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 * $Id$
20 */
21
22#include <bsp/vectors.h>
23
24exception_handler_t globalExceptHdl = C_exception_handler;
25
26/* T. Straumann: provide a stack trace
27 * <strauman@slac.stanford.edu>, 6/26/2001
28 */
29typedef struct LRFrameRec_ {
30  struct LRFrameRec_ *frameLink;
31  unsigned long *lr;
32} LRFrameRec, *LRFrame;
33
34#define STACK_CLAMP 50          /* in case we have a corrupted bottom */
35
36static uint32_t ppc_exc_get_DAR_dflt(void)
37{
38  if (ppc_cpu_is_60x())
39    return PPC_SPECIAL_PURPOSE_REGISTER(DAR);
40  else
41    switch (ppc_cpu_is_bookE()) {
42      default:
43        break;
44      case PPC_BOOKE_STD:
45      case PPC_BOOKE_E500:
46        return PPC_SPECIAL_PURPOSE_REGISTER(DEAR_BOOKE);
47      case PPC_BOOKE_405:
48        return PPC_SPECIAL_PURPOSE_REGISTER(DEAR_405);
49    }
50  return 0xdeadbeef;
51}
52
53uint32_t (*ppc_exc_get_DAR)(void) = ppc_exc_get_DAR_dflt;
54
55void BSP_printStackTrace(BSP_Exception_frame *excPtr)
56{
57  LRFrame f;
58  int i;
59  LRFrame sp;
60  void *lr;
61
62  printk("Stack Trace: \n  ");
63  if (excPtr) {
64    printk("IP: 0x%08x, ", excPtr->EXC_SRR0);
65    sp = (LRFrame) excPtr->GPR1;
66    lr = (void *) excPtr->EXC_LR;
67  } else {
68    /* there's no macro for this */
69    __asm__ __volatile__("mr %0, 1":"=r"(sp));
70    lr = (LRFrame) ppc_link_register();
71  }
72  printk("LR: 0x%08x\n", lr);
73  for (f = (LRFrame) sp, i = 0; f->frameLink && i < STACK_CLAMP; f = f->frameLink) {
74    printk("--^ 0x%08x", (long) (f->frameLink->lr));
75    if (!(++i % 5))
76      printk("\n");
77  }
78  if (i >= STACK_CLAMP) {
79    printk("Too many stack frames (stack possibly corrupted), giving up...\n");
80  } else {
81    if (i % 5)
82      printk("\n");
83  }
84}
85
86void C_exception_handler(BSP_Exception_frame *excPtr)
87{
88  static int nest = 0;
89
90  int recoverable = 0;
91  rtems_id id = 0;
92  int synch;
93  unsigned n;
94  rtems_status_code sc;
95
96  /* Catch recursion */
97  nest++;
98
99  if (nest > 2) {
100    /* maybe printk() or dereferencing excPtr caused an exception;
101     * die silently...
102     */
103    while (1);
104  }
105
106  synch = (int) excPtr->_EXC_number >= 0;
107  n = excPtr->_EXC_number & 0x7fff;
108
109  printk("Exception handler called for exception %d (0x%x)\n", n, n);
110  printk("\t Next PC or Address of fault = %08x\n", excPtr->EXC_SRR0);
111  printk("\t Saved MSR = %08x\n", excPtr->EXC_SRR1);
112
113  if (nest > 1) {
114    printk("Recursion in the exception handler detected; I'll spin now...\n");
115    while (1);
116  }
117
118  /* Try to find out more about the context where this happened */
119  printk("\t Context: ");
120  if (rtems_interrupt_is_in_progress()) {
121    printk("ISR");
122  } else if (!_Thread_Executing) {
123    printk("Initialization (_Thread_Executing not available yet)");
124  } else {
125    if (RTEMS_SUCCESSFUL != (sc = rtems_task_ident(RTEMS_SELF, RTEMS_LOCAL, &id))) {
126      printk("Unable to determine faulting task; rtems_task_ident() returned %u", sc);
127      id = 0;
128    } else {
129      printk("Task ID 0x%08x", id);
130    }
131  }
132  printk("\n");
133
134  /* Dump registers */
135
136  printk("\t R0  = %08x", excPtr->GPR0);
137  if (synch) {
138    printk(" R1  = %08x", excPtr->GPR1);
139    printk(" R2  = %08x", excPtr->GPR2);
140  } else {
141    printk("               ");
142    printk("               ");
143  }
144  printk(" R3  = %08x\n", excPtr->GPR3);
145  printk("\t R4  = %08x", excPtr->GPR4);
146  printk(" R5  = %08x", excPtr->GPR5);
147  printk(" R6  = %08x", excPtr->GPR6);
148  printk(" R7  = %08x\n", excPtr->GPR7);
149  printk("\t R8  = %08x", excPtr->GPR8);
150  printk(" R9  = %08x", excPtr->GPR9);
151  printk(" R10 = %08x", excPtr->GPR10);
152  printk(" R11 = %08x\n", excPtr->GPR11);
153  printk("\t R12 = %08x", excPtr->GPR12);
154  if (synch) {
155    printk(" R13 = %08x", excPtr->GPR13);
156    printk(" R14 = %08x", excPtr->GPR14);
157    printk(" R15 = %08x\n", excPtr->GPR15);
158    printk("\t R16 = %08x", excPtr->GPR16);
159    printk(" R17 = %08x", excPtr->GPR17);
160    printk(" R18 = %08x", excPtr->GPR18);
161    printk(" R19 = %08x\n", excPtr->GPR19);
162    printk("\t R20 = %08x", excPtr->GPR20);
163    printk(" R21 = %08x", excPtr->GPR21);
164    printk(" R22 = %08x", excPtr->GPR22);
165    printk(" R23 = %08x\n", excPtr->GPR23);
166    printk("\t R24 = %08x", excPtr->GPR24);
167    printk(" R25 = %08x", excPtr->GPR25);
168    printk(" R26 = %08x", excPtr->GPR26);
169    printk(" R27 = %08x\n", excPtr->GPR27);
170    printk("\t R28 = %08x", excPtr->GPR28);
171    printk(" R29 = %08x", excPtr->GPR29);
172    printk(" R30 = %08x", excPtr->GPR30);
173    printk(" R31 = %08x\n", excPtr->GPR31);
174  } else {
175    printk("\n");
176  }
177  printk("\t CR  = %08x\n", excPtr->EXC_CR);
178  printk("\t CTR = %08x\n", excPtr->EXC_CTR);
179  printk("\t XER = %08x\n", excPtr->EXC_XER);
180  printk("\t LR  = %08x\n", excPtr->EXC_LR);
181
182  /* Would be great to print DAR but unfortunately,
183   * that is not portable across different CPUs.
184   * AFAIK on classic PPC DAR is SPR 19, on the
185   * 405 we have DEAR = SPR 0x3d5 and booE says
186   * DEAR = SPR 61 :-(
187   */
188  if (ppc_exc_get_DAR) {
189    printk("\t DAR = %08x\n", ppc_exc_get_DAR());
190  }
191
192  BSP_printStackTrace(excPtr);
193
194  if (excPtr->_EXC_number == ASM_DEC_VECTOR)
195    recoverable = 1;
196  if (excPtr->_EXC_number == ASM_SYS_VECTOR)
197#ifdef TEST_RAW_EXCEPTION_CODE
198    recoverable = 1;
199#else
200    recoverable = 0;
201#endif
202  if (!recoverable) {
203    if (id) {
204      printk("Suspending faulting task (0x%08x)\n", id);
205      /* Unnest here because rtems_task_suspend() never returns */
206      nest--;
207      rtems_task_suspend(id);
208    } else {
209      printk("unrecoverable exception!!! Push reset button\n");
210      while (1);
211    }
212  } else {
213    nest--;
214  }
215}
Note: See TracBrowser for help on using the repository browser.