VM8086 Support, Starting on VESA Driver
[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         __asm__ __volatile__ ("cli");
47         
48         //Log_Debug("X86", "Error %i at 0x%08x", Regs->int_num, Regs->eip);
49         
50         // Page Fault
51         if(Regs->int_num == 14)
52         {
53                 __asm__ __volatile__ ("mov %%cr2, %0":"=r"(cr));
54                 MM_PageFault( cr, Regs->err_code, Regs );
55                 return ;
56         }
57         
58         // VM8086 GPF
59         if(Regs->int_num == 13 && Regs->eflags & 0x20000)
60         {
61                 VM8086_GPF(Regs);
62                 return ;
63         }
64         
65         Warning("CPU Error %i - %s, Code: 0x%x",
66                 Regs->int_num, csaERROR_NAMES[Regs->int_num], Regs->err_code);
67         Warning(" CS:EIP = 0x%04x:%08x", Regs->cs, Regs->eip);
68         Warning(" SS:ESP = 0x%04x:%08x", Regs->ss, Regs->esp);
69         Warning(" EFLAGS = 0x%08x", Regs->eflags);
70         Warning(" EAX %08x ECX %08x EDX %08x EBX %08x",
71                 Regs->eax, Regs->ecx, Regs->edx, Regs->ebx);
72         Warning(" ESP %08x EBP %08x ESI %08x EDI %08x",
73                 Regs->esp, Regs->ebp, Regs->esi, Regs->edi);
74         Warning(" DS %04x ES %04x FS %04x GS %04x",
75                 Regs->ds, Regs->es, Regs->fs, Regs->gs);
76         
77         // Control Registers
78         __asm__ __volatile__ ("mov %%cr0, %0":"=r"(cr));
79         Warning(" CR0 0x%08x", cr);
80         __asm__ __volatile__ ("mov %%cr2, %0":"=r"(cr));
81         Warning(" CR2 0x%08x", cr);
82         __asm__ __volatile__ ("mov %%cr3, %0":"=r"(cr));
83         Warning(" CR3 0x%08x", cr);
84         
85         switch( Regs->int_num )
86         {
87         case 6:
88                 Warning(" Offending bytes: %02x %02x %02x %02x",
89                         *(Uint8*)Regs->eip+0, *(Uint8*)Regs->eip+1,
90                         *(Uint8*)Regs->eip+2, *(Uint8*)Regs->eip+3);
91                 break;
92         }
93         
94         // Print Stack Backtrace
95         Error_Backtrace(Regs->eip, Regs->ebp);
96         
97         // Dump running threads
98         Threads_Dump();
99         
100         for(;;) __asm__ __volatile__ ("hlt");
101 }
102 /**
103  * \fn void Error_Backtrace(Uint eip, Uint ebp)
104  * \brief Unrolls the stack to trace execution
105  */
106 void Error_Backtrace(Uint eip, Uint ebp)
107 {
108          int    i = 0;
109         Uint    delta = 0;
110         char    *str = NULL;
111         
112         //if(eip < 0xC0000000 && eip > 0x1000)
113         //{
114         //      LogF("Backtrace: User - 0x%x\n", eip);
115         //      return;
116         //}
117         
118         if(eip > 0xE0000000)
119         {
120                 LogF("Backtrace: Data Area - 0x%x\n", eip);
121                 return;
122         }
123         
124         if(eip > 0xC8000000)
125         {
126                 LogF("Backtrace: Kernel Module - 0x%x\n", eip);
127                 return;
128         }
129         
130         //str = Debug_GetSymbol(eip, &delta);
131         if(str == NULL)
132                 LogF("Backtrace: 0x%x", eip);
133         else
134                 LogF("Backtrace: %s+0x%x", str, delta);
135         if(!MM_GetPhysAddr(ebp))
136         {
137                 LogF("\nBacktrace: Invalid EBP, stopping\n");
138                 return;
139         }
140         
141         
142         while( MM_GetPhysAddr(ebp) && i < MAX_BACKTRACE )
143         {
144                 //str = Debug_GetSymbol(*(Uint*)(ebp+4), &delta);
145                 if(str == NULL)
146                         LogF(" >> 0x%x", *(Uint*)(ebp+4));
147                 else
148                         LogF(" >> %s+0x%x", str, delta);
149                 ebp = *(Uint*)ebp;
150                 i++;
151         }
152         LogF("\n");
153 }
154
155 /**
156  * \fn void StartupPrint(char *Str)
157  */
158 void StartupPrint(char *Str)
159 {
160         Uint16  *buf = (void*)0xC00B8000;
161          int    i = 0;
162         static int      line = 0;
163         while(*Str)
164         {
165                 buf[line*80 + i++] = *Str | 0x0700;
166                 Str ++;
167         }
168         
169         while(i < 80)   buf[line*80 + i++] = 0x0720;
170         
171         line ++;
172         if(line == 25)
173         {
174                 line --;
175                 memcpy(buf, &buf[80], 80*24*2);
176                 memset(&buf[80*24], 0, 80*2);
177         }
178 }
179
180 // === EXPORTS ===
181 EXPORT(__stack_chk_fail);

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