IDT

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
JFF

IDT

Post by JFF »

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....
GT

RE:IDT

Post by GT »

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));
}
JFF

RE:IDT

Post by JFF »

!!! Everything works now !... Bochs doesn't crash... I'll test with vmware to be sure if everything is OK....

Thanks ;) i should have check that before...


JFF
Post Reply