71 lines
1.7 KiB
C
71 lines
1.7 KiB
C
#include "idt.h"
|
|
#include "stddef.h"
|
|
|
|
static struct idtEntry idt[IDT_NUM];
|
|
|
|
int idtSetup()
|
|
{
|
|
struct idtRegister idtr;
|
|
|
|
for (int i = 0; i < IDT_NUM; i++) {
|
|
struct idtEntry *idte = idt + i;
|
|
|
|
/* Setup an empty IDTE interrupt gate, see figure 5-2 in Intel
|
|
x86 doc, vol 3 */
|
|
idte->seg_sel = BUILD_SEGMENT_SELECTOR(RING_0, 0, SEGMENT_IDX_CODE);
|
|
idte->reserved = 0;
|
|
idte->flags = 0;
|
|
idte->type = 0x6; /* Interrupt gate (110b) */
|
|
idte->op_size = 1; /* 32bits instructions */
|
|
|
|
/* Disabled it for now */
|
|
idte->zero = 0;
|
|
idte->offset_low = 0;
|
|
idte->offset_high = 0;
|
|
idte->dpl = 0;
|
|
idte->present = 0;
|
|
}
|
|
|
|
/*
|
|
* Setup the IDT register, see Intel x86 doc vol 3, section 5.8.
|
|
*/
|
|
|
|
/* Address of the IDT */
|
|
idtr.base_addr = (uint32_t)idt;
|
|
|
|
/* The limit is the maximum offset in bytes from the base address of
|
|
the IDT */
|
|
idtr.limit = sizeof(idt) - 1;
|
|
|
|
/* Commit the IDT into the CPU */
|
|
asm volatile("lidt %0\n" ::"m"(idtr) : "memory");
|
|
|
|
return 0;
|
|
}
|
|
|
|
int idt_set_handler(int index, unsigned int addr, int priviledge)
|
|
{
|
|
struct idtEntry *idte;
|
|
|
|
if (index < 0 || index >= IDT_NUM)
|
|
return -1;
|
|
if ((priviledge < 0) || priviledge > 3)
|
|
return -1;
|
|
|
|
idte = idt + index;
|
|
|
|
if (addr != (unsigned int)NULL) {
|
|
idte->offset_low = addr & 0xffff;
|
|
idte->offset_high = (addr >> 16) & 0xffff;
|
|
idte->dpl = priviledge;
|
|
idte->present = 1;
|
|
} else {
|
|
idte->offset_low = 0;
|
|
idte->offset_high = 0;
|
|
idte->dpl = 0;
|
|
idte->present = 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|