3adf8d56636c2692b156bf8d8f565de49da7a3fc
[tpg/acess2.git] / KernelLand / Kernel / arch / x86 / kpanic.c
1 /*
2  * Acess 2 Kernel
3  * - By John Hodge (thePowersGang)
4  * 
5  * kpanic.c
6  * - x86 Kernel Panic Handler
7  */
8
9 #include <acess.h>
10 #include <proc.h>
11
12 // === CONSTANTS ===
13 #define FB      ((Uint16 *)(KERNEL_BASE|0xB8000))
14 #define BGC     0x4F00  // White on Red
15 //#define BGC   0xC000  // Black on Bright Red
16 //#define BGC   0x1F00  // White on Blue (BSOD!)
17
18 // === IMPORTS ===
19 extern Uint32   GetEIP(void);
20 extern void     Error_Backtrace(Uint32 eip, Uint32 ebp);
21 #if USE_MP
22 extern void     MP_SendIPIVector(int CPU, Uint8 Vector);
23 extern int      giNumCPUs;
24 extern int      GetCPUNum(void);
25 #endif
26
27 // === PROTOTYPES ===
28 void    KernelPanic_SetMode(void);
29 void    KernelPanic_PutChar(char Ch);
30
31 // === CONSTANTS ===
32 const struct {
33         Uint16  IdxPort;
34         Uint16  DatPort;
35         Uint8   Index;
36         Uint8   Value;
37 }       caRegValues[] = {
38         //{0x3C0, 0x3C0, 0x10, 0x0C},   // Mode Control (Blink Enabled)
39         {0x3C0, 0x3C0, 0x10, 0x04},     // Mode Control (Blink Disabled)
40         {0x3C0, 0x3C0, 0x11, 0x00},     // Overscan Register
41         {0x3C0, 0x3C0, 0x12, 0x0F},     // Color Plane Enable
42         {0x3C0, 0x3C0, 0x13, 0x08},     // Horizontal Panning
43         {0x3C0, 0x3C0, 0x14, 0x00},     // Color Select
44         {0    , 0x3C2, 0   , 0x67},     // Miscellaneous Output Register
45         {0x3C4, 0x3C5, 0x01, 0x00},     // Clock Mode Register
46         {0x3C4, 0x3C5, 0x03, 0x00},     // Character select
47         {0x3C4, 0x3C5, 0x04, 0x07},     // Memory Mode Register
48         {0x3CE, 0x3CF, 0x05, 0x10},     // Mode Register
49         {0x3CE, 0x3CF, 0x06, 0x0E},     // Miscellaneous Register
50         {0x3D4, 0x3D5, 0x00, 0x5F},     // Horizontal Total
51         {0x3D4, 0x3D5, 0x01, 0x4F},     // Horizontal Display Enable End
52         {0x3D4, 0x3D5, 0x02, 0x50},     // Horizontal Blank Start
53         {0x3D4, 0x3D5, 0x03, 0x82},     // Horizontal Blank End
54         {0x3D4, 0x3D5, 0x04, 0x55},     // Horizontal Retrace Start
55         {0x3D4, 0x3D5, 0x05, 0x81},     // Horizontal Retrace End
56         {0x3D4, 0x3D5, 0x06, 0xBF},     // Vertical Total
57         {0x3D4, 0x3D5, 0x07, 0x1F},     // Overflow Register
58         {0x3D4, 0x3D5, 0x08, 0x00},     // Preset row scan
59         {0x3D4, 0x3D5, 0x09, 0x4F},     // Maximum Scan Line
60         {0x3D4, 0x3D5, 0x10, 0x9C},     // Vertical Retrace Start
61         {0x3D4, 0x3D5, 0x11, 0x8E},     // Vertical Retrace End
62         {0x3D4, 0x3D5, 0x12, 0x8F},     // Vertical Display Enable End
63         {0x3D4, 0x3D5, 0x13, 0x28},     // Logical Width
64         {0x3D4, 0x3D5, 0x14, 0x1F},     // Underline Location
65         {0x3D4, 0x3D5, 0x15, 0x96},     // Vertical Blank Start
66         {0x3D4, 0x3D5, 0x16, 0xB9},     // Vertical Blank End
67         {0x3D4, 0x3D5, 0x17, 0xA3}      // CRTC Mode Control
68 };
69 #define NUM_REGVALUES   (sizeof(caRegValues)/sizeof(caRegValues[0]))
70
71 // === GLOBALS ===
72  int    giKP_Pos = 0;
73
74 // === CODE ===
75 /**
76  * \brief Sets the screen mode for a kernel panic
77  */
78 void KernelPanic_SetMode(void)
79 {
80          int    i;
81
82         __asm__ __volatile__ ("cli");   // Stop the processor!
83         
84         // This function is called by Panic(), but MM_PageFault and the
85         // CPU exception handers also call it, so let's not clear the screen
86         // twice
87         if( giKP_Pos )  return ;
88         
89         // Restore VGA 0xB8000 text mode
90         #if 0
91         for( i = 0; i < NUM_REGVALUES; i++ )
92         {
93                 // Reset Flip-Flop
94                 if( caRegValues[i].IdxPort == 0x3C0 )   inb(0x3DA);
95                 
96                 if( caRegValues[i].IdxPort )
97                         outb(caRegValues[i].IdxPort, caRegValues[i].Index);
98                 outb(caRegValues[i].DatPort, caRegValues[i].Value);
99         }
100         
101         inb(0x3DA);
102         outb(0x3C0, 0x20);
103         #endif
104
105         #if USE_MP
106         // Send halt to all processors
107         for( i = 0; i < giNumCPUs; i ++ )
108         {
109                 if(i == GetCPUNum())    continue ;
110                 FB[i] = BGC|('A'+i);
111                 MP_SendIPIVector(i, 0xED);
112         }
113         #endif
114         
115         #if ENABLE_KPANIC_MODE
116         // Clear Screen
117         for( i = 0; i < 80*25; i++ )
118         {
119                 FB[i] = BGC;
120         }
121         
122         {
123                 Uint32  eip = GetEIP();
124                 Uint32  ebp;
125                 __asm__ __volatile__ ("mov %%ebp, %0" : "=r" (ebp));
126                 Error_Backtrace(eip, ebp);
127         }
128         #endif
129 }
130
131 void KernelPanic_PutChar(char Ch)
132 {
133         #if ENABLE_KPANIC_MODE
134         if( giKP_Pos > 80*25 )  return ;
135         switch(Ch)
136         {
137         case '\t':
138                 do {
139                         FB[giKP_Pos] &= 0xFF00;
140                         FB[giKP_Pos++] |= ' ';
141                 } while(giKP_Pos & 7);
142                 break;
143         
144         case '\n':
145                 giKP_Pos += 80;
146         case '\r':
147                 giKP_Pos -= giKP_Pos % 80;
148                 break;
149         
150         default:
151                 if(' ' <= Ch && Ch < 0x7F)
152                 {
153                         FB[giKP_Pos] &= 0xFF00;
154                         FB[giKP_Pos] |= Ch;
155                 }
156                 giKP_Pos ++;
157                 break;
158         }
159         #if 0
160         {
161                 char    s[2] = {Ch,0};
162                 VT_int_PutString(gpVT_CurTerm, s);
163         }
164         #endif
165         #endif // ENABLE_KPANIC_MODE
166 }

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