xref: /nrf52832-nimble/rt-thread/libcpu/ppc/ppc405/traps.c (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero #include <rtthread.h>
2*10465441SEvalZero #include <asm/processor.h>
3*10465441SEvalZero #include <asm/ppc4xx-uic.h>
4*10465441SEvalZero 
5*10465441SEvalZero /* Returns 0 if exception not found and fixup otherwise.  */
6*10465441SEvalZero extern unsigned long search_exception_table(unsigned long);
7*10465441SEvalZero 
8*10465441SEvalZero /* THIS NEEDS CHANGING to use the board info structure.
9*10465441SEvalZero  */
10*10465441SEvalZero #define END_OF_MEM	0x800000
11*10465441SEvalZero #define UICB0_ALL	0
12*10465441SEvalZero 
13*10465441SEvalZero #define ESR_MCI 0x80000000
14*10465441SEvalZero #define ESR_PIL 0x08000000
15*10465441SEvalZero #define ESR_PPR 0x04000000
16*10465441SEvalZero #define ESR_PTR 0x02000000
17*10465441SEvalZero #define ESR_DST 0x00800000
18*10465441SEvalZero #define ESR_DIZ 0x00400000
19*10465441SEvalZero #define ESR_U0F 0x00008000
20*10465441SEvalZero 
set_tsr(unsigned long val)21*10465441SEvalZero rt_inline void set_tsr(unsigned long val)
22*10465441SEvalZero {
23*10465441SEvalZero     mtspr(SPRN_TSR, val);
24*10465441SEvalZero }
25*10465441SEvalZero 
get_esr(void)26*10465441SEvalZero rt_inline rt_uint32_t get_esr(void)
27*10465441SEvalZero {
28*10465441SEvalZero     rt_uint32_t val;
29*10465441SEvalZero 
30*10465441SEvalZero     val = mfspr(SPRN_ESR);
31*10465441SEvalZero     return val;
32*10465441SEvalZero }
33*10465441SEvalZero 
34*10465441SEvalZero /*
35*10465441SEvalZero  * Trap & Exception support
36*10465441SEvalZero  */
37*10465441SEvalZero 
print_backtrace(unsigned long * sp)38*10465441SEvalZero void print_backtrace(unsigned long *sp)
39*10465441SEvalZero {
40*10465441SEvalZero     int cnt = 0;
41*10465441SEvalZero     unsigned long i;
42*10465441SEvalZero 
43*10465441SEvalZero     rt_kprintf("Call backtrace: ");
44*10465441SEvalZero     while (sp) {
45*10465441SEvalZero         if ((rt_uint32_t)sp > END_OF_MEM)
46*10465441SEvalZero             break;
47*10465441SEvalZero 
48*10465441SEvalZero         i = sp[1];
49*10465441SEvalZero         if (cnt++ % 7 == 0)
50*10465441SEvalZero             rt_kprintf("\n");
51*10465441SEvalZero         rt_kprintf("%08lX ", i);
52*10465441SEvalZero         if (cnt > 32) break;
53*10465441SEvalZero         sp = (unsigned long *)*sp;
54*10465441SEvalZero     }
55*10465441SEvalZero     rt_kprintf("\n");
56*10465441SEvalZero }
57*10465441SEvalZero 
show_regs(struct pt_regs * regs)58*10465441SEvalZero void show_regs(struct pt_regs * regs)
59*10465441SEvalZero {
60*10465441SEvalZero     int i;
61*10465441SEvalZero 
62*10465441SEvalZero     rt_kprintf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DEAR: %08lX\n",
63*10465441SEvalZero            regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
64*10465441SEvalZero     rt_kprintf("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
65*10465441SEvalZero            regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
66*10465441SEvalZero            regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
67*10465441SEvalZero            regs->msr&MSR_IR ? 1 : 0,
68*10465441SEvalZero            regs->msr&MSR_DR ? 1 : 0);
69*10465441SEvalZero 
70*10465441SEvalZero     rt_kprintf("\n");
71*10465441SEvalZero     for (i = 0;  i < 32;  i++) {
72*10465441SEvalZero         if ((i % 8) == 0) {
73*10465441SEvalZero             rt_kprintf("GPR%02d: ", i);
74*10465441SEvalZero         }
75*10465441SEvalZero 
76*10465441SEvalZero         rt_kprintf("%08lX ", regs->gpr[i]);
77*10465441SEvalZero         if ((i % 8) == 7) {
78*10465441SEvalZero             rt_kprintf("\n");
79*10465441SEvalZero         }
80*10465441SEvalZero     }
81*10465441SEvalZero }
82*10465441SEvalZero 
panic(const char * fmt,...)83*10465441SEvalZero void panic(const char *fmt, ...)
84*10465441SEvalZero {
85*10465441SEvalZero     while(1);
86*10465441SEvalZero }
87*10465441SEvalZero 
88*10465441SEvalZero void
_exception(int signr,struct pt_regs * regs)89*10465441SEvalZero _exception(int signr, struct pt_regs *regs)
90*10465441SEvalZero {
91*10465441SEvalZero     show_regs(regs);
92*10465441SEvalZero     print_backtrace((unsigned long *)regs->gpr[1]);
93*10465441SEvalZero     panic("Exception");
94*10465441SEvalZero }
95*10465441SEvalZero 
96*10465441SEvalZero unsigned long
search_exception_table(unsigned long addr)97*10465441SEvalZero search_exception_table(unsigned long addr)
98*10465441SEvalZero {
99*10465441SEvalZero         unsigned long ret = 0;
100*10465441SEvalZero 
101*10465441SEvalZero         /* There is only the kernel to search.  */
102*10465441SEvalZero         // ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
103*10465441SEvalZero         /* if the serial port does not hang in exception, rt_kprintf can be used */
104*10465441SEvalZero         if (ret) return ret;
105*10465441SEvalZero 
106*10465441SEvalZero         return 0;
107*10465441SEvalZero }
108*10465441SEvalZero 
109*10465441SEvalZero /*
110*10465441SEvalZero  * Handle external interrupts
111*10465441SEvalZero  */
external_interrupt(struct pt_regs * regs)112*10465441SEvalZero void external_interrupt(struct pt_regs *regs)
113*10465441SEvalZero {
114*10465441SEvalZero     u32 uic_msr;
115*10465441SEvalZero 
116*10465441SEvalZero     /*
117*10465441SEvalZero      * Read masked interrupt status register to determine interrupt source
118*10465441SEvalZero      */
119*10465441SEvalZero     uic_msr = mfdcr(uic0msr);
120*10465441SEvalZero 
121*10465441SEvalZero     mtdcr(uic0sr, (uic_msr & UICB0_ALL));
122*10465441SEvalZero 
123*10465441SEvalZero     if (uic_msr & ~(UICB0_ALL))
124*10465441SEvalZero     {
125*10465441SEvalZero         uic_interrupt(UIC0_DCR_BASE, 0);
126*10465441SEvalZero     }
127*10465441SEvalZero 
128*10465441SEvalZero     return;
129*10465441SEvalZero }
130*10465441SEvalZero 
MachineCheckException(struct pt_regs * regs)131*10465441SEvalZero void MachineCheckException(struct pt_regs *regs)
132*10465441SEvalZero {
133*10465441SEvalZero     unsigned long fixup, val;
134*10465441SEvalZero 
135*10465441SEvalZero     if ((fixup = search_exception_table(regs->nip)) != 0) {
136*10465441SEvalZero         regs->nip = fixup;
137*10465441SEvalZero         val = mfspr(MCSR);
138*10465441SEvalZero         /* Clear MCSR */
139*10465441SEvalZero         mtspr(SPRN_MCSR, val);
140*10465441SEvalZero         return;
141*10465441SEvalZero     }
142*10465441SEvalZero 
143*10465441SEvalZero     rt_kprintf("Machine Check Exception.\n");
144*10465441SEvalZero     rt_kprintf("Caused by (from msr): ");
145*10465441SEvalZero     rt_kprintf("regs %p ", regs);
146*10465441SEvalZero 
147*10465441SEvalZero     val = get_esr();
148*10465441SEvalZero 
149*10465441SEvalZero     if (val& ESR_IMCP) {
150*10465441SEvalZero         rt_kprintf("Instruction");
151*10465441SEvalZero         mtspr(ESR, val & ~ESR_IMCP);
152*10465441SEvalZero     } else {
153*10465441SEvalZero         rt_kprintf("Data");
154*10465441SEvalZero     }
155*10465441SEvalZero     rt_kprintf(" machine check.\n");
156*10465441SEvalZero 
157*10465441SEvalZero     show_regs(regs);
158*10465441SEvalZero     print_backtrace((unsigned long *)regs->gpr[1]);
159*10465441SEvalZero     panic("machine check");
160*10465441SEvalZero }
161*10465441SEvalZero 
AlignmentException(struct pt_regs * regs)162*10465441SEvalZero void AlignmentException(struct pt_regs *regs)
163*10465441SEvalZero {
164*10465441SEvalZero     show_regs(regs);
165*10465441SEvalZero     print_backtrace((unsigned long *)regs->gpr[1]);
166*10465441SEvalZero     panic("Alignment Exception");
167*10465441SEvalZero }
168*10465441SEvalZero 
ProgramCheckException(struct pt_regs * regs)169*10465441SEvalZero void ProgramCheckException(struct pt_regs *regs)
170*10465441SEvalZero {
171*10465441SEvalZero     long esr_val;
172*10465441SEvalZero 
173*10465441SEvalZero     show_regs(regs);
174*10465441SEvalZero 
175*10465441SEvalZero     esr_val = get_esr();
176*10465441SEvalZero     if( esr_val & ESR_PIL )
177*10465441SEvalZero         rt_kprintf( "** Illegal Instruction **\n" );
178*10465441SEvalZero     else if( esr_val & ESR_PPR )
179*10465441SEvalZero         rt_kprintf( "** Privileged Instruction **\n" );
180*10465441SEvalZero     else if( esr_val & ESR_PTR )
181*10465441SEvalZero         rt_kprintf( "** Trap Instruction **\n" );
182*10465441SEvalZero 
183*10465441SEvalZero     print_backtrace((unsigned long *)regs->gpr[1]);
184*10465441SEvalZero     panic("Program Check Exception");
185*10465441SEvalZero }
186*10465441SEvalZero 
DecrementerPITException(struct pt_regs * regs)187*10465441SEvalZero void DecrementerPITException(struct pt_regs *regs)
188*10465441SEvalZero {
189*10465441SEvalZero     /* reset PIT interrupt */
190*10465441SEvalZero     set_tsr(0x08000000);
191*10465441SEvalZero 
192*10465441SEvalZero     /* increase a OS Tick */
193*10465441SEvalZero     rt_tick_increase();
194*10465441SEvalZero }
195*10465441SEvalZero 
UnknownException(struct pt_regs * regs)196*10465441SEvalZero void UnknownException(struct pt_regs *regs)
197*10465441SEvalZero {
198*10465441SEvalZero 
199*10465441SEvalZero     rt_kprintf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
200*10465441SEvalZero            regs->nip, regs->msr, regs->trap);
201*10465441SEvalZero     _exception(0, regs);
202*10465441SEvalZero }
203*10465441SEvalZero 
DebugException(struct pt_regs * regs)204*10465441SEvalZero void DebugException(struct pt_regs *regs)
205*10465441SEvalZero {
206*10465441SEvalZero     rt_kprintf("Debugger trap at @ %lx @regs %lx\n", regs->nip, (rt_uint32_t)regs );
207*10465441SEvalZero     show_regs(regs);
208*10465441SEvalZero }
209