/* * ---------- header ---------------------------------------------------------- * * project kaneton * * license kaneton * * file /home/mycure/kane...hine/architecture/ia32/educational/idt.c * * created renaud voltz [sun feb 12 02:02:19 2006] * updated julien quintard [mon apr 11 13:44:56 2011] */ /* * ---------- information ----------------------------------------------------- * * this file provides functionalities for managing the IDT - Interrupt * Descriptor Table. * * for more information regarding the handlers triggered through the IDT, * please have a look at the handler.c file. */ /* * ---------- includes -------------------------------------------------------- */ #include /* * ---------- globals --------------------------------------------------------- */ at_idte _idt[ARCHITECTURE_IDT_SIZE]; /* * ---------- functions ------------------------------------------------------- */ /* FIXME[complete if necessary] */ t_error architecture_idt_dump(void) { t_uint16 i; module_call(console, message, '#', "IDT: table(0x%08x) size(%u)\n", _idt, ARCHITECTURE_IDT_SIZE); for (i = 0; i < ARCHITECTURE_IDT_SIZE; i++) { t_privilege privilege; t_paddr offset; char* type; char flag; if (!(_idt[i] & ARCHITECTURE_IDTE_PRESENT)) continue; offset = ARCHITECTURE_IDTE_OFFSET_GET(_idt[i]); privilege = ARCHITECTURE_IDTE_DPL_GET(_idt[i]); if (_idt[i] & ARCHITECTURE_IDTE_32BIT) flag = 's'; else flag = '.'; if ((_idt[i] & ARCHITECTURE_IDTE_TRAP) == ARCHITECTURE_IDTE_TRAP) type = "trap"; else if ((_idt[i] & ARCHITECTURE_IDTE_INTERRUPT) == ARCHITECTURE_IDTE_INTERRUPT) type = "interrupt"; else type = "task"; module_call(console, message, '#', " %u: offset(0x%08x) type(%s) " "privilege(%u) flags(%c)\n", i, offset, type, privilege, flag); } MACHINE_LEAVE(); } t_error architecture_idt_import(void) { as_idtr lidt; lidt.limit = ARCHITECTURE_IDT_SIZE * sizeof (at_idte); lidt.base = (t_paddr) &_idt; ARCHITECTURE_LIDT(lidt); platform_pic_initialize(); MACHINE_LEAVE(); } t_error architecture_idt_enable(void) { ARCHITECTURE_STI(); MACHINE_LEAVE(); } t_error architecture_idt_disable(void) { ARCHITECTURE_CLI(); MACHINE_LEAVE(); } t_error architecture_idt_insert(t_uint16 index, t_paddr offset, t_flags flags) { if (index >= ARCHITECTURE_IDT_SIZE) MACHINE_ESCAPE("out-of-bound insertion"); if (_idt[index] & ARCHITECTURE_IDTE_PRESENT) MACHINE_ESCAPE("the IDT entry to update is already in use"); t_uint16 sselector; architecture_gdt_selector(1, ARCHITECTURE_PRIVILEGE_RING0, &sselector); _idt[index] = ARCHITECTURE_IDTE_INTERRUPT | ARCHITECTURE_IDTE_PRESENT | ARCHITECTURE_IDTE_OFFSET_SET(offset) | ARCHITECTURE_IDTE_SEGMENT_SET(sselector) | ARCHITECTURE_IDTE_32BIT | flags; MACHINE_LEAVE(); } t_error architecture_idt_reserve(t_paddr base, t_flags flags, t_uint16* index) { t_uint16 i; if (index == NULL) MACHINE_ESCAPE("the 'index' argument is null"); *index = 0; for (i = 0; i < ARCHITECTURE_IDT_SIZE; i++) if (!(_idt[i] & ARCHITECTURE_IDTE_PRESENT)) { *index = i; break; } if (architecture_idt_insert(*index, base, flags) != ERROR_OK) MACHINE_ESCAPE("unable to insert the segment in the IDT"); MACHINE_LEAVE(); } t_error architecture_idt_delete(t_uint16 index) { if (index >= ARCHITECTURE_IDT_SIZE) MACHINE_ESCAPE("out-of-bound insertion"); if (!(_idt[index] & ARCHITECTURE_IDTE_PRESENT)) MACHINE_ESCAPE("the IDT entry to delete is not present"); memset(&_idt[index], 0x0, sizeof (at_idte)); MACHINE_LEAVE(); } t_error architecture_idt_build(void) { memset(_idt, 0x0, ARCHITECTURE_IDT_SIZE * sizeof (at_idte)); MACHINE_LEAVE(); }