summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2017-06-01 15:30:02 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2017-06-01 15:30:02 +0200
commit6b4d85b294f6e1a30d9703a2ef492ba6f3b1cc33 (patch)
treec3d57333f20ccbeb67c366c4a6f49fa2af617fee
parent4b139d9287358011fddb672f2a4e5b377c2278ed (diff)
downloadabaos-6b4d85b294f6e1a30d9703a2ef492ba6f3b1cc33.tar.gz
abaos-6b4d85b294f6e1a30d9703a2ef492ba6f3b1cc33.tar.bz2
EOI acknoledgment of PICs, also showing PIT events are coming in
-rw-r--r--src/.gdbinit2
-rw-r--r--src/interrupts.c39
-rw-r--r--src/interrupts.h2
-rw-r--r--src/kernel.c9
4 files changed, 41 insertions, 11 deletions
diff --git a/src/.gdbinit b/src/.gdbinit
index 94edd63..12d2269 100644
--- a/src/.gdbinit
+++ b/src/.gdbinit
@@ -2,4 +2,4 @@ target remote localhost:1234
symbol-file kernel.sym
break entry
c
-wh
+wh 10
diff --git a/src/interrupts.c b/src/interrupts.c
index c04eb59..feb3aab 100644
--- a/src/interrupts.c
+++ b/src/interrupts.c
@@ -54,6 +54,9 @@
#define ICW4_BUFFER 0x08
#define ICW4_FULLY_NESTED 0x10
+// OCW2
+#define OCW2_EOI 0x20 // non-specific End Of Interrupt
+
// must be global: when called via assembly code we loose the context
// of the interrupt handler structure
interrupt_t interrupt;
@@ -92,7 +95,8 @@ void interrupts_init( interrupt_t *interrupt )
port8_write( &interrupt->PIC_master_control, ICW1_ICW4 | ICW1_INIT );
port8_write( &interrupt->PIC_slave_control, ICW1_ICW4 | ICW1_INIT );
- // set IRQ base of both PICS (ICW2)
+ // set IRQ base of both PICS (ICW2), remap them so they
+ // don't collide with CPU exceptions (this is true after 0x20)
port8_write( &interrupt->PIC_master_data, ICW2_IRQ_BASE_MASTER );
port8_write( &interrupt->PIC_slave_data, ICW2_IRQ_BASE_SLAVE );
@@ -104,6 +108,13 @@ void interrupts_init( interrupt_t *interrupt )
// TODO: use buffered mode later?
port8_write( &interrupt->PIC_master_data, ICW4_8086 );
port8_write( &interrupt->PIC_slave_data, ICW4_8086 );
+
+ // done, enable all IRQs by setting the interrupt mask register
+ // 0 for all bits. We are not interested in the old state of
+ // the mask as we are initializing in protected mode
+ // TODO: later we will mask uninmported interrupts maybe?
+ port8_write( &interrupt->PIC_master_data, 0 );
+ port8_write( &interrupt->PIC_slave_data, 0 );
// tell CPU where the IDT is
interrupt->idt_pointer.size = 256 * sizeof( interrupt_gate_descriptor_t ) - 1;
@@ -137,9 +148,11 @@ uint32_t interrupts_exception_division_by_zero( uint32_t esp )
return esp;
}
+static int pit_counter = 0;
uint32_t interrupts_interrupt_PIT( uint32_t esp )
{
- puts( "PIT PIT PIT PIT PIT PIT PIT" );
+ pit_counter++;
+ printf( "PIT PIT PIT PIT PIT PIT PIT %d", pit_counter );
return esp;
}
@@ -154,12 +167,20 @@ uint32_t interrupts_handle_interrupt( uint8_t interrupt_no, uint32_t esp )
{
interrupt_handler_t handler = interrupt.interrupt_handler[interrupt_no];
- if( handler != NULL ) {
- uint32_t new_esp = handler( esp );
- return new_esp;
+ if( handler == NULL ) {
+ kernel_panic( "Unhandled interrupt 0x%X with ESP 0x%X\n", interrupt_no, esp );
}
-
- kernel_panic( "Unhandled interrupt 0x%X with ESP 0x%X\n", interrupt_no, esp );
-
- return esp;
+
+ uint32_t new_esp = handler( esp );
+
+ // send ACK to PIC for hardware interrups
+ if( interrupt_no >= IRQ_BASE && interrupt_no <= IRQ_BASE + 16 ) {
+ if( interrupt_no < IRQ_BASE + 8 ) {
+ port8_write( &interrupt.PIC_master_control, OCW2_EOI );
+ } else {
+ port8_write( &interrupt.PIC_slave_control, OCW2_EOI );
+ }
+ }
+
+ return new_esp;
}
diff --git a/src/interrupts.h b/src/interrupts.h
index 0b514ea..64f1b43 100644
--- a/src/interrupts.h
+++ b/src/interrupts.h
@@ -47,7 +47,9 @@ typedef struct {
interrupt_descriptor_table_pointer_t idt_pointer;
interrupt_gate_descriptor_t descriptor_table[NOF_INTERRUPTS];
interrupt_handler_t interrupt_handler[NOF_INTERRUPTS];
+ // PIC master control register: command and status register
port8_t PIC_master_control;
+ // PIC master data register: interrupt mask and data register
port8_t PIC_master_data;
// since PC/AT we always have a slave PIC, we don't support the PC/XT architecture
// with just one PIC
diff --git a/src/kernel.c b/src/kernel.c
index ceb1380..8759f18 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -52,10 +52,17 @@ void entry( void )
int y_pos = vga_get_cursor_y( &vga );
int x_pos = vga_get_cursor_x( &vga );
int i = 0;
- for( i = 0; i < 10000; i++ ) {
+ for( i = 0; i < 100000; i++ ) {
if( i % 1000 == 1 ) {
vga_put_char_at( &vga, x_pos, y_pos, '.' );
x_pos++;
+ if( x_pos > vga.res_x ) {
+ x_pos = 0;
+ y_pos++;
+ if( y_pos > vga.res_y ) {
+ y_pos = 0;
+ }
+ }
// serial_put_char( &serial, '.' );
//~ int y = 0;
//~ int x = 12 / y;