Kernel - Fix compilation on x86_64 and armv7 (for MM changes)
[tpg/acess2.git] / KernelLand / Kernel / arch / x86_64 / errors.c
1 /*
2  * Acess2 x86_64 Project
3  * - Error Handling
4  */
5 #include <acess.h>
6 #include <proc.h>
7 #include <mm_virt.h>
8 #include <threads_int.h>        // Needed for SSE handling
9 #include <debug_hooks.h>
10
11 #define MAX_BACKTRACE   6
12
13 // === IMPORTS ===
14 extern int      MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs);
15 extern void     Error_Backtrace(Uint IP, Uint BP);
16 extern void     Proc_EnableSSE(void);
17 extern void     Proc_RestoreSSE(Uint32 Data);
18
19 // === PROTOTYPES ===
20 void    Error_Handler(tRegs *Regs);
21
22 // === GLOBALS ==
23 const char * const csaERROR_NAMES[] = {
24         "Divide By Zero", "Debug", "NMI Exception", "INT3",
25         "INTO", "Out of Bounds", "Invalid Opcode", "Coprocessor not avaliable",
26         "Double Fault", "Coprocessor Segment Overrun", "Bad TSS", "Segment Not Present",
27         "Stack Fault Exception", "GPF", "#PF", "Reserved",
28         "Floating Point Exception", "Alignment Check Exception", "Machine Check Exception",     "Reserved",
29         "Reserved", "Reserved", "Reserved", "Reserved",
30         "Reserved", "Reserved", "Reserved", "Reserved",
31         "Reserved", "Reserved", "Reserved", "Reserved"
32         };
33
34 // === CODE ===
35 void Error_Handler(tRegs *Regs)
36 {
37         Uint    cr;
38
39         if( Regs->IntNum == 7 )
40         {
41                 tThread *thread = Proc_GetCurThread();
42                 if(!thread->SavedState.bSSEModified)
43                 {
44                         Proc_EnableSSE();
45                         if(!thread->SavedState.SSE)
46                                 thread->SavedState.SSE = malloc(sizeof(tSSEState) + 0xF);
47                         else
48                                 Proc_RestoreSSE( ((Uint)thread->SavedState.SSE + 0xF) & ~0xF );
49                         thread->SavedState.bSSEModified = 1;
50 //                      __asm__ __volatile__ ("sti");
51                         return ;
52                 }
53                 // oops, SSE enabled but a #NM, bad news
54         }
55         
56         if( Regs->IntNum == 14 ) {
57                 __asm__ __volatile__ ("mov %%cr2, %0":"=r"(cr));
58                 if( MM_PageFault(cr, Regs->ErrorCode, Regs) == 0 )
59                         return ;
60         }
61         else {
62                 Debug_KernelPanic();
63
64                 Error_Backtrace(Regs->RIP, Regs->RBP);
65         }
66         
67         Log("CPU Error %x, Code: 0x%x", Regs->IntNum, Regs->ErrorCode);
68         Log(" - %s", csaERROR_NAMES[Regs->IntNum]);
69         Log(" CS:RIP = 0x%04x:%016llx", Regs->CS, Regs->RIP);
70         Log(" SS:RSP = 0x%04x:%016llx", Regs->SS, Regs->RSP);
71         Log(" RFLAGS = 0x%016llx", Regs->RFlags);
72         
73         Log(" RAX %016llx RCX %016llx RDX %016llx RBX %016llx",
74                 Regs->RAX, Regs->RCX, Regs->RDX, Regs->RBX);
75         Log(" RSP %016llx RBP %016llx RSI %016llx RDI %016llx",
76                 Regs->RSP, Regs->RBP, Regs->RSP, Regs->RDI);
77         Log(" R8  %016llx R9  %016llx R10 %016llx R11 %016llx",
78                 Regs->R8, Regs->R9, Regs->R10, Regs->R11);
79         Log(" R12 %016llx R13 %016llx R14 %016llx R15 %016llx",
80                 Regs->R12, Regs->R13, Regs->R14, Regs->R15);
81         Log(" FS %04x GS %04x", Regs->FS, Regs->GS);
82         
83         
84         // Control Registers
85         __asm__ __volatile__ ("mov %%cr0, %0":"=r"(cr));
86         Warning(" CR0 0x%08x", cr);
87         __asm__ __volatile__ ("mov %%cr2, %0":"=r"(cr));
88         Warning(" CR2 0x%016llx", cr);
89         __asm__ __volatile__ ("mov %%cr3, %0":"=r"(cr));
90         Warning(" CR3 0x%016llx", cr);
91         __asm__ __volatile__ ("mov %%cr4, %0":"=r"(cr));
92         Warning(" CR4 0x%08x", cr);
93         
94         switch( Regs->IntNum )
95         {
96         case 6: // #UD
97                 Warning(" Offending bytes: %02x %02x %02x %02x",
98                         *(Uint8*)(Regs->RIP+0), *(Uint8*)(Regs->RIP+1),
99                         *(Uint8*)(Regs->RIP+2), *(Uint8*)(Regs->RIP+3)
100                         );
101                 break;
102         case 2: // NMI
103                 Threads_Dump();
104                 break;
105         }
106         
107         __asm__ __volatile__ ("cli");
108         for(;;)
109                 __asm__ __volatile__ ("hlt");
110 }
111
112 void Proc_PrintBacktrace(void)
113 {
114         Uint64  *rbp;
115         __asm__ __volatile__ ("mov %%rbp, %0" : "=r" (rbp));
116         Error_Backtrace( rbp[1], rbp[0] );
117 }
118
119 /**
120  * \fn void Error_Backtrace(Uint eip, Uint ebp)
121  * \brief Unrolls the stack to trace execution
122  * \param eip   Current Instruction Pointer
123  * \param ebp   Current Base Pointer (Stack Frame)
124  */
125 void Error_Backtrace(Uint IP, Uint BP)
126 {
127          int    i = 0;
128         
129         //if(eip < 0xC0000000 && eip > 0x1000)
130         //{
131         //      LogF("Backtrace: User - 0x%x\n", eip);
132         //      return;
133         //}
134         
135         if( IP > USER_MAX && IP < MM_KERNEL_CODE
136          && (MM_MODULE_MIN > IP || IP > MM_MODULE_MAX)
137                 )
138         {
139                 LogF("Backtrace: Data Area - %p\n", IP);
140                 return;
141         }
142         
143         //str = Debug_GetSymbol(eip, &delta);
144         //if(str == NULL)
145                 LogF("Backtrace: %p", IP);
146         //else
147         //      LogF("Backtrace: %s+0x%x", str, delta);
148         if( !MM_GetPhysAddr( (void*)BP ) )
149         {
150                 LogF("\nBacktrace: Invalid BP, stopping\n");
151                 return;
152         }
153         
154         
155         while( MM_GetPhysAddr( (void*)BP) && MM_GetPhysAddr((void*)(BP+8+7)) && i < MAX_BACKTRACE )
156         {
157                 //str = Debug_GetSymbol(*(Uint*)(ebp+4), &delta);
158                 //if(str == NULL)
159                         LogF(" >> 0x%llx", ((Uint*)BP)[1]);
160                 //else
161                 //      LogF(" >> %s+0x%x", str, delta);
162                 BP = ((Uint*)BP)[0];
163                 i++;
164         }
165         LogF("\n");
166 }

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