diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2017-06-01 15:30:02 +0200 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2017-06-01 15:30:02 +0200 |
commit | 6b4d85b294f6e1a30d9703a2ef492ba6f3b1cc33 (patch) | |
tree | c3d57333f20ccbeb67c366c4a6f49fa2af617fee | |
parent | 4b139d9287358011fddb672f2a4e5b377c2278ed (diff) | |
download | abaos-6b4d85b294f6e1a30d9703a2ef492ba6f3b1cc33.tar.gz abaos-6b4d85b294f6e1a30d9703a2ef492ba6f3b1cc33.tar.bz2 |
EOI acknoledgment of PICs, also showing PIT events are coming in
-rw-r--r-- | src/.gdbinit | 2 | ||||
-rw-r--r-- | src/interrupts.c | 39 | ||||
-rw-r--r-- | src/interrupts.h | 2 | ||||
-rw-r--r-- | src/kernel.c | 9 |
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; |