33#include <interrupt/idt.h>
44#include <interrupt/irq.h>
55
6+ /* ELF 呼び出しスナップショット(elf.c でセットされる) */
7+ extern volatile uint64_t elf_call_snapshot_func_addr ;
8+ extern volatile uint64_t elf_call_snapshot_rdi ;
9+ extern volatile uint64_t elf_call_snapshot_rsi ;
10+ extern volatile uint64_t elf_call_snapshot_rdx ;
11+ extern volatile uint64_t elf_call_snapshot_rsp ;
12+
613/* PIC ports */
714#define PIC1_COMMAND 0x20
815#define PIC1_DATA 0x21
@@ -122,15 +129,48 @@ extern void page_fault_handler(uint32_t vec);
122129extern void page_fault_handler_ex (uint32_t vec , uint32_t error_code ,
123130 uint32_t eip );
124131
125- /**
126- * @fn irq_exception_ex
127- * @brief 例外発生時の拡張ハンドラ
128- */
132+ static volatile int first_exception = 1 ;
133+ static uint64_t saved_rip = 0 ;
134+ static uint64_t saved_rsp = 0 ;
135+ static uint64_t saved_cs = 0 ;
136+ static uint32_t saved_vec = 0 ;
137+ /* ISR stub がセットする、PUSH_ALL 後の RSP を保存するデバッグ変数 */
138+ volatile uint64_t last_isr_stack = 0 ;
139+
129140/**
130141 * @fn irq_exception_ex
131142 * @brief 例外発生時の拡張ハンドラ
132143 */
133144void irq_exception_ex (uint32_t vec , uint32_t error_code ) {
145+ if (first_exception ) {
146+ first_exception = 0 ;
147+ saved_vec = vec ;
148+ uint64_t * stack_ptr = (uint64_t * )last_isr_stack ;
149+
150+ printk ("ISR stack snapshot (first 24 qwords at %p):\n" ,
151+ stack_ptr );
152+ for (int i = 0 ; i < 24 ; i ++ ) {
153+ printk (" stack[%02d]=0x%016lx\n" , i ,
154+ (unsigned long )stack_ptr [i ]);
155+ }
156+
157+ uint64_t maybe_rip = 0 , maybe_cs = 0 , maybe_rsp = 0 ;
158+ for (int idx = 17 ; idx <= 20 ; idx ++ ) {
159+ uint64_t val = stack_ptr [idx ];
160+ if (val != 0 ) {
161+ maybe_rip = val ;
162+ maybe_cs = (idx + 1 <= 23 ) ?
163+ stack_ptr [idx + 1 ] :
164+ 0 ;
165+ break ;
166+ }
167+ }
168+
169+ saved_rip = maybe_rip ;
170+ saved_cs = maybe_cs ;
171+ saved_rsp = 0 ; /* kernel-mode exception: SS/RSP not pushed */
172+ }
173+
134174 const char * exception_names [] = { "Divide by Zero" ,
135175 "Debug" ,
136176 "NMI" ,
@@ -153,44 +193,32 @@ void irq_exception_ex(uint32_t vec, uint32_t error_code) {
153193 "SIMD FP Exception" ,
154194 "Virtualization Exception" ,
155195 "Control Protection Exception" };
156- const char * name = (vec < 22 ) ? exception_names [vec ] :
157- "Unknown Exception" ;
196+ const char * name = (saved_vec < 22 ) ? exception_names [saved_vec ] :
197+ "Unknown Exception" ;
158198
159199 printk ("\n!!! CPU EXCEPTION !!!\n" );
160- printk ("Exception: %s (vector %u)\n" , name , (unsigned )vec );
200+ printk ("Exception: %s (vector %u)\n" , name , (unsigned )saved_vec );
161201 printk ("Error code: 0x%x\n" , (unsigned )error_code );
162202
163203 if (vec == 14 ) {
164204 // Page Fault - print CR2
165205 uint64_t fault_addr ;
166206 asm volatile ("mov %%cr2, %0" : "=r" (fault_addr ));
167207 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 );
179208 }
180209
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 ]);
192- }
193- }
210+ printk ("FIRST EXCEPTION INFO:\n" );
211+ printk (" RIP: 0x%lx\n" , saved_rip );
212+ printk (" CS: 0x%lx\n" , saved_cs );
213+ printk (" RSP: 0x%lx\n" , saved_rsp );
214+
215+ /* ELF 呼び出し直前のスナップショットが存在すれば表示する(デバッグ用) */
216+ printk ("ELF: call-snapshot: func=0x%lx rdi=0x%lx rsi=0x%lx rdx=0x%lx rsp=0x%lx\n" ,
217+ (unsigned long )elf_call_snapshot_func_addr ,
218+ (unsigned long )elf_call_snapshot_rdi ,
219+ (unsigned long )elf_call_snapshot_rsi ,
220+ (unsigned long )elf_call_snapshot_rdx ,
221+ (unsigned long )elf_call_snapshot_rsp );
194222
195223 while (1 ) {
196224 asm volatile ("hlt" );
0 commit comments