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__ ("sti"); // Should be OK, TODO: Test
79 __asm__ __volatile__ ("mov %%cr2, %0":"=r"(cr));
80 MM_PageFault( cr, Regs->err_code, Regs );
85 if(Regs->int_num == 13 && Regs->eflags & 0x20000)
91 // Check if it's a user mode fault
92 if( Regs->eip < KERNEL_BASE || (Regs->cs & 3) == 3 ) {
93 Log_Warning("Arch", "User Fault - %s, Code: 0x%x",
94 csaERROR_NAMES[Regs->int_num], Regs->err_code);
95 Log_Warning("Arch", "at CS:EIP %04x:%08x",
97 switch( Regs->int_num )
100 case 0: Threads_Fault(FAULT_DIV0); break;
102 case 6: Threads_Fault(FAULT_OPCODE); break;
104 case 13: Threads_Fault(FAULT_ACCESS); break;
105 // Floating Point Exception
106 case 16: Threads_Fault(FAULT_FLOAT); break;
108 default: Threads_Fault(FAULT_MISC); break;
115 LogF("CPU %i Error %i - %s, Code: 0x%x - At %08x",
117 Regs->int_num, csaERROR_NAMES[Regs->int_num], Regs->err_code,
120 //Warning("CPU Error %i - %s, Code: 0x%x",
121 // Regs->int_num, csaERROR_NAMES[Regs->int_num], Regs->err_code);
122 //Warning(" CS:EIP = 0x%04x:%08x", Regs->cs, Regs->eip);
123 __ASM__ ("xchg %bx, %bx");
125 Warning(" SS:ESP = 0x0010:%08x", (Uint)Regs+sizeof(tRegs));
127 Warning(" SS:ESP = 0x%04x:%08x", Regs->ss, Regs->esp);
128 Warning(" EFLAGS = 0x%08x", Regs->eflags);
129 Warning(" EAX %08x ECX %08x EDX %08x EBX %08x",
130 Regs->eax, Regs->ecx, Regs->edx, Regs->ebx);
131 Warning(" ESP %08x EBP %08x ESI %08x EDI %08x",
132 Regs->esp, Regs->ebp, Regs->esi, Regs->edi);
133 Warning(" DS %04x ES %04x FS %04x GS %04x",
134 Regs->ds, Regs->es, Regs->fs, Regs->gs);
137 __asm__ __volatile__ ("mov %%cr0, %0":"=r"(cr));
138 Warning(" CR0 0x%08x", cr);
139 __asm__ __volatile__ ("mov %%cr2, %0":"=r"(cr));
140 Warning(" CR2 0x%08x", cr);
141 __asm__ __volatile__ ("mov %%cr3, %0":"=r"(cr));
142 Warning(" CR3 0x%08x", cr);
144 switch( Regs->int_num )
147 Warning(" Offending bytes: %02x %02x %02x %02x",
148 *(Uint8*)Regs->eip+0, *(Uint8*)Regs->eip+1,
149 *(Uint8*)Regs->eip+2, *(Uint8*)Regs->eip+3);
153 // Print Stack Backtrace
154 Error_Backtrace(Regs->eip, Regs->ebp);
156 // Dump running threads
159 for(;;) __asm__ __volatile__ ("hlt");
162 * \fn void Error_Backtrace(Uint eip, Uint ebp)
163 * \brief Unrolls the stack to trace execution
164 * \param eip Current Instruction Pointer
165 * \param ebp Current Base Pointer (Stack Frame)
167 void Error_Backtrace(Uint eip, Uint ebp)
173 //if(eip < 0xC0000000 && eip > 0x1000)
175 // LogF("Backtrace: User - 0x%x\n", eip);
181 LogF("Backtrace: Data Area - 0x%x\n", eip);
187 LogF("Backtrace: Kernel Module - 0x%x\n", eip);
191 //str = Debug_GetSymbol(eip, &delta);
193 LogF("Backtrace: 0x%x", eip);
195 LogF("Backtrace: %s+0x%x", str, delta);
196 if(!MM_GetPhysAddr(ebp))
198 LogF("\nBacktrace: Invalid EBP, stopping\n");
203 while( MM_GetPhysAddr(ebp) && i < MAX_BACKTRACE )
205 //str = Debug_GetSymbol(*(Uint*)(ebp+4), &delta);
207 LogF(" >> 0x%x", *(Uint*)(ebp+4));
209 LogF(" >> %s+0x%x", str, delta);
217 * \fn void StartupPrint(char *Str)
218 * \brief Str String to print
219 * \note WHY IS THIS HERE?!?!
221 void StartupPrint(char *Str)
223 Uint16 *buf = (void*)0xC00B8000;
228 buf[line*80 + i++] = *Str | 0x0700;
232 // Clear the rest of the line
234 buf[line*80 + i++] = 0x0720;
240 memcpy(buf, &buf[80], 80*24*2);
241 memset(&buf[80*24], 0, 80*2);
246 EXPORT(__stack_chk_fail);