Slight Changes, mostly fixing CPU error reporting
[tpg/acess2.git] / Kernel / arch / x86 / errors.c
1 /*
2  * Acess2 - x86 Architecture
3  * arch/x86/errors.c
4  * - CPU Error Handler
5  */
6 #include <acess.h>
7 #include <proc.h>
8
9 // === CONSTANTS ===
10 #define MAX_BACKTRACE   8       //!< Maximum distance to trace the stack backwards
11
12 // === IMPORTS ===
13 extern void     MM_PageFault(Uint Addr, Uint ErrorCode, tRegs *Regs);
14 extern void Threads_Dump();
15
16 // === PROTOTYPES ===
17 void    Error_Backtrace(Uint eip, Uint ebp);
18
19 // === GLOBALS ===
20 const char *csaERROR_NAMES[] = {
21         "Divide By Zero", "Debug", "NMI Exception", "INT3",
22         "INTO", "Out of Bounds", "Invalid Opcode", "Coprocessor not avaliable",
23         "Double Fault", "Coprocessor Segment Overrun", "Bad TSS", "Segment Not Present",
24         "Stack Fault Exception", "GPF", "#PF", "Reserved",
25         "Floating Point Exception", "Alignment Check Exception", "Machine Check Exception",     "Reserved",
26         "Reserved", "Reserved", "Reserved", "Reserved",
27         "Reserved", "Reserved", "Reserved", "Reserved",
28         "Reserved", "Reserved", "Reserved", "Reserved"
29         };
30
31 // === CODE ===
32 void __stack_chk_fail()
33 {
34         Panic("FATAL ERROR: Stack Check Failed\n");
35         for(;;);
36 }
37
38 /**
39  * \fn void ErrorHandler(tRegs *Regs)
40  * \brief General Error Handler
41  */
42 void ErrorHandler(tRegs *Regs)
43 {
44         Uint    cr;
45         __asm__ __volatile__ ("cli");
46         
47         if(Regs->int_num == 14)
48         {
49                 __asm__ __volatile__ ("mov %%cr2, %0":"=r"(cr));
50                 MM_PageFault( cr, Regs->err_code, Regs );
51                 return ;
52         }
53         
54         Warning("CPU Error %i - %s, Code: 0x%x",
55                 Regs->int_num, csaERROR_NAMES[Regs->int_num], Regs->err_code);
56         Warning(" CS:EIP = 0x%04x:%08x", Regs->cs, Regs->eip);
57         Warning(" SS:ESP = 0x%04x:%08x", Regs->ss, Regs->esp);
58         Warning(" EFLAGS = 0x%08x", Regs->eflags);
59         Warning(" EAX %08x ECX %08x EDX %08x EBX %08x",
60                 Regs->eax, Regs->ecx, Regs->edx, Regs->ebx);
61         Warning(" ESP %08x EBP %08x ESI %08x EDI %08x",
62                 Regs->esp, Regs->ebp, Regs->esi, Regs->edi);
63         Warning(" DS %04x ES %04x FS %04x GS %04x",
64                 Regs->ds, Regs->es, Regs->fs, Regs->gs);
65         
66         // Control Registers
67         __asm__ __volatile__ ("mov %%cr0, %0":"=r"(cr));
68         Warning(" CR0 0x%08x", cr);
69         __asm__ __volatile__ ("mov %%cr2, %0":"=r"(cr));
70         Warning(" CR2 0x%08x", cr);
71         __asm__ __volatile__ ("mov %%cr3, %0":"=r"(cr));
72         Warning(" CR3 0x%08x", cr);
73         
74         switch( Regs->int_num )
75         {
76         case 6:
77                 Warning(" Offending bytes: %02x %02x %02x %02x",
78                         *(Uint8*)Regs->eip+0, *(Uint8*)Regs->eip+1,
79                         *(Uint8*)Regs->eip+2, *(Uint8*)Regs->eip+3);
80                 break;
81         }
82         
83         // Print Stack Backtrace
84         Error_Backtrace(Regs->eip, Regs->ebp);
85         
86         // Dump running threads
87         Threads_Dump();
88         
89         for(;;) __asm__ __volatile__ ("hlt");
90 }
91 /**
92  * \fn void Error_Backtrace(Uint eip, Uint ebp)
93  * \brief Unrolls the stack to trace execution
94  */
95 void Error_Backtrace(Uint eip, Uint ebp)
96 {
97          int    i = 0;
98         Uint    delta = 0;
99         char    *str = NULL;
100         
101         //if(eip < 0xC0000000 && eip > 0x1000)
102         //{
103         //      LogF("Backtrace: User - 0x%x\n", eip);
104         //      return;
105         //}
106         
107         if(eip > 0xE0000000)
108         {
109                 LogF("Backtrace: Data Area - 0x%x\n", eip);
110                 return;
111         }
112         
113         if(eip > 0xC8000000)
114         {
115                 LogF("Backtrace: Kernel Module - 0x%x\n", eip);
116                 return;
117         }
118         
119         //str = Debug_GetSymbol(eip, &delta);
120         if(str == NULL)
121                 LogF("Backtrace: 0x%x", eip);
122         else
123                 LogF("Backtrace: %s+0x%x", str, delta);
124         if(!MM_GetPhysAddr(ebp))
125         {
126                 LogF("\nBacktrace: Invalid EBP, stopping\n");
127                 return;
128         }
129         
130         
131         while( MM_GetPhysAddr(ebp) && i < MAX_BACKTRACE )
132         {
133                 //str = Debug_GetSymbol(*(Uint*)(ebp+4), &delta);
134                 if(str == NULL)
135                         LogF(" >> 0x%x", *(Uint*)(ebp+4));
136                 else
137                         LogF(" >> %s+0x%x", str, delta);
138                 ebp = *(Uint*)ebp;
139                 i++;
140         }
141         LogF("\n");
142 }
143
144 /**
145  * \fn void StartupPrint(char *Str)
146  */
147 void StartupPrint(char *Str)
148 {
149         Uint16  *buf = (void*)0xC00B8000;
150          int    i = 0;
151         static int      line = 0;
152         while(*Str)
153         {
154                 buf[line*80 + i++] = *Str | 0x0700;
155                 Str ++;
156         }
157         
158         while(i < 80)   buf[line*80 + i++] = 0x0720;
159         
160         line ++;
161         if(line == 25)
162         {
163                 line --;
164                 memcpy(buf, &buf[80], 80*24*2);
165                 memset(&buf[80*24], 0, 80*2);
166         }
167 }
168
169 // === EXPORTS ===
170 EXPORT(__stack_chk_fail);

UCC git Repository :: git.ucc.asn.au