d1856db17758bc94b48d36837f981f2c4ac7db36
[tpg/acess2.git] / 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
9 #define MAX_BACKTRACE   6
10
11 // === IMPORTS ===
12  int    MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs);
13 void    Error_Backtrace(Uint IP, Uint BP);
14
15 // === PROTOTYPES ===
16 void    Error_Handler(tRegs *Regs);
17
18 // === GLOBALS ==
19 const char * const csaERROR_NAMES[] = {
20         "Divide By Zero", "Debug", "NMI Exception", "INT3",
21         "INTO", "Out of Bounds", "Invalid Opcode", "Coprocessor not avaliable",
22         "Double Fault", "Coprocessor Segment Overrun", "Bad TSS", "Segment Not Present",
23         "Stack Fault Exception", "GPF", "#PF", "Reserved",
24         "Floating Point Exception", "Alignment Check Exception", "Machine Check Exception",     "Reserved",
25         "Reserved", "Reserved", "Reserved", "Reserved",
26         "Reserved", "Reserved", "Reserved", "Reserved",
27         "Reserved", "Reserved", "Reserved", "Reserved"
28         };
29
30 // === CODE ===
31 void Error_Handler(tRegs *Regs)
32 {
33         Uint    cr;
34         
35         if( Regs->IntNum == 14 ) {
36                 __asm__ __volatile__ ("mov %%cr2, %0":"=r"(cr));
37                 if( MM_PageFault(cr, Regs->ErrorCode, Regs) == 0 )
38                         return ;
39         }
40         else {
41                 Debug_KernelPanic();
42
43                 Error_Backtrace(Regs->RIP, Regs->RBP);
44         }
45         
46         Log("CPU Error %x, Code: 0x%x", Regs->IntNum, Regs->ErrorCode);
47 //      Log(" - %s", csaERROR_NAMES[Regs->IntNum]);
48         Log(" CS:RIP = 0x%04x:%016llx", Regs->CS, Regs->RIP);
49         Log(" SS:RSP = 0x%04x:%016llx", Regs->SS, Regs->RSP);
50         Log(" RFLAGS = 0x%016llx", Regs->RFlags);
51         
52         Log(" RAX %016llx RCX %016llx RDX %016llx RBX %016llx",
53                 Regs->RAX, Regs->RCX, Regs->RDX, Regs->RBX);
54         Log(" RSP %016llx RBP %016llx RSI %016llx RDI %016llx",
55                 Regs->RSP, Regs->RBP, Regs->RSP, Regs->RDI);
56         Log(" R8  %016llx R9  %016llx R10 %016llx R11 %016llx",
57                 Regs->R8, Regs->R9, Regs->R10, Regs->R11);
58         Log(" R12 %016llx R13 %016llx R14 %016llx R15 %016llx",
59                 Regs->R12, Regs->R13, Regs->R14, Regs->R15);
60         Log(" FS %04x GS %04x", Regs->FS, Regs->GS);
61         
62         
63         // Control Registers
64         __asm__ __volatile__ ("mov %%cr0, %0":"=r"(cr));
65         Warning(" CR0 0x%08x", cr);
66         __asm__ __volatile__ ("mov %%cr2, %0":"=r"(cr));
67         Warning(" CR2 0x%016llx", cr);
68         __asm__ __volatile__ ("mov %%cr3, %0":"=r"(cr));
69         Warning(" CR3 0x%016llx", cr);
70         __asm__ __volatile__ ("mov %%cr4, %0":"=r"(cr));
71         Warning(" CR4 0x%08x", cr);
72         
73         switch( Regs->IntNum )
74         {
75         case 6: // #UD
76                 Warning(" Offending bytes: %02x %02x %02x %02x",
77                         *(Uint8*)(Regs->RIP+0), *(Uint8*)(Regs->RIP+1),
78                         *(Uint8*)(Regs->RIP+2), *(Uint8*)(Regs->RIP+3)
79                         );
80                 break;
81         }
82         
83         __asm__ __volatile__ ("cli");
84         for(;;)
85                 __asm__ __volatile__ ("hlt");
86 }
87
88 /**
89  * \fn void Error_Backtrace(Uint eip, Uint ebp)
90  * \brief Unrolls the stack to trace execution
91  * \param eip   Current Instruction Pointer
92  * \param ebp   Current Base Pointer (Stack Frame)
93  */
94 void Error_Backtrace(Uint IP, Uint BP)
95 {
96          int    i = 0;
97         
98         //if(eip < 0xC0000000 && eip > 0x1000)
99         //{
100         //      LogF("Backtrace: User - 0x%x\n", eip);
101         //      return;
102         //}
103         
104         if( IP > USER_MAX && IP < MM_KERNEL_CODE
105          && (MM_MODULE_MIN > IP || IP > MM_MODULE_MAX)
106                 )
107         {
108                 LogF("Backtrace: Data Area - %p\n", IP);
109                 return;
110         }
111         
112         //str = Debug_GetSymbol(eip, &delta);
113         //if(str == NULL)
114                 LogF("Backtrace: %p", IP);
115         //else
116         //      LogF("Backtrace: %s+0x%x", str, delta);
117         if( !MM_GetPhysAddr(BP) )
118         {
119                 LogF("\nBacktrace: Invalid BP, stopping\n");
120                 return;
121         }
122         
123         
124         while( MM_GetPhysAddr(BP) && MM_GetPhysAddr(BP+8+7) && i < MAX_BACKTRACE )
125         {
126                 //str = Debug_GetSymbol(*(Uint*)(ebp+4), &delta);
127                 //if(str == NULL)
128                         LogF(" >> 0x%llx", ((Uint*)BP)[1]);
129                 //else
130                 //      LogF(" >> %s+0x%x", str, delta);
131                 BP = ((Uint*)BP)[0];
132                 i++;
133         }
134         LogF("\n");
135 }

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