summaryrefslogtreecommitdiff
path: root/src/hardware/interrupts.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/hardware/interrupts.c')
-rw-r--r--src/hardware/interrupts.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/src/hardware/interrupts.c b/src/hardware/interrupts.c
index 614dbf0..4ca0f14 100644
--- a/src/hardware/interrupts.c
+++ b/src/hardware/interrupts.c
@@ -7,9 +7,6 @@
#include "keyboard.h"
-// TODO: for now the code segment is the first entry in the boot GDT
-#define GDT_CODE_SEGMENT_SELECTOR 8
-
// the Present bit in a IDT entry
#define IDT_PRESENT_BIT 0x80
@@ -75,15 +72,17 @@ void interrupt_handler_init( interrupt_handler_t *handler, uint8_t interrupt_no,
// of the interrupt handler structure
static interrupt_t *active_interrupt;
-void interrupts_init( interrupt_t *interrupt )
+void interrupts_init( interrupt_t *interrupt, uint16_t gdt_code_segment_selector, task_manager_t *task_manager )
{
memset( interrupt, 0, sizeof( interrupt_t ) );
interrupt_handler_t empty_interrupt_handler;
interrupt_handler_init_void( &empty_interrupt_handler );
+
+ interrupt->task_manager = task_manager;
for( int i = 0; i < NOF_INTERRUPTS; i++ ) {
- interrupts_register_interrupt_gate( interrupt, i, GDT_CODE_SEGMENT_SELECTOR,
+ interrupts_register_interrupt_gate( interrupt, i, gdt_code_segment_selector,
&interrupts_ignore_request, KERNEL_RING, IDT_TYPE_INTERRUPT_GATE );
interrupts_register_interrupt_handler( empty_interrupt_handler );
}
@@ -92,7 +91,7 @@ void interrupts_init( interrupt_t *interrupt )
interrupt_handler_t divide_by_zero_interrupt_handler;
interrupt_handler_init( &divide_by_zero_interrupt_handler, 0x00, interrupt, interrupts_exception_division_by_zero, NULL );
- interrupts_register_interrupt_gate( interrupt, 0x00, GDT_CODE_SEGMENT_SELECTOR,
+ interrupts_register_interrupt_gate( interrupt, 0x00, gdt_code_segment_selector,
&interrupts_handle_exception_0x00, KERNEL_RING, IDT_TYPE_INTERRUPT_GATE );
interrupts_register_interrupt_handler( divide_by_zero_interrupt_handler );
@@ -100,16 +99,16 @@ void interrupts_init( interrupt_t *interrupt )
interrupt_handler_t pit_interrupt_handler;
interrupt_handler_init( &pit_interrupt_handler, IRQ_BASE + 0x00, interrupt, interrupts_interrupt_PIT, NULL );
- interrupts_register_interrupt_gate( interrupt, IRQ_BASE + 0x00, GDT_CODE_SEGMENT_SELECTOR,
+ interrupts_register_interrupt_gate( interrupt, IRQ_BASE + 0x00, gdt_code_segment_selector,
&interrupts_handle_irq_0x00, KERNEL_RING, IDT_TYPE_INTERRUPT_GATE );
interrupts_register_interrupt_handler( pit_interrupt_handler );
// IRQ 1 - PS/2 keyboard
- interrupts_register_interrupt_gate( interrupt, IRQ_BASE + 0x01, GDT_CODE_SEGMENT_SELECTOR,
+ interrupts_register_interrupt_gate( interrupt, IRQ_BASE + 0x01, gdt_code_segment_selector,
&interrupts_handle_irq_0x01, KERNEL_RING, IDT_TYPE_INTERRUPT_GATE );
// IRQ 12 - PS/2 mouse
- interrupts_register_interrupt_gate( interrupt, IRQ_BASE + 0x0C, GDT_CODE_SEGMENT_SELECTOR,
+ interrupts_register_interrupt_gate( interrupt, IRQ_BASE + 0x0C, gdt_code_segment_selector,
&interrupts_handle_irq_0x0C, KERNEL_RING, IDT_TYPE_INTERRUPT_GATE );
port8_init( &interrupt->PIC_master_control, 0x20 );
@@ -202,8 +201,13 @@ uint32_t interrupts_handle_interrupt( interrupt_t *interrupt, uint8_t interrupt_
}
uint32_t new_esp = handler->handle( handler, esp );
-
- // send ACK to PIC for hardware interrups
+
+ // timer interrupt, schedule the tasks
+ if( interrupt_no == IRQ_BASE + 0x00 ) {
+ new_esp = (uint32_t)task_manager_schedule_task( interrupt->task_manager, (cpu_state_t *)esp );
+ }
+
+ // send ACK to PIC for hardware interrupts
if( interrupt_no >= IRQ_BASE && interrupt_no <= IRQ_BASE + 16 ) {
port8_write( &interrupt->PIC_master_control, OCW2_EOI );
if( interrupt_no >= IRQ_BASE + 8 ) {