I can't find what's not working in my code.... i'm stuck to this for almost a week now.
void idt_init()
{
dword IDTR[2];
kprintf(" ----> Initializing interrupts\n");
idt = (idt_t*)IDT;
memset((void*)idt, 0, NIDT * sizeof(idt_t));
// Reprogram the PIC
kprintf(" ----> Reprogram the PICS\n");
remap_pics(0x20, 0x28);
kprintf(" ----> Load the IDTR\n");
// end - start - 1
IDTR[0] = (NIDT * sizeof(idt_t) - 1) << 16;
IDTR[1] = (dword)idt;
kprintf("[0]=%x [1]=%x\n", IDTR[0], IDTR[1]);
// LIDT : update the IDTR
kprintf(" ----> Updating IDTR\n");
__asm__ __volatile__ ("lidt (%0) " : : "r" (((byte *)IDTR) + 2));
}
__inline__ void set_gate (int vect, word settings, void* addr, word sel)
{
unsigned long offset = (unsigned long)addr;
// Register an interrupt handler
if (vect < 0 || vect >= NIDT)
panic ("Invalid vector");
// Set the actual values of interrupt
idt[vect].offset_l = offset & 0xFFFF;
idt[vect].offset_h = offset >> 16;
idt[vect].selector = (sel * sizeof(gdt_t)) << 2;
idt[vect].settings = settings;
}
__inline__ void set_trap_gate (int vect, void* addr, word dpl)
{
switch (dpl)
{
case 0 :
set_gate (vect, IDT_PRESENT | IDT_TRAP | IDT_32BIT | IDT_DPL0,
addr, GDT_KCODE_SEL);
break;
case 1 :
set_gate (vect, IDT_PRESENT | IDT_TRAP | IDT_32BIT | IDT_DPL1,
addr, GDT_KCODE_SEL);
break;
case 2 :
set_gate (vect, IDT_PRESENT | IDT_TRAP | IDT_32BIT | IDT_DPL2,
addr, GDT_KCODE_SEL);
break;
case 3 :
set_gate (vect, IDT_PRESENT | IDT_TRAP | IDT_32BIT | IDT_DPL3,
addr, GDT_KCODE_SEL);
break;
}
}
void exceptions(dword nb)
{
ckprintf(">>Excepion Occured : \n", FRONT_BWHITE | BACK_RED);
kprintf("%s <<", except[nb]);
disable();
halt();
}
void set_exceptions()
{
set_trap_gate(0, DivideError, 0);
[...]
}
my idt struct looks like this :
typedef struct
{
word offset_l;
word selector;
word settings;
word offset_h;
} idt_t;
my #define are :
#define IDT 0x12000
#define NIDT 256
#define IDT_DPL0 0x0000
#define IDT_DPL1 0x2000
#define IDT_DPL2 0x4000
#define IDT_DPL3 0x6000
#define IDT_PRESENT 0x8000
#define IDT_TRAP 0x0700
#define IDT_INT 0x0600
#define IDT_TASK 0x0500
#define IDT_32BIT 0x0800
interrupt handlers look all like this :
/* exceptions.s */
DivideError_reentry:
iret
DivideError:
push %ds
push %es
push %fs
push %gs
pusha
pushl $0x0
call exceptions
popl %eax
popa
pop %gs
pop %fs
pop %es
pop %ds
jmp DivideError_reentry
Except is an array of msg_t (char [30]) with the exception message to be printed.
I can also say that vmware seems to execute everything correctly until some exception occur (only used 'asm("int $0");' to test it) and then reboot. Bochs seems to crash on the kprintf before the lidt instruction....
IDT
RE:IDT
Possibly that LIDT instruction is messed up, if that's where Bochs is crashing? Not sure, but I know this one works, maybe try it instead and see if it helps:
static inline void lidt(void *base, UInt16 limit)
{
struct
{
UInt16 limit __attribute__ ((packed));
UInt32 base __attribute__ ((packed));
} pack = {limit, (UInt32)base};
__asm__ __volatile__("lidt %0" : : "m" (pack));
}
static inline void lidt(void *base, UInt16 limit)
{
struct
{
UInt16 limit __attribute__ ((packed));
UInt32 base __attribute__ ((packed));
} pack = {limit, (UInt32)base};
__asm__ __volatile__("lidt %0" : : "m" (pack));
}