no coprocessor exception (i386) invoked dunno why
Posted: Thu Dec 29, 2005 6:00 pm
Hi,
I'm seeing some strange behaviour from a very simple software task switcher I'm trying to implement. Any ideas would be greatly appreciated.
My switch ISR is int 18. I'm using bochs to do my testing.
In a nutshell, the problem appears to be, at the end of the task switch ISR, (when starting a new task), the new task code seems to get executed, but immediately (??) invokes interrupt #7 (no coprocessor I think). Here's stuff to substantiate my claim:
Task switch ISR:
000100a4 <_TrapISR>:
100a4: 50 push %eax
100a5: 53 push %ebx
100a6: 51 push %ecx
100a7: 52 push %edx
100a8: 56 push %esi
100a9: 57 push %edi
100aa: 55 push %ebp
100ab: a1 ec 07 01 00 mov 0x107ec,%eax
100b0: 89 20 mov %esp,(%eax)
100b2: a1 e4 07 01 00 mov 0x107e4,%eax
100b7: 8b 20 mov (%eax),%esp
100b9: 5d pop %ebp
100ba: 5f pop %edi
100bb: 5e pop %esi
100bc: 5a pop %edx
100bd: 59 pop %ecx
100be: 5b pop %ebx
100bf: 58 pop %eax
100c0: cf iret
The following ISR gets invoked after _TrapISR completes.
000100c5 <_XXXISR>:
100c5: 58 pop %eax
100c6: 5b pop %ebx
100c7: 59 pop %ecx
100c8: 5a pop %edx
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ I added these pops to work out how I get here.
100c9: eb fe jmp 100c9 <_XXXISR+0x4>
...
The output from Bochs
EAX has return address,
EBX has CS
ECX has flags
000100c9-p[XGUI ] >>PANIC<< POWER button turned off.
000100c9-i[SYS ] Last time is 1135900224
000100c9-i[XGUI ] Exit.
000100c9-i[CPU0 ] protected mode
000100c9-i[CPU0 ] CS.d_b = 32 bit
000100c9-i[CPU0 ] SS.d_b = 32 bit
000100c9-i[CPU0 ] | EAX=000100e0 EBX=00000010 ECX=00007202 EDX=00000000
000100c9-i[CPU0 ] | ESP=000106cc EBP=33333333 ESI=11111111 EDI=22222222
000100c9-i[CPU0 ] | IOPL=3 NV UP DI PL NZ NA PO NC
000100c9-i[CPU0 ] | SEG selector base limit G D
000100c9-i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
000100c9-i[CPU0 ] | CS:0010( 0002| 0| 0) 00000000 000fffff 1 1
000100c9-i[CPU0 ] | DS:0018( 0003| 0| 0) 00000000 000fffff 1 1
000100c9-i[CPU0 ] | SS:0020( 0004| 0| 0) 00000000 000fffff 1 1
000100c9-i[CPU0 ] | ES:0020( 0004| 0| 0) 00000000 000fffff 1 1
000100c9-i[CPU0 ] | FS:0020( 0004| 0| 0) 00000000 000fffff 1 1
000100c9-i[CPU0 ] | GS:0020( 0004| 0| 0) 00000000 000fffff 1 1
000100c9-i[CPU0 ] | EIP=000100c9 (000100c9)
000100c9-i[CPU0 ] | CR0=0x00000011 CR1=0 CR2=0x00000000
000100c9-i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
000100c9-i[ ] restoring default signal behavior
The return address (in EAX) has the following code:
000100e0 <idle_main>:
100e0: eb fe jmp 100e0 <idle_main>
100e2: 89 f6 mov %esi,%esi
What could possibly have caused that exception?
I think I have setup the IDT properly, but incase it provides any help, here it is:
#define ADDRESS_HI(a) a##hi
#define ADDRESS_LO(a) a##lo
#define ISR_DESC(offset) \
.word ADDRESS_LO(offset) ; \
.word 16; /* XXX bootldr sets*/ \
.byte 0; \
.byte 0x8e; \
.word ADDRESS_HI(offset)
idt: .word (idt_end-idt)
.long (idt)
.word 0
#define DEFINE_ISR(x) ISR_DESC(x)
#include "isr.h"
idt_end:
// isr.h
DEFINE_ISR(_UnhandledISR) // 0 Division by 0
DEFINE_ISR(_UnhandledISR) // 1 Single step
DEFINE_ISR(_UnhandledISR) // 2 NMI
DEFINE_ISR(_UnhandledISR) // 3 Breakpoint
DEFINE_ISR(_UnhandledISR) // 4 Overflow
DEFINE_ISR(_UnhandledISR) // 5 Bound range
DEFINE_ISR(_UnhandledISR) // 6 Invalid Opcode
DEFINE_ISR(_XXXISR) // 7 No coprocessor
DEFINE_ISR(_UnhandledISR) // 8 Double fault
DEFINE_ISR(_UnhandledISR) // 9 Co-pro seg overrun
DEFINE_ISR(_UnhandledISR) // 10 Invalid TSS
DEFINE_ISR(_UnhandledISR) // 11 Seg not presemt
DEFINE_ISR(_UnhandledISR) // 12 Stack exception
DEFINE_ISR(_GpfISR) // 13 Gen Protection Fault
DEFINE_ISR(_UnhandledISR) // 14 Page flt
//DEFINE_ISR(_UnhandledISR) // 15 missed on purpose
DEFINE_ISR(_UnhandledISR) // 16 Co-proc error
DEFINE_ISR(_UnhandledISR) // 17 Arrangement error
DEFINE_ISR(_TrapISR) // 18
Once again any help will be greatly appreciated.
I'm seeing some strange behaviour from a very simple software task switcher I'm trying to implement. Any ideas would be greatly appreciated.
My switch ISR is int 18. I'm using bochs to do my testing.
In a nutshell, the problem appears to be, at the end of the task switch ISR, (when starting a new task), the new task code seems to get executed, but immediately (??) invokes interrupt #7 (no coprocessor I think). Here's stuff to substantiate my claim:
Task switch ISR:
000100a4 <_TrapISR>:
100a4: 50 push %eax
100a5: 53 push %ebx
100a6: 51 push %ecx
100a7: 52 push %edx
100a8: 56 push %esi
100a9: 57 push %edi
100aa: 55 push %ebp
100ab: a1 ec 07 01 00 mov 0x107ec,%eax
100b0: 89 20 mov %esp,(%eax)
100b2: a1 e4 07 01 00 mov 0x107e4,%eax
100b7: 8b 20 mov (%eax),%esp
100b9: 5d pop %ebp
100ba: 5f pop %edi
100bb: 5e pop %esi
100bc: 5a pop %edx
100bd: 59 pop %ecx
100be: 5b pop %ebx
100bf: 58 pop %eax
100c0: cf iret
The following ISR gets invoked after _TrapISR completes.
000100c5 <_XXXISR>:
100c5: 58 pop %eax
100c6: 5b pop %ebx
100c7: 59 pop %ecx
100c8: 5a pop %edx
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ I added these pops to work out how I get here.
100c9: eb fe jmp 100c9 <_XXXISR+0x4>
...
The output from Bochs
EAX has return address,
EBX has CS
ECX has flags
000100c9-p[XGUI ] >>PANIC<< POWER button turned off.
000100c9-i[SYS ] Last time is 1135900224
000100c9-i[XGUI ] Exit.
000100c9-i[CPU0 ] protected mode
000100c9-i[CPU0 ] CS.d_b = 32 bit
000100c9-i[CPU0 ] SS.d_b = 32 bit
000100c9-i[CPU0 ] | EAX=000100e0 EBX=00000010 ECX=00007202 EDX=00000000
000100c9-i[CPU0 ] | ESP=000106cc EBP=33333333 ESI=11111111 EDI=22222222
000100c9-i[CPU0 ] | IOPL=3 NV UP DI PL NZ NA PO NC
000100c9-i[CPU0 ] | SEG selector base limit G D
000100c9-i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
000100c9-i[CPU0 ] | CS:0010( 0002| 0| 0) 00000000 000fffff 1 1
000100c9-i[CPU0 ] | DS:0018( 0003| 0| 0) 00000000 000fffff 1 1
000100c9-i[CPU0 ] | SS:0020( 0004| 0| 0) 00000000 000fffff 1 1
000100c9-i[CPU0 ] | ES:0020( 0004| 0| 0) 00000000 000fffff 1 1
000100c9-i[CPU0 ] | FS:0020( 0004| 0| 0) 00000000 000fffff 1 1
000100c9-i[CPU0 ] | GS:0020( 0004| 0| 0) 00000000 000fffff 1 1
000100c9-i[CPU0 ] | EIP=000100c9 (000100c9)
000100c9-i[CPU0 ] | CR0=0x00000011 CR1=0 CR2=0x00000000
000100c9-i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
000100c9-i[ ] restoring default signal behavior
The return address (in EAX) has the following code:
000100e0 <idle_main>:
100e0: eb fe jmp 100e0 <idle_main>
100e2: 89 f6 mov %esi,%esi
What could possibly have caused that exception?
I think I have setup the IDT properly, but incase it provides any help, here it is:
#define ADDRESS_HI(a) a##hi
#define ADDRESS_LO(a) a##lo
#define ISR_DESC(offset) \
.word ADDRESS_LO(offset) ; \
.word 16; /* XXX bootldr sets*/ \
.byte 0; \
.byte 0x8e; \
.word ADDRESS_HI(offset)
idt: .word (idt_end-idt)
.long (idt)
.word 0
#define DEFINE_ISR(x) ISR_DESC(x)
#include "isr.h"
idt_end:
// isr.h
DEFINE_ISR(_UnhandledISR) // 0 Division by 0
DEFINE_ISR(_UnhandledISR) // 1 Single step
DEFINE_ISR(_UnhandledISR) // 2 NMI
DEFINE_ISR(_UnhandledISR) // 3 Breakpoint
DEFINE_ISR(_UnhandledISR) // 4 Overflow
DEFINE_ISR(_UnhandledISR) // 5 Bound range
DEFINE_ISR(_UnhandledISR) // 6 Invalid Opcode
DEFINE_ISR(_XXXISR) // 7 No coprocessor
DEFINE_ISR(_UnhandledISR) // 8 Double fault
DEFINE_ISR(_UnhandledISR) // 9 Co-pro seg overrun
DEFINE_ISR(_UnhandledISR) // 10 Invalid TSS
DEFINE_ISR(_UnhandledISR) // 11 Seg not presemt
DEFINE_ISR(_UnhandledISR) // 12 Stack exception
DEFINE_ISR(_GpfISR) // 13 Gen Protection Fault
DEFINE_ISR(_UnhandledISR) // 14 Page flt
//DEFINE_ISR(_UnhandledISR) // 15 missed on purpose
DEFINE_ISR(_UnhandledISR) // 16 Co-proc error
DEFINE_ISR(_UnhandledISR) // 17 Arrangement error
DEFINE_ISR(_TrapISR) // 18
Once again any help will be greatly appreciated.