mbr_asm/core/idt.c

69 lines
1.7 KiB
C
Raw Normal View History

#include "idt.h"
2018-06-30 01:00:47 +02:00
static struct idtEntry idt[IDT_NUM];
int idtSetup()
{
2018-06-30 01:00:47 +02:00
struct idtRegister idtr;
for (int i = 0; i < IDT_NUM; i++) {
struct idtEntry *idte = idt + i;
2018-06-30 01:00:47 +02:00
/* 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 */
2018-06-30 01:00:47 +02:00
/* Disabled it for now */
idte->zero = 0;
idte->offset_low = 0;
idte->offset_high = 0;
idte->dpl = 0;
idte->present = 0;
}
2018-06-30 01:00:47 +02:00
/*
* Setup the IDT register, see Intel x86 doc vol 3, section 5.8.
*/
2018-06-30 01:00:47 +02:00
/* Address of the IDT */
idtr.base_addr = (uint32_t)idt;
2018-06-30 01:00:47 +02:00
/* The limit is the maximum offset in bytes from the base address of
the IDT */
idtr.limit = sizeof(idt) - 1;
2018-06-30 01:00:47 +02:00
/* Commit the IDT into the CPU */
asm volatile("lidt %0\n" ::"m"(idtr) : "memory");
2018-06-30 01:00:47 +02:00
return 0;
}
2018-06-26 16:41:06 +02:00
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;
2018-06-30 01:00:47 +02:00
idte = idt + index;
2018-06-26 16:41:06 +02:00
if (addr != (unsigned int)NULL) {
idte->offset_low = addr & 0xffff;
idte->offset_high = (addr >> 16) & 0xffff;
2018-06-26 16:41:06 +02:00
idte->dpl = priviledge;
idte->present = 1;
2018-06-30 01:00:47 +02:00
} else {
idte->offset_low = 0;
idte->offset_high = 0;
idte->dpl = 0;
idte->present = 0;
2018-06-26 16:41:06 +02:00
}
return 0;
}