Avancement sur l'IDT
This commit is contained in:
parent
0f1a851d35
commit
3c84ce392d
@ -27,8 +27,180 @@
|
||||
|
||||
#include <kaneton.h>
|
||||
|
||||
/*
|
||||
* ---------- externs ---------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* the segment manager which contains the current IDT.
|
||||
*/
|
||||
|
||||
extern m_segment _segment;
|
||||
|
||||
/*
|
||||
* ---------- 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",
|
||||
_segment.machine.idt.table,
|
||||
_segment.machine.idt.size);
|
||||
|
||||
for (i = 0; i < _segment.machine.idt.size; i++)
|
||||
{
|
||||
t_privilege privilege;
|
||||
t_paddr offset;
|
||||
char* type;
|
||||
char flag;
|
||||
|
||||
if (!(_segment.machine.idt.table[i] & ARCHITECTURE_IDTE_PRESENT))
|
||||
continue;
|
||||
|
||||
offset = ARCHITECTURE_IDTE_OFFSET_GET(_segment.machine.idt.table[i]);
|
||||
|
||||
privilege = ARCHITECTURE_IDTE_DPL_GET(_segment.machine.idt.table[i]);
|
||||
|
||||
if (_segment.machine.idt.table[i] & ARCHITECTURE_GDTE_32BIT)
|
||||
flag = 's';
|
||||
else
|
||||
flag = '.';
|
||||
|
||||
if ((_segment.machine.idt.table[i] & ARCHITECTURE_IDTE_TRAP) == ARCHITECTURE_IDTE_TRAP)
|
||||
type = "trap";
|
||||
else if ((_segment.machine.idt.table[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(as_idt* idt)
|
||||
{
|
||||
as_idtr idtr;
|
||||
|
||||
if (idt == NULL)
|
||||
MACHINE_ESCAPE("the 'idt' argument is null");
|
||||
|
||||
idtr.base = (t_paddr)idt->table;
|
||||
idtr.limit = idt->size * sizeof (at_idte);
|
||||
|
||||
ARCHITECTURE_LIDT(idtr);
|
||||
|
||||
memcpy(&_segment.machine.idt, idt, sizeof (as_idt));
|
||||
|
||||
MACHINE_LEAVE();
|
||||
}
|
||||
|
||||
t_error architecture_idt_export(as_idt* idt)
|
||||
{
|
||||
as_idtr idtr;
|
||||
at_idte* source;
|
||||
at_idte* dest;
|
||||
|
||||
if (idt == NULL)
|
||||
MACHINE_ESCAPE("the 'idt' argument is null");
|
||||
|
||||
ARCHITECTURE_SIDT(idtr);
|
||||
|
||||
source = (at_idte*)idtr.base;
|
||||
dest = idt->table;
|
||||
|
||||
memcpy(dest, source, idtr.limit);
|
||||
|
||||
idt->size = idtr.limit / sizeof (at_idte);
|
||||
|
||||
MACHINE_LEAVE();
|
||||
}
|
||||
|
||||
t_error architecture_idt_insert(t_uint16 index,
|
||||
t_paddr offset,
|
||||
t_flags flags)
|
||||
{
|
||||
if (index >= _segment.machine.idt.size)
|
||||
MACHINE_ESCAPE("out-of-bound insertion");
|
||||
|
||||
if (_segment.machine.idt.table[index] & ARCHITECTURE_IDTE_PRESENT)
|
||||
MACHINE_ESCAPE("the IDT entry to update is already in use");
|
||||
|
||||
_segment.machine.idt.table[index] =
|
||||
ARCHITECTURE_IDTE_INTERRUPT |
|
||||
ARCHITECTURE_IDTE_PRESENT |
|
||||
ARCHITECTURE_IDTE_OFFSET_SET(offset) |
|
||||
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 < _segment.machine.idt.size; i++)
|
||||
if (!(_segment.machine.idt.table[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 >= _segment.machine.idt.size)
|
||||
MACHINE_ESCAPE("out-of-bound insertion");
|
||||
|
||||
if (!(_segment.machine.idt.table[index] & ARCHITECTURE_IDTE_PRESENT))
|
||||
MACHINE_ESCAPE("the IDT entry to delete is not present");
|
||||
|
||||
memset(&_segment.machine.idt.table[index], 0x0, sizeof (at_idte));
|
||||
|
||||
MACHINE_LEAVE();
|
||||
}
|
||||
|
||||
t_error architecture_idt_build(t_paddr base,
|
||||
t_psize size,
|
||||
as_idt* idt)
|
||||
{
|
||||
if (idt == NULL)
|
||||
MACHINE_ESCAPE("the 'idt' argument is null");
|
||||
|
||||
if (size > (ARCHITECTURE_IDT_SIZE * sizeof (at_idte)))
|
||||
MACHINE_ESCAPE("the given size is too large as exceeding the IDT's "
|
||||
"theoretically maximum capacity");
|
||||
|
||||
if (base % sizeof (at_idte))
|
||||
base += sizeof (at_idte) - (base % sizeof (at_idte));
|
||||
|
||||
idt->table = (at_idte*)base;
|
||||
idt->size = size / sizeof (at_idte);
|
||||
|
||||
memset(idt->table, 0x0, idt->size * sizeof (at_idte));
|
||||
|
||||
MACHINE_LEAVE();
|
||||
}
|
||||
|
@ -102,12 +102,58 @@
|
||||
#define ARCHITECTURE_IDT_IRQ_ATA2 \
|
||||
ARCHITECTURE_IDT_IRQ_BASE + 15
|
||||
|
||||
|
||||
/* Fixed at K1 */
|
||||
#define ARCHITECTURE_IDT_SIZE 256
|
||||
|
||||
|
||||
#define ARCHITECTURE_IDTE_TASK (5LL << 40)
|
||||
#define ARCHITECTURE_IDTE_INTERRUPT (6LL << 40)
|
||||
#define ARCHITECTURE_IDTE_TRAP (7LL << 40)
|
||||
|
||||
#define ARCHITECTURE_IDTE_32BIT (1LL << 43)
|
||||
#define ARCHITECTURE_IDTE_PRESENT (1LL << 47)
|
||||
|
||||
#define ARCHITECTURE_IDTE_OFFSET_SET(_offset_) \
|
||||
(at_gdte)((((at_idte)(_offset_) & 0x0000ffff)) | \
|
||||
(((at_idte)(_offset_) & 0xffff0000) << 32))
|
||||
|
||||
#define ARCHITECTURE_IDTE_OFFSET_GET(_idte_) \
|
||||
(t_paddr)((((_idte_) >> 00) & 0x0000ffff) | \
|
||||
(((_idte_) >> 32) & 0xffff0000))
|
||||
|
||||
#define ARCHITECTURE_IDTE_DPL_SET(_privilege_) \
|
||||
(((at_idte)(_privilege_) & 0x3) << 45)
|
||||
|
||||
#define ARCHITECTURE_IDTE_DPL_GET(_idte_) \
|
||||
(((_idte_) >> 45) & 0x3)
|
||||
|
||||
/* EOFIXME */
|
||||
|
||||
/*
|
||||
* ---------- dependencies ----------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <core/types.h>
|
||||
|
||||
/*
|
||||
* ---------- types -----------------------------------------------------------
|
||||
*/
|
||||
|
||||
typedef t_uint64 at_idte;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
at_idte* table;
|
||||
t_uint16 size;
|
||||
} as_idt;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
t_uint16 limit;
|
||||
t_paddr base;
|
||||
} __attribute__ ((packed)) as_idtr;
|
||||
|
||||
/*
|
||||
* ---------- prototypes ------------------------------------------------------
|
||||
*
|
||||
@ -118,6 +164,25 @@
|
||||
* ../idt.c
|
||||
*/
|
||||
|
||||
t_error architecture_idt_dump(void);
|
||||
|
||||
t_error architecture_idt_build(t_paddr base,
|
||||
t_psize size,
|
||||
as_idt* idt);
|
||||
|
||||
t_error architecture_idt_import(as_idt* idt);
|
||||
|
||||
t_error architecture_idt_export(as_idt* idt);
|
||||
|
||||
t_error architecture_idt_insert(t_uint16 index,
|
||||
t_paddr base,
|
||||
t_flags flags);
|
||||
|
||||
t_error architecture_idt_reserve(t_paddr base,
|
||||
t_flags flags,
|
||||
t_uint16* index);
|
||||
|
||||
t_error architecture_idt_delete(t_uint16 index);
|
||||
|
||||
/*
|
||||
* eop
|
||||
|
@ -40,6 +40,33 @@ d_event glue_event_dispatch =
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
glue_event_initialize,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* FIXED at K1 */
|
||||
|
||||
/*
|
||||
* ---------- functions -------------------------------------------------------
|
||||
*/
|
||||
|
||||
t_error glue_event_initialize(void)
|
||||
{
|
||||
t_uint16 i;
|
||||
|
||||
if (architecture_idt_build() != ERROR_OK)
|
||||
MACHINE_ESCAPE("unable to initialize the IDT");
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
if (architecture_idt_insert(i, ) != ERROR_OK)
|
||||
{
|
||||
MACHINE_ESCAPE("unable to insert the %u IDT", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MACHINE_LEAVE();
|
||||
}
|
||||
|
||||
/* EOFIX */
|
||||
|
@ -75,6 +75,10 @@
|
||||
* ../event.c
|
||||
*/
|
||||
|
||||
t_error glue_event_reserve(i_event id,
|
||||
t_type type,
|
||||
u_event_handler handler,
|
||||
t_data data);
|
||||
|
||||
/*
|
||||
* eop
|
||||
|
@ -49,6 +49,7 @@
|
||||
struct \
|
||||
{ \
|
||||
as_gdt gdt; \
|
||||
as_idt idt; \
|
||||
} machine;
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user