This repository has been archived on 2021-03-01. You can view files and clone it, but cannot push or open issues or pull requests.
kaneton/kaneton/machine/architecture/ia32/educational/idt.c

181 lines
3.8 KiB
C
Raw Normal View History

2013-02-11 21:04:30 +00:00
/*
* ---------- 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 <kaneton.h>
2013-02-15 22:06:15 +00:00
/*
2013-02-16 22:11:04 +00:00
* ---------- globals ---------------------------------------------------------
2013-02-15 22:06:15 +00:00
*/
2013-02-16 22:11:04 +00:00
at_idte _idt[ARCHITECTURE_IDT_SIZE];
2013-02-15 22:06:15 +00:00
2013-02-11 21:04:30 +00:00
/*
* ---------- functions -------------------------------------------------------
*/
/* FIXME[complete if necessary] */
2013-02-15 22:06:15 +00:00
t_error architecture_idt_dump(void)
{
t_uint16 i;
module_call(console, message,
'#', "IDT: table(0x%08x) size(%u)\n",
2013-02-16 22:11:04 +00:00
_idt, ARCHITECTURE_IDT_SIZE);
2013-02-15 22:06:15 +00:00
2013-02-16 22:11:04 +00:00
for (i = 0; i < ARCHITECTURE_IDT_SIZE; i++)
2013-02-15 22:06:15 +00:00
{
t_privilege privilege;
t_paddr offset;
char* type;
char flag;
2013-02-16 22:11:04 +00:00
if (!(_idt[i] & ARCHITECTURE_IDTE_PRESENT))
2013-02-15 22:06:15 +00:00
continue;
2013-02-16 22:11:04 +00:00
offset = ARCHITECTURE_IDTE_OFFSET_GET(_idt[i]);
2013-02-15 22:06:15 +00:00
2013-02-16 22:11:04 +00:00
privilege = ARCHITECTURE_IDTE_DPL_GET(_idt[i]);
2013-02-15 22:06:15 +00:00
2013-02-17 03:30:09 +00:00
if (_idt[i] & ARCHITECTURE_IDTE_32BIT)
2013-02-15 22:06:15 +00:00
flag = 's';
else
flag = '.';
2013-02-16 22:11:04 +00:00
if ((_idt[i] & ARCHITECTURE_IDTE_TRAP) == ARCHITECTURE_IDTE_TRAP)
2013-02-15 22:06:15 +00:00
type = "trap";
2013-02-16 22:11:04 +00:00
else if ((_idt[i] & ARCHITECTURE_IDTE_INTERRUPT) == ARCHITECTURE_IDTE_INTERRUPT)
2013-02-15 22:06:15 +00:00
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();
}
2013-02-16 23:47:06 +00:00
t_error architecture_idt_import(void)
{
as_idtr lidt;
lidt.limit = ARCHITECTURE_IDT_SIZE * sizeof (at_idte);
lidt.base = (t_paddr) &_idt;
2013-02-17 05:17:41 +00:00
ARCHITECTURE_LIDT(lidt);
platform_pic_initialize();
2013-02-16 23:47:06 +00:00
MACHINE_LEAVE();
}
t_error architecture_idt_enable(void)
{
ARCHITECTURE_STI();
MACHINE_LEAVE();
}
t_error architecture_idt_disable(void)
{
ARCHITECTURE_CLI();
MACHINE_LEAVE();
}
2013-02-15 22:06:15 +00:00
t_error architecture_idt_insert(t_uint16 index,
t_paddr offset,
t_flags flags)
{
2013-02-16 22:11:04 +00:00
if (index >= ARCHITECTURE_IDT_SIZE)
2013-02-15 22:06:15 +00:00
MACHINE_ESCAPE("out-of-bound insertion");
2013-02-16 22:11:04 +00:00
if (_idt[index] & ARCHITECTURE_IDTE_PRESENT)
2013-02-15 22:06:15 +00:00
MACHINE_ESCAPE("the IDT entry to update is already in use");
2013-02-16 23:47:06 +00:00
t_uint16 sselector;
architecture_gdt_selector(1, ARCHITECTURE_PRIVILEGE_RING0, &sselector);
2013-02-16 22:11:04 +00:00
_idt[index] =
2013-02-15 22:06:15 +00:00
ARCHITECTURE_IDTE_INTERRUPT |
ARCHITECTURE_IDTE_PRESENT |
ARCHITECTURE_IDTE_OFFSET_SET(offset) |
2013-02-16 23:47:06 +00:00
ARCHITECTURE_IDTE_SEGMENT_SET(sselector) |
2013-02-15 22:06:15 +00:00
ARCHITECTURE_IDTE_32BIT |
flags;
2013-02-17 03:30:09 +00:00
2013-02-15 22:06:15 +00:00
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;
2013-02-16 22:11:04 +00:00
for (i = 0; i < ARCHITECTURE_IDT_SIZE; i++)
if (!(_idt[i] & ARCHITECTURE_IDTE_PRESENT))
2013-02-15 22:06:15 +00:00
{
*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)
{
2013-02-16 22:11:04 +00:00
if (index >= ARCHITECTURE_IDT_SIZE)
2013-02-15 22:06:15 +00:00
MACHINE_ESCAPE("out-of-bound insertion");
2013-02-16 22:11:04 +00:00
if (!(_idt[index] & ARCHITECTURE_IDTE_PRESENT))
2013-02-15 22:06:15 +00:00
MACHINE_ESCAPE("the IDT entry to delete is not present");
2013-02-16 22:11:04 +00:00
memset(&_idt[index], 0x0, sizeof (at_idte));
2013-02-15 22:06:15 +00:00
MACHINE_LEAVE();
}
2013-02-16 23:47:06 +00:00
t_error architecture_idt_build(void)
2013-02-15 22:06:15 +00:00
{
2013-02-16 22:11:04 +00:00
memset(_idt, 0x0, ARCHITECTURE_IDT_SIZE * sizeof (at_idte));
2013-02-15 22:06:15 +00:00
MACHINE_LEAVE();
}