From: Kevin O'Connor Date: Thu, 13 Mar 2008 01:27:02 +0000 (-0400) Subject: Move keyboard setup to kbd.c. X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=2018eff2cf3f4caced677a7c3bc0b0b9af5bc8d7;p=seabios.git Move keyboard setup to kbd.c. Now kbd.c is compiled by both 16bit and 32bit code. --- diff --git a/Makefile b/Makefile index 10c849c..fcb5169 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ OUT=out/ # Source files SRC16=floppy.c disk.c system.c clock.c serial.c kbd.c mouse.c output.c \ boot.c ata.c cdrom.c apm.c util.c -SRC32=post.c output.c rombios32.c util.c ata.c +SRC32=post.c output.c rombios32.c util.c ata.c kbd.c TABLESRC=font.c cbt.c floppy_dbt.c cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \ diff --git a/src/kbd.c b/src/kbd.c index 86a470e..29ef1b3 100644 --- a/src/kbd.c +++ b/src/kbd.c @@ -9,6 +9,154 @@ #include "util.h" // debug_enter #include "config.h" // CONFIG_* +//-------------------------------------------------------------------------- +// keyboard_panic +//-------------------------------------------------------------------------- +static void +keyboard_panic(u16 status) +{ + // If you're getting a 993 keyboard panic here, + // please see the comment in keyboard_init + + BX_PANIC("Keyboard error:%u\n",status); +} + +static void +kbd_flush(u8 code) +{ + u16 max = 0xffff; + while ((inb(PORT_PS2_STATUS) & 0x02) && (--max > 0)) + outb(code, PORT_DIAG); + if (!max && code != 0xff) + keyboard_panic(code); +} + +static void +kbd_waitdata(u8 code) +{ + u16 max = 0xffff; + while ( ((inb(PORT_PS2_STATUS) & 0x01) == 0) && (--max>0) ) + outb(code, PORT_DIAG); + if (!max) + keyboard_panic(code); +} + +//-------------------------------------------------------------------------- +// keyboard_init +//-------------------------------------------------------------------------- +// this file is based on LinuxBIOS implementation of keyboard.c +static void +keyboard_init() +{ + /* ------------------- Flush buffers ------------------------*/ + /* Wait until buffer is empty */ + kbd_flush(0xff); + + /* flush incoming keys */ + u16 max=0x2000; + while (--max > 0) { + outb(0x00, PORT_DIAG); + if (inb(PORT_PS2_STATUS) & 0x01) { + inb(PORT_PS2_DATA); + max = 0x2000; + } + } + + // Due to timer issues, and if the IPS setting is > 15000000, + // the incoming keys might not be flushed here. That will + // cause a panic a few lines below. See sourceforge bug report : + // [ 642031 ] FATAL: Keyboard RESET error:993 + + /* ------------------- controller side ----------------------*/ + /* send cmd = 0xAA, self test 8042 */ + outb(0xaa, PORT_PS2_STATUS); + + kbd_flush(0x00); + kbd_waitdata(0x01); + + /* read self-test result, 0x55 should be returned from 0x60 */ + if (inb(PORT_PS2_DATA) != 0x55) + keyboard_panic(991); + + /* send cmd = 0xAB, keyboard interface test */ + outb(0xab, PORT_PS2_STATUS); + + kbd_flush(0x10); + kbd_waitdata(0x11); + + /* read keyboard interface test result, */ + /* 0x00 should be returned form 0x60 */ + if (inb(PORT_PS2_DATA) != 0x00) + keyboard_panic(992); + + /* Enable Keyboard clock */ + outb(0xae, PORT_PS2_STATUS); + outb(0xa8, PORT_PS2_STATUS); + + /* ------------------- keyboard side ------------------------*/ + /* reset kerboard and self test (keyboard side) */ + outb(0xff, PORT_PS2_DATA); + + kbd_flush(0x20); + kbd_waitdata(0x21); + + /* keyboard should return ACK */ + if (inb(PORT_PS2_DATA) != 0xfa) + keyboard_panic(993); + + kbd_waitdata(0x31); + + if (inb(PORT_PS2_DATA) != 0xaa) + keyboard_panic(994); + + /* Disable keyboard */ + outb(0xf5, PORT_PS2_DATA); + + kbd_flush(0x40); + kbd_waitdata(0x41); + + /* keyboard should return ACK */ + if (inb(PORT_PS2_DATA) != 0xfa) + keyboard_panic(995); + + /* Write Keyboard Mode */ + outb(0x60, PORT_PS2_STATUS); + + kbd_flush(0x50); + + /* send cmd: scan code convert, disable mouse, enable IRQ 1 */ + outb(0x61, PORT_PS2_DATA); + + kbd_flush(0x60); + + /* Enable keyboard */ + outb(0xf4, PORT_PS2_DATA); + + kbd_flush(0x70); + kbd_waitdata(0x71); + + /* keyboard should return ACK */ + if (inb(PORT_PS2_DATA) != 0xfa) + keyboard_panic(996); + + outb(0x77, PORT_DIAG); +} + +void +kbd_setup() +{ + u16 x = offsetof(struct bios_data_area_s, kbd_buf) - 0x400; + SET_BDA(kbd_mode, 0x10); + SET_BDA(kbd_buf_head, x); + SET_BDA(kbd_buf_tail, x); + SET_BDA(kbd_buf_start_offset, x); + + SET_BDA(kbd_buf_end_offset + , x + FIELD_SIZEOF(struct bios_data_area_s, kbd_buf)); + + keyboard_init(); +} + static u8 enqueue_key(u8 scan_code, u8 ascii_code) { diff --git a/src/kbd.h b/src/kbd.h new file mode 100644 index 0000000..5fb2400 --- /dev/null +++ b/src/kbd.h @@ -0,0 +1,17 @@ +/* + * kbd.h + * Keyboard support for BIOS. + * + * Copyright (C) 2008 Nguyen Anh Quynh + * + * This file may be distributed under the terms of the GNU GPLv3 license. + */ + +#ifndef __KBD_H +#define __KBD_H + +#include "types.h" + +void kbd_setup(); + +#endif diff --git a/src/post.c b/src/post.c index 3ff8f30..5254997 100644 --- a/src/post.c +++ b/src/post.c @@ -12,6 +12,7 @@ #include "util.h" // memset #include "biosvar.h" // struct bios_data_area_s #include "ata.h" +#include "kbd.h" #define bda ((struct bios_data_area_s *)0) #define ebda ((struct extended_bios_data_area_s *)(EBDA_SEG<<4)) @@ -98,153 +99,6 @@ pit_setup() outb(0x0, PORT_PIT_COUNTER0); } -//-------------------------------------------------------------------------- -// keyboard_panic -//-------------------------------------------------------------------------- -static void -keyboard_panic(u16 status) -{ - // If you're getting a 993 keyboard panic here, - // please see the comment in keyboard_init - - BX_PANIC("Keyboard error:%u\n",status); -} - -static void -kbd_flush(u8 code) -{ - u16 max = 0xffff; - while ((inb(PORT_PS2_STATUS) & 0x02) && (--max > 0)) - outb(code, PORT_DIAG); - if (!max && code != 0xff) - keyboard_panic(code); -} - -static void -kbd_waitdata(u8 code) -{ - u16 max = 0xffff; - while ( ((inb(PORT_PS2_STATUS) & 0x01) == 0) && (--max>0) ) - outb(code, PORT_DIAG); - if (!max) - keyboard_panic(code); -} - -//-------------------------------------------------------------------------- -// keyboard_init -//-------------------------------------------------------------------------- -// this file is based on LinuxBIOS implementation of keyboard.c -static void -keyboard_init() -{ - /* ------------------- Flush buffers ------------------------*/ - /* Wait until buffer is empty */ - kbd_flush(0xff); - - /* flush incoming keys */ - u16 max=0x2000; - while (--max > 0) { - outb(0x00, PORT_DIAG); - if (inb(PORT_PS2_STATUS) & 0x01) { - inb(PORT_PS2_DATA); - max = 0x2000; - } - } - - // Due to timer issues, and if the IPS setting is > 15000000, - // the incoming keys might not be flushed here. That will - // cause a panic a few lines below. See sourceforge bug report : - // [ 642031 ] FATAL: Keyboard RESET error:993 - - /* ------------------- controller side ----------------------*/ - /* send cmd = 0xAA, self test 8042 */ - outb(0xaa, PORT_PS2_STATUS); - - kbd_flush(0x00); - kbd_waitdata(0x01); - - /* read self-test result, 0x55 should be returned from 0x60 */ - if (inb(PORT_PS2_DATA) != 0x55) - keyboard_panic(991); - - /* send cmd = 0xAB, keyboard interface test */ - outb(0xab, PORT_PS2_STATUS); - - kbd_flush(0x10); - kbd_waitdata(0x11); - - /* read keyboard interface test result, */ - /* 0x00 should be returned form 0x60 */ - if (inb(PORT_PS2_DATA) != 0x00) - keyboard_panic(992); - - /* Enable Keyboard clock */ - outb(0xae, PORT_PS2_STATUS); - outb(0xa8, PORT_PS2_STATUS); - - /* ------------------- keyboard side ------------------------*/ - /* reset kerboard and self test (keyboard side) */ - outb(0xff, PORT_PS2_DATA); - - kbd_flush(0x20); - kbd_waitdata(0x21); - - /* keyboard should return ACK */ - if (inb(PORT_PS2_DATA) != 0xfa) - keyboard_panic(993); - - kbd_waitdata(0x31); - - if (inb(PORT_PS2_DATA) != 0xaa) - keyboard_panic(994); - - /* Disable keyboard */ - outb(0xf5, PORT_PS2_DATA); - - kbd_flush(0x40); - kbd_waitdata(0x41); - - /* keyboard should return ACK */ - if (inb(PORT_PS2_DATA) != 0xfa) - keyboard_panic(995); - - /* Write Keyboard Mode */ - outb(0x60, PORT_PS2_STATUS); - - kbd_flush(0x50); - - /* send cmd: scan code convert, disable mouse, enable IRQ 1 */ - outb(0x61, PORT_PS2_DATA); - - kbd_flush(0x60); - - /* Enable keyboard */ - outb(0xf4, PORT_PS2_DATA); - - kbd_flush(0x70); - kbd_waitdata(0x71); - - /* keyboard should return ACK */ - if (inb(PORT_PS2_DATA) != 0xfa) - keyboard_panic(996); - - outb(0x77, PORT_DIAG); -} - -static void -kbd_setup() -{ - u16 x = offsetof(struct bios_data_area_s, kbd_buf) - 0x400; - SET_BDA(kbd_mode, 0x10); - SET_BDA(kbd_buf_head, x); - SET_BDA(kbd_buf_tail, x); - SET_BDA(kbd_buf_start_offset, x); - - SET_BDA(kbd_buf_end_offset, x + sizeof(bda->kbd_buf)); - - keyboard_init(); -} - static u16 detect_parport(u16 port, u8 timeout, u8 count) {