version 1.1.1.1, 2008/06/03 10:38:45 |
version 1.1.1.1.2.1, 2008/08/13 17:12:30 |
|
|
trap_handler(struct cpu_regs *regs) |
trap_handler(struct cpu_regs *regs) |
{ |
{ |
u_long trap_no = regs->trap_no; |
u_long trap_no = regs->trap_no; |
|
#ifdef DEBUG |
|
task_t self = cur_task(); |
|
#endif |
|
|
if (trap_no > 18) |
if (trap_no > 18) |
panic("Unknown trap"); |
panic("Unknown trap"); |
|
|
* by known routine to access user space. |
* by known routine to access user space. |
*/ |
*/ |
if (trap_no == 14 && regs->cs == KERNEL_CS && |
if (trap_no == 14 && regs->cs == KERNEL_CS && |
(regs->eip == (u_long)known_fault1 || |
(regs->eip == (uint32_t)known_fault1 || |
regs->eip == (u_long)known_fault2 || |
regs->eip == (uint32_t)known_fault2 || |
regs->eip == (u_long)known_fault3)) { |
regs->eip == (uint32_t)known_fault3)) { |
printk("\n*** Detect Fault! task:%s (id:%x) ***\n", |
DPRINTF(("\n*** Detect Fault! address=%x task=%s ***\n", |
cur_task()->name ? cur_task()->name : "no name", |
get_cr2(), |
cur_task()); |
self->name != NULL ? self->name : "no name", self)); |
|
regs->eip = (uint32_t)umem_fault; |
regs->eip = (u_long)umem_fault; |
|
return; |
return; |
} |
} |
#ifdef DEBUG |
#ifdef DEBUG |
printk("============================\n"); |
printf("============================\n"); |
printk("Trap %x: %s\n", trap_no, trap_name[trap_no]); |
printf("Trap %x: %s\n", (u_int)trap_no, trap_name[trap_no]); |
if (trap_no == 14) |
if (trap_no == 14) |
printk(" Fault address=%x\n", get_cr2()); |
printf(" Fault address=%x\n", get_cr2()); |
printk("============================\n"); |
printf("============================\n"); |
trap_dump(regs); |
trap_dump(regs); |
if (regs->cs == KERNEL_CS) { |
if (regs->cs == KERNEL_CS) { |
interrupt_mask(0); |
interrupt_mask(0); |
sti(); |
interrupt_enable(); |
for (;;) ; |
for (;;) ; |
} |
} |
#endif |
#endif |
|
|
static void |
static void |
trap_dump(struct cpu_regs *r) |
trap_dump(struct cpu_regs *r) |
{ |
{ |
u_long ss, esp, *fp; |
task_t self = cur_task(); |
|
uint32_t ss, esp, *fp; |
u_int i; |
u_int i; |
|
|
if (r->cs & 3) { |
if (r->cs & 3) { |
|
|
esp = r->esp; |
esp = r->esp; |
} else { |
} else { |
ss = r->ds; |
ss = r->ds; |
esp = (u_long)r; |
esp = (uint32_t)r; |
} |
} |
printk("Trap frame %x error %x\n", r, r->err_code); |
printf("Trap frame %x error %x\n", r, r->err_code); |
printk(" eax %08x ebx %08x ecx %08x edx %08x esi %08x edi %08x\n", |
printf(" eax %08x ebx %08x ecx %08x edx %08x esi %08x edi %08x\n", |
r->eax, r->ebx, r->ecx, r->edx, r->esi, r->edi); |
r->eax, r->ebx, r->ecx, r->edx, r->esi, r->edi); |
printk(" eip %08x esp %08x ebp %08x eflags %08x\n", |
printf(" eip %08x esp %08x ebp %08x eflags %08x\n", |
r->eip, esp, r->ebp, r->eflags); |
r->eip, esp, r->ebp, r->eflags); |
printk(" cs %08x ss %08x ds %08x es %08x esp0 %08x\n", |
printf(" cs %08x ss %08x ds %08x es %08x esp0 %08x\n", |
r->cs, ss, r->ds, r->es, tss_get()); |
r->cs, ss, r->ds, r->es, tss_get()); |
|
|
if (irq_level > 0) |
if (irq_level > 0) |
printk(" >> trap in isr (irq_level=%d)\n", irq_level); |
printf(" >> trap in isr (irq_level=%d)\n", irq_level); |
printk(" >> interrupt is %s\n", |
printf(" >> interrupt is %s\n", |
(get_eflags() & EFL_IF) ? "enabled" : "disabled"); |
(get_eflags() & EFL_IF) ? "enabled" : "disabled"); |
|
|
if (r->cs == KERNEL_CS) |
if (r->cs == KERNEL_CS) |
printk(" >> Oops! it's kernel mode now!!!\n"); |
printf(" >> Oops! it's kernel mode now!!!\n"); |
else |
printf(" >> task=%s (id:%x)\n", |
printk(" >> task:%s (id:%x)\n", |
self->name != NULL ? self->name : "no name", self); |
cur_task()->name ? cur_task()->name : "no name", |
|
cur_task()); |
|
|
|
if (r->cs == KERNEL_CS) { |
if (r->cs == KERNEL_CS) { |
printk("Stack trace:\n"); |
printf("Stack trace:\n"); |
fp = (u_long *)r->ebp; |
fp = (uint32_t *)r->ebp; |
for (i = 0; i < 8; i++) { |
for (i = 0; i < 8; i++) { |
if (fp == 0) |
if (fp == 0) |
break; |
break; |
fp = (u_long *)(*fp); /* XXX: may cause fault */ |
fp = (uint32_t *)(*fp); /* XXX: may cause fault */ |
if (!(*(fp + 1) && *fp)) |
if (!(*(fp + 1) && *fp)) |
break; |
break; |
printk(" %08x\n", *(fp + 1)); |
printf(" %08x\n", *(fp + 1)); |
} |
} |
} |
} |
} |
} |