summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2017-06-02 09:38:38 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2017-06-02 09:38:38 +0200
commit0b034e25560ec3d5c73d0d2ced8632eecbbaff8f (patch)
tree86dbcbc3ddb79d0f232e0144a56351d6d90888f8
parent32db109e61f7e67c85907f36d00518d662238087 (diff)
downloadabaos-0b034e25560ec3d5c73d0d2ced8632eecbbaff8f.tar.gz
abaos-0b034e25560ec3d5c73d0d2ced8632eecbbaff8f.tar.bz2
some work on keyboard initialization
-rw-r--r--doc/LINKS.TODO3
-rw-r--r--src/Makefile4
-rw-r--r--src/kernel.c1
-rw-r--r--src/keyboard.c96
-rw-r--r--src/stage1_functions.asm2
5 files changed, 99 insertions, 7 deletions
diff --git a/doc/LINKS.TODO b/doc/LINKS.TODO
index 53cc093..daf9016 100644
--- a/doc/LINKS.TODO
+++ b/doc/LINKS.TODO
@@ -43,4 +43,7 @@ http://wiki.osdev.org/8259_PIC
keyboard:
http://wiki.osdev.org/"8042"_PS/2_Controller
+https://www.lowlevel.eu/wiki/Keyboard_Controller
+PIT:
+http://wiki.osdev.org/Programmable_Interval_Timer
diff --git a/src/Makefile b/src/Makefile
index 14aa939..d72f5aa 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 20)
+# loads only the first sector, so adapt NOF_LOAD_SECTORS to 21)
image.bin: boot.bin kernel.bin magic.bin
cat boot.bin kernel.bin > image.tmp
- truncate -s 10240 image.tmp
+ truncate -s 10752 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/kernel.c b/src/kernel.c
index 732151e..d4dba01 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -36,6 +36,7 @@ void entry( void )
interrupt_t interrupt;
interrupts_init( &interrupt );
+ puts( "Initializing PS/2 keyboard" );
keyboard_t keyboard;
keyboard_init( &keyboard );
interrupt_handler_t keyboard_interrupt_handler;
diff --git a/src/keyboard.c b/src/keyboard.c
index f89332c..c591c6a 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1,7 +1,62 @@
+#include <stdbool.h>
+
#include "keyboard.h"
#include "stdio.h"
+// status register on command port (read)
+#define STATUS_REG_OUTPUT_BUF_FULL 0x01
+#define STATUS_REG_INPUT_BUF_FULL 0x02
+
+// generic PS/2 commands
+#define COMMAND_GET_STATE 0x20
+#define COMMAND_SET_STATE 0x60
+#define COMMAND_DISABLE_PORT1 0xAD
+#define COMMAND_ENABLE_PORT1 0xAE
+
+// keyboard specific commands, PSAUX1
+#define KBD_COMMAND_SET_LEDS 0xED
+#define KBD_SET_SCANCODE 0xF0
+#define KBD_ACTIVATE 0xF4
+
+#define STATUS_CONTROL_CONFIG_ENABLE_IRQ_PORT1 0x01
+#define STATUS_CONTROL_CONFIG_CLOCK_PORT1 0x10
+
+// keyboard LED status codes
+#define KBD_LED_SCROLL_LOCK_ON 0x01
+#define KBD_LED_NUM_LOCK_ON 0x02
+#define KBD_LED_CAPS_LOCK_ON 0x04
+#define KBD_LED_ALL_OFF 0x00
+#define KBD_LED_ALL_ON KBD_LED_SCROLL_LOCK_ON | KBD_LED_NUM_LOCK_ON | KBD_LED_CAPS_LOCK_ON
+
+// keyboard scan codes
+#define KBD_SCANCODE_1 0x01
+#define KBD_SCANCODE_2 0x02
+#define KBD_SCANCODE_3 0x03
+
+static bool has_data( keyboard_t *keyboard )
+{
+ return ( port8_read( &keyboard->command_port ) & STATUS_REG_OUTPUT_BUF_FULL ) == STATUS_REG_OUTPUT_BUF_FULL;
+}
+
+static uint8_t read_data( keyboard_t *keyboard )
+{
+ while( ( port8_read( &keyboard->command_port ) & STATUS_REG_OUTPUT_BUF_FULL ) == 0 ) { }
+ return port8_read( &keyboard->data_port );
+}
+
+static void send_command( keyboard_t *keyboard, uint8_t command )
+{
+ while( port8_read( &keyboard->command_port ) & STATUS_REG_INPUT_BUF_FULL ) { }
+ port8_write( &keyboard->command_port, command );
+}
+
+static void write_data( keyboard_t *keyboard, uint8_t data )
+{
+ while( port8_read( &keyboard->command_port ) & STATUS_REG_INPUT_BUF_FULL ) { }
+ port8_write( &keyboard->data_port, data );
+}
+
void keyboard_init( keyboard_t *keyboard )
{
memset( keyboard, 0, sizeof( keyboard_t ) );
@@ -9,14 +64,47 @@ void keyboard_init( keyboard_t *keyboard )
port8_init( &keyboard->command_port, 0x64 );
port8_init( &keyboard->data_port, 0x60 );
+ // first switch off port 1
+ send_command( keyboard, 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 );
+ }
+
+ // enable port 1
+ send_command( keyboard, COMMAND_ENABLE_PORT1 );
+
+ // enable interrupts for port 1
+ send_command( keyboard, COMMAND_GET_STATE );
+ uint8_t status = read_data( keyboard );
+ status |= STATUS_CONTROL_CONFIG_ENABLE_IRQ_PORT1;
+ status &= ~STATUS_CONTROL_CONFIG_CLOCK_PORT1;
+ send_command( keyboard, COMMAND_SET_STATE );
+ write_data( keyboard, status );
+
+ // disable all LEDs on keyboard
+ //~ send_command( keyboard, KBD_COMMAND_SET_LEDS );
+ //~ write_data( keyboard, KBD_LED_ALL_ON );
+
+ // set scan code
+ //~ send_command( keyboard, KBD_SET_SCANCODE );
+ //~ write_data( keyboard, KBD_SCANCODE_2 );
+
+ // activate keyboard
+ //~ send_command( keyboard, KBD_ACTIVATE );
}
-
+
uint32_t keyboard_handle_interrupt( interrupt_handler_t *handler, uint32_t esp )
{
keyboard_t *keyboard = (keyboard_t *)handler->driver;
- uint8_t key = port8_read( &keyboard->data_port );
- printf( "KBD 0x%X ", key );
-
+ if( has_data( keyboard ) ) {
+ uint8_t scancode = read_data( keyboard );
+ printf( "KBD 0x%X ", scancode );
+ } else {
+ printf( "SPURIOUS KBD INTERRUPT " );
+ }
+
return esp;
}
diff --git a/src/stage1_functions.asm b/src/stage1_functions.asm
index 8953b9c..46fbc74 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 20
+NOF_LOAD_SECTORS equ 21
; IN bx: begin of memory area to dump
; IN ax: number of words to dump