2 * Acess2 - x86 Architecture
10 #define MAX_BACKTRACE 8 //!< Maximum distance to trace the stack backwards
13 extern void MM_PageFault(Uint Addr, Uint ErrorCode, tRegs *Regs);
14 extern void VM8086_GPF(tRegs *Regs);
15 extern void Threads_Dump(void);
16 extern void Threads_Fault(int Num);
17 extern int GetCPUNum(void);
20 void __stack_chk_fail(void);
21 void ErrorHandler(tRegs *Regs);
22 void Error_Backtrace(Uint eip, Uint ebp);
23 void StartupPrint(char *Str);
26 const char *csaERROR_NAMES[] = {
27 "Divide By Zero", "Debug", "NMI Exception", "INT3",
28 "INTO", "Out of Bounds", "Invalid Opcode", "Coprocessor not avaliable",
29 "Double Fault", "Coprocessor Segment Overrun", "Bad TSS", "Segment Not Present",
30 "Stack Fault Exception", "GPF", "#PF", "Reserved",
31 "Floating Point Exception", "Alignment Check Exception", "Machine Check Exception", "Reserved",
32 "Reserved", "Reserved", "Reserved", "Reserved",
33 "Reserved", "Reserved", "Reserved", "Reserved",
34 "Reserved", "Reserved", "Reserved", "Reserved"
39 * \brief Keeps GCC happy
41 void __stack_chk_fail(void)
43 Panic("FATAL ERROR: Stack Check Failed\n");
48 * \fn void ErrorHandler(tRegs *Regs)
49 * \brief General Error Handler
50 * \param Regs Register state at error
52 void ErrorHandler(tRegs *Regs)
56 //if( Regs && !(Regs->int_num == 13 && Regs->eflags & 0x20000) )
57 // __asm__ __volatile__ ("xchg %bx, %bx");
58 //Log_Debug("X86", "Regs = %p", Regs);
59 //Log_Debug("X86", "Error %i at 0x%08x", Regs->int_num, Regs->eip);
61 __asm__ __volatile__ ("cli");
63 // Debug exception (used for single-stepping)
64 if(Regs->int_num == 1)
66 static Uint32 lastEIP = 0;
67 tThread *thread = Proc_GetCurThread();
68 if( Regs->eip == lastEIP )
70 Log("%p(%i %s) IP=%08x", thread, thread->TID, thread->ThreadName, Regs->eip);
76 if(Regs->int_num == 14)
78 __asm__ __volatile__ ("mov %%cr2, %0":"=r"(cr));
79 MM_PageFault( cr, Regs->err_code, Regs );
84 if(Regs->int_num == 13 && Regs->eflags & 0x20000)
90 // Check if it's a user mode fault
91 if( Regs->eip < KERNEL_BASE || (Regs->cs & 3) == 3 ) {
92 Log_Warning("Arch", "User Fault - %s, Code: 0x%x",
93 csaERROR_NAMES[Regs->int_num], Regs->err_code);
94 Log_Warning("Arch", "at CS:EIP %04x:%08x",
96 switch( Regs->int_num )
99 case 0: Threads_Fault(FAULT_DIV0); break;
101 case 6: Threads_Fault(FAULT_OPCODE); break;
103 case 13: Threads_Fault(FAULT_ACCESS); break;
104 // Floating Point Exception
105 case 16: Threads_Fault(FAULT_FLOAT); break;
107 default: Threads_Fault(FAULT_MISC); break;
114 LogF("CPU %i Error %i - %s, Code: 0x%x - At %08x",
116 Regs->int_num, csaERROR_NAMES[Regs->int_num], Regs->err_code,
119 //Warning("CPU Error %i - %s, Code: 0x%x",
120 // Regs->int_num, csaERROR_NAMES[Regs->int_num], Regs->err_code);
121 //Warning(" CS:EIP = 0x%04x:%08x", Regs->cs, Regs->eip);
122 __ASM__ ("xchg %bx, %bx");
124 Warning(" SS:ESP = 0x0010:%08x", (Uint)Regs+sizeof(tRegs));
126 Warning(" SS:ESP = 0x%04x:%08x", Regs->ss, Regs->esp);
127 Warning(" EFLAGS = 0x%08x", Regs->eflags);
128 Warning(" EAX %08x ECX %08x EDX %08x EBX %08x",
129 Regs->eax, Regs->ecx, Regs->edx, Regs->ebx);
130 Warning(" ESP %08x EBP %08x ESI %08x EDI %08x",
131 Regs->esp, Regs->ebp, Regs->esi, Regs->edi);
132 Warning(" DS %04x ES %04x FS %04x GS %04x",
133 Regs->ds, Regs->es, Regs->fs, Regs->gs);
136 __asm__ __volatile__ ("mov %%cr0, %0":"=r"(cr));
137 Warning(" CR0 0x%08x", cr);
138 __asm__ __volatile__ ("mov %%cr2, %0":"=r"(cr));
139 Warning(" CR2 0x%08x", cr);
140 __asm__ __volatile__ ("mov %%cr3, %0":"=r"(cr));
141 Warning(" CR3 0x%08x", cr);
143 switch( Regs->int_num )
146 Warning(" Offending bytes: %02x %02x %02x %02x",
147 *(Uint8*)Regs->eip+0, *(Uint8*)Regs->eip+1,
148 *(Uint8*)Regs->eip+2, *(Uint8*)Regs->eip+3);
152 // Print Stack Backtrace
153 Error_Backtrace(Regs->eip, Regs->ebp);
155 // Dump running threads
158 for(;;) __asm__ __volatile__ ("hlt");
161 * \fn void Error_Backtrace(Uint eip, Uint ebp)
162 * \brief Unrolls the stack to trace execution
163 * \param eip Current Instruction Pointer
164 * \param ebp Current Base Pointer (Stack Frame)
166 void Error_Backtrace(Uint eip, Uint ebp)
172 //if(eip < 0xC0000000 && eip > 0x1000)
174 // LogF("Backtrace: User - 0x%x\n", eip);
180 LogF("Backtrace: Data Area - 0x%x\n", eip);
186 LogF("Backtrace: Kernel Module - 0x%x\n", eip);
190 //str = Debug_GetSymbol(eip, &delta);
192 LogF("Backtrace: 0x%x", eip);
194 LogF("Backtrace: %s+0x%x", str, delta);
195 if(!MM_GetPhysAddr(ebp))
197 LogF("\nBacktrace: Invalid EBP, stopping\n");
202 while( MM_GetPhysAddr(ebp) && i < MAX_BACKTRACE )
204 //str = Debug_GetSymbol(*(Uint*)(ebp+4), &delta);
206 LogF(" >> 0x%x", *(Uint*)(ebp+4));
208 LogF(" >> %s+0x%x", str, delta);
216 * \fn void StartupPrint(char *Str)
217 * \brief Str String to print
218 * \note WHY IS THIS HERE?!?!
220 void StartupPrint(char *Str)
222 Uint16 *buf = (void*)0xC00B8000;
227 buf[line*80 + i++] = *Str | 0x0700;
231 // Clear the rest of the line
233 buf[line*80 + i++] = 0x0720;
239 memcpy(buf, &buf[80], 80*24*2);
240 memset(&buf[80*24], 0, 80*2);
245 EXPORT(__stack_chk_fail);