From 3c84ce392d84fd5f1d17ee3fe885972ef7d12d42 Mon Sep 17 00:00:00 2001 From: Mercier Pierre-Olivier Date: Fri, 15 Feb 2013 23:06:15 +0100 Subject: [PATCH] Avancement sur l'IDT --- .../architecture/ia32/educational/idt.c | 172 ++++++++++++++++++ .../ia32/educational/include/idt.h | 65 +++++++ .../glue/ibm-pc.ia32/educational/event.c | 29 ++- .../ibm-pc.ia32/educational/include/event.h | 4 + .../ibm-pc.ia32/educational/include/segment.h | 1 + 5 files changed, 270 insertions(+), 1 deletion(-) diff --git a/kaneton/machine/architecture/ia32/educational/idt.c b/kaneton/machine/architecture/ia32/educational/idt.c index 3b857f2..cdad9ea 100644 --- a/kaneton/machine/architecture/ia32/educational/idt.c +++ b/kaneton/machine/architecture/ia32/educational/idt.c @@ -27,8 +27,180 @@ #include +/* + * ---------- 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(); +} diff --git a/kaneton/machine/architecture/ia32/educational/include/idt.h b/kaneton/machine/architecture/ia32/educational/include/idt.h index 9d19eab..76e12ae 100644 --- a/kaneton/machine/architecture/ia32/educational/include/idt.h +++ b/kaneton/machine/architecture/ia32/educational/include/idt.h @@ -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 +/* + * ---------- 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 diff --git a/kaneton/machine/glue/ibm-pc.ia32/educational/event.c b/kaneton/machine/glue/ibm-pc.ia32/educational/event.c index 0d7e027..799c788 100644 --- a/kaneton/machine/glue/ibm-pc.ia32/educational/event.c +++ b/kaneton/machine/glue/ibm-pc.ia32/educational/event.c @@ -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 */ diff --git a/kaneton/machine/glue/ibm-pc.ia32/educational/include/event.h b/kaneton/machine/glue/ibm-pc.ia32/educational/include/event.h index c5a47db..5503f19 100644 --- a/kaneton/machine/glue/ibm-pc.ia32/educational/include/event.h +++ b/kaneton/machine/glue/ibm-pc.ia32/educational/include/event.h @@ -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 diff --git a/kaneton/machine/glue/ibm-pc.ia32/educational/include/segment.h b/kaneton/machine/glue/ibm-pc.ia32/educational/include/segment.h index ae1248b..f305744 100644 --- a/kaneton/machine/glue/ibm-pc.ia32/educational/include/segment.h +++ b/kaneton/machine/glue/ibm-pc.ia32/educational/include/segment.h @@ -49,6 +49,7 @@ struct \ { \ as_gdt gdt; \ + as_idt idt; \ } machine; /*