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

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