Added boot process information to help someone find out what really happens.
[bootos.git] / stage2 / exceptions.c
blob70dda2390dd9e58b0312a6de8b90c4ba033186a0
1 /* exceptions.c - exception handling
3 Copyright (C) 2010-2011 Hector Martin "marcan" <hector@marcansoft.com>
5 This code is licensed to you under the terms of the GNU GPL, version 2;
6 see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
7 */
9 #include "types.h"
10 #include "exceptions.h"
11 #include "mm.h"
12 #include "string.h"
13 #include "debug.h"
14 #include "lv1call.h"
16 extern u8 _exc_vec[], _exc_vec_end[];
18 struct exc_data *exc = (void*)0x2000;
20 static void print_exception(int exception)
22 int i;
24 u32 tid;
25 asm("mfspr %0, 0x88" : "=r"(tid));
26 tid = 2-(tid>>30);
27 printf("\nException %04x occurred on thread %d!\n", exception, tid);
29 for (i=0; i<32; i+=4) {
30 printf("r%d-%d: ", i, i+3);
31 if (i<8) printf(" ");
32 if (i==8) printf(" ");
33 printf("%16lx %16lx %16lx %16lx\n", exc->regs[i], exc->regs[i+1], exc->regs[i+2], exc->regs[i+3]);
36 printf("LR: %016lx\n", exc->lr);
37 printf("CTR: %016lx\n", exc->ctr);
38 printf("CR: %08lx\n", exc->cr);
39 printf("XER: %08lx\n", exc->xer);
40 printf("DAR: %016lx\n", exc->dar);
41 printf("DSISR: %08lx\n", exc->dsisr);
42 printf("SRR0: %016lx\n", exc->srr0);
43 printf("SRR1: %016lx\n", exc->srr1);
47 void exception_handler(int exception)
49 switch(exception) {
50 case 0x300: // Data Storage
51 if ((exc->dsisr & (1<<30)) && mm_loadhtab(exc->dar))
52 return;
53 break;
54 case 0x380: // Data Segment
55 if (mm_loadseg(exc->dar))
56 return;
57 break;
58 case 0x400: // Instruction Storage
59 if ((exc->srr1 & (1<<30)) && mm_loadhtab(exc->srr0))
60 return;
61 break;
62 case 0x480: // Instruction Segment
63 if (mm_loadseg(exc->srr0))
64 return;
65 break;
67 print_exception(exception);
68 printf("\nUnhandled exception. Panicing...\n");
69 lv1_panic(0);
70 while(1);
73 void exceptions_init(void)
75 u64 addr;
77 printf("Installing exception handlers...\n");
79 for (addr=0x100; addr<0x2000; addr+=0x20) {
80 u32 *p = (u32*)addr;
81 memcpy(p, _exc_vec, _exc_vec_end - _exc_vec);
82 p[6] |= addr; // patch exception number
83 sync_before_exec(p, 0x20);