summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2017-06-01 19:14:44 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2017-06-01 19:14:44 +0200
commitec014db9fa3f6b5b7ad3491c20f2c2a65c56a7a6 (patch)
tree6b645b6be055be47a8f5dbf22ae1c191386148e8
parent15a2290a168fa9de80256bb7cefe13384ae3e58b (diff)
downloadabaos-ec014db9fa3f6b5b7ad3491c20f2c2a65c56a7a6.tar.gz
abaos-ec014db9fa3f6b5b7ad3491c20f2c2a65c56a7a6.tar.bz2
introducted a interrupt handler object
-rw-r--r--doc/LINKS.TODO1
-rw-r--r--src/Makefile4
-rw-r--r--src/interrupts.c41
-rw-r--r--src/interrupts.h11
-rw-r--r--src/stage1_functions.asm2
5 files changed, 47 insertions, 12 deletions
diff --git a/doc/LINKS.TODO b/doc/LINKS.TODO
index a7b3f15..df6471d 100644
--- a/doc/LINKS.TODO
+++ b/doc/LINKS.TODO
@@ -39,4 +39,5 @@ http://prettyos.de
PIC:
http://www.brokenthorn.com/Resources/OSDevPic.html
+http://wiki.osdev.org/8259_PIC
diff --git a/src/Makefile b/src/Makefile
index 3e89a74..9c6a931 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -13,10 +13,10 @@ all: image.bin kernel.sym
# + M * 512 (M is currently 7) = 3144 for kernel.bin
# + 1 * 512 = 512 for magic.bin
# (M + N + 1 is the number of sectors to be read in stage 2, as stage 1
-# loads only the first sector, so adapt NOF_LOAD_SECTORS to 19)
+# loads only the first sector, so adapt NOF_LOAD_SECTORS to 20)
image.bin: boot.bin kernel.bin magic.bin
cat boot.bin kernel.bin > image.tmp
- truncate -s 9728 image.tmp
+ truncate -s 10240 image.tmp
cat image.tmp magic.bin > image.bin
boot.bin: boot.asm boot_gdt.asm stage1_functions.asm stage2_functions.asm stage2_switch_mode.asm stage2_a20.asm
diff --git a/src/interrupts.c b/src/interrupts.c
index 07a7e55..0c3c72a 100644
--- a/src/interrupts.c
+++ b/src/interrupts.c
@@ -57,6 +57,20 @@
// OCW2
#define OCW2_EOI 0x20 // non-specific End Of Interrupt
+void interrupt_handler_init_void( interrupt_handler_t *handler )
+{
+ memset( handler, 0, sizeof( interrupt_handler_t ) );
+}
+
+void interrupt_handler_init( interrupt_handler_t *handler, uint8_t interrupt_no, struct interrupt_t *interrupt, interrupt_handler_func_t handle )
+{
+ memset( handler, 0, sizeof( interrupt_handler_t ) );
+
+ handler->interrupt_no = interrupt_no;
+ handler->interrupt = interrupt;
+ handler->handle = handle;
+}
+
// must be global: when called via assembly code we loose the context
// of the interrupt handler structure
static interrupt_t *active_interrupt;
@@ -64,27 +78,39 @@ static interrupt_t *active_interrupt;
void interrupts_init( interrupt_t *interrupt )
{
memset( interrupt, 0, sizeof( interrupt_t ) );
+
+ interrupt_handler_t empty_interrupt_handler;
+ interrupt_handler_init_void( &empty_interrupt_handler );
for( int i = 0; i < NOF_INTERRUPTS; i++ ) {
interrupts_register_interrupt( interrupt, i, GDT_CODE_SEGMENT_SELECTOR,
&interrupts_ignore_request, KERNEL_RING, IDT_TYPE_INTERRUPT_GATE,
- NULL );
+ empty_interrupt_handler );
}
// divide-by-zero exception 0x00
+ interrupt_handler_t divide_by_zero_interrupt_handler;
+ interrupt_handler_init( &divide_by_zero_interrupt_handler, 0x00, interrupt, interrupts_exception_division_by_zero );
+
interrupts_register_interrupt( interrupt, 0x00, GDT_CODE_SEGMENT_SELECTOR,
&interrupts_handle_exception_0x00, KERNEL_RING, IDT_TYPE_INTERRUPT_GATE,
- &interrupts_exception_division_by_zero );
+ divide_by_zero_interrupt_handler );
// IRQ 0 - PIT - programmable interrupt timer
+ interrupt_handler_t pit_interrupt_handler;
+ interrupt_handler_init( &pit_interrupt_handler, IRQ_BASE + 0x00, interrupt, interrupts_interrupt_PIT );
+
interrupts_register_interrupt( interrupt, IRQ_BASE + 0x00, GDT_CODE_SEGMENT_SELECTOR,
&interrupts_handle_irq_0x00, KERNEL_RING, IDT_TYPE_INTERRUPT_GATE,
- &interrupts_interrupt_PIT );
+ pit_interrupt_handler );
// IRQ 1 - keyboard
+ interrupt_handler_t keyboard_interrupt_handler;
+ interrupt_handler_init( &keyboard_interrupt_handler, IRQ_BASE + 0x01, interrupt, interrupts_interrupt_keyboard );
+
interrupts_register_interrupt( interrupt, IRQ_BASE + 0x01, GDT_CODE_SEGMENT_SELECTOR,
&interrupts_handle_irq_0x01, KERNEL_RING, IDT_TYPE_INTERRUPT_GATE,
- &interrupts_interrupt_keyboard );
+ keyboard_interrupt_handler );
port8_init( &interrupt->PIC_master_control, 0x20 );
port8_init( &interrupt->PIC_master_data, 0x21 );
@@ -117,7 +143,7 @@ void interrupts_init( interrupt_t *interrupt )
port8_write( &interrupt->PIC_slave_data, 0 );
// tell CPU where the IDT is
- interrupt->idt_pointer.size = 256 * sizeof( interrupt_gate_descriptor_t ) - 1;
+ interrupt->idt_pointer.size = NOF_INTERRUPTS * sizeof( interrupt_gate_descriptor_t ) - 1;
interrupt->idt_pointer.base = (uint32_t)interrupt->descriptor_table;
interrupts_load_idt( &interrupt->idt_pointer );
@@ -168,7 +194,6 @@ printf( "Hex number is 0x%X and string is '%s'\n", x, "abaos" );
return esp;
}
-
uint32_t interrupts_handle_static_interrupt( uint8_t interrupt_no, uint32_t esp )
{
if( active_interrupt == NULL ) {
@@ -182,11 +207,11 @@ uint32_t interrupts_handle_interrupt( interrupt_t *interrupt, uint8_t interrupt_
{
interrupt_handler_t handler = interrupt->interrupt_handler[interrupt_no];
- if( handler == NULL ) {
+ if( handler.handle == NULL ) {
kernel_panic( "Unhandled interrupt 0x%X with ESP 0x%X\n", interrupt_no, esp );
}
- uint32_t new_esp = handler( interrupt, esp );
+ uint32_t new_esp = handler.handle( interrupt, esp );
// send ACK to PIC for hardware interrups
if( interrupt_no >= IRQ_BASE && interrupt_no <= IRQ_BASE + 16 ) {
diff --git a/src/interrupts.h b/src/interrupts.h
index 0cdb6cc..82f95f4 100644
--- a/src/interrupts.h
+++ b/src/interrupts.h
@@ -43,7 +43,16 @@ typedef struct {
struct interrupt_t;
-typedef uint32_t (*interrupt_handler_t)( struct interrupt_t *interrupt, uint32_t esp );
+typedef uint32_t (*interrupt_handler_func_t)( struct interrupt_t *interrupt, uint32_t esp );
+
+typedef struct interrupt_handler_t {
+ uint8_t interrupt_no;
+ struct interrupt_t *interrupt;
+ interrupt_handler_func_t handle;
+} interrupt_handler_t;
+
+void interrupt_handler_init_void( interrupt_handler_t *handler );
+void interrupt_handler_init( interrupt_handler_t *handler, uint8_t interrupt_no, struct interrupt_t *interrupt, interrupt_handler_func_t handle );
typedef struct interrupt_t {
interrupt_descriptor_table_pointer_t idt_pointer;
diff --git a/src/stage1_functions.asm b/src/stage1_functions.asm
index c2e1bcd..8953b9c 100644
--- a/src/stage1_functions.asm
+++ b/src/stage1_functions.asm
@@ -2,7 +2,7 @@
; 3 * 512 for bootloader stage2 and the kernel code
; (note: the first sector gets loaded by the BIOS, so
; subtract 1 here!)
-NOF_LOAD_SECTORS equ 19
+NOF_LOAD_SECTORS equ 20
; IN bx: begin of memory area to dump
; IN ax: number of words to dump