diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2017-07-20 09:31:30 +0200 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2017-07-20 09:31:30 +0200 |
commit | 7eae4edb86fc65b2e99bf81757aeb00392d8a60d (patch) | |
tree | 2ee5c92be2ca55dcd30dc3e9632bcfa4dfd9a095 /src | |
parent | 43fcc1ca57149c5a87502f0c23a2c85e4d28264a (diff) | |
download | abaos-7eae4edb86fc65b2e99bf81757aeb00392d8a60d.tar.gz abaos-7eae4edb86fc65b2e99bf81757aeb00392d8a60d.tar.bz2 |
added a virtual keyboard driver interface, made the PS/2 keyboard a specialization of it
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 12 | ||||
-rw-r--r-- | src/drivers/hdi/keyboard.c | 44 | ||||
-rw-r--r-- | src/drivers/hdi/keyboard.h (renamed from src/drivers/hdi/ps2/keyboard.h) | 16 | ||||
-rw-r--r-- | src/drivers/hdi/mouse.h | 2 | ||||
-rw-r--r-- | src/drivers/hdi/ps2/ps2keyboard.c (renamed from src/drivers/hdi/ps2/keyboard.c) | 114 | ||||
-rw-r--r-- | src/drivers/hdi/ps2/ps2keyboard.h | 33 | ||||
-rw-r--r-- | src/kernel/kernel.c | 6 |
7 files changed, 146 insertions, 81 deletions
diff --git a/src/Makefile b/src/Makefile index 5b67063..1696e6c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -36,7 +36,7 @@ kernel.bin: kernel.elf kernel.sym: kernel.elf $(OBJCOPY) --only-keep-debug kernel.elf kernel.sym -kernel.elf: kernel/entry.o kernel/kernel.o kernel/kernel_asm.o kernel/console.o kernel/vgatext.o kernel/serial.o kernel/memorymanagement.o kernel/tasks.o hardware/port.o hardware/port_asm.o hardware/interrupts.o hardware/interrupts_asm.o hardware/pci.o drivers/driver.o drivers/hdi/mouse.o drivers/hdi/ps2/keyboard.o drivers/hdi/ps2/ps2mouse.o drivers/video/vga.o drivers/video/vga_font.o drivers/net/rtl8139.o gui/widget.o gui/composite_widget.o gui/window.o gui/desktop.o gui/text_widget.o libc/string.o libc/stdlib.o libc/stdio.o libc/setjmp.o +kernel.elf: kernel/entry.o kernel/kernel.o kernel/kernel_asm.o kernel/console.o kernel/vgatext.o kernel/serial.o kernel/memorymanagement.o kernel/tasks.o hardware/port.o hardware/port_asm.o hardware/interrupts.o hardware/interrupts_asm.o hardware/pci.o drivers/driver.o drivers/hdi/mouse.o drivers/hdi/keyboard.o drivers/hdi/ps2/ps2keyboard.o drivers/hdi/ps2/ps2mouse.o drivers/video/vga.o drivers/video/vga_font.o drivers/net/rtl8139.o gui/widget.o gui/composite_widget.o gui/window.o gui/desktop.o gui/text_widget.o libc/string.o libc/stdlib.o libc/stdio.o libc/setjmp.o $(LD) -o kernel.elf -N -n -Ttext 0x8800 -e kernel_entry --oformat elf32-i386 \ kernel/entry.o \ kernel/kernel.o kernel/kernel_asm.o \ @@ -46,7 +46,8 @@ kernel.elf: kernel/entry.o kernel/kernel.o kernel/kernel_asm.o kernel/console.o hardware/interrupts.o hardware/interrupts_asm.o \ hardware/pci.o \ drivers/driver.o drivers/hdi/mouse.o \ - drivers/hdi/ps2/keyboard.o drivers/hdi/ps2/ps2mouse.o \ + drivers/hdi/keyboard.o \ + drivers/hdi/ps2/ps2keyboard.o drivers/hdi/ps2/ps2mouse.o \ drivers/video/vga.o drivers/video/vga_font.o \ drivers/net/rtl8139.o \ libc/string.o libc/stdlib.o libc/stdio.o libc/setjmp.o \ @@ -101,8 +102,11 @@ drivers/driver.o: drivers/driver.c drivers/driver.h drivers/hdi/mouse.o: drivers/hdi/mouse.c drivers/hdi/mouse.h $(CC) $(CFLAGS) -c -o drivers/hdi/mouse.o drivers/hdi/mouse.c -drivers/hdi/ps2/keyboard.o: drivers/hdi/ps2/keyboard.c drivers/hdi/ps2/keyboard.h - $(CC) $(CFLAGS) -c -o drivers/hdi/ps2/keyboard.o drivers/hdi/ps2/keyboard.c +drivers/hdi/keyboard.o: drivers/hdi/keyboard.c drivers/hdi/keyboard.h + $(CC) $(CFLAGS) -c -o drivers/hdi/keyboard.o drivers/hdi/keyboard.c + +drivers/hdi/ps2/ps2keyboard.o: drivers/hdi/ps2/ps2keyboard.c drivers/hdi/ps2/ps2keyboard.h + $(CC) $(CFLAGS) -c -o drivers/hdi/ps2/ps2keyboard.o drivers/hdi/ps2/ps2keyboard.c drivers/hdi/ps2/ps2mouse.o: drivers/hdi/ps2/ps2mouse.c drivers/hdi/ps2/ps2mouse.h $(CC) $(CFLAGS) -c -o drivers/hdi/ps2/ps2mouse.o drivers/hdi/ps2/ps2mouse.c diff --git a/src/drivers/hdi/keyboard.c b/src/drivers/hdi/keyboard.c new file mode 100644 index 0000000..dd7ff65 --- /dev/null +++ b/src/drivers/hdi/keyboard.c @@ -0,0 +1,44 @@ +#include "keyboard.h" + +#include "string.h" +#include "kernel.h" + +static keyboard_vtable_t const keyboard_vtable = { + { + keyboard_activate, + keyboard_deactivate, + keyboard_deinit, + keyboard_print_info + } +}; + +void keyboard_init( keyboard_t *keyboard, keyboard_event_handler_t handler, interrupt_t *interrupt, void *context ) +{ + memset( keyboard, 0, sizeof( keyboard_t ) ); + + driver_init( (driver_t *)keyboard, DRIVER_TYPE_KEYBOARD, interrupt, context ); + + keyboard->handler = handler; + + ((driver_t *)keyboard)->vtable = (driver_vtable_t *)&keyboard_vtable; +} + +void keyboard_deinit( void *obj ) +{ + // nothing to be done +} + +void keyboard_activate( void *obj ) +{ + kernel_panic( "Activating generic keyboard driver should not be called directly." ); +} + +void keyboard_deactivate( void *obj ) +{ + kernel_panic( "Deactivating generic keyboard driver should not be called directly." ); +} + +void keyboard_print_info( void *obj ) +{ + kernel_panic( "Printing info of generic keyboard driver should not be called directly." ); +} diff --git a/src/drivers/hdi/ps2/keyboard.h b/src/drivers/hdi/keyboard.h index a0e06ef..aab7383 100644 --- a/src/drivers/hdi/ps2/keyboard.h +++ b/src/drivers/hdi/keyboard.h @@ -1,15 +1,8 @@ #ifndef KEYBOARD_H #define KEYBOARD_H -#include <stdbool.h> - -#include "string.h" - -#include "interrupts.h" -#include "port.h" - #include "driver.h" - + typedef enum { KEYBOARD_EVENT_TYPE_KEY_PRESSED, KEYBOARD_EVENT_TYPE_KEY_RELEASED @@ -46,12 +39,7 @@ typedef void (*keyboard_event_handler_t)( keyboard_event_t *event, void *context typedef struct { driver_t base; - interrupt_t *interrupts; - port8_t command_port; - port8_t data_port; - bool shift; keyboard_event_handler_t handler; - interrupt_handler_t interrupt_handler; } keyboard_t; typedef struct { @@ -64,6 +52,4 @@ void keyboard_deactivate( void *obj ); void keyboard_deinit( void *obj ); void keyboard_print_info( void *obj ); -uint32_t keyboard_handle_interrupt( interrupt_handler_t *handler, uint32_t esp ); - #endif // KEYBOARD_H diff --git a/src/drivers/hdi/mouse.h b/src/drivers/hdi/mouse.h index 90417f3..5b3d08f 100644 --- a/src/drivers/hdi/mouse.h +++ b/src/drivers/hdi/mouse.h @@ -50,6 +50,4 @@ void mouse_print_info( void *obj ); void mouse_set_resolution( void *obj, const uint32_t x, const uint32_t y ); void mouse_set_position( void *obj, const uint32_t x, const uint32_t y ); -uint32_t mouse_handle_interrupt( interrupt_handler_t *handler, uint32_t esp ); - #endif // MOUSE_H diff --git a/src/drivers/hdi/ps2/keyboard.c b/src/drivers/hdi/ps2/ps2keyboard.c index 9c5a246..4151c56 100644 --- a/src/drivers/hdi/ps2/keyboard.c +++ b/src/drivers/hdi/ps2/ps2keyboard.c @@ -1,4 +1,4 @@ -#include "keyboard.h" +#include "ps2keyboard.h" #include "stdio.h" // status register on command port (read) @@ -34,28 +34,28 @@ #undef DEBUG -static uint8_t read_data( keyboard_t *keyboard ) +static uint8_t read_data( ps2keyboard_t *ps2keyboard ) { - while( ( port8_read( &keyboard->command_port ) & STATUS_REG_OUTPUT_BUF_FULL ) == 0 ) { } - return port8_read( &keyboard->data_port ); + while( ( port8_read( &ps2keyboard->command_port ) & STATUS_REG_OUTPUT_BUF_FULL ) == 0 ) { } + return port8_read( &ps2keyboard->data_port ); } -static void send_command( keyboard_t *keyboard, uint8_t command ) +static void send_command( ps2keyboard_t *ps2keyboard, uint8_t command ) { - while( port8_read( &keyboard->command_port ) & STATUS_REG_INPUT_BUF_FULL ) { } - port8_write( &keyboard->command_port, command ); + while( port8_read( &ps2keyboard->command_port ) & STATUS_REG_INPUT_BUF_FULL ) { } + port8_write( &ps2keyboard->command_port, command ); } -static void write_data( keyboard_t *keyboard, uint8_t data ) +static void write_data( ps2keyboard_t *ps2keyboard, uint8_t data ) { - while( port8_read( &keyboard->command_port ) & STATUS_REG_INPUT_BUF_FULL ) { } - port8_write( &keyboard->data_port, data ); + while( port8_read( &ps2keyboard->command_port ) & STATUS_REG_INPUT_BUF_FULL ) { } + port8_write( &ps2keyboard->data_port, data ); } /* -static void read_ack( keyboard_t *keyboard ) +static void read_ack( ps2keyboard_t *ps2keyboard ) { - uint8_t data = read_data( keyboard ); + uint8_t data = read_data( ps2keyboard ); if( data == 0xFA ) { return; } else { @@ -64,82 +64,82 @@ static void read_ack( keyboard_t *keyboard ) } */ -static keyboard_vtable_t const keyboard_vtable = { +static keyboard_vtable_t const ps2keyboard_vtable = { { - keyboard_activate, - keyboard_deactivate, - keyboard_deinit, - keyboard_print_info + ps2keyboard_activate, + ps2keyboard_deactivate, + ps2keyboard_deinit, + ps2keyboard_print_info } }; -void keyboard_init( keyboard_t *keyboard, keyboard_event_handler_t handler, interrupt_t *interrupt, void *context ) +void ps2keyboard_init( ps2keyboard_t *ps2keyboard, keyboard_event_handler_t handler, interrupt_t *interrupt, void *context ) { - memset( keyboard, 0, sizeof( keyboard_t ) ); + memset( ps2keyboard, 0, sizeof( ps2keyboard_t ) ); - driver_init( (driver_t *)keyboard, DRIVER_TYPE_KEYBOARD, interrupt, context ); + driver_init( (driver_t *)ps2keyboard, DRIVER_TYPE_KEYBOARD, interrupt, context ); - port8_init( &keyboard->command_port, 0x64 ); - port8_init( &keyboard->data_port, 0x60 ); + port8_init( &ps2keyboard->command_port, 0x64 ); + port8_init( &ps2keyboard->data_port, 0x60 ); - keyboard->shift = false; - keyboard->handler = handler; + ps2keyboard->shift = false; + ps2keyboard->base.handler = handler; - ((driver_t *)keyboard)->vtable = (driver_vtable_t *)&keyboard_vtable; + ((driver_t *)ps2keyboard)->vtable = (driver_vtable_t *)&ps2keyboard_vtable; } -void keyboard_activate( void *obj ) +void ps2keyboard_activate( void *obj ) { puts( "Activating driver for PS/2 keyboard.." ); driver_t *driver = obj; - keyboard_t *keyboard = obj; + ps2keyboard_t *ps2keyboard = obj; // first switch off port 1 - send_command( keyboard, COMMAND_DISABLE_PORT1 ); + send_command( ps2keyboard, COMMAND_DISABLE_PORT1 ); // consume character pressed before executing the kernel - while( port8_read( &keyboard->command_port ) & STATUS_REG_OUTPUT_BUF_FULL ) { - port8_read( &keyboard->data_port ); + while( port8_read( &ps2keyboard->command_port ) & STATUS_REG_OUTPUT_BUF_FULL ) { + port8_read( &ps2keyboard->data_port ); } // enable interrupts for port 1 - send_command( keyboard, COMMAND_GET_STATE ); - uint8_t status = read_data( keyboard ); + send_command( ps2keyboard, COMMAND_GET_STATE ); + uint8_t status = read_data( ps2keyboard ); status |= STATUS_CONTROL_CONFIG_ENABLE_IRQ_PORT1; status &= ~STATUS_CONTROL_CONFIG_CLOCK_PORT1; - send_command( keyboard, COMMAND_SET_STATE ); - write_data( keyboard, status ); + send_command( ps2keyboard, COMMAND_SET_STATE ); + write_data( ps2keyboard, status ); // disable all LEDs on keyboard - //~ send_command( keyboard, KBD_COMMAND_SET_LEDS ); - //~ write_data( keyboard, KBD_LED_ALL_ON ); + //~ send_command( ps2keyboard, KBD_COMMAND_SET_LEDS ); + //~ write_data( ps2keyboard, KBD_LED_ALL_ON ); // set scan code - //~ send_command( keyboard, KBD_SET_SCANCODE ); - //~ write_data( keyboard, KBD_SCANCODE_2 ); + //~ send_command( ps2keyboard, KBD_SET_SCANCODE ); + //~ write_data( ps2keyboard, KBD_SCANCODE_2 ); // activate keyboard - //send_command( keyboard, KBD_ACTIVATE ); - //read_ack( keyboard ); + //send_command( ps2keyboard, KBD_ACTIVATE ); + //read_ack( ps2keyboard ); - interrupt_handler_init( &keyboard->interrupt_handler, IRQ_BASE + 0x01, driver->interrupt, keyboard_handle_interrupt, obj ); - interrupts_register_interrupt_handler( keyboard->interrupt_handler ); + interrupt_handler_init( &ps2keyboard->interrupt_handler, IRQ_BASE + 0x01, driver->interrupt, ps2keyboard_handle_interrupt, obj ); + interrupts_register_interrupt_handler( ps2keyboard->interrupt_handler ); // enable port 1 - send_command( keyboard, COMMAND_ENABLE_PORT1 ); + send_command( ps2keyboard, COMMAND_ENABLE_PORT1 ); } -void keyboard_deactivate( void *obj ) +void ps2keyboard_deactivate( void *obj ) { puts( "Deactivating driver for PS/2 keyboard.." ); - keyboard_t *keyboard = obj; + ps2keyboard_t *ps2keyboard = obj; - send_command( keyboard, COMMAND_DISABLE_PORT1 ); + send_command( ps2keyboard, COMMAND_DISABLE_PORT1 ); } -void keyboard_deinit( void *obj ) +void ps2keyboard_deinit( void *obj ) { // nothing to do } @@ -262,13 +262,13 @@ static keycode_t scancode_to_keycode( scancode_set_t set, uint8_t scan_code ) #define SCAN_CODE_LEFT_SHIFT 0x2A #define SCAN_CODE_RIGHT_SHIFT 0x36 -uint32_t keyboard_handle_interrupt( interrupt_handler_t *handler, uint32_t esp ) +uint32_t ps2keyboard_handle_interrupt( interrupt_handler_t *handler, uint32_t esp ) { - keyboard_t *keyboard = (keyboard_t *)handler->driver; + ps2keyboard_t *ps2keyboard = (ps2keyboard_t *)handler->driver; // we can only wake up on IRQ1 because we don't send commands // after initialization - uint8_t scan_code = port8_read( &keyboard->data_port ); + uint8_t scan_code = port8_read( &ps2keyboard->data_port ); // we get break code when the high bit is set, so the // the key is released @@ -282,14 +282,14 @@ uint32_t keyboard_handle_interrupt( interrupt_handler_t *handler, uint32_t esp ) if( scan_code == SCAN_CODE_LEFT_SHIFT || scan_code == SCAN_CODE_RIGHT_SHIFT ) { if( break_code ) { - keyboard->shift = false; + ps2keyboard->shift = false; } else { - keyboard->shift = true; + ps2keyboard->shift = true; } } scancode_set_t code_set = SCANCODE_SET_NORMAL; - if( keyboard->shift ) { + if( ps2keyboard->shift ) { code_set = SCANCODE_SET_SHIFT; } @@ -297,7 +297,7 @@ uint32_t keyboard_handle_interrupt( interrupt_handler_t *handler, uint32_t esp ) #ifdef DEBUG printf( "KBD SCAN:0x%X S:%d B:%d S:%d T:0x%X '%c' 0x%X\n", - scan_code, code_set, break_code, keyboard->shift, + scan_code, code_set, break_code, ps2keyboard->shift, key_code.type, key_code.c, key_code.c ); #endif @@ -308,7 +308,7 @@ uint32_t keyboard_handle_interrupt( interrupt_handler_t *handler, uint32_t esp ) event.type = KEYBOARD_EVENT_TYPE_KEY_PRESSED; } event.modifiers = 0; - if( keyboard->shift ) { + if( ps2keyboard->shift ) { event.modifiers |= KEYBOARD_MODIFIER_SHIFT; } // TODO: for control, alt, meta, etc. @@ -320,12 +320,12 @@ uint32_t keyboard_handle_interrupt( interrupt_handler_t *handler, uint32_t esp ) event.key = KEYBOARD_KEY_ESC; } - keyboard->handler( &event, keyboard->base.context ); + ps2keyboard->base.handler( &event, ps2keyboard->base.base.context ); return esp; } -void keyboard_print_info( void *obj ) +void ps2keyboard_print_info( void *obj ) { puts( "PS/2 keyboard driver" ); } diff --git a/src/drivers/hdi/ps2/ps2keyboard.h b/src/drivers/hdi/ps2/ps2keyboard.h new file mode 100644 index 0000000..a5b66ca --- /dev/null +++ b/src/drivers/hdi/ps2/ps2keyboard.h @@ -0,0 +1,33 @@ +#ifndef PS2KEYBOARD_H +#define PS2KEYBOARD_H + +#include <stdbool.h> + +#include "string.h" + +#include "interrupts.h" +#include "port.h" + +#include "keyboard.h" + +typedef struct { + keyboard_t base; + port8_t command_port; + port8_t data_port; + bool shift; + interrupt_handler_t interrupt_handler; +} ps2keyboard_t; + +typedef struct { + keyboard_vtable_t base; +} ps2keyboard_vtable_t; + +void ps2keyboard_init( ps2keyboard_t *ps2keyboard, keyboard_event_handler_t handler, interrupt_t *interrupt, void *context ); +void ps2keyboard_activate( void *obj ); +void ps2keyboard_deactivate( void *obj ); +void ps2keyboard_deinit( void *obj ); +void ps2keyboard_print_info( void *obj ); + +uint32_t ps2keyboard_handle_interrupt( interrupt_handler_t *handler, uint32_t esp ); + +#endif // PS2KEYBOARD_H diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 9bb1054..91d9988 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -11,7 +11,7 @@ #include "stdio.h" #include "interrupts.h" #include "driver.h" -#include "keyboard.h" +#include "ps2keyboard.h" #include "ps2mouse.h" #include "pci.h" #include "memorymanagement.h" @@ -129,8 +129,8 @@ void kernel_main( void ) // hard-wired drivers - global_context.keyboard = (keyboard_t *)malloc( sizeof( keyboard_t ) ); - keyboard_init( global_context.keyboard, &handle_keyboard_event, &interrupt, (void *)&global_context ); + global_context.keyboard = (keyboard_t *)malloc( sizeof( ps2keyboard_t ) ); + ps2keyboard_init( (ps2keyboard_t *)global_context.keyboard, &handle_keyboard_event, &interrupt, (void *)&global_context ); driver_manager_add_driver( &global_context.driver_manager, (driver_t *)global_context.keyboard ); global_context.mouse = (mouse_t *)malloc( sizeof( ps2mouse_t ) ); |