@@ -122,31 +122,79 @@ extern void page_fault_handler(uint32_t vec);
122122extern void page_fault_handler_ex (uint32_t vec , uint32_t error_code ,
123123 uint32_t eip );
124124
125- void irq_exception_c (uint32_t vec ) {
126- if (vec == 14 ) {
127- page_fault_handler (vec );
128- } else {
129- /* other exceptions: just spin */
130- printk ("exception vec=%u\n" , (unsigned )vec );
131- while (1 ) {
132- }
133- }
134- }
135-
125+ /**
126+ * @fn irq_exception_ex
127+ * @brief 例外発生時の拡張ハンドラ
128+ */
136129/**
137130 * @fn irq_exception_ex
138131 * @brief 例外発生時の拡張ハンドラ
139132 */
140133void irq_exception_ex (uint32_t vec , uint32_t error_code ) {
134+ const char * exception_names [] = { "Divide by Zero" ,
135+ "Debug" ,
136+ "NMI" ,
137+ "Breakpoint" ,
138+ "Overflow" ,
139+ "Bound Range Exceeded" ,
140+ "Invalid Opcode" ,
141+ "Device Not Available" ,
142+ "Double Fault" ,
143+ "Coprocessor Segment Overrun" ,
144+ "Invalid TSS" ,
145+ "Segment Not Present" ,
146+ "Stack-Segment Fault" ,
147+ "General Protection Fault" ,
148+ "Page Fault" ,
149+ "Reserved" ,
150+ "x87 FPU Error" ,
151+ "Alignment Check" ,
152+ "Machine Check" ,
153+ "SIMD FP Exception" ,
154+ "Virtualization Exception" ,
155+ "Control Protection Exception" };
156+ const char * name = (vec < 22 ) ? exception_names [vec ] :
157+ "Unknown Exception" ;
158+
159+ printk ("\n!!! CPU EXCEPTION !!!\n" );
160+ printk ("Exception: %s (vector %u)\n" , name , (unsigned )vec );
161+ printk ("Error code: 0x%x\n" , (unsigned )error_code );
162+
141163 if (vec == 14 ) {
142- // C言語からEIPを正確に取得するのは難しいため、ここでは0を渡す
143- page_fault_handler_ex (vec , error_code , 0 );
144- } else {
145- printk ("exception ex vec=%u err=0x%x\n" , (unsigned )vec ,
146- (unsigned )error_code );
147- while (1 ) {
164+ // Page Fault - print CR2
165+ uint64_t fault_addr ;
166+ asm volatile ("mov %%cr2, %0" : "=r" (fault_addr ));
167+ printk ("Page Fault at address: 0x%lx\n" , fault_addr );
168+ printk ("Error code bits: P=%d W=%d U=%d R=%d I=%d\n" ,
169+ error_code & 1 , (error_code >> 1 ) & 1 ,
170+ (error_code >> 2 ) & 1 , (error_code >> 3 ) & 1 ,
171+ (error_code >> 4 ) & 1 );
172+ } else if (vec == 13 ) {
173+ // GPF
174+ printk ("GPF Error code breakdown:\n" );
175+ printk (" External: %d\n" , (error_code >> 0 ) & 1 );
176+ printk (" IDT: %d\n" , (error_code >> 1 ) & 1 );
177+ printk (" TI: %d\n" , (error_code >> 2 ) & 1 );
178+ printk (" Selector Index: 0x%x\n" , (error_code >> 3 ) & 0x1FFF );
179+ }
180+
181+ uint64_t rsp , cr3 ;
182+ asm volatile ("mov %%rsp, %0" : "=r" (rsp ));
183+ asm volatile ("mov %%cr3, %0" : "=r" (cr3 ));
184+ printk ("RSP=0x%lx CR3=0x%lx\n" , rsp , cr3 );
185+
186+ // スタック上のiretqフレームを表示(可能であれば)
187+ if (vec == 6 ) { // Invalid Opcode
188+ printk ("Attempting to read iretq frame from stack:\n" );
189+ uint64_t * stack_ptr = (uint64_t * )rsp ;
190+ for (int i = 0 ; i < 8 ; i ++ ) {
191+ printk (" [RSP+%d] = 0x%016lx\n" , i * 8 , stack_ptr [i ]);
148192 }
149193 }
194+
195+ while (1 ) {
196+ asm volatile ("hlt" );
197+ }
150198}
151199
152200/**
@@ -156,6 +204,40 @@ void irq_exception_ex(uint32_t vec, uint32_t error_code) {
156204void idt_init (void ) {
157205 pic_remap ();
158206
207+ /* CPU例外ハンドラ (0-31) */
208+ extern void isr0 (void );
209+ extern void isr1 (void );
210+ extern void isr2 (void );
211+ extern void isr3 (void );
212+ extern void isr4 (void );
213+ extern void isr5 (void );
214+ extern void isr6 (void );
215+ extern void isr7 (void );
216+ extern void isr8 (void );
217+ extern void isr9 (void );
218+ extern void isr10 (void );
219+ extern void isr11 (void );
220+ extern void isr12 (void );
221+ extern void isr13 (void );
222+ extern void isr14 (void );
223+ extern void isr15 (void );
224+ extern void isr16 (void );
225+ extern void isr17 (void );
226+ extern void isr18 (void );
227+ extern void isr19 (void );
228+ extern void isr20 (void );
229+ extern void isr21 (void );
230+ extern void isr22 (void );
231+ extern void isr23 (void );
232+ extern void isr24 (void );
233+ extern void isr25 (void );
234+ extern void isr26 (void );
235+ extern void isr27 (void );
236+ extern void isr28 (void );
237+ extern void isr29 (void );
238+ extern void isr30 (void );
239+ extern void isr31 (void );
240+
159241 /* 明示的に各isrシンボルをextern宣言し、それをIDTに登録する(脳筋だぜぇ〜www */
160242 extern void isr32 (void );
161243 extern void isr33 (void );
@@ -177,7 +259,41 @@ void idt_init(void) {
177259
178260 extern void isr128 (void );
179261
262+ /* CPU例外を登録 */
263+ idt_set_gate (0 , (uint64_t )isr0 );
264+ idt_set_gate (1 , (uint64_t )isr1 );
265+ idt_set_gate (2 , (uint64_t )isr2 );
266+ idt_set_gate (3 , (uint64_t )isr3 );
267+ idt_set_gate (4 , (uint64_t )isr4 );
268+ idt_set_gate (5 , (uint64_t )isr5 );
269+ idt_set_gate (6 , (uint64_t )isr6 );
270+ idt_set_gate (7 , (uint64_t )isr7 );
271+ idt_set_gate (8 , (uint64_t )isr8 );
272+ idt_set_gate (9 , (uint64_t )isr9 );
273+ idt_set_gate (10 , (uint64_t )isr10 );
274+ idt_set_gate (11 , (uint64_t )isr11 );
275+ idt_set_gate (12 , (uint64_t )isr12 );
276+ idt_set_gate (13 , (uint64_t )isr13 );
180277 idt_set_gate (14 , (uint64_t )isr14 ); /* page fault */
278+ idt_set_gate (15 , (uint64_t )isr15 );
279+ idt_set_gate (16 , (uint64_t )isr16 );
280+ idt_set_gate (17 , (uint64_t )isr17 );
281+ idt_set_gate (18 , (uint64_t )isr18 );
282+ idt_set_gate (19 , (uint64_t )isr19 );
283+ idt_set_gate (20 , (uint64_t )isr20 );
284+ idt_set_gate (21 , (uint64_t )isr21 );
285+ idt_set_gate (22 , (uint64_t )isr22 );
286+ idt_set_gate (23 , (uint64_t )isr23 );
287+ idt_set_gate (24 , (uint64_t )isr24 );
288+ idt_set_gate (25 , (uint64_t )isr25 );
289+ idt_set_gate (26 , (uint64_t )isr26 );
290+ idt_set_gate (27 , (uint64_t )isr27 );
291+ idt_set_gate (28 , (uint64_t )isr28 );
292+ idt_set_gate (29 , (uint64_t )isr29 );
293+ idt_set_gate (30 , (uint64_t )isr30 );
294+ idt_set_gate (31 , (uint64_t )isr31 );
295+
296+ /* IRQハンドラ */
181297 idt_set_gate (32 , (uint64_t )isr32 );
182298 idt_set_gate (33 , (uint64_t )isr33 );
183299 idt_set_gate (34 , (uint64_t )isr34 );
0 commit comments