summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2000-08-30 08:15:30 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2000-08-30 08:15:30 +0000
commit3cbb63ac774a21e13f5f75271810754b70ff311d (patch)
tree66325321fdf790e0fc19503652fca633fdb7f5b0
parentfe602cfef04bd6458431647d3ec903f209bb13db (diff)
downloadrtems-3cbb63ac774a21e13f5f75271810754b70ff311d.tar.bz2
2000-08-26 Rosimildo da Silva <rdasilva@connecttel.com>
* Major rework of the "/dev/console" driver. * Added termios support for stdin ( keyboard ). * Added ioctls() to support modes similar to Linux( XLATE, RAW, MEDIUMRAW ). * Added Keyboard mapping and handling of the keyboard's leds. * Added Micro FrameBuffer driver ( "/dev/fb0" ) for bare VGA controller ( 16 colors ). * Added PS/2 and Serial mouse support for PC386 BSP. * console/defkeymap.c: New file. * console/fb_vga.c: New file. * console/fb_vga.h: New file. * console/i386kbd.h: New file. * console/kd.h: New file. * console/keyboard.c: New file. * console/keyboard.h: New file. * console/mouse_parser.c: New file. * console/mouse_parser.h: New file. * console/pc_keyb.c: New file. * console/ps2_drv.h: New file. * console/ps2_mouse.c: New file. * console/ps2_mouse.h: New file. * console/serial_mouse.c: New file. * console/serial_mouse.h: New file. * console/vgainit.c: New file. * console/vt.c: New file. * console/Makefile.am: Reflect new files. * console/console.c, console/inch.c, console/outch.c: Console functionality modifications. * startup/Makefile.am: Pick up tty_drv.c and gdb_glue.c
-rw-r--r--c/src/lib/libbsp/i386/pc386/ChangeLog32
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/Makefile.am19
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/console.c187
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/defkeymap.c263
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/fb_vga.c245
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/fb_vga.h81
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/i386kbd.h189
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/inch.c298
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/kd.h114
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/keyboard.c928
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/keyboard.h588
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/mouse_parser.c400
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/mouse_parser.h36
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/outch.c21
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/pc_keyb.c648
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/ps2_drv.h80
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/ps2_mouse.c708
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/ps2_mouse.h146
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/serial_mouse.c348
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/serial_mouse.h86
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/vgainit.c766
-rw-r--r--c/src/lib/libbsp/i386/pc386/console/vt.c347
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/Makefile.am3
23 files changed, 6182 insertions, 351 deletions
diff --git a/c/src/lib/libbsp/i386/pc386/ChangeLog b/c/src/lib/libbsp/i386/pc386/ChangeLog
index 101734ce64..7c43e92c7f 100644
--- a/c/src/lib/libbsp/i386/pc386/ChangeLog
+++ b/c/src/lib/libbsp/i386/pc386/ChangeLog
@@ -1,3 +1,35 @@
+2000-08-26 Rosimildo da Silva <rdasilva@connecttel.com>
+
+ * Major rework of the "/dev/console" driver.
+ * Added termios support for stdin ( keyboard ).
+ * Added ioctls() to support modes similar to Linux( XLATE,
+ RAW, MEDIUMRAW ).
+ * Added Keyboard mapping and handling of the keyboard's leds.
+ * Added Micro FrameBuffer driver ( "/dev/fb0" ) for bare VGA
+ controller ( 16 colors ).
+ * Added PS/2 and Serial mouse support for PC386 BSP.
+ * console/defkeymap.c: New file.
+ * console/fb_vga.c: New file.
+ * console/fb_vga.h: New file.
+ * console/i386kbd.h: New file.
+ * console/kd.h: New file.
+ * console/keyboard.c: New file.
+ * console/keyboard.h: New file.
+ * console/mouse_parser.c: New file.
+ * console/mouse_parser.h: New file.
+ * console/pc_keyb.c: New file.
+ * console/ps2_drv.h: New file.
+ * console/ps2_mouse.c: New file.
+ * console/ps2_mouse.h: New file.
+ * console/serial_mouse.c: New file.
+ * console/serial_mouse.h: New file.
+ * console/vgainit.c: New file.
+ * console/vt.c: New file.
+ * console/Makefile.am: Reflect new files.
+ * console/console.c, console/inch.c, console/outch.c: Console
+ functionality modifications.
+ * startup/Makefile.am: Pick up tty_drv.c and gdb_glue.c
+
2000-08-10 Joel Sherrill <joel@OARcorp.com>
* ChangeLog: New file.
diff --git a/c/src/lib/libbsp/i386/pc386/console/Makefile.am b/c/src/lib/libbsp/i386/pc386/console/Makefile.am
index 6d8f0695d4..d95fa73f0a 100644
--- a/c/src/lib/libbsp/i386/pc386/console/Makefile.am
+++ b/c/src/lib/libbsp/i386/pc386/console/Makefile.am
@@ -8,7 +8,10 @@ VPATH = @srcdir@:@srcdir@/../../shared/io
PGM = $(ARCH)/console.rel
-C_FILES = console.c inch.c outch.c
+RTEMS_H_FILES = keyboard.h kd.h serial_mouse.h ps2_drv.h fb_vga.h
+
+C_FILES = console.c inch.c outch.c defkeymap.c fb_vga.c keyboard.c \
+ mouse_parser.c pc_keyb.c ps2_mouse.c serial_mouse.c vgainit.c vt.c
S_FILES = videoAsm.S
console_rel_OBJECTS = $(C_FILES:%.c=$(ARCH)/%.o) $(S_FILES:%.S=$(ARCH)/%.o)
@@ -16,6 +19,10 @@ console_rel_OBJECTS = $(C_FILES:%.c=$(ARCH)/%.o) $(S_FILES:%.S=$(ARCH)/%.o)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../../automake/lib.am
+
+PREINSTALL_FILES = $(PROJECT_INCLUDE) \
+ $(RTEMS_H_FILES:%.h=$(PROJECT_INCLUDE)/rtems/%.h)
+
#
# (OPTIONAL) Add local stuff here using +=
#
@@ -23,13 +30,19 @@ include $(top_srcdir)/../../../../../../automake/lib.am
$(PGM): $(console_rel_OBJECTS)
$(make-rel)
+$(PROJECT_INCLUDE)/rtems:
+ $(mkinstalldirs) $@
+
+$(PROJECT_INCLUDE)/rtems/%.h: %.h
+ $(INSTALL_DATA) $< $@
+
# the .rel file built here will be put into libbsp.a by
# ../wrapup/Makefile
-all-local: $(ARCH) $(console_rel_OBJECTS) $(PGM)
+all-local: $(PREINSTALL_FILES) $(ARCH) $(console_rel_OBJECTS) $(PGM)
.PRECIOUS: $(PGM)
-EXTRA_DIST = console.c inch.c outch.c videoAsm.S
+EXTRA_DIST = $(C_FILES) $(RTEMS_H_FILES) $(S_FILES)
include $(top_srcdir)/../../../../../../automake/local.am
diff --git a/c/src/lib/libbsp/i386/pc386/console/console.c b/c/src/lib/libbsp/i386/pc386/console/console.c
index fff960eb91..2293d81389 100644
--- a/c/src/lib/libbsp/i386/pc386/console/console.c
+++ b/c/src/lib/libbsp/i386/pc386/console/console.c
@@ -44,6 +44,9 @@ void __assert (const char *file, int line, const char *msg);
#include <uart.h>
#include <libcpu/cpuModel.h>
+#include <rtems/mw_uid.h>
+#include "mouse_parser.h"
+
/*
* Possible value for console input/output :
* BSP_CONSOLE_PORT_CONSOLE
@@ -65,12 +68,13 @@ int BSPPrintkPort = BSP_CONSOLE_PORT_CONSOLE;
int BSPBaseBaud = 115200;
extern BSP_polling_getchar_function_type BSP_poll_char;
+extern int getch( void );
+extern void kbd_init( void );
/*-------------------------------------------------------------------------+
| External Prototypes
+--------------------------------------------------------------------------*/
-extern void _IBMPC_keyboard_isr(void);
-extern rtems_boolean _IBMPC_scankey(char *); /* defined in 'inch.c' */
+extern void keyboard_interrupt(void);
extern char BSP_wait_polled_input(void);
extern void _IBMPC_initVideo(void);
@@ -79,9 +83,10 @@ static void isr_on(const rtems_irq_connect_data *);
static void isr_off(const rtems_irq_connect_data *);
static int isr_is_on(const rtems_irq_connect_data *);
+extern int rtems_kbpoll( void );
static rtems_irq_connect_data console_isr_data = {BSP_KEYBOARD,
- _IBMPC_keyboard_isr,
+ keyboard_interrupt,
isr_on,
isr_off,
isr_is_on};
@@ -104,6 +109,44 @@ isr_is_on(const rtems_irq_connect_data *irq)
return BSP_irq_enabled_at_i8259s(irq->name);
}
+extern char _IBMPC_inch(void);
+extern int rtems_kbpoll( void );
+
+static int
+ibmpc_console_write(int minor, const char *buf, int len)
+{
+ int count;
+ for (count = 0; count < len; count++)
+ {
+ _IBMPC_outch( buf[ count ] );
+ if( buf[ count ] == '\n')
+ _IBMPC_outch( '\r' ); /* LF = LF + CR */
+ }
+ return 0;
+}
+
+
+int kbd_poll_read( int minor )
+{
+ if( rtems_kbpoll() )
+ {
+ int c = getch();
+ return c;
+ }
+ return -1;
+}
+
+/*
+static void* termios_ttyp_console = NULL;
+void enq_key( char key )
+{
+ if( termios_ttyp_console )
+ {
+ rtems_termios_enqueue_raw_characters(termios_ttyp_console, &key,1 );
+ }
+}
+*/
+
void __assert (const char *file, int line, const char *msg)
{
static char exit_msg[] = "EXECUTIVE SHUTDOWN! Any key to reboot...";
@@ -144,18 +187,26 @@ console_initialize(rtems_device_major_number major,
{
rtems_status_code status;
+
+ /* Initialize the KBD interface */
+ kbd_init();
+
+ /*
+ * Set up TERMIOS
+ */
+ rtems_termios_initialize ();
+
/*
* The video was initialized in the start.s code and does not need
* to be reinitialized.
*/
-
if(BSPConsolePort == BSP_CONSOLE_PORT_CONSOLE)
{
/* Install keyboard interrupt handler */
status = BSP_install_rtems_irq_handler(&console_isr_data);
- if (!status)
+ if (!status)
{
printk("Error installing keyboard interrupt handler!\n");
rtems_fatal_error_occurred(status);
@@ -172,32 +223,25 @@ console_initialize(rtems_device_major_number major,
else
{
/*
- * Set up TERMIOS
- */
- rtems_termios_initialize ();
-
- /*
* Do device-specific initialization
*/
-
/* 9600-8-N-1 */
BSP_uart_init(BSPConsolePort, 9600, 0);
/* Set interrupt handler */
if(BSPConsolePort == BSP_UART_COM1)
- {
- console_isr_data.name = BSP_UART_COM1_IRQ;
- console_isr_data.hdl = BSP_uart_termios_isr_com1;
+ {
+ console_isr_data.name = BSP_UART_COM1_IRQ;
+ console_isr_data.hdl = BSP_uart_termios_isr_com1;
- }
+ }
else
- {
+ {
assert(BSPConsolePort == BSP_UART_COM2);
- console_isr_data.name = BSP_UART_COM2_IRQ;
- console_isr_data.hdl = BSP_uart_termios_isr_com2;
- }
-
+ console_isr_data.name = BSP_UART_COM2_IRQ;
+ console_isr_data.hdl = BSP_uart_termios_isr_com2;
+ }
status = BSP_install_rtems_irq_handler(&console_isr_data);
if (!status){
@@ -269,7 +313,7 @@ console_open(rtems_device_major_number major,
{
NULL, /* firstOpen */
console_last_close, /* lastClose */
- NULL, /* pollRead */
+ NULL, /* pollRead */
BSP_uart_termios_write_com1, /* write */
conSetAttr, /* setAttributes */
NULL, /* stopRemoteTx */
@@ -279,8 +323,23 @@ console_open(rtems_device_major_number major,
if(BSPConsolePort == BSP_CONSOLE_PORT_CONSOLE)
{
+
+ /* Let's set the routines for termios to poll the
+ * Kbd queue for data
+ */
+ cb.pollRead = kbd_poll_read;
+ cb.outputUsesInterrupts = 0;
+ /* write the "echo" if it is on */
+ cb.write = ibmpc_console_write;
+
+ cb.setAttributes = NULL;
++console_open_count;
- return RTEMS_SUCCESSFUL;
+ status = rtems_termios_open (major, minor, arg, &cb);
+ if(status != RTEMS_SUCCESSFUL)
+ {
+ printk("Error openning console device\n");
+ }
+ return status;
}
if(BSPConsolePort == BSP_UART_COM2)
@@ -316,19 +375,7 @@ console_close(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
- rtems_device_driver res = RTEMS_SUCCESSFUL;
-
- if(BSPConsolePort != BSP_CONSOLE_PORT_CONSOLE)
- {
- res = rtems_termios_close (arg);
- }
- else {
- if (--console_open_count == 0) {
- console_last_close(major, minor, arg);
- }
- }
-
- return res;
+ return rtems_termios_close (arg);
} /* console_close */
@@ -342,38 +389,7 @@ console_read(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
- rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
- char *buffer = rw_args->buffer;
- int count, maximum = rw_args->count;
-
- if(BSPConsolePort != BSP_CONSOLE_PORT_CONSOLE)
- {
- return rtems_termios_read (arg);
- }
-
- for (count = 0; count < maximum; count++)
- {
- /* Get character */
- buffer[count] = _IBMPC_inch_sleep();
-
- /* Echo character to screen */
- _IBMPC_outch(buffer[count]);
- if (buffer[count] == '\r')
- {
- _IBMPC_outch('\n'); /* CR = CR + LF */
- }
-
- if (buffer[count] == '\n' || buffer[count] == '\r')
- {
- /* What if this goes past the end of the buffer? We're hosed. [bhc] */
- buffer[count++] = '\n';
- buffer[count] = '\0';
- break;
- }
- }
-
- rw_args->bytes_moved = count;
- return ((count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED);
+ return rtems_termios_read( arg );
} /* console_read */
@@ -389,25 +405,21 @@ console_write(rtems_device_major_number major,
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
char *buffer = rw_args->buffer;
- int count, maximum = rw_args->count;
+ int maximum = rw_args->count;
if(BSPConsolePort != BSP_CONSOLE_PORT_CONSOLE)
{
return rtems_termios_write (arg);
}
- for (count = 0; count < maximum; count++)
- {
- _IBMPC_outch(buffer[count]);
- if (buffer[count] == '\n')
- _IBMPC_outch('\r'); /* LF = LF + CR */
- }
-
+ /* write data to VGA */
+ ibmpc_console_write( minor, buffer, maximum );
rw_args->bytes_moved = maximum;
return RTEMS_SUCCESSFUL;
} /* console_write */
+extern int vt_ioctl( unsigned int cmd, unsigned long arg);
/*
* Handle ioctl request.
@@ -418,12 +430,25 @@ console_control(rtems_device_major_number major,
void * arg
)
{
- if(BSPConsolePort != BSP_CONSOLE_PORT_CONSOLE)
- {
- return rtems_termios_ioctl (arg);
- }
-
- return RTEMS_SUCCESSFUL;
+ rtems_libio_ioctl_args_t *args = arg;
+ switch (args->command)
+ {
+ default:
+ if( vt_ioctl( args->command, (unsigned long)args->buffer ) != 0 )
+ return rtems_termios_ioctl (arg);
+ break;
+
+ case MW_UID_REGISTER_DEVICE:
+ printk( "SerialMouse: reg=%s\n", args->buffer );
+ register_kbd_msg_queue( args->buffer, 0 );
+ break;
+
+ case MW_UID_UNREGISTER_DEVICE:
+ unregister_kbd_msg_queue( 0 );
+ break;
+ }
+ args->ioctl_return = 0;
+ return RTEMS_SUCCESSFUL;
}
static int
diff --git a/c/src/lib/libbsp/i386/pc386/console/defkeymap.c b/c/src/lib/libbsp/i386/pc386/console/defkeymap.c
new file mode 100644
index 0000000000..3ed68fd38c
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/defkeymap.c
@@ -0,0 +1,263 @@
+/* Do not edit this file! It was automatically generated by */
+/* loadkeys --mktable defkeymap.map > defkeymap.c */
+
+#include <sys/types.h>
+#include <rtems/keyboard.h>
+#include <rtems/kd.h>
+
+u_short plain_map[NR_KEYS] = {
+ 0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036,
+ 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009,
+ 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
+ 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73,
+ 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b,
+ 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76,
+ 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c,
+ 0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
+ 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307,
+ 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
+ 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a,
+ 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+ 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
+ 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+};
+
+u_short shift_map[NR_KEYS] = {
+ 0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e,
+ 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009,
+ 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49,
+ 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53,
+ 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a,
+ 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56,
+ 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c,
+ 0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e,
+ 0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf213, 0xf203, 0xf307,
+ 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
+ 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a,
+ 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+ 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
+ 0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116,
+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+};
+
+u_short altgr_map[NR_KEYS] = {
+ 0xf200, 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200,
+ 0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200,
+ 0xfb71, 0xfb77, 0xf918, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
+ 0xfb6f, 0xfb70, 0xf200, 0xf07e, 0xf201, 0xf702, 0xf914, 0xfb73,
+ 0xf917, 0xf919, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf200,
+ 0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xf916, 0xfb76,
+ 0xf915, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
+ 0xf703, 0xf200, 0xf207, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510,
+ 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf202, 0xf911,
+ 0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b,
+ 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516,
+ 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+ 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
+ 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+};
+
+u_short ctrl_map[NR_KEYS] = {
+ 0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e,
+ 0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf200,
+ 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
+ 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf702, 0xf001, 0xf013,
+ 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
+ 0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016,
+ 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c,
+ 0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
+ 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf204, 0xf307,
+ 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
+ 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf10a,
+ 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+ 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
+ 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+};
+
+u_short shift_ctrl_map[NR_KEYS] = {
+ 0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200,
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200,
+ 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
+ 0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013,
+ 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
+ 0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016,
+ 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
+ 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307,
+ 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
+ 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200,
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+ 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
+ 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+};
+
+u_short alt_map[NR_KEYS] = {
+ 0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836,
+ 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809,
+ 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869,
+ 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873,
+ 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b,
+ 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876,
+ 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c,
+ 0xf703, 0xf820, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
+ 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf907,
+ 0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901,
+ 0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a,
+ 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+ 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
+ 0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+};
+
+u_short ctrl_alt_map[NR_KEYS] = {
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+ 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809,
+ 0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813,
+ 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200,
+ 0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816,
+ 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
+ 0xf703, 0xf200, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
+ 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf200, 0xf307,
+ 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
+ 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf50a,
+ 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+ 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
+ 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c,
+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+};
+
+ushort *key_maps[MAX_NR_KEYMAPS] = {
+ plain_map, shift_map, altgr_map, 0,
+ ctrl_map, shift_ctrl_map, 0, 0,
+ alt_map, 0, 0, 0,
+ ctrl_alt_map, 0
+};
+
+unsigned int keymap_count = 7;
+
+/*
+ * Philosophy: most people do not define more strings, but they who do
+ * often want quite a lot of string space. So, we statically allocate
+ * the default and allocate dynamically in chunks of 512 bytes.
+ */
+
+char func_buf[] = {
+ '\033', '[', '[', 'A', 0,
+ '\033', '[', '[', 'B', 0,
+ '\033', '[', '[', 'C', 0,
+ '\033', '[', '[', 'D', 0,
+ '\033', '[', '[', 'E', 0,
+ '\033', '[', '1', '7', '~', 0,
+ '\033', '[', '1', '8', '~', 0,
+ '\033', '[', '1', '9', '~', 0,
+ '\033', '[', '2', '0', '~', 0,
+ '\033', '[', '2', '1', '~', 0,
+ '\033', '[', '2', '3', '~', 0,
+ '\033', '[', '2', '4', '~', 0,
+ '\033', '[', '2', '5', '~', 0,
+ '\033', '[', '2', '6', '~', 0,
+ '\033', '[', '2', '8', '~', 0,
+ '\033', '[', '2', '9', '~', 0,
+ '\033', '[', '3', '1', '~', 0,
+ '\033', '[', '3', '2', '~', 0,
+ '\033', '[', '3', '3', '~', 0,
+ '\033', '[', '3', '4', '~', 0,
+ '\033', '[', '1', '~', 0,
+ '\033', '[', '2', '~', 0,
+ '\033', '[', '3', '~', 0,
+ '\033', '[', '4', '~', 0,
+ '\033', '[', '5', '~', 0,
+ '\033', '[', '6', '~', 0,
+ '\033', '[', 'M', 0,
+ '\033', '[', 'P', 0,
+};
+
+char *funcbufptr = func_buf;
+int funcbufsize = sizeof(func_buf);
+int funcbufleft = 0; /* space left */
+
+char *func_table[MAX_NR_FUNC] = {
+ func_buf + 0,
+ func_buf + 5,
+ func_buf + 10,
+ func_buf + 15,
+ func_buf + 20,
+ func_buf + 25,
+ func_buf + 31,
+ func_buf + 37,
+ func_buf + 43,
+ func_buf + 49,
+ func_buf + 55,
+ func_buf + 61,
+ func_buf + 67,
+ func_buf + 73,
+ func_buf + 79,
+ func_buf + 85,
+ func_buf + 91,
+ func_buf + 97,
+ func_buf + 103,
+ func_buf + 109,
+ func_buf + 115,
+ func_buf + 120,
+ func_buf + 125,
+ func_buf + 130,
+ func_buf + 135,
+ func_buf + 140,
+ func_buf + 145,
+ 0,
+ 0,
+ func_buf + 149,
+ 0,
+};
+
+struct kbdiacr accent_table[MAX_DIACR] = {
+ {'`', 'A', '\300'}, {'`', 'a', '\340'},
+ {'\'', 'A', '\301'}, {'\'', 'a', '\341'},
+ {'^', 'A', '\302'}, {'^', 'a', '\342'},
+ {'~', 'A', '\303'}, {'~', 'a', '\343'},
+ {'"', 'A', '\304'}, {'"', 'a', '\344'},
+ {'O', 'A', '\305'}, {'o', 'a', '\345'},
+ {'0', 'A', '\305'}, {'0', 'a', '\345'},
+ {'A', 'A', '\305'}, {'a', 'a', '\345'},
+ {'A', 'E', '\306'}, {'a', 'e', '\346'},
+ {',', 'C', '\307'}, {',', 'c', '\347'},
+ {'`', 'E', '\310'}, {'`', 'e', '\350'},
+ {'\'', 'E', '\311'}, {'\'', 'e', '\351'},
+ {'^', 'E', '\312'}, {'^', 'e', '\352'},
+ {'"', 'E', '\313'}, {'"', 'e', '\353'},
+ {'`', 'I', '\314'}, {'`', 'i', '\354'},
+ {'\'', 'I', '\315'}, {'\'', 'i', '\355'},
+ {'^', 'I', '\316'}, {'^', 'i', '\356'},
+ {'"', 'I', '\317'}, {'"', 'i', '\357'},
+ {'-', 'D', '\320'}, {'-', 'd', '\360'},
+ {'~', 'N', '\321'}, {'~', 'n', '\361'},
+ {'`', 'O', '\322'}, {'`', 'o', '\362'},
+ {'\'', 'O', '\323'}, {'\'', 'o', '\363'},
+ {'^', 'O', '\324'}, {'^', 'o', '\364'},
+ {'~', 'O', '\325'}, {'~', 'o', '\365'},
+ {'"', 'O', '\326'}, {'"', 'o', '\366'},
+ {'/', 'O', '\330'}, {'/', 'o', '\370'},
+ {'`', 'U', '\331'}, {'`', 'u', '\371'},
+ {'\'', 'U', '\332'}, {'\'', 'u', '\372'},
+ {'^', 'U', '\333'}, {'^', 'u', '\373'},
+ {'"', 'U', '\334'}, {'"', 'u', '\374'},
+ {'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
+ {'T', 'H', '\336'}, {'t', 'h', '\376'},
+ {'s', 's', '\337'}, {'"', 'y', '\377'},
+ {'s', 'z', '\337'}, {'i', 'j', '\377'},
+};
+
+unsigned int accent_table_size = 68;
+
diff --git a/c/src/lib/libbsp/i386/pc386/console/fb_vga.c b/c/src/lib/libbsp/i386/pc386/console/fb_vga.c
new file mode 100644
index 0000000000..29b840f728
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/fb_vga.c
@@ -0,0 +1,245 @@
+/*
+/////////////////////////////////////////////////////////////////////////////
+// $Header$
+//
+// Copyright (c) 2000 - Rosimildo da Silva ( rdasilva@connecttel.com )
+//
+// MODULE DESCRIPTION:
+// This module implements the micro FB driver for "Bare VGA". It uses the
+// routines for "bare hardware" that comes with MicroWindows.
+//
+// MODIFICATION/HISTORY:
+//
+// $Log$
+//
+/////////////////////////////////////////////////////////////////////////////
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+
+#include <bsp.h>
+#include <irq.h>
+#include <rtems/libio.h>
+
+#include <rtems/mw_fb.h>
+
+/* these routines are defined in the microwindows code. This
+ driver is here more as an example of how to implement and
+ use the micro FB interface
+*/
+extern void ega_hwinit( void );
+extern void ega_hwterm( void );
+
+
+/* screen information for the VGA driver */
+static struct fb_screeninfo fb_info =
+{
+ 640, 480, /* screen size x, y */
+ 4, /* bits per pixel */
+ 80, /* chars per line */
+ (volatile char *)0xA0000, /* buffer pointer */
+ 0x10000, /* buffer size */
+ FB_TYPE_VGA_PLANES, /* type of dsplay */
+ FB_VISUAL_PSEUDOCOLOR /* color scheme used */
+};
+
+
+static __u16 red16[] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff
+};
+static __u16 green16[] = {
+ 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa,
+ 0x5555, 0x5555, 0xffff, 0xffff, 0x5555, 0x5555, 0xffff, 0xffff
+};
+static __u16 blue16[] = {
+ 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa,
+ 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff
+};
+
+/*
+ * fbvga device driver INITIALIZE entry point.
+ */
+rtems_device_driver
+fbvga_initialize( rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_status_code status;
+
+ printk( "FBVGA -- driver initializing..\n" );
+ /*
+ * Register the device
+ */
+ status = rtems_io_register_name ("/dev/fb0", major, 0);
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ printk("Error registering FBVGA device!\n");
+ rtems_fatal_error_occurred( status );
+ }
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/*
+ * fbvga device driver OPEN entry point
+ */
+rtems_device_driver
+fbvga_open( rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+/* rtems_status_code status; */
+ printk( "FBVGA open called.\n" );
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * fbvga device driver CLOSE entry point
+ */
+rtems_device_driver
+fbvga_close(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ printk( "FBVGA close called.\n" );
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/*
+ * fbvga device driver READ entry point.
+ * Read characters from the PS/2 mouse.
+ */
+rtems_device_driver
+fbvga_read( rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
+ printk( "FBVGA read called.\n" );
+ rw_args->bytes_moved = 0;
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/*
+ * fbvga device driver WRITE entry point.
+ * Write characters to the PS/2 mouse.
+ */
+rtems_device_driver
+fbvga_write( rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg)
+{
+ rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
+ printk( "FBVGA write called.\n" );
+ rw_args->bytes_moved = 0;
+ return RTEMS_SUCCESSFUL;
+}
+
+
+static int get_screen_info( struct fb_screeninfo *info )
+{
+ *info = fb_info;
+ return 0;
+}
+
+
+static int get_palette( struct fb_cmap *cmap )
+{
+ __u32 i;
+
+ if( cmap->start + cmap->len >= 16 )
+ return 1;
+
+ for( i = 0; i < cmap->len; i++ )
+ {
+ cmap->red[ cmap->start + i ] = red16[ cmap->start + i ];
+ cmap->green[ cmap->start + i ] = green16[ cmap->start + i ];
+ cmap->blue[ cmap->start + i ] = blue16[ cmap->start + i ];
+ }
+ return 0;
+}
+
+
+static int set_palette( struct fb_cmap *cmap )
+{
+ __u32 i;
+
+ if( cmap->start + cmap->len >= 16 )
+ return 1;
+
+ for( i = 0; i < cmap->len; i++ )
+ {
+ red16[ cmap->start + i ] = cmap->red[ cmap->start + i ];
+ green16[ cmap->start + i ] = cmap->green[ cmap->start + i ];
+ blue16[ cmap->start + i ] = cmap->blue[ cmap->start + i ];
+ }
+ return 0;
+}
+
+
+/*
+ * IOCTL entry point -- This method is called to carry
+ * all services of this interface.
+ */
+rtems_device_driver
+fbvga_control( rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ rtems_libio_ioctl_args_t *args = arg;
+ printk( "FBVGA ioctl called, cmd=%x\n", args->command );
+ switch( args->command )
+ {
+ case FB_SCREENINFO:
+ args->ioctl_return = get_screen_info( args->buffer );
+ break;
+ case FB_GETPALETTE:
+ args->ioctl_return = get_palette( args->buffer );
+ break;
+ case FB_SETPALETTE:
+ args->ioctl_return = set_palette( args->buffer );
+ break;
+
+ /* this function would execute one of the routines of the
+ * interface based on the operation requested
+ */
+ case FB_EXEC_FUNCTION:
+ {
+ struct fb_exec_function *env = args->buffer;
+ switch( env->func_no )
+ {
+ case FB_FUNC_ENTER_GRAPHICS:
+ /* enter graphics mode*/
+ ega_hwinit();
+ break;
+
+ case FB_FUNC_EXIT_GRAPHICS:
+ /* leave graphics mode*/
+ ega_hwterm();
+ break;
+
+ case FB_FUNC_IS_DIRTY:
+ break;
+
+ case FB_FUNC_GET_MODE:
+ break;
+
+ default:
+ break;
+ }
+ }
+ /* no break on purpose */
+ default:
+ args->ioctl_return = 0;
+ break;
+
+ }
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/c/src/lib/libbsp/i386/pc386/console/fb_vga.h b/c/src/lib/libbsp/i386/pc386/console/fb_vga.h
new file mode 100644
index 0000000000..122c1484fb
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/fb_vga.h
@@ -0,0 +1,81 @@
+#ifndef __fbvga_drv__
+#define __fbvga_drv__
+/***************************************************************************
+ *
+ * $Header$
+ *
+ * Copyright (c) 2000 -- Rosimildo da Silva.
+ *
+ * MODULE DESCRIPTION:
+ * Prototype routines for the fbvga driver.
+ *
+ * by: Rosimildo da Silva:
+ * rdasilva@connecttel.com
+ * http://www.connecttel.com
+ *
+ * MODIFICATION/HISTORY:
+ *
+ * $Log$
+ ****************************************************************************/
+
+/* functions */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* fbvga prototype entry points */
+rtems_device_driver fbvga_initialize(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver fbvga_open(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver fbvga_control(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver fbvga_close(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+
+rtems_device_driver fbvga_read(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver fbvga_write(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver fbvga_control(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+#define FBVGA_DRIVER_TABLE_ENTRY \
+ { fbvga_initialize, fbvga_open, fbvga_close, \
+ fbvga_read, fbvga_write, fbvga_control }
+
+#ifdef __cplusplus
+}
+#endif
+/* end of include file */
+
+#endif /* __fbvga_drv__ */
+
+
diff --git a/c/src/lib/libbsp/i386/pc386/console/i386kbd.h b/c/src/lib/libbsp/i386/pc386/console/i386kbd.h
new file mode 100644
index 0000000000..0fe5700fb4
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/i386kbd.h
@@ -0,0 +1,189 @@
+/*
+ * linux/include/asm-i386/keyboard.h
+ *
+ * Created 3 Nov 1996 by Geert Uytterhoeven
+ */
+
+/*
+ * This file contains the i386 architecture specific keyboard definitions
+ */
+
+#ifndef _I386_KEYBOARD_H
+#define _I386_KEYBOARD_H
+
+#include <i386_io.h>
+
+#define KEYBOARD_IRQ 1
+#define DISABLE_KBD_DURING_INTERRUPTS 0
+
+extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
+extern int pckbd_getkeycode(unsigned int scancode);
+extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
+ char raw_mode);
+extern char pckbd_unexpected_up(unsigned char keycode);
+extern void pckbd_leds(unsigned char leds);
+extern void pckbd_init_hw(void);
+extern unsigned char pckbd_sysrq_xlate[128];
+
+#define kbd_setkeycode pckbd_setkeycode
+#define kbd_getkeycode pckbd_getkeycode
+#define kbd_translate pckbd_translate
+#define kbd_unexpected_up pckbd_unexpected_up
+#define kbd_leds pckbd_leds
+#define kbd_init_hw pckbd_init_hw
+#define kbd_sysrq_xlate pckbd_sysrq_xlate
+
+#define SYSRQ_KEY 0x54
+
+/* resource allocation */
+#define kbd_request_region() /* request_region(0x60, 16, "keyboard") */
+#define kbd_request_irq(handler) /* request_irq(KEYBOARD_IRQ, handler, 0, "keyboard", NULL) */
+
+/* How to access the keyboard macros on this platform. */
+#define kbd_read_input() inb(KBD_DATA_REG)
+#define kbd_read_status() inb(KBD_STATUS_REG)
+#define kbd_write_output(val) outb(val, KBD_DATA_REG)
+#define kbd_write_command(val) outb(val, KBD_CNTL_REG)
+
+/* Some stoneage hardware needs delays after some operations. */
+#define kbd_pause() do { } while(0)
+
+/*
+ * Machine specific bits for the PS/2 driver
+ */
+
+#define AUX_IRQ 12
+
+#define aux_request_irq(hand, dev_id) /* request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id) */
+
+#define aux_free_irq(dev_id) /* free_irq(AUX_IRQ, dev_id) */
+
+
+
+/*
+ * include/linux/pc_keyb.h
+ *
+ * PC Keyboard And Keyboard Controller
+ *
+ * (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ */
+
+/*
+ * Configuration Switches
+ */
+
+#undef KBD_REPORT_ERR /* Report keyboard errors */
+#define KBD_REPORT_UNKN /* Report unknown scan codes */
+#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */
+#undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */
+#undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */
+
+
+
+#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */
+#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */
+#define KBD_TIMEOUT 1000 /* Timeout in ms for keyboard command acknowledge */
+
+/*
+ * Internal variables of the driver
+ */
+
+extern unsigned char pckbd_read_mask;
+extern unsigned char aux_device_present;
+
+/*
+ * Keyboard Controller Registers on normal PCs.
+ */
+
+#define KBD_STATUS_REG 0x64 /* Status register (R) */
+#define KBD_CNTL_REG 0x64 /* Controller command register (W) */
+#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */
+
+/*
+ * Keyboard Controller Commands
+ */
+
+#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
+#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */
+#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */
+#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */
+#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */
+#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */
+#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */
+#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */
+#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */
+#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */
+#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if
+ initiated by the auxiliary device */
+#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */
+
+/*
+ * Keyboard Commands
+ */
+
+#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
+#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
+#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
+#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */
+#define KBD_CMD_RESET 0xFF /* Reset */
+
+/*
+ * Keyboard Replies
+ */
+
+#define KBD_REPLY_POR 0xAA /* Power on reset */
+#define KBD_REPLY_ACK 0xFA /* Command ACK */
+#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
+
+/*
+ * Status Register Bits
+ */
+
+#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
+#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
+#define KBD_STAT_SELFTEST 0x04 /* Self test successful */
+#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */
+#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */
+#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
+#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */
+#define KBD_STAT_PERR 0x80 /* Parity error */
+
+#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF)
+
+/*
+ * Controller Mode Register Bits
+ */
+
+#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */
+#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */
+#define KBD_MODE_SYS 0x04 /* The system flag (?) */
+#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */
+#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */
+#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */
+#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
+#define KBD_MODE_RFU 0x80
+
+/*
+ * Mouse Commands
+ */
+
+#define AUX_SET_RES 0xE8 /* Set resolution */
+#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
+#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
+#define AUX_GET_SCALE 0xE9 /* Get scaling factor */
+#define AUX_SET_STREAM 0xEA /* Set stream mode */
+#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
+#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
+#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
+#define AUX_RESET 0xFF /* Reset aux device */
+#define AUX_ACK 0xFA /* Command byte ACK. */
+
+#define AUX_BUF_SIZE 2048 /* This might be better divisible by
+ three to make overruns stay in sync
+ but then the read function would need
+ a lock etc - ick */
+
+#define mark_bh(x)
+
+#endif /* _I386_KEYBOARD_H */
+
diff --git a/c/src/lib/libbsp/i386/pc386/console/inch.c b/c/src/lib/libbsp/i386/pc386/console/inch.c
index f355d6979d..3aa3ad706d 100644
--- a/c/src/lib/libbsp/i386/pc386/console/inch.c
+++ b/c/src/lib/libbsp/i386/pc386/console/inch.c
@@ -18,8 +18,9 @@
| With the following copyright notice:
| With the following copyright notice:
| **************************************************************************
-| * COPYRIGHT (c) 1989-1999.
+| * COPYRIGHT (c) 1989-1998.
| * On-Line Applications Research Corporation (OAR).
+| * Copyright assigned to U.S. Government, 1994.
| *
| * The license and distribution terms for this file may be
| * found in found in the file LICENSE in this distribution or at
@@ -35,38 +36,9 @@
/*-------------------------------------------------------------------------+
| Constants
+--------------------------------------------------------------------------*/
-#define KBD_CTL 0x61 /* -------------------------------- */
-#define KBD_DATA 0x60 /* Ports for PC keyboard controller */
-#define KBD_STATUS 0x64 /* -------------------------------- */
+#define KBD_BUF_SIZE 256
-#define KBD_BUF_SIZE 256
-
-/*-------------------------------------------------------------------------+
-| Global Variables
-+--------------------------------------------------------------------------*/
-static char key_map[] =
-{
- 0,033,'1','2','3','4','5','6','7','8','9','0','-','=','\b','\t',
- 'q','w','e','r','t','y','u','i','o','p','[',']',015,0x80,
- 'a','s','d','f','g','h','j','k','l',';',047,0140,0x80,
- 0134,'z','x','c','v','b','n','m',',','.','/',0x80,
- '*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
- 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
- 0x80,0x80,0x80,'0',0177
-}; /* Keyboard scancode -> character map with no modifiers. */
-
-static char shift_map[] =
-{
- 0,033,'!','@','#','$','%','^','&','*','(',')','_','+','\b','\t',
- 'Q','W','E','R','T','Y','U','I','O','P','{','}',015,0x80,
- 'A','S','D','F','G','H','J','K','L',':',042,'~',0x80,
- '|','Z','X','C','V','B','N','M','<','>','?',0x80,
- '*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
- 0x80,0x80,0x80,0x80,'7','8','9',0x80,'4','5','6',0x80,
- '1','2','3','0',177
-}; /* Keyboard scancode -> character map with SHIFT key modifier. */
-
-static char kbd_buffer[KBD_BUF_SIZE];
+static unsigned short kbd_buffer[KBD_BUF_SIZE];
static rtems_unsigned16 kbd_first = 0;
static rtems_unsigned16 kbd_last = 0;
static rtems_unsigned16 kbd_end = KBD_BUF_SIZE - 1;
@@ -84,249 +56,43 @@ void rtemsReboot(void)
outport_byte(0x64, 0xFE); /* use keyboard controler to do the job... */
} /* rtemsReboot */
-/*-------------------------------------------------------------------------+
-| Function: _IBMPC_scankey
-| Description: This function can be called during a poll for input, or by
-| an ISR. Basically any time you want to process a keypress.
-| Global Variables: key_map, shift_map.
-| Arguments: outChar - character read in case of a valid reading,
-| otherwise unchanged.
-| Returns: TRUE in case a valid character has been read,
-| FALSE otherwise.
-+--------------------------------------------------------------------------*/
-rtems_boolean
-_IBMPC_scankey(char *outChar)
-{
- unsigned char inChar;
- static int alt_pressed = 0;
- static int ctrl_pressed = 0;
- static int shift_pressed = 0;
- static int caps_pressed = 0;
- static int extended = 0;
-
- *outChar = NULL; /* default value if we return FALSE */
-
- /* Read keyboard controller, toggle enable */
- inport_byte(KBD_CTL, inChar);
- outport_byte(KBD_CTL, inChar & ~0x80);
- outport_byte(KBD_CTL, inChar | 0x80);
- outport_byte(KBD_CTL, inChar & ~0x80);
- /* See if it has data */
- inport_byte(KBD_STATUS, inChar);
- if ((inChar & 0x01) == 0)
- return FALSE;
-
- /* Read the data. Handle nonsense with shift, control, etc. */
- inport_byte(KBD_DATA, inChar);
-
- if (extended)
- extended--;
-
- switch (inChar)
- {
- case 0xe0:
- extended = 2;
- return FALSE;
- break;
- case 0x38:
- alt_pressed = 1;
- return FALSE;
- break;
- case 0xb8:
- alt_pressed = 0;
- return FALSE;
- break;
-
- case 0x1d:
- ctrl_pressed = 1;
- return FALSE;
- break;
- case 0x9d:
- ctrl_pressed = 0;
- return FALSE;
- break;
-
- case 0x2a:
- if (extended)
- return FALSE;
- case 0x36:
- shift_pressed = 1;
- return FALSE;
- break;
- case 0xaa:
- if (extended)
- return FALSE;
- case 0xb6:
- shift_pressed = 0;
- return FALSE;
- break;
-
- case 0x3a:
- caps_pressed = 1;
- return FALSE;
- break;
- case 0xba:
- caps_pressed = 0;
- return FALSE;
- break;
-
- case 0x53:
- if (ctrl_pressed && alt_pressed)
- rtemsReboot(); /* ctrl+alt+del -> reboot */
- break;
-
- /*
- * Ignore unrecognized keys--usually arrow and such
- */
- default:
- if ((inChar & 0x80) || (inChar > 0x39))
- /* High-bit on means key is being released, not pressed */
- return FALSE;
- break;
- } /* switch */
-
- /* Strip high bit, look up in our map */
- inChar &= 0x7f;
- if (ctrl_pressed)
- {
- *outChar = key_map[inChar];
- *outChar &= 037;
- }
- else
- {
- *outChar = shift_pressed ? shift_map[inChar] : key_map[inChar];
- if (caps_pressed)
- {
- if (*outChar >= 'A' && *outChar <= 'Z')
- *outChar += 'a' - 'A';
- else if (*outChar >= 'a' && *outChar <= 'z')
- *outChar -= 'a' - 'A';
- }
- }
-
- return TRUE;
-} /* _IBMPC_scankey */
-
-/*-------------------------------------------------------------------------+
-| Function: _IBMPC_keyboard_isr
-| Description: Interrupt Service Routine for keyboard (0x01) IRQ.
-| Global Variables: kbd_buffer, kbd_first, kbd_last.
-| Arguments: vector - standard RTEMS argument - see documentation.
-| Returns: standard return value - see documentation.
-+--------------------------------------------------------------------------*/
-void _IBMPC_keyboard_isr()
+#define disable __asm__ __volatile__("cli")
+#define enable __asm__ __volatile__("sti");
+/*
+ * Check if a key has been pressed. This is a non-destructive
+ * call, meaning, it keeps the key in the buffer.
+ */
+int rtems_kbpoll( void )
{
- if (_IBMPC_scankey(&kbd_buffer[kbd_last]))
- {
- /* Got one; save it if there is enough room in buffer. */
- unsigned int next = (kbd_last == kbd_end) ? 0 : kbd_last + 1;
-
- if (next != kbd_first)
- {
- kbd_last = next;
- }
- }
-} /* _IBMPC_keyboard_isr */
-
+ int rc;
+ disable;
+ rc = ( kbd_first != kbd_last ) ? TRUE : FALSE;
+ enable;
+ return rc;
+}
-/*-------------------------------------------------------------------------+
-| Function: _IBMPC_chrdy
-| Description: Check keyboard ISR buffer and return character if not empty.
-| Global Variables: kbd_buffer, kbd_first, kbd_last.
-| Arguments: c - character read if keyboard buffer not empty, otherwise
-| unchanged.
-| Returns: TRUE if keyboard buffer not empty, FALSE otherwise.
-+--------------------------------------------------------------------------*/
-rtems_boolean
-_IBMPC_chrdy(char *c)
+int getch( void )
{
- /* FIX ME!!! It doesn't work without something like the following line.
- Find out why! */
- printk("");
-
- /* Check buffer our ISR builds */
- if (kbd_first != kbd_last)
+ int c;
+ while( kbd_first == kbd_last )
{
- *c = kbd_buffer[kbd_first];
-
- kbd_first = (kbd_first + 1) % KBD_BUF_SIZE;
- return TRUE;
+ rtems_task_wake_after( 10 );
}
- else
- return FALSE;
-} /* _IBMPC_chrdy */
-
-
-/*-------------------------------------------------------------------------+
-| Function: _IBMPC_inch
-| Description: Poll keyboard until a character is ready and return it.
-| Global Variables: None.
-| Arguments: None.
-| Returns: character read from keyboard.
-+--------------------------------------------------------------------------*/
-char
-_IBMPC_inch(void)
-{
- char c;
- while (!_IBMPC_chrdy(&c))
- continue;
-
- return c;
-} /* _IBMPC_inch */
-
-
- /*
- * Routine that can be used before interrupt management is initialized.
- */
-
-char
-BSP_wait_polled_input(void)
-{
- char c;
- while (!_IBMPC_scankey(&c))
- continue;
-
+ c = kbd_buffer[ kbd_first ];
+ kbd_first = (kbd_first + 1) % KBD_BUF_SIZE;
return c;
}
-/*-------------------------------------------------------------------------+
-| Function: _IBMPC_inch_sleep
-| Description: If charcter is ready return it, otherwise sleep until
-| it is ready
-| Global Variables: None.
-| Arguments: None.
-| Returns: character read from keyboard.
-+--------------------------------------------------------------------------*/
-char
-_IBMPC_inch_sleep(void)
+void add_to_queue( unsigned short b )
{
- char c;
- rtems_interval ticks_per_second;
-
- ticks_per_second = 0;
-
- for(;;)
- {
- if(_IBMPC_chrdy(&c))
- {
- return c;
- }
-
- if(ticks_per_second == 0)
- {
- rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND,
- &ticks_per_second);
- }
- rtems_task_wake_after((ticks_per_second+24)/25);
- }
-
- return c;
-} /* _IBMPC_inch */
-
-
-
-
-
+ unsigned int next;
+ kbd_buffer[ kbd_last ] = b;
+ next = (kbd_last == kbd_end) ? 0 : kbd_last + 1;
+ if( next != kbd_first )
+ {
+ kbd_last = next;
+ }
+}
diff --git a/c/src/lib/libbsp/i386/pc386/console/kd.h b/c/src/lib/libbsp/i386/pc386/console/kd.h
new file mode 100644
index 0000000000..7833abfa9d
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/kd.h
@@ -0,0 +1,114 @@
+/*
+/////////////////////////////////////////////////////////////////////////////
+// $Header$
+//
+// MODULE DESCRIPTION:
+//
+// This module was based on the Linux version kd.h
+//
+// by: Rosimildo da Silva: rdasilva@connecttel.com
+//
+// MODIFICATION/HISTORY:
+// $Log$
+//
+/////////////////////////////////////////////////////////////////////////////
+*/
+
+#ifndef _LINUX_KD_H
+#define _LINUX_KD_H
+#include <sys/types.h>
+
+/* 0x4B is 'K', to avoid collision with termios and vt */
+
+#define KIOCSOUND 0x4B2F /* start sound generation (0 for off) */
+#define KDMKTONE 0x4B30 /* generate tone */
+
+#define KDGETLED 0x4B31 /* return current led state */
+#define KDSETLED 0x4B32 /* set led state [lights, not flags] */
+#define LED_SCR 0x01 /* scroll lock led */
+#define LED_CAP 0x04 /* caps lock led */
+#define LED_NUM 0x02 /* num lock led */
+
+#define KDGKBTYPE 0x4B33 /* get keyboard type */
+#define KB_84 0x01
+#define KB_101 0x02 /* this is what we always answer */
+#define KB_OTHER 0x03
+
+#define KDSETMODE 0x4B3A /* set text/graphics mode */
+#define KD_TEXT 0x00
+#define KD_GRAPHICS 0x01
+#define KD_TEXT0 0x02 /* obsolete */
+#define KD_TEXT1 0x03 /* obsolete */
+#define KDGETMODE 0x4B3B /* get current mode */
+
+#define K_RAW 0x00
+#define K_XLATE 0x01
+#define K_MEDIUMRAW 0x02
+#define K_UNICODE 0x03
+#define KDGKBMODE 0x4B44 /* gets current keyboard mode */
+#define KDSKBMODE 0x4B45 /* sets current keyboard mode */
+
+#define K_METABIT 0x03
+#define K_ESCPREFIX 0x04
+#define KDGKBMETA 0x4B62 /* gets meta key handling mode */
+#define KDSKBMETA 0x4B63 /* sets meta key handling mode */
+
+#define K_SCROLLLOCK 0x01
+#define K_CAPSLOCK 0x02
+#define K_NUMLOCK 0x04
+#define KDGKBLED 0x4B64 /* get led flags (not lights) */
+#define KDSKBLED 0x4B65 /* set led flags (not lights) */
+
+struct kbentry {
+ unsigned char kb_table;
+ unsigned char kb_index;
+ unsigned short kb_value;
+};
+#define K_NORMTAB 0x00
+#define K_SHIFTTAB 0x01
+#define K_ALTTAB 0x02
+#define K_ALTSHIFTTAB 0x03
+
+#define KDGKBENT 0x4B46 /* gets one entry in translation table */
+#define KDSKBENT 0x4B47 /* sets one entry in translation table */
+
+struct kbsentry {
+ unsigned char kb_func;
+ unsigned char kb_string[512];
+};
+
+
+struct kbdiacr {
+ unsigned char diacr, base, result;
+};
+struct kbdiacrs {
+ unsigned int kb_cnt; /* number of entries in following array */
+ struct kbdiacr kbdiacr[256]; /* MAX_DIACR from keyboard.h */
+};
+#define KDGKBDIACR 0x4B4A /* read kernel accent table */
+#define KDSKBDIACR 0x4B4B /* write kernel accent table */
+
+struct kbkeycode {
+ unsigned int scancode, keycode;
+};
+#define KDGETKEYCODE 0x4B4C /* read kernel keycode table entry */
+#define KDSETKEYCODE 0x4B4D /* write kernel keycode table entry */
+
+#define KDSIGACCEPT 0x4B4E /* accept kbd generated signals */
+
+#define KDGHWCLK 0x4B50 /* get hardware clock */
+#define KDSHWCLK 0x4B51 /* set hardware clock */
+
+struct kbd_repeat {
+ int delay; /* in msec; <= 0: don't change */
+ int rate; /* in msec; <= 0: don't change */
+};
+
+#define KDKBDREP 0x4B52 /* set keyboard delay/repeat rate;
+ * actually used values are returned */
+
+/* note: 0x4B00-0x4B4E all have had a value at some time;
+ don't reuse for the time being */
+/* note: 0x4B60-0x4B6D, 0x4B70-0x4B72 used above */
+
+#endif /* _LINUX_KD_H */
diff --git a/c/src/lib/libbsp/i386/pc386/console/keyboard.c b/c/src/lib/libbsp/i386/pc386/console/keyboard.c
new file mode 100644
index 0000000000..5520ae7354
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/keyboard.c
@@ -0,0 +1,928 @@
+/*
+ * linux/drivers/char/keyboard.c
+ *
+ * Written for linux by Johan Myreen as a translation from
+ * the assembly version by Linus (with diacriticals added)
+ *
+ * Some additional features added by Christoph Niemann (ChN), March 1993
+ *
+ * Loadable keymaps by Risto Kankkunen, May 1993
+ *
+ * Diacriticals redone & other small changes, aeb@cwi.nl, June 1993
+ * Added decr/incr_console, dynamic keymaps, Unicode support,
+ * dynamic function/string keys, led setting, Sept 1994
+ * `Sticky' modifier keys, 951006.
+ *
+ * 11-11-96: SAK should now work in the raw mode (Martin Mares)
+ *
+ * Modified to provide 'generic' keyboard support by Hamish Macdonald
+ * Merge with the m68k keyboard driver and split-off of the PC low-level
+ * parts by Geert Uytterhoeven, May 1997
+ *
+ * 27-05-97: Added support for the Magic SysRq Key (Martin Mares)
+ * 30-07-98: Dead keys redone, aeb@cwi.nl.
+ * -------------------------------------------------------------------
+ * End of Linux - Copyright notes...
+ *
+ * Ported to RTEMS to provide the basic fuctionality to the console driver.
+ * by: Rosimildo da Silva: rdasilva@connecttel.com
+ *
+ */
+
+#include <sys/types.h>
+#include <rtems/keyboard.h>
+#include "i386kbd.h"
+#include <rtems/kd.h>
+#include <bsp.h>
+
+#define SIZE(x) (sizeof(x)/sizeof((x)[0]))
+
+#ifndef KBD_DEFMODE
+#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
+#endif
+
+#ifndef KBD_DEFLEDS
+/*
+ * Some laptops take the 789uiojklm,. keys as number pad when NumLock
+ * is on. This seems a good reason to start with NumLock off.
+ */
+#define KBD_DEFLEDS 0
+#endif
+
+#ifndef KBD_DEFLOCK
+#define KBD_DEFLOCK 0
+#endif
+
+extern void add_to_queue( unsigned short );
+extern void rtemsReboot( void );
+
+
+
+int set_bit(int nr, unsigned long * addr)
+{
+ int mask, retval;
+
+ addr += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+ cli();
+ retval = (mask & *addr) != 0;
+ *addr |= mask;
+ sti();
+ return retval;
+}
+
+int clear_bit(int nr, unsigned long * addr)
+{
+ int mask, retval;
+
+ addr += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+ cli();
+ retval = (mask & *addr) != 0;
+ *addr &= ~mask;
+ sti();
+ return retval;
+}
+
+int test_bit(int nr, unsigned long * addr)
+{
+ int mask;
+
+ addr += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+ return ((mask & *addr) != 0);
+}
+
+#define test_and_set_bit(x,y) set_bit(x,y)
+#define test_and_clear_bit(x,y) clear_bit(x,y)
+
+
+/*
+ * global state includes the following, and various static variables
+ * in this module: prev_scancode, shift_state, diacr, npadch, dead_key_next.
+ * (last_console is now a global variable)
+ */
+#define BITS_PER_LONG 32
+
+/* shift state counters.. */
+static unsigned char k_down[NR_SHIFT] = {0, };
+/* keyboard key bitmap */
+static unsigned long key_down[256/BITS_PER_LONG] = { 0, };
+
+static int dead_key_next = 0;
+/*
+ * In order to retrieve the shift_state (for the mouse server), either
+ * the variable must be global, or a new procedure must be created to
+ * return the value. I chose the former way.
+ */
+int shift_state = 0;
+static int npadch = -1; /* -1 or number assembled on pad */
+static unsigned char diacr = 0;
+static char rep = 0; /* flag telling character repeat */
+
+/* default console for RTEMS */
+static int fg_console = 0;
+
+
+struct kbd_struct kbd_table[MAX_NR_CONSOLES];
+static struct kbd_struct * kbd = kbd_table;
+
+void compute_shiftstate(void);
+
+typedef void (*k_hand)(unsigned char value, char up_flag);
+typedef void (k_handfn)(unsigned char value, char up_flag);
+
+static k_handfn
+ do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
+ do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2,
+ do_ignore;
+
+static k_hand key_handler[16] = {
+ do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
+ do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2,
+ do_ignore, do_ignore
+};
+
+/* Key types processed even in raw modes */
+
+#define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT))
+
+typedef void (*void_fnp)(void);
+typedef void (void_fn)(void);
+
+
+static void show_mem(void)
+{
+}
+static void show_state(void)
+{
+}
+
+static void_fn do_null, enter, show_ptregs, send_intr, lastcons, caps_toggle,
+ num, hold, scroll_forw, scroll_back, boot_it, caps_on, compose,
+ SAK, decr_console, incr_console, spawn_console, bare_num;
+
+static void_fnp spec_fn_table[] = {
+ do_null, enter, show_ptregs, show_mem,
+ show_state, send_intr, lastcons, caps_toggle,
+ num, hold, scroll_forw, scroll_back,
+ boot_it, caps_on, compose, SAK,
+ decr_console, incr_console, spawn_console, bare_num
+};
+
+#define SPECIALS_ALLOWED_IN_RAW_MODE (1 << KVAL(K_SAK))
+
+/* maximum values each key_handler can handle */
+const int max_vals[] = {
+ 255, SIZE(func_table) - 1, SIZE(spec_fn_table) - 1, NR_PAD - 1,
+ NR_DEAD - 1, 255, 3, NR_SHIFT - 1,
+ 255, NR_ASCII - 1, NR_LOCK - 1, 255,
+ NR_LOCK - 1, 255
+};
+
+const int NR_TYPES = SIZE(max_vals);
+
+/* N.B. drivers/macintosh/mac_keyb.c needs to call put_queue */
+static void put_queue(int);
+static unsigned char handle_diacr(unsigned char);
+
+#ifdef CONFIG_MAGIC_SYSRQ
+static int sysrq_pressed;
+#endif
+
+/*
+ * Many other routines do put_queue, but I think either
+ * they produce ASCII, or they produce some user-assigned
+ * string, and in both cases we might assume that it is
+ * in utf-8 already.
+ */
+void to_utf8(ushort c) {
+ if (c < 0x80)
+ put_queue(c); /* 0******* */
+ else if (c < 0x800) {
+ put_queue(0xc0 | (c >> 6)); /* 110***** 10****** */
+ put_queue(0x80 | (c & 0x3f));
+ } else {
+ put_queue(0xe0 | (c >> 12)); /* 1110**** 10****** 10****** */
+ put_queue(0x80 | ((c >> 6) & 0x3f));
+ put_queue(0x80 | (c & 0x3f));
+ }
+ /* UTF-8 is defined for words of up to 31 bits,
+ but we need only 16 bits here */
+}
+
+
+/*
+ * Translation of escaped scancodes to keycodes.
+ * This is now user-settable (for machines were it makes sense).
+ */
+
+int setkeycode(unsigned int scancode, unsigned int keycode)
+{
+ return kbd_setkeycode(scancode, keycode);
+}
+
+int getkeycode(unsigned int scancode)
+{
+ return kbd_getkeycode(scancode);
+}
+
+void handle_scancode(unsigned char scancode, int down)
+{
+ unsigned char keycode;
+ char up_flag = down ? 0 : 0200;
+ char raw_mode;
+
+ mark_bh(CONSOLE_BH);
+
+#if 0
+ tty = ttytab? ttytab[fg_console]: NULL;
+ if (tty && (!tty->driver_data)) {
+ /*
+ * We touch the tty structure via the the ttytab array
+ * without knowing whether or not tty is open, which
+ * is inherently dangerous. We currently rely on that
+ * fact that console_open sets tty->driver_data when
+ * it opens it, and clears it when it closes it.
+ */
+ tty = NULL;
+ }
+#endif
+
+ kbd = kbd_table + fg_console;
+ if ((raw_mode = (kbd->kbdmode == VC_RAW))) {
+ put_queue(scancode | up_flag);
+ /* we do not return yet, because we want to maintain
+ the key_down array, so that we have the correct
+ values when finishing RAW mode or when changing VT's */
+ }
+
+ /*
+ * Convert scancode to keycode
+ */
+ if (!kbd_translate(scancode, &keycode, raw_mode))
+ return;
+
+ /*
+ * At this point the variable `keycode' contains the keycode.
+ * Note: the keycode must not be 0 (++Geert: on m68k 0 is valid).
+ * We keep track of the up/down status of the key, and
+ * return the keycode if in MEDIUMRAW mode.
+ */
+
+ if (up_flag) {
+ rep = 0;
+ if(!test_and_clear_bit(keycode, key_down))
+ up_flag = kbd_unexpected_up(keycode);
+ } else
+ rep = test_and_set_bit(keycode, key_down);
+
+
+#ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */
+ if (keycode == SYSRQ_KEY) {
+ sysrq_pressed = !up_flag;
+ return;
+ } else if (sysrq_pressed) {
+ if (!up_flag && sysrq_enabled)
+ handle_sysrq(kbd_sysrq_xlate[keycode], kbd_pt_regs, kbd, tty);
+ return;
+ }
+#endif
+
+
+ if (kbd->kbdmode == VC_MEDIUMRAW) {
+ /* soon keycodes will require more than one byte */
+ put_queue(keycode + up_flag);
+ raw_mode = 1; /* Most key classes will be ignored */
+ }
+ /*
+ * Small change in philosophy: earlier we defined repetition by
+ * rep = keycode == prev_keycode;
+ * prev_keycode = keycode;
+ * but now by the fact that the depressed key was down already.
+ * Does this ever make a difference? Yes.
+ */
+
+ /*
+ * Repeat a key only if the input buffers are empty or the
+ * characters get echoed locally. This makes key repeat usable
+ * with slow applications and under heavy loads.
+ */
+ if (!rep || vc_kbd_mode(kbd,VC_REPEAT) ) {
+/*
+ || (vc_kbd_mode(kbd,VC_REPEAT) && tty &&
+ (L_ECHO(tty) || (tty->driver.chars_in_buffer(tty) == 0)))) {
+*/
+ u_short keysym;
+ u_char type;
+
+ /* the XOR below used to be an OR */
+ int shift_final = shift_state ^ kbd->lockstate ^ kbd->slockstate;
+ ushort *key_map = key_maps[shift_final];
+
+
+ if (key_map != NULL) {
+ keysym = key_map[keycode];
+ type = KTYP(keysym);
+
+ if (type >= 0xf0) {
+ type -= 0xf0;
+ if (raw_mode && ! (TYPES_ALLOWED_IN_RAW_MODE & (1 << type)))
+ return;
+ if (type == KT_LETTER) {
+ type = KT_LATIN;
+ if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
+ key_map = key_maps[shift_final ^ (1<<KG_SHIFT)];
+ if (key_map)
+ keysym = key_map[keycode];
+ }
+ }
+
+ (*key_handler[type])(keysym & 0xff, up_flag);
+
+ if (type != KT_SLOCK)
+ kbd->slockstate = 0;
+
+ } else {
+ /* maybe only if (kbd->kbdmode == VC_UNICODE) ? */
+ if (!up_flag && !raw_mode)
+ to_utf8(keysym);
+ }
+ } else {
+ /* maybe beep? */
+ /* we have at least to update shift_state */
+#if 1 /* how? two almost equivalent choices follow */
+ compute_shiftstate();
+#else
+ keysym = U(plain_map[keycode]);
+ type = KTYP(keysym);
+ if (type == KT_SHIFT)
+ (*key_handler[type])(keysym & 0xff, up_flag);
+#endif
+ }
+ }
+}
+
+static void ( *driver_input_handler_kbd )( void *, unsigned short, unsigned long ) = 0;
+/*
+ */
+void kbd_set_driver_handler( void ( *handler )( void *, unsigned short, unsigned long ) )
+{
+ driver_input_handler_kbd = handler;
+}
+
+static void put_queue(int ch)
+{
+ if( driver_input_handler_kbd )
+ {
+ driver_input_handler_kbd( ( void *)kbd, (unsigned short)ch, 0 );
+ }
+ else
+ {
+ add_to_queue( ch );
+ }
+}
+
+
+static void puts_queue(char *cp)
+{
+ while (*cp) {
+ put_queue( *cp );
+ cp++;
+ }
+}
+
+static void applkey(int key, char mode)
+{
+ static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
+
+ buf[1] = (mode ? 'O' : '[');
+ buf[2] = key;
+ puts_queue(buf);
+}
+
+static void enter(void)
+{
+ if (diacr) {
+ put_queue(diacr);
+ diacr = 0;
+ }
+ put_queue(13);
+
+ if (vc_kbd_mode(kbd,VC_CRLF))
+ put_queue(10);
+
+}
+
+static void caps_toggle(void)
+{
+ if (rep)
+ return;
+ chg_vc_kbd_led(kbd, VC_CAPSLOCK);
+}
+
+static void caps_on(void)
+{
+ if (rep)
+ return;
+ set_vc_kbd_led(kbd, VC_CAPSLOCK);
+}
+
+static void show_ptregs(void)
+{
+}
+
+static void hold(void)
+{
+ if (rep )
+ return;
+ chg_vc_kbd_led(kbd, VC_SCROLLOCK );
+
+}
+
+static void num(void)
+{
+
+ if (vc_kbd_mode(kbd,VC_APPLIC))
+ applkey('P', 1);
+ else
+ bare_num();
+}
+
+/*
+ * Bind this to Shift-NumLock if you work in application keypad mode
+ * but want to be able to change the NumLock flag.
+ * Bind this to NumLock if you prefer that the NumLock key always
+ * changes the NumLock flag.
+ */
+static void bare_num(void)
+{
+ if (!rep)
+ chg_vc_kbd_led(kbd,VC_NUMLOCK);
+}
+
+static void lastcons(void)
+{
+}
+
+static void decr_console(void)
+{
+}
+
+static void incr_console(void)
+{
+}
+
+static void send_intr(void)
+{
+}
+
+static void scroll_forw(void)
+{
+}
+
+static void scroll_back(void)
+{
+}
+
+static void boot_it(void)
+{
+ printk( "boot_it() " );
+ rtemsReboot();
+}
+
+static void compose(void)
+{
+ dead_key_next = 1;
+}
+
+int spawnpid, spawnsig;
+
+static void spawn_console(void)
+{
+}
+
+static void SAK(void)
+{
+}
+
+static void do_ignore(unsigned char value, char up_flag)
+{
+}
+
+static void do_null()
+{
+ compute_shiftstate();
+}
+
+static void do_spec(unsigned char value, char up_flag)
+{
+ if (up_flag)
+ return;
+ if (value >= SIZE(spec_fn_table))
+ return;
+
+ if ((kbd->kbdmode == VC_RAW || kbd->kbdmode == VC_MEDIUMRAW) &&
+ !(SPECIALS_ALLOWED_IN_RAW_MODE & (1 << value)))
+ return;
+
+ spec_fn_table[value]();
+}
+
+static void do_lowercase(unsigned char value, char up_flag)
+{
+}
+
+static void do_self(unsigned char value, char up_flag)
+{
+ if (up_flag)
+ return; /* no action, if this is a key release */
+
+ if (diacr)
+ value = handle_diacr(value);
+
+ if (dead_key_next) {
+ dead_key_next = 0;
+ diacr = value;
+ return;
+ }
+ put_queue(value);
+}
+
+#define A_GRAVE '`'
+#define A_ACUTE '\''
+#define A_CFLEX '^'
+#define A_TILDE '~'
+#define A_DIAER '"'
+#define A_CEDIL ','
+static unsigned char ret_diacr[NR_DEAD] =
+ {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER, A_CEDIL };
+
+/* Obsolete - for backwards compatibility only */
+static void do_dead(unsigned char value, char up_flag)
+{
+ value = ret_diacr[value];
+ printk( " do_dead( %X ) ", value );
+ do_dead2(value,up_flag);
+}
+
+/*
+ * Handle dead key. Note that we now may have several
+ * dead keys modifying the same character. Very useful
+ * for Vietnamese.
+ */
+static void do_dead2(unsigned char value, char up_flag)
+{
+ if (up_flag)
+ return;
+ diacr = (diacr ? handle_diacr(value) : value);
+}
+
+
+/*
+ * We have a combining character DIACR here, followed by the character CH.
+ * If the combination occurs in the table, return the corresponding value.
+ * Otherwise, if CH is a space or equals DIACR, return DIACR.
+ * Otherwise, conclude that DIACR was not combining after all,
+ * queue it and return CH.
+ */
+unsigned char handle_diacr(unsigned char ch)
+{
+ int d = diacr;
+ int i;
+
+ diacr = 0;
+
+ for (i = 0; i < accent_table_size; i++) {
+ if (accent_table[i].diacr == d && accent_table[i].base == ch)
+ return accent_table[i].result;
+ }
+ if (ch == ' ' || ch == d)
+ return d;
+
+ put_queue(d);
+ return ch;
+}
+
+static void do_cons(unsigned char value, char up_flag)
+{
+ if (up_flag)
+ return;
+}
+
+static void do_fn(unsigned char value, char up_flag)
+{
+ if (up_flag)
+ return;
+
+ if (value < SIZE(func_table)) {
+ if (func_table[value])
+ puts_queue(func_table[value]);
+ } else
+ printk( "do_fn called with value=%d\n", value);
+}
+
+static void do_pad(unsigned char value, char up_flag)
+{
+ static const char *pad_chars = "0123456789+-*/\015,.?()";
+ static const char *app_map = "pqrstuvwxylSRQMnnmPQ";
+
+ if (up_flag)
+ return; /* no action, if this is a key release */
+
+ /* kludge... shift forces cursor/number keys */
+ if (vc_kbd_mode(kbd,VC_APPLIC) && !k_down[KG_SHIFT]) {
+ applkey(app_map[value], 1);
+ return;
+ }
+ if (!vc_kbd_led(kbd,VC_NUMLOCK))
+ switch (value) {
+ case KVAL(K_PCOMMA):
+ case KVAL(K_PDOT):
+ do_fn(KVAL(K_REMOVE), 0);
+ return;
+ case KVAL(K_P0):
+ do_fn(KVAL(K_INSERT), 0);
+ return;
+ case KVAL(K_P1):
+ do_fn(KVAL(K_SELECT), 0);
+ return;
+ case KVAL(K_P2):
+ do_cur(KVAL(K_DOWN), 0);
+ return;
+ case KVAL(K_P3):
+ do_fn(KVAL(K_PGDN), 0);
+ return;
+ case KVAL(K_P4):
+ do_cur(KVAL(K_LEFT), 0);
+ return;
+ case KVAL(K_P6):
+ do_cur(KVAL(K_RIGHT), 0);
+ return;
+ case KVAL(K_P7):
+ do_fn(KVAL(K_FIND), 0);
+ return;
+ case KVAL(K_P8):
+ do_cur(KVAL(K_UP), 0);
+ return;
+ case KVAL(K_P9):
+ do_fn(KVAL(K_PGUP), 0);
+ return;
+ case KVAL(K_P5):
+ applkey('G', vc_kbd_mode(kbd, VC_APPLIC));
+ return;
+ }
+
+ put_queue(pad_chars[value]);
+
+ if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
+ put_queue(10);
+
+}
+
+static void do_cur(unsigned char value, char up_flag)
+{
+ static const char *cur_chars = "BDCA";
+ if (up_flag)
+ return;
+
+ applkey(cur_chars[value], vc_kbd_mode(kbd,VC_CKMODE));
+}
+
+static void do_shift(unsigned char value, char up_flag)
+{
+ int old_state = shift_state;
+
+ if (rep)
+ return;
+
+ /* Mimic typewriter:
+ a CapsShift key acts like Shift but undoes CapsLock */
+ if (value == KVAL(K_CAPSSHIFT)) {
+ value = KVAL(K_SHIFT);
+ if (!up_flag)
+ clr_vc_kbd_led(kbd, VC_CAPSLOCK);
+ }
+
+ if (up_flag) {
+ /* handle the case that two shift or control
+ keys are depressed simultaneously */
+ if (k_down[value])
+ k_down[value]--;
+ } else
+ k_down[value]++;
+
+ if (k_down[value])
+ shift_state |= (1 << value);
+ else
+ shift_state &= ~ (1 << value);
+
+ /* kludge */
+ if (up_flag && shift_state != old_state && npadch != -1) {
+ if (kbd->kbdmode == VC_UNICODE)
+ to_utf8(npadch & 0xffff);
+ else
+ put_queue(npadch & 0xff);
+ npadch = -1;
+ }
+}
+
+/* called after returning from RAW mode or when changing consoles -
+ recompute k_down[] and shift_state from key_down[] */
+/* maybe called when keymap is undefined, so that shiftkey release is seen */
+void compute_shiftstate(void)
+{
+ int i, j, k, sym, val;
+
+ shift_state = 0;
+ for(i=0; i < SIZE(k_down); i++)
+ k_down[i] = 0;
+
+ for(i=0; i < SIZE(key_down); i++)
+ if(key_down[i]) { /* skip this word if not a single bit on */
+ k = i*BITS_PER_LONG;
+ for(j=0; j<BITS_PER_LONG; j++,k++)
+ if(test_bit(k, key_down)) {
+ sym = U(plain_map[k]);
+ if(KTYP(sym) == KT_SHIFT) {
+ val = KVAL(sym);
+ if (val == KVAL(K_CAPSSHIFT))
+ val = KVAL(K_SHIFT);
+ k_down[val]++;
+ shift_state |= (1<<val);
+ }
+ }
+ }
+}
+
+static void do_meta(unsigned char value, char up_flag)
+{
+ if (up_flag)
+ return;
+
+ if (vc_kbd_mode(kbd, VC_META)) {
+ put_queue('\033');
+ put_queue(value);
+ } else
+ put_queue(value | 0x80);
+}
+
+static void do_ascii(unsigned char value, char up_flag)
+{
+ int base;
+
+ if (up_flag)
+ return;
+
+ if (value < 10) /* decimal input of code, while Alt depressed */
+ base = 10;
+ else { /* hexadecimal input of code, while AltGr depressed */
+ value -= 10;
+ base = 16;
+ }
+
+ if (npadch == -1)
+ npadch = value;
+ else
+ npadch = npadch * base + value;
+}
+
+static void do_lock(unsigned char value, char up_flag)
+{
+ if (up_flag || rep)
+ return;
+ chg_vc_kbd_lock(kbd, value);
+}
+
+static void do_slock(unsigned char value, char up_flag)
+{
+ if (up_flag || rep)
+ return;
+
+ chg_vc_kbd_slock(kbd, value);
+}
+
+/*
+ * The leds display either (i) the status of NumLock, CapsLock, ScrollLock,
+ * or (ii) whatever pattern of lights people want to show using KDSETLED,
+ * or (iii) specified bits of specified words in kernel memory.
+ */
+
+static unsigned char ledstate = 0xff; /* undefined */
+static unsigned char ledioctl;
+
+unsigned char getledstate(void) {
+ return ledstate;
+}
+
+void setledstate(struct kbd_struct *kbd, unsigned int led) {
+ if (!(led & ~7)) {
+ ledioctl = led;
+ kbd->ledmode = LED_SHOW_IOCTL;
+ } else
+ ;
+ kbd->ledmode = LED_SHOW_FLAGS;
+ set_leds();
+}
+
+static struct ledptr {
+ unsigned int *addr;
+ unsigned int mask;
+ unsigned char valid:1;
+} ledptrs[3];
+
+void register_leds(int console, unsigned int led,
+ unsigned int *addr, unsigned int mask) {
+ struct kbd_struct *kbd = kbd_table + console;
+
+ if (led < 3) {
+ ledptrs[led].addr = addr;
+ ledptrs[led].mask = mask;
+ ledptrs[led].valid = 1;
+ kbd->ledmode = LED_SHOW_MEM;
+ } else
+ kbd->ledmode = LED_SHOW_FLAGS;
+}
+
+static inline unsigned char getleds(void){
+
+
+ struct kbd_struct *kbd = kbd_table + fg_console;
+
+ unsigned char leds;
+
+ if (kbd->ledmode == LED_SHOW_IOCTL)
+ return ledioctl;
+ leds = kbd->ledflagstate;
+ if (kbd->ledmode == LED_SHOW_MEM) {
+ if (ledptrs[0].valid) {
+ if (*ledptrs[0].addr & ledptrs[0].mask)
+ leds |= 1;
+ else
+ leds &= ~1;
+ }
+ if (ledptrs[1].valid) {
+ if (*ledptrs[1].addr & ledptrs[1].mask)
+ leds |= 2;
+ else
+ leds &= ~2;
+ }
+ if (ledptrs[2].valid) {
+ if (*ledptrs[2].addr & ledptrs[2].mask)
+ leds |= 4;
+ else
+ leds &= ~4;
+ }
+ }
+ return leds;
+}
+
+/*
+ * This routine is the bottom half of the keyboard interrupt
+ * routine, and runs with all interrupts enabled. It does
+ * console changing, led setting and copy_to_cooked, which can
+ * take a reasonably long time.
+ *
+ * Aside from timing (which isn't really that important for
+ * keyboard interrupts as they happen often), using the software
+ * interrupt routines for this thing allows us to easily mask
+ * this when we don't want any of the above to happen. Not yet
+ * used, but this allows for easy and efficient race-condition
+ * prevention later on.
+ */
+static void kbd_bh(void)
+{
+ unsigned char leds = getleds();
+ if (leds != ledstate) {
+ ledstate = leds;
+ kbd_leds(leds);
+ }
+}
+
+
+void set_leds(void)
+{
+ kbd_bh();
+}
+
+
+int kbd_init(void)
+{
+
+ int i;
+ struct kbd_struct kbd0;
+ kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS;
+ kbd0.ledmode = LED_SHOW_MEM;
+ kbd0.lockstate = KBD_DEFLOCK;
+ kbd0.slockstate = 0;
+ kbd0.modeflags = KBD_DEFMODE;
+ kbd0.kbdmode = VC_XLATE;
+
+ for (i = 0 ; i < MAX_NR_CONSOLES ; i++)
+ kbd_table[i] = kbd0;
+
+ kbd_init_hw();
+ mark_bh(KEYBOARD_BH);
+ return 0;
+}
+
diff --git a/c/src/lib/libbsp/i386/pc386/console/keyboard.h b/c/src/lib/libbsp/i386/pc386/console/keyboard.h
new file mode 100644
index 0000000000..054bcf9910
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/keyboard.h
@@ -0,0 +1,588 @@
+/*
+/////////////////////////////////////////////////////////////////////////////
+// $Header$
+//
+// MODULE DESCRIPTION:
+//
+// This module was based on the Linux version keyboard.h + kbd_kern.h
+//
+// by: Rosimildo da Silva: rdasilva@connecttel.com
+//
+// MODIFICATION/HISTORY:
+// $Log$
+//
+/////////////////////////////////////////////////////////////////////////////
+*/
+
+#ifndef __LINUX_KEYBOARD_H
+#define __LINUX_KEYBOARD_H
+
+#define KG_SHIFT 0
+#define KG_CTRL 2
+#define KG_ALT 3
+#define KG_ALTGR 1
+#define KG_SHIFTL 4
+#define KG_SHIFTR 5
+#define KG_CTRLL 6
+#define KG_CTRLR 7
+#define KG_CAPSSHIFT 8
+
+#define NR_SHIFT 9
+
+#define NR_KEYS 128
+#define MAX_NR_KEYMAPS 256
+/* This means 64Kb if all keymaps are allocated. Only the superuser
+ may increase the number of keymaps beyond MAX_NR_OF_USER_KEYMAPS. */
+#define MAX_NR_OF_USER_KEYMAPS 256 /* should be at least 7 */
+
+extern const int NR_TYPES;
+extern unsigned short *key_maps[MAX_NR_KEYMAPS];
+extern unsigned short plain_map[NR_KEYS];
+extern unsigned char keyboard_type;
+
+#define MAX_NR_FUNC 256 /* max nr of strings assigned to keys */
+#define MAX_NR_CONSOLES 1
+
+
+extern char *func_table[MAX_NR_FUNC];
+
+#define KT_LATIN 0 /* we depend on this being zero */
+#define KT_LETTER 11 /* symbol that can be acted upon by CapsLock */
+#define KT_FN 1
+#define KT_SPEC 2
+#define KT_PAD 3
+#define KT_DEAD 4
+#define KT_CONS 5
+#define KT_CUR 6
+#define KT_SHIFT 7
+#define KT_META 8
+#define KT_ASCII 9
+#define KT_LOCK 10
+#define KT_SLOCK 12
+
+#define K(t,v) (((t)<<8)|(v))
+#define KTYP(x) ((x) >> 8)
+#define KVAL(x) ((x) & 0xff)
+
+#define K_F1 K(KT_FN,0)
+#define K_F2 K(KT_FN,1)
+#define K_F3 K(KT_FN,2)
+#define K_F4 K(KT_FN,3)
+#define K_F5 K(KT_FN,4)
+#define K_F6 K(KT_FN,5)
+#define K_F7 K(KT_FN,6)
+#define K_F8 K(KT_FN,7)
+#define K_F9 K(KT_FN,8)
+#define K_F10 K(KT_FN,9)
+#define K_F11 K(KT_FN,10)
+#define K_F12 K(KT_FN,11)
+#define K_F13 K(KT_FN,12)
+#define K_F14 K(KT_FN,13)
+#define K_F15 K(KT_FN,14)
+#define K_F16 K(KT_FN,15)
+#define K_F17 K(KT_FN,16)
+#define K_F18 K(KT_FN,17)
+#define K_F19 K(KT_FN,18)
+#define K_F20 K(KT_FN,19)
+#define K_FIND K(KT_FN,20)
+#define K_INSERT K(KT_FN,21)
+#define K_REMOVE K(KT_FN,22)
+#define K_SELECT K(KT_FN,23)
+#define K_PGUP K(KT_FN,24) /* PGUP is a synonym for PRIOR */
+#define K_PGDN K(KT_FN,25) /* PGDN is a synonym for NEXT */
+#define K_MACRO K(KT_FN,26)
+#define K_HELP K(KT_FN,27)
+#define K_DO K(KT_FN,28)
+#define K_PAUSE K(KT_FN,29)
+#define K_F21 K(KT_FN,30)
+#define K_F22 K(KT_FN,31)
+#define K_F23 K(KT_FN,32)
+#define K_F24 K(KT_FN,33)
+#define K_F25 K(KT_FN,34)
+#define K_F26 K(KT_FN,35)
+#define K_F27 K(KT_FN,36)
+#define K_F28 K(KT_FN,37)
+#define K_F29 K(KT_FN,38)
+#define K_F30 K(KT_FN,39)
+#define K_F31 K(KT_FN,40)
+#define K_F32 K(KT_FN,41)
+#define K_F33 K(KT_FN,42)
+#define K_F34 K(KT_FN,43)
+#define K_F35 K(KT_FN,44)
+#define K_F36 K(KT_FN,45)
+#define K_F37 K(KT_FN,46)
+#define K_F38 K(KT_FN,47)
+#define K_F39 K(KT_FN,48)
+#define K_F40 K(KT_FN,49)
+#define K_F41 K(KT_FN,50)
+#define K_F42 K(KT_FN,51)
+#define K_F43 K(KT_FN,52)
+#define K_F44 K(KT_FN,53)
+#define K_F45 K(KT_FN,54)
+#define K_F46 K(KT_FN,55)
+#define K_F47 K(KT_FN,56)
+#define K_F48 K(KT_FN,57)
+#define K_F49 K(KT_FN,58)
+#define K_F50 K(KT_FN,59)
+#define K_F51 K(KT_FN,60)
+#define K_F52 K(KT_FN,61)
+#define K_F53 K(KT_FN,62)
+#define K_F54 K(KT_FN,63)
+#define K_F55 K(KT_FN,64)
+#define K_F56 K(KT_FN,65)
+#define K_F57 K(KT_FN,66)
+#define K_F58 K(KT_FN,67)
+#define K_F59 K(KT_FN,68)
+#define K_F60 K(KT_FN,69)
+#define K_F61 K(KT_FN,70)
+#define K_F62 K(KT_FN,71)
+#define K_F63 K(KT_FN,72)
+#define K_F64 K(KT_FN,73)
+#define K_F65 K(KT_FN,74)
+#define K_F66 K(KT_FN,75)
+#define K_F67 K(KT_FN,76)
+#define K_F68 K(KT_FN,77)
+#define K_F69 K(KT_FN,78)
+#define K_F70 K(KT_FN,79)
+#define K_F71 K(KT_FN,80)
+#define K_F72 K(KT_FN,81)
+#define K_F73 K(KT_FN,82)
+#define K_F74 K(KT_FN,83)
+#define K_F75 K(KT_FN,84)
+#define K_F76 K(KT_FN,85)
+#define K_F77 K(KT_FN,86)
+#define K_F78 K(KT_FN,87)
+#define K_F79 K(KT_FN,88)
+#define K_F80 K(KT_FN,89)
+#define K_F81 K(KT_FN,90)
+#define K_F82 K(KT_FN,91)
+#define K_F83 K(KT_FN,92)
+#define K_F84 K(KT_FN,93)
+#define K_F85 K(KT_FN,94)
+#define K_F86 K(KT_FN,95)
+#define K_F87 K(KT_FN,96)
+#define K_F88 K(KT_FN,97)
+#define K_F89 K(KT_FN,98)
+#define K_F90 K(KT_FN,99)
+#define K_F91 K(KT_FN,100)
+#define K_F92 K(KT_FN,101)
+#define K_F93 K(KT_FN,102)
+#define K_F94 K(KT_FN,103)
+#define K_F95 K(KT_FN,104)
+#define K_F96 K(KT_FN,105)
+#define K_F97 K(KT_FN,106)
+#define K_F98 K(KT_FN,107)
+#define K_F99 K(KT_FN,108)
+#define K_F100 K(KT_FN,109)
+#define K_F101 K(KT_FN,110)
+#define K_F102 K(KT_FN,111)
+#define K_F103 K(KT_FN,112)
+#define K_F104 K(KT_FN,113)
+#define K_F105 K(KT_FN,114)
+#define K_F106 K(KT_FN,115)
+#define K_F107 K(KT_FN,116)
+#define K_F108 K(KT_FN,117)
+#define K_F109 K(KT_FN,118)
+#define K_F110 K(KT_FN,119)
+#define K_F111 K(KT_FN,120)
+#define K_F112 K(KT_FN,121)
+#define K_F113 K(KT_FN,122)
+#define K_F114 K(KT_FN,123)
+#define K_F115 K(KT_FN,124)
+#define K_F116 K(KT_FN,125)
+#define K_F117 K(KT_FN,126)
+#define K_F118 K(KT_FN,127)
+#define K_F119 K(KT_FN,128)
+#define K_F120 K(KT_FN,129)
+#define K_F121 K(KT_FN,130)
+#define K_F122 K(KT_FN,131)
+#define K_F123 K(KT_FN,132)
+#define K_F124 K(KT_FN,133)
+#define K_F125 K(KT_FN,134)
+#define K_F126 K(KT_FN,135)
+#define K_F127 K(KT_FN,136)
+#define K_F128 K(KT_FN,137)
+#define K_F129 K(KT_FN,138)
+#define K_F130 K(KT_FN,139)
+#define K_F131 K(KT_FN,140)
+#define K_F132 K(KT_FN,141)
+#define K_F133 K(KT_FN,142)
+#define K_F134 K(KT_FN,143)
+#define K_F135 K(KT_FN,144)
+#define K_F136 K(KT_FN,145)
+#define K_F137 K(KT_FN,146)
+#define K_F138 K(KT_FN,147)
+#define K_F139 K(KT_FN,148)
+#define K_F140 K(KT_FN,149)
+#define K_F141 K(KT_FN,150)
+#define K_F142 K(KT_FN,151)
+#define K_F143 K(KT_FN,152)
+#define K_F144 K(KT_FN,153)
+#define K_F145 K(KT_FN,154)
+#define K_F146 K(KT_FN,155)
+#define K_F147 K(KT_FN,156)
+#define K_F148 K(KT_FN,157)
+#define K_F149 K(KT_FN,158)
+#define K_F150 K(KT_FN,159)
+#define K_F151 K(KT_FN,160)
+#define K_F152 K(KT_FN,161)
+#define K_F153 K(KT_FN,162)
+#define K_F154 K(KT_FN,163)
+#define K_F155 K(KT_FN,164)
+#define K_F156 K(KT_FN,165)
+#define K_F157 K(KT_FN,166)
+#define K_F158 K(KT_FN,167)
+#define K_F159 K(KT_FN,168)
+#define K_F160 K(KT_FN,169)
+#define K_F161 K(KT_FN,170)
+#define K_F162 K(KT_FN,171)
+#define K_F163 K(KT_FN,172)
+#define K_F164 K(KT_FN,173)
+#define K_F165 K(KT_FN,174)
+#define K_F166 K(KT_FN,175)
+#define K_F167 K(KT_FN,176)
+#define K_F168 K(KT_FN,177)
+#define K_F169 K(KT_FN,178)
+#define K_F170 K(KT_FN,179)
+#define K_F171 K(KT_FN,180)
+#define K_F172 K(KT_FN,181)
+#define K_F173 K(KT_FN,182)
+#define K_F174 K(KT_FN,183)
+#define K_F175 K(KT_FN,184)
+#define K_F176 K(KT_FN,185)
+#define K_F177 K(KT_FN,186)
+#define K_F178 K(KT_FN,187)
+#define K_F179 K(KT_FN,188)
+#define K_F180 K(KT_FN,189)
+#define K_F181 K(KT_FN,190)
+#define K_F182 K(KT_FN,191)
+#define K_F183 K(KT_FN,192)
+#define K_F184 K(KT_FN,193)
+#define K_F185 K(KT_FN,194)
+#define K_F186 K(KT_FN,195)
+#define K_F187 K(KT_FN,196)
+#define K_F188 K(KT_FN,197)
+#define K_F189 K(KT_FN,198)
+#define K_F190 K(KT_FN,199)
+#define K_F191 K(KT_FN,200)
+#define K_F192 K(KT_FN,201)
+#define K_F193 K(KT_FN,202)
+#define K_F194 K(KT_FN,203)
+#define K_F195 K(KT_FN,204)
+#define K_F196 K(KT_FN,205)
+#define K_F197 K(KT_FN,206)
+#define K_F198 K(KT_FN,207)
+#define K_F199 K(KT_FN,208)
+#define K_F200 K(KT_FN,209)
+#define K_F201 K(KT_FN,210)
+#define K_F202 K(KT_FN,211)
+#define K_F203 K(KT_FN,212)
+#define K_F204 K(KT_FN,213)
+#define K_F205 K(KT_FN,214)
+#define K_F206 K(KT_FN,215)
+#define K_F207 K(KT_FN,216)
+#define K_F208 K(KT_FN,217)
+#define K_F209 K(KT_FN,218)
+#define K_F210 K(KT_FN,219)
+#define K_F211 K(KT_FN,220)
+#define K_F212 K(KT_FN,221)
+#define K_F213 K(KT_FN,222)
+#define K_F214 K(KT_FN,223)
+#define K_F215 K(KT_FN,224)
+#define K_F216 K(KT_FN,225)
+#define K_F217 K(KT_FN,226)
+#define K_F218 K(KT_FN,227)
+#define K_F219 K(KT_FN,228)
+#define K_F220 K(KT_FN,229)
+#define K_F221 K(KT_FN,230)
+#define K_F222 K(KT_FN,231)
+#define K_F223 K(KT_FN,232)
+#define K_F224 K(KT_FN,233)
+#define K_F225 K(KT_FN,234)
+#define K_F226 K(KT_FN,235)
+#define K_F227 K(KT_FN,236)
+#define K_F228 K(KT_FN,237)
+#define K_F229 K(KT_FN,238)
+#define K_F230 K(KT_FN,239)
+#define K_F231 K(KT_FN,240)
+#define K_F232 K(KT_FN,241)
+#define K_F233 K(KT_FN,242)
+#define K_F234 K(KT_FN,243)
+#define K_F235 K(KT_FN,244)
+#define K_F236 K(KT_FN,245)
+#define K_F237 K(KT_FN,246)
+#define K_F238 K(KT_FN,247)
+#define K_F239 K(KT_FN,248)
+#define K_F240 K(KT_FN,249)
+#define K_F241 K(KT_FN,250)
+#define K_F242 K(KT_FN,251)
+#define K_F243 K(KT_FN,252)
+#define K_F244 K(KT_FN,253)
+#define K_F245 K(KT_FN,254)
+#define K_UNDO K(KT_FN,255)
+
+
+#define K_HOLE K(KT_SPEC,0)
+#define K_ENTER K(KT_SPEC,1)
+#define K_SH_REGS K(KT_SPEC,2)
+#define K_SH_MEM K(KT_SPEC,3)
+#define K_SH_STAT K(KT_SPEC,4)
+#define K_BREAK K(KT_SPEC,5)
+#define K_CONS K(KT_SPEC,6)
+#define K_CAPS K(KT_SPEC,7)
+#define K_NUM K(KT_SPEC,8)
+#define K_HOLD K(KT_SPEC,9)
+#define K_SCROLLFORW K(KT_SPEC,10)
+#define K_SCROLLBACK K(KT_SPEC,11)
+#define K_BOOT K(KT_SPEC,12)
+#define K_CAPSON K(KT_SPEC,13)
+#define K_COMPOSE K(KT_SPEC,14)
+#define K_SAK K(KT_SPEC,15)
+#define K_DECRCONSOLE K(KT_SPEC,16)
+#define K_INCRCONSOLE K(KT_SPEC,17)
+#define K_SPAWNCONSOLE K(KT_SPEC,18)
+#define K_BARENUMLOCK K(KT_SPEC,19)
+
+#define K_ALLOCATED K(KT_SPEC,126) /* dynamically allocated keymap */
+#define K_NOSUCHMAP K(KT_SPEC,127) /* returned by KDGKBENT */
+
+#define K_P0 K(KT_PAD,0)
+#define K_P1 K(KT_PAD,1)
+#define K_P2 K(KT_PAD,2)
+#define K_P3 K(KT_PAD,3)
+#define K_P4 K(KT_PAD,4)
+#define K_P5 K(KT_PAD,5)
+#define K_P6 K(KT_PAD,6)
+#define K_P7 K(KT_PAD,7)
+#define K_P8 K(KT_PAD,8)
+#define K_P9 K(KT_PAD,9)
+#define K_PPLUS K(KT_PAD,10) /* key-pad plus */
+#define K_PMINUS K(KT_PAD,11) /* key-pad minus */
+#define K_PSTAR K(KT_PAD,12) /* key-pad asterisk (star) */
+#define K_PSLASH K(KT_PAD,13) /* key-pad slash */
+#define K_PENTER K(KT_PAD,14) /* key-pad enter */
+#define K_PCOMMA K(KT_PAD,15) /* key-pad comma: kludge... */
+#define K_PDOT K(KT_PAD,16) /* key-pad dot (period): kludge... */
+#define K_PPLUSMINUS K(KT_PAD,17) /* key-pad plus/minus */
+#define K_PPARENL K(KT_PAD,18) /* key-pad left parenthesis */
+#define K_PPARENR K(KT_PAD,19) /* key-pad right parenthesis */
+
+#define NR_PAD 20
+
+#define K_DGRAVE K(KT_DEAD,0)
+#define K_DACUTE K(KT_DEAD,1)
+#define K_DCIRCM K(KT_DEAD,2)
+#define K_DTILDE K(KT_DEAD,3)
+#define K_DDIERE K(KT_DEAD,4)
+#define K_DCEDIL K(KT_DEAD,5)
+
+#define NR_DEAD 6
+
+#define K_DOWN K(KT_CUR,0)
+#define K_LEFT K(KT_CUR,1)
+#define K_RIGHT K(KT_CUR,2)
+#define K_UP K(KT_CUR,3)
+
+#define K_SHIFT K(KT_SHIFT,KG_SHIFT)
+#define K_CTRL K(KT_SHIFT,KG_CTRL)
+#define K_ALT K(KT_SHIFT,KG_ALT)
+#define K_ALTGR K(KT_SHIFT,KG_ALTGR)
+#define K_SHIFTL K(KT_SHIFT,KG_SHIFTL)
+#define K_SHIFTR K(KT_SHIFT,KG_SHIFTR)
+#define K_CTRLL K(KT_SHIFT,KG_CTRLL)
+#define K_CTRLR K(KT_SHIFT,KG_CTRLR)
+#define K_CAPSSHIFT K(KT_SHIFT,KG_CAPSSHIFT)
+
+#define K_ASC0 K(KT_ASCII,0)
+#define K_ASC1 K(KT_ASCII,1)
+#define K_ASC2 K(KT_ASCII,2)
+#define K_ASC3 K(KT_ASCII,3)
+#define K_ASC4 K(KT_ASCII,4)
+#define K_ASC5 K(KT_ASCII,5)
+#define K_ASC6 K(KT_ASCII,6)
+#define K_ASC7 K(KT_ASCII,7)
+#define K_ASC8 K(KT_ASCII,8)
+#define K_ASC9 K(KT_ASCII,9)
+#define K_HEX0 K(KT_ASCII,10)
+#define K_HEX1 K(KT_ASCII,11)
+#define K_HEX2 K(KT_ASCII,12)
+#define K_HEX3 K(KT_ASCII,13)
+#define K_HEX4 K(KT_ASCII,14)
+#define K_HEX5 K(KT_ASCII,15)
+#define K_HEX6 K(KT_ASCII,16)
+#define K_HEX7 K(KT_ASCII,17)
+#define K_HEX8 K(KT_ASCII,18)
+#define K_HEX9 K(KT_ASCII,19)
+#define K_HEXa K(KT_ASCII,20)
+#define K_HEXb K(KT_ASCII,21)
+#define K_HEXc K(KT_ASCII,22)
+#define K_HEXd K(KT_ASCII,23)
+#define K_HEXe K(KT_ASCII,24)
+#define K_HEXf K(KT_ASCII,25)
+
+#define NR_ASCII 26
+
+#define K_SHIFTLOCK K(KT_LOCK,KG_SHIFT)
+#define K_CTRLLOCK K(KT_LOCK,KG_CTRL)
+#define K_ALTLOCK K(KT_LOCK,KG_ALT)
+#define K_ALTGRLOCK K(KT_LOCK,KG_ALTGR)
+#define K_SHIFTLLOCK K(KT_LOCK,KG_SHIFTL)
+#define K_SHIFTRLOCK K(KT_LOCK,KG_SHIFTR)
+#define K_CTRLLLOCK K(KT_LOCK,KG_CTRLL)
+#define K_CTRLRLOCK K(KT_LOCK,KG_CTRLR)
+
+#define K_SHIFT_SLOCK K(KT_SLOCK,KG_SHIFT)
+#define K_CTRL_SLOCK K(KT_SLOCK,KG_CTRL)
+#define K_ALT_SLOCK K(KT_SLOCK,KG_ALT)
+#define K_ALTGR_SLOCK K(KT_SLOCK,KG_ALTGR)
+#define K_SHIFTL_SLOCK K(KT_SLOCK,KG_SHIFTL)
+#define K_SHIFTR_SLOCK K(KT_SLOCK,KG_SHIFTR)
+#define K_CTRLL_SLOCK K(KT_SLOCK,KG_CTRLL)
+#define K_CTRLR_SLOCK K(KT_SLOCK,KG_CTRLR)
+
+#define NR_LOCK 8
+
+#define MAX_DIACR 256
+
+extern struct kbdiacr accent_table[MAX_DIACR];
+extern unsigned int accent_table_size;
+
+/* kbd_kern.h --- header file from linux --- */
+extern int shift_state;
+
+extern char *func_table[MAX_NR_FUNC];
+extern char func_buf[];
+extern char *funcbufptr;
+extern int funcbufsize, funcbufleft;
+
+/*
+ * kbd->xxx contains the VC-local things (flag settings etc..)
+ *
+ * Note: externally visible are LED_SCR, LED_NUM, LED_CAP defined in kd.h
+ * The code in KDGETLED / KDSETLED depends on the internal and
+ * external order being the same.
+ *
+ * Note: lockstate is used as index in the array key_map.
+ */
+struct kbd_struct {
+
+ unsigned char lockstate;
+/* 8 modifiers - the names do not have any meaning at all;
+ they can be associated to arbitrarily chosen keys */
+#define VC_SHIFTLOCK KG_SHIFT /* shift lock mode */
+#define VC_ALTGRLOCK KG_ALTGR /* altgr lock mode */
+#define VC_CTRLLOCK KG_CTRL /* control lock mode */
+#define VC_ALTLOCK KG_ALT /* alt lock mode */
+#define VC_SHIFTLLOCK KG_SHIFTL /* shiftl lock mode */
+#define VC_SHIFTRLOCK KG_SHIFTR /* shiftr lock mode */
+#define VC_CTRLLLOCK KG_CTRLL /* ctrll lock mode */
+#define VC_CTRLRLOCK KG_CTRLR /* ctrlr lock mode */
+ unsigned char slockstate; /* for `sticky' Shift, Ctrl, etc. */
+
+ unsigned char ledmode:2; /* one 2-bit value */
+#define LED_SHOW_FLAGS 0 /* traditional state */
+#define LED_SHOW_IOCTL 1 /* only change leds upon ioctl */
+#define LED_SHOW_MEM 2 /* `heartbeat': peek into memory */
+
+ unsigned char ledflagstate:3; /* flags, not lights */
+ unsigned char default_ledflagstate:3;
+#define VC_SCROLLOCK 0 /* scroll-lock mode */
+#define VC_NUMLOCK 1 /* numeric lock mode */
+#define VC_CAPSLOCK 2 /* capslock mode */
+
+ unsigned char kbdmode:2; /* one 2-bit value */
+#define VC_XLATE 0 /* translate keycodes using keymap */
+#define VC_MEDIUMRAW 1 /* medium raw (keycode) mode */
+#define VC_RAW 2 /* raw (scancode) mode */
+#define VC_UNICODE 3 /* Unicode mode */
+
+ unsigned char modeflags:5;
+#define VC_APPLIC 0 /* application key mode */
+#define VC_CKMODE 1 /* cursor key mode */
+#define VC_REPEAT 2 /* keyboard repeat */
+#define VC_CRLF 3 /* 0 - enter sends CR, 1 - enter sends CRLF */
+#define VC_META 4 /* 0 - meta, 1 - meta=prefix with ESC */
+};
+
+extern struct kbd_struct kbd_table[];
+
+extern int kbd_init(void);
+
+extern unsigned char getledstate(void);
+extern void setledstate(struct kbd_struct *kbd, unsigned int led);
+
+extern inline void show_console(void)
+{
+}
+
+extern inline void set_console(int nr)
+{
+}
+
+extern void set_leds(void);
+
+extern inline int vc_kbd_mode(struct kbd_struct * kbd, int flag)
+{
+ return ((kbd->modeflags >> flag) & 1);
+}
+
+extern inline int vc_kbd_led(struct kbd_struct * kbd, int flag)
+{
+ return ((kbd->ledflagstate >> flag) & 1);
+}
+
+extern inline void set_vc_kbd_mode(struct kbd_struct * kbd, int flag)
+{
+ kbd->modeflags |= 1 << flag;
+}
+
+extern inline void set_vc_kbd_led(struct kbd_struct * kbd, int flag)
+{
+ kbd->ledflagstate |= 1 << flag;
+}
+
+extern inline void clr_vc_kbd_mode(struct kbd_struct * kbd, int flag)
+{
+ kbd->modeflags &= ~(1 << flag);
+}
+
+extern inline void clr_vc_kbd_led(struct kbd_struct * kbd, int flag)
+{
+ kbd->ledflagstate &= ~(1 << flag);
+}
+
+extern inline void chg_vc_kbd_lock(struct kbd_struct * kbd, int flag)
+{
+ kbd->lockstate ^= 1 << flag;
+}
+
+extern inline void chg_vc_kbd_slock(struct kbd_struct * kbd, int flag)
+{
+ kbd->slockstate ^= 1 << flag;
+}
+
+extern inline void chg_vc_kbd_mode(struct kbd_struct * kbd, int flag)
+{
+ kbd->modeflags ^= 1 << flag;
+}
+
+extern inline void chg_vc_kbd_led(struct kbd_struct * kbd, int flag)
+{
+ kbd->ledflagstate ^= 1 << flag;
+ set_leds();
+}
+
+#define U(x) ((x) ^ 0xf000)
+
+/* keyboard.c */
+
+int getkeycode(unsigned int scancode);
+int setkeycode(unsigned int scancode, unsigned int keycode);
+void compute_shiftstate(void);
+
+/* defkeymap.c */
+
+extern unsigned int keymap_count;
+
+
+#endif
diff --git a/c/src/lib/libbsp/i386/pc386/console/mouse_parser.c b/c/src/lib/libbsp/i386/pc386/console/mouse_parser.c
new file mode 100644
index 0000000000..ca068df87d
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/mouse_parser.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 1999 Greg Haerr <greg@censoft.com>
+ * Portions Copyright (c) 1991 David I. Bell
+ * Permission is granted to use, distribute, or modify this source,
+ * provided that this copyright notice remains intact.
+ *
+ * UNIX Serial Port Mouse Driver
+ *
+ * This driver opens a serial port directly, and interprets serial data.
+ * Microsoft, PC, Logitech and PS/2 mice are supported.
+ * The PS/2 mouse is only supported if the OS runs the mouse
+ * byte codes through the serial port.
+ *
+ * The following environment variables control the mouse type expected
+ * and the serial port to open.
+ *
+ * Environment Var Default Allowed
+ * MOUSE_TYPE pc ms, pc, logi, ps2
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <rtems.h>
+#include <bsp.h>
+#include "keyboard.h"
+#include "mouse_parser.h"
+#include "serial_mouse.h"
+
+
+/* NOTE NOTE NOTE NOTE:
+ Select here the mouse type !!!!!
+*/
+#ifndef MOUSE_TYPE
+#define MOUSE_TYPE "ms" /* default mouse type "ms","pc","ps2" */
+#endif
+
+/* states for the mouse*/
+#define IDLE 0 /* start of byte sequence */
+#define XSET 1 /* setting x delta */
+#define YSET 2 /* setting y delta */
+#define XADD 3 /* adjusting x delta */
+#define YADD 4 /* adjusting y delta */
+
+/* values in the bytes returned by the mouse for the buttons*/
+#define PC_LEFT_BUTTON 4
+#define PC_MIDDLE_BUTTON 2
+#define PC_RIGHT_BUTTON 1
+
+#define MS_LEFT_BUTTON 2
+#define MS_RIGHT_BUTTON 1
+
+#define PS2_CTRL_BYTE 0x08
+#define PS2_LEFT_BUTTON 1
+#define PS2_RIGHT_BUTTON 2
+
+/* Bit fields in the bytes sent by the mouse.*/
+#define TOP_FIVE_BITS 0xf8
+#define BOTTOM_THREE_BITS 0x07
+#define TOP_BIT 0x80
+#define SIXTH_BIT 0x40
+#define BOTTOM_TWO_BITS 0x03
+#define THIRD_FOURTH_BITS 0x0c
+#define BOTTOM_SIX_BITS 0x3f
+
+/* local data*/
+static int state; /* IDLE, XSET, ... */
+static BUTTON buttons; /* current mouse buttons pressed*/
+static BUTTON availbuttons; /* which buttons are available */
+static COORD xd; /* change in x */
+static COORD yd; /* change in y */
+
+static int left; /* because the button values change */
+static int middle; /* between mice, the buttons are */
+static int right; /* redefined */
+
+static int (*parse)( int ); /* parse routine */
+
+/* local routines*/
+static int ParsePC(int); /* routine to interpret PC mouse */
+static int ParseMS(int); /* routine to interpret MS mouse */
+static int ParsePS2(int); /* routine to interpret PS/2 mouse */
+
+extern void uart_set_driver_handler( int port, void ( *handler )( void *, char *, int ) );
+extern void kbd_set_driver_handler( void ( *handler )( void *, unsigned short, unsigned long ) );
+extern void ps2_set_driver_handler( int port, void ( *handler )( void *, char *, int ) );
+
+/*
+ * Open up the mouse device.
+ * Returns the fd if successful, or negative if unsuccessful.
+ */
+int MOU_Init()
+{
+ char *type;
+
+ /* get mouse type and port*/
+ type = MOUSE_TYPE;
+
+ /* set button bits and parse procedure*/
+ if(!strcmp(type, "pc") || !strcmp(type, "logi")) {
+ /* pc or logitech mouse*/
+ left = PC_LEFT_BUTTON;
+ middle = PC_MIDDLE_BUTTON;
+ right = PC_RIGHT_BUTTON;
+ parse = ParsePC;
+ } else if (strcmp(type, "ms") == 0) {
+ /* microsoft mouse*/
+ left = MS_LEFT_BUTTON;
+ right = MS_RIGHT_BUTTON;
+ middle = 0;
+ parse = ParseMS;
+ } else if (strcmp(type, "ps2") == 0) {
+ /* PS/2 mouse*/
+ left = PS2_LEFT_BUTTON;
+ right = PS2_RIGHT_BUTTON;
+ middle = 0;
+ parse = ParsePS2;
+ } else
+ return -1;
+
+ printk("Device: /dev/mouse -- mouse type is: %s\n", MOUSE_TYPE );
+
+ /* initialize data*/
+ availbuttons = left | middle | right;
+ state = IDLE;
+ buttons = 0;
+ xd = 0;
+ yd = 0;
+ return 0;
+}
+
+/*
+ * Attempt to read bytes from the mouse and interpret them.
+ * Returns -1 on error, 0 if either no bytes were read or not enough
+ * was read for a complete state, or 1 if the new state was read.
+ * When a new state is read, the current buttons and x and y deltas
+ * are returned. This routine does not block.
+ */
+int MOU_Data( int ch, COORD *dx, COORD *dy, COORD *dz, BUTTON *bptr)
+{
+ int b;
+
+ /*
+ * Loop over all the bytes read in the buffer, parsing them.
+ * When a complete state has been read, return the results,
+ * leaving further bytes in the buffer for later calls.
+ */
+ if( (*parse)( ch ) )
+ {
+ *dx = xd;
+ *dy = yd;
+ *dz = 0;
+ b = 0;
+ if(buttons & left)
+ b |= LBUTTON;
+ if(buttons & right)
+ b |= RBUTTON;
+ if(buttons & middle)
+ b |= MBUTTON;
+ *bptr = b;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Input routine for PC mouse.
+ * Returns nonzero when a new mouse state has been completed.
+ */
+static int ParsePC(int byte)
+{
+ int sign; /* sign of movement */
+
+ switch (state) {
+ case IDLE:
+ if ((byte & TOP_FIVE_BITS) == TOP_BIT) {
+ buttons = ~byte & BOTTOM_THREE_BITS;
+ state = XSET;
+ }
+ break;
+
+ case XSET:
+ sign = 1;
+ if (byte > 127) {
+ byte = 256 - byte;
+ sign = -1;
+ }
+ xd = byte * sign;
+ state = YSET;
+ break;
+
+ case YSET:
+ sign = 1;
+ if (byte > 127) {
+ byte = 256 - byte;
+ sign = -1;
+ }
+ yd = -byte * sign;
+ state = XADD;
+ break;
+
+ case XADD:
+ sign = 1;
+ if (byte > 127) {
+ byte = 256 - byte;
+ sign = -1;
+ }
+ xd += byte * sign;
+ state = YADD;
+ break;
+
+ case YADD:
+ sign = 1;
+ if (byte > 127) {
+ byte = 256 - byte;
+ sign = -1;
+ }
+ yd -= byte * sign;
+ state = IDLE;
+ return 1;
+ }
+ return 0;
+}
+
+
+/*
+ * Input routine for Microsoft mouse.
+ * Returns nonzero when a new mouse state has been completed.
+ */
+static int ParseMS(int byte)
+{
+ switch (state) {
+ case IDLE:
+ if (byte & SIXTH_BIT) {
+ buttons = (byte >> 4) & BOTTOM_TWO_BITS;
+ yd = ((byte & THIRD_FOURTH_BITS) << 4);
+ xd = ((byte & BOTTOM_TWO_BITS) << 6);
+ state = XADD;
+ }
+ break;
+
+ case XADD:
+ xd |= (byte & BOTTOM_SIX_BITS);
+ state = YADD;
+ break;
+
+ case YADD:
+ yd |= (byte & BOTTOM_SIX_BITS);
+ state = IDLE;
+ if (xd > 127)
+ xd -= 256;
+ if (yd > 127)
+ yd -= 256;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Input routine for PS/2 mouse.
+ * Returns nonzero when a new mouse state has been completed.
+ */
+static int ParsePS2(int byte)
+{
+ switch (state) {
+ case IDLE:
+ if (byte & PS2_CTRL_BYTE) {
+ buttons = byte &
+ (PS2_LEFT_BUTTON|PS2_RIGHT_BUTTON);
+ state = XSET;
+ }
+ break;
+
+ case XSET:
+ if(byte > 127)
+ byte -= 256;
+ xd = byte;
+ state = YSET;
+ break;
+
+ case YSET:
+ if(byte > 127)
+ byte -= 256;
+ yd = -byte;
+ state = IDLE;
+ return 1;
+ }
+ return 0;
+}
+
+static rtems_id queue_id = 0;
+
+/* generic keyboard parser */
+static void mouse_parser( void *ptr, char *buffer, int size )
+{
+ COORD dx;
+ COORD dy;
+ COORD dz;
+ BUTTON bptr;
+ while( size-- )
+ {
+ if( MOU_Data( *buffer++, &dx, &dy, &dz, &bptr ) )
+ {
+ struct MW_UID_MESSAGE m;
+ m.type = MV_UID_REL_POS;
+ /* buttons definitons have been selected to match */
+ m.m.pos.btns = bptr;
+ m.m.pos.x = dx;
+ m.m.pos.y = dy;
+ m.m.pos.z = dz;
+/* printk( "Mouse: msg: dx=%d, dy=%d, btn=%X\n", dx, dy, bptr ); */
+ rtems_message_queue_send( queue_id, ( void * )&m, sizeof( struct MW_UID_MESSAGE ) );
+ }
+ }
+}
+
+/* enable the mouse to add messages to the queue */
+void register_mou_msg_queue( char * q_name, int port )
+{
+ rtems_name queue_name;
+ rtems_status_code status;
+ queue_name = rtems_build_name( q_name[0],
+ q_name[1],
+ q_name[2],
+ q_name[3] );
+ status = rtems_message_queue_ident( queue_name, RTEMS_LOCAL, &queue_id );
+ if( status != RTEMS_SUCCESSFUL )
+ {
+ printk( "UID_Queue: error open queue: %d\n", status );
+ return;
+ }
+ MOU_Init();
+ if( port == -1 )
+ {
+ /* we know the mouse type in this case, let's initialize everything */
+ left = PS2_LEFT_BUTTON;
+ right = PS2_RIGHT_BUTTON;
+ middle = 0;
+ parse = ParsePS2;
+ ps2_set_driver_handler( port, mouse_parser );
+ }
+ else
+ {
+ uart_set_driver_handler( port, mouse_parser );
+ }
+}
+
+/* stop the mouse from adding messages to the queue */
+void unregister_mou_msg_queue( int port )
+{
+ if( port == -1 )
+ {
+ ps2_set_driver_handler( port, NULL );
+ }
+ else
+ {
+ uart_set_driver_handler( port, NULL );
+ }
+}
+
+/* adds a kbd message to the queue */
+static void kbd_parser( void *ptr, unsigned short keycode, unsigned long mods )
+{
+ struct MW_UID_MESSAGE m;
+ struct kbd_struct * kbd = ( struct kbd_struct *)ptr;
+
+ m.type = MV_UID_KBD;
+ m.m.kbd.code = keycode;
+ m.m.kbd.modifiers = kbd->ledflagstate;
+ m.m.kbd.mode = kbd->kbdmode;
+ /* printk( "kbd: msg: keycode=%X, mod=%X\n", keycode, mods ); */
+ rtems_message_queue_send( queue_id, ( void * )&m,
+ sizeof( struct MW_UID_MESSAGE ) );
+}
+
+void register_kbd_msg_queue( char *q_name, int port )
+{
+ rtems_name queue_name;
+ rtems_status_code status;
+
+ queue_name = rtems_build_name( q_name[0],
+ q_name[1],
+ q_name[2],
+ q_name[3] );
+ status = rtems_message_queue_ident( queue_name, RTEMS_LOCAL, &queue_id );
+ if( status != RTEMS_SUCCESSFUL )
+ {
+ printk( "UID_Queue: error open queue: %d\n", status );
+ return;
+ }
+ kbd_set_driver_handler( kbd_parser );
+}
+
+
+void unregister_kbd_msg_queue( int port )
+{
+ kbd_set_driver_handler( NULL );
+}
diff --git a/c/src/lib/libbsp/i386/pc386/console/mouse_parser.h b/c/src/lib/libbsp/i386/pc386/console/mouse_parser.h
new file mode 100644
index 0000000000..7956a14599
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/mouse_parser.h
@@ -0,0 +1,36 @@
+#ifndef __mouse_parser_h__
+#define __mouse_parser_h__
+
+#include <rtems/mw_uid.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Use the same definitions as the user interface */
+#define RBUTTON MV_BUTTON_RIGHT
+#define MBUTTON MV_BUTTON_CENTER
+#define LBUTTON MV_BUTTON_LEFT
+
+typedef int COORD; /* device coordinates*/
+typedef unsigned int BUTTON; /* mouse button mask*/
+
+/* local routines */
+int MOU_Init();
+int MOU_Data( int ch, COORD *dx, COORD *dy, COORD *dz, BUTTON *bptr );
+
+/* Mouse Interface */
+void register_mou_msg_queue( char * qname, int port );
+void unregister_mou_msg_queue( int port );
+
+/* KBD Interface */
+void register_kbd_msg_queue( char *qname, int port );
+void unregister_kbd_msg_queue( int port );
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __mouse_parser_h__ */
+
diff --git a/c/src/lib/libbsp/i386/pc386/console/outch.c b/c/src/lib/libbsp/i386/pc386/console/outch.c
index 1d5c1f9c38..bdb44a1d8d 100644
--- a/c/src/lib/libbsp/i386/pc386/console/outch.c
+++ b/c/src/lib/libbsp/i386/pc386/console/outch.c
@@ -179,3 +179,24 @@ _IBMPC_initVideo(void)
videoPrintf("maxCol = %d, maxRow = %d\n", (unsigned) maxCol, (unsigned) maxRow);
#endif
} /* _IBMPC_initVideo */
+
+
+/* for old DOS compatibility n-curses type of applications */
+void gotoxy( int x, int y )
+{
+ row = x;
+ column = y;
+ wr_cursor(row * maxCol + column, ioCrtBaseAddr);
+}
+
+
+int whereX( void )
+{
+ return row;
+}
+
+int whereY( void )
+{
+ return column;
+}
+
diff --git a/c/src/lib/libbsp/i386/pc386/console/pc_keyb.c b/c/src/lib/libbsp/i386/pc386/console/pc_keyb.c
new file mode 100644
index 0000000000..0b94666504
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/pc_keyb.c
@@ -0,0 +1,648 @@
+/*
+ * linux/drivers/char/pc_keyb.c
+ *
+ * Separation of the PC low-level part by Geert Uytterhoeven, May 1997
+ * See keyboard.c for the whole history.
+ *
+ * Major cleanup by Martin Mares, May 1997
+ *
+ * Combined the keyboard and PS/2 mouse handling into one file,
+ * because they share the same hardware.
+ * Johan Myreen <jem@iki.fi> 1998-10-08.
+ *
+ * Code fixes to handle mouse ACKs properly.
+ * C. Scott Ananian <cananian@alumni.princeton.edu> 1999-01-29.
+ *
+ * Ported to RTEMS by Rosimildo da Silva
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <bsp.h>
+#include "i386kbd.h"
+
+/* keyboard.c */
+extern void handle_scancode(unsigned char scancode, int down);
+
+static unsigned char handle_kbd_event(void);
+static void kbd_write_command_w(int data);
+static void kbd_write_output_w(int data);
+
+/* Some configuration switches are present in the include file... */
+
+/* Simple translation table for the SysRq keys */
+
+#ifdef CONFIG_MAGIC_SYSRQ
+unsigned char pckbd_sysrq_xlate[128] =
+ "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
+ "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
+ "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
+ "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
+ "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
+ "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
+ "\r\000/"; /* 0x60 - 0x6f */
+#endif
+
+/* used only by send_data - set by keyboard_interrupt */
+static volatile unsigned char reply_expected = 0;
+static volatile unsigned char acknowledge = 0;
+static volatile unsigned char resend = 0;
+
+/*
+ * Translation of escaped scancodes to keycodes.
+ * This is now user-settable.
+ * The keycodes 1-88,96-111,119 are fairly standard, and
+ * should probably not be changed - changing might confuse X.
+ * X also interprets scancode 0x5d (KEY_Begin).
+ *
+ * For 1-88 keycode equals scancode.
+ */
+
+#define E0_KPENTER 96
+#define E0_RCTRL 97
+#define E0_KPSLASH 98
+#define E0_PRSCR 99
+#define E0_RALT 100
+#define E0_BREAK 101 /* (control-pause) */
+#define E0_HOME 102
+#define E0_UP 103
+#define E0_PGUP 104
+#define E0_LEFT 105
+#define E0_RIGHT 106
+#define E0_END 107
+#define E0_DOWN 108
+#define E0_PGDN 109
+#define E0_INS 110
+#define E0_DEL 111
+
+#define E1_PAUSE 119
+
+/*
+ * The keycodes below are randomly located in 89-95,112-118,120-127.
+ * They could be thrown away (and all occurrences below replaced by 0),
+ * but that would force many users to use the `setkeycodes' utility, where
+ * they needed not before. It does not matter that there are duplicates, as
+ * long as no duplication occurs for any single keyboard.
+ */
+#define SC_LIM 89
+
+#define FOCUS_PF1 85 /* actual code! */
+#define FOCUS_PF2 89
+#define FOCUS_PF3 90
+#define FOCUS_PF4 91
+#define FOCUS_PF5 92
+#define FOCUS_PF6 93
+#define FOCUS_PF7 94
+#define FOCUS_PF8 95
+#define FOCUS_PF9 120
+#define FOCUS_PF10 121
+#define FOCUS_PF11 122
+#define FOCUS_PF12 123
+
+#define JAP_86 124
+/* tfj@olivia.ping.dk:
+ * The four keys are located over the numeric keypad, and are
+ * labelled A1-A4. It's an rc930 keyboard, from
+ * Regnecentralen/RC International, Now ICL.
+ * Scancodes: 59, 5a, 5b, 5c.
+ */
+#define RGN1 124
+#define RGN2 125
+#define RGN3 126
+#define RGN4 127
+
+static unsigned char high_keys[128 - SC_LIM] = {
+ RGN1, RGN2, RGN3, RGN4, 0, 0, 0, /* 0x59-0x5f */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
+ 0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12, /* 0x68-0x6f */
+ 0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3, /* 0x70-0x77 */
+ FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7, /* 0x78-0x7b */
+ FOCUS_PF8, JAP_86, FOCUS_PF10, 0 /* 0x7c-0x7f */
+};
+
+/* BTC */
+#define E0_MACRO 112
+/* LK450 */
+#define E0_F13 113
+#define E0_F14 114
+#define E0_HELP 115
+#define E0_DO 116
+#define E0_F17 117
+#define E0_KPMINPLUS 118
+/*
+ * My OmniKey generates e0 4c for the "OMNI" key and the
+ * right alt key does nada. [kkoller@nyx10.cs.du.edu]
+ */
+#define E0_OK 124
+/*
+ * New microsoft keyboard is rumoured to have
+ * e0 5b (left window button), e0 5c (right window button),
+ * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
+ * [or: Windows_L, Windows_R, TaskMan]
+ */
+#define E0_MSLW 125
+#define E0_MSRW 126
+#define E0_MSTM 127
+
+static unsigned char e0_keys[128] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x07 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x08-0x0f */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */
+ 0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0, /* 0x18-0x1f */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */
+ 0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR, /* 0x30-0x37 */
+ E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP, /* 0x38-0x3f */
+ E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME, /* 0x40-0x47 */
+ E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
+ E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0, /* 0x50-0x57 */
+ 0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0, /* 0x58-0x5f */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
+ 0, 0, 0, 0, 0, 0, 0, E0_MACRO, /* 0x68-0x6f */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */
+ 0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7f */
+};
+
+
+static void mdelay( unsigned long t )
+{
+ Wait_X_ms( t );
+}
+
+int pckbd_setkeycode(unsigned int scancode, unsigned int keycode)
+{
+ if (scancode < SC_LIM || scancode > 255 || keycode > 127)
+ return -EINVAL;
+ if (scancode < 128)
+ high_keys[scancode - SC_LIM] = keycode;
+ else
+ e0_keys[scancode - 128] = keycode;
+ return 0;
+}
+
+int pckbd_getkeycode(unsigned int scancode)
+{
+ return
+ (scancode < SC_LIM || scancode > 255) ? -EINVAL :
+ (scancode < 128) ? high_keys[scancode - SC_LIM] :
+ e0_keys[scancode - 128];
+}
+
+static int do_acknowledge(unsigned char scancode)
+{
+ if (reply_expected) {
+ /* Unfortunately, we must recognise these codes only if we know they
+ * are known to be valid (i.e., after sending a command), because there
+ * are some brain-damaged keyboards (yes, FOCUS 9000 again) which have
+ * keys with such codes :(
+ */
+ if (scancode == KBD_REPLY_ACK) {
+ acknowledge = 1;
+ reply_expected = 0;
+ return 0;
+ } else if (scancode == KBD_REPLY_RESEND) {
+ resend = 1;
+ reply_expected = 0;
+ return 0;
+ }
+ /* Should not happen... */
+ printk( "keyboard reply expected - got %02x\n", scancode);
+ }
+ return 1;
+}
+
+int pckbd_translate(unsigned char scancode, unsigned char *keycode,
+ char raw_mode)
+{
+ static int prev_scancode = 0;
+
+
+ /* special prefix scancodes.. */
+ if (scancode == 0xe0 || scancode == 0xe1) {
+ prev_scancode = scancode;
+ return 0;
+ }
+
+ /* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */
+ if (scancode == 0x00 || scancode == 0xff) {
+ prev_scancode = 0;
+ return 0;
+ }
+
+ scancode &= 0x7f;
+
+ if (prev_scancode) {
+ /*
+ * usually it will be 0xe0, but a Pause key generates
+ * e1 1d 45 e1 9d c5 when pressed, and nothing when released
+ */
+ if (prev_scancode != 0xe0) {
+ if (prev_scancode == 0xe1 && scancode == 0x1d) {
+ prev_scancode = 0x100;
+ return 0;
+ } else if (prev_scancode == 0x100 && scancode == 0x45) {
+ *keycode = E1_PAUSE;
+ prev_scancode = 0;
+ } else {
+#ifdef KBD_REPORT_UNKN
+ if (!raw_mode)
+ printk("keyboard: unknown e1 escape sequence\n");
+#endif
+ prev_scancode = 0;
+ return 0;
+ }
+ } else {
+ prev_scancode = 0;
+ /*
+ * The keyboard maintains its own internal caps lock and
+ * num lock statuses. In caps lock mode E0 AA precedes make
+ * code and E0 2A follows break code. In num lock mode,
+ * E0 2A precedes make code and E0 AA follows break code.
+ * We do our own book-keeping, so we will just ignore these.
+ */
+ /*
+ * For my keyboard there is no caps lock mode, but there are
+ * both Shift-L and Shift-R modes. The former mode generates
+ * E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs.
+ * So, we should also ignore the latter. - aeb@cwi.nl
+ */
+ if (scancode == 0x2a || scancode == 0x36)
+ return 0;
+
+ if (e0_keys[scancode])
+ *keycode = e0_keys[scancode];
+ else {
+#ifdef KBD_REPORT_UNKN
+ if (!raw_mode)
+ printk( "keyboard: unknown scancode e0 %02x\n",
+ scancode);
+#endif
+ return 0;
+ }
+ }
+ } else if (scancode >= SC_LIM) {
+ /* This happens with the FOCUS 9000 keyboard
+ Its keys PF1..PF12 are reported to generate
+ 55 73 77 78 79 7a 7b 7c 74 7e 6d 6f
+ Moreover, unless repeated, they do not generate
+ key-down events, so we have to zero up_flag below */
+ /* Also, Japanese 86/106 keyboards are reported to
+ generate 0x73 and 0x7d for \ - and \ | respectively. */
+ /* Also, some Brazilian keyboard is reported to produce
+ 0x73 and 0x7e for \ ? and KP-dot, respectively. */
+
+ *keycode = high_keys[scancode - SC_LIM];
+ if (!*keycode) {
+ if (!raw_mode) {
+#ifdef KBD_REPORT_UNKN
+ printk( "keyboard: unrecognized scancode (%02x)"
+ " - ignored\n", scancode);
+#endif
+ }
+ return 0;
+ }
+ } else
+ *keycode = scancode;
+ return 1;
+}
+
+char pckbd_unexpected_up(unsigned char keycode)
+{
+ /* unexpected, but this can happen: maybe this was a key release for a
+ FOCUS 9000 PF key; if we want to see it, we have to clear up_flag */
+ if (keycode >= SC_LIM || keycode == 85)
+ return 0;
+ else
+ return 0200;
+}
+
+
+
+static void kb_wait(void)
+{
+ unsigned long timeout = KBC_TIMEOUT;
+
+ do {
+ /*
+ * "handle_kbd_event()" will handle any incoming events
+ * while we wait - keypresses or mouse movement.
+ */
+ unsigned char status = handle_kbd_event();
+
+ if (! (status & KBD_STAT_IBF))
+ return;
+ mdelay(1);
+ timeout--;
+ } while (timeout);
+#ifdef KBD_REPORT_TIMEOUTS
+ printk( "Keyboard timed out[1]\n");
+#endif
+}
+
+
+/*
+ * This reads the keyboard status port, and does the
+ * appropriate action.
+ *
+ * It requires that we hold the keyboard controller
+ * spinlock.
+ */
+static unsigned char handle_kbd_event(void)
+{
+ unsigned char status = kbd_read_status();
+ unsigned int work = 10000;
+
+ while (status & KBD_STAT_OBF) {
+ unsigned char scancode;
+
+ scancode = kbd_read_input();
+ if (status & KBD_STAT_MOUSE_OBF) {
+#if 0
+ handle_mouse_event(scancode);
+#endif
+ } else {
+ if (do_acknowledge(scancode))
+ handle_scancode(scancode, !(scancode & 0x80));
+ mark_bh(KEYBOARD_BH);
+ }
+
+ status = kbd_read_status();
+
+ if(!work--)
+ {
+ printk( "pc_keyb: controller jammed (0x%02X).\n", status);
+ break;
+ }
+ return status;
+ }
+
+ /*
+ * the commands to set the leds for some reason, returns 0x14, 0x16
+ * and I am intepreting as an ACK, because the original code from
+ * Linux was timeing out here...
+ */
+ acknowledge = 1;
+ reply_expected = 0;
+ resend = 0;
+ return status;
+}
+
+
+void keyboard_interrupt( void )
+{
+ handle_kbd_event();
+}
+
+/*
+ * send_data sends a character to the keyboard and waits
+ * for an acknowledge, possibly retrying if asked to. Returns
+ * the success status.
+ *
+ * Don't use 'jiffies', so that we don't depend on interrupts
+ */
+static int send_data(unsigned char data)
+{
+ int retries = 3;
+
+ do {
+ unsigned long timeout = KBD_TIMEOUT;
+
+ acknowledge = 0; /* Set by interrupt routine on receipt of ACK. */
+ resend = 0;
+ reply_expected = 1;
+ kbd_write_output_w(data);
+ for (;;) {
+ if (acknowledge)
+ return 1;
+ if (resend)
+ break;
+ mdelay(1);
+ if (!--timeout) {
+#ifdef KBD_REPORT_TIMEOUTS
+ printk("Keyboard timeout[2]\n");
+#endif
+ return 0;
+ }
+ }
+ } while (retries-- > 0);
+#ifdef KBD_REPORT_TIMEOUTS
+ printk( "keyboard: Too many NACKs -- noisy kbd cable?\n");
+#endif
+ return 0;
+}
+
+void pckbd_leds(unsigned char leds)
+{
+ if (!send_data(KBD_CMD_SET_LEDS) || !send_data(leds))
+ send_data(KBD_CMD_ENABLE); /* re-enable kbd if any errors */
+}
+
+/*
+ * In case we run on a non-x86 hardware we need to initialize both the
+ * keyboard controller and the keyboard. On a x86, the BIOS will
+ * already have initialized them.
+ *
+ * Some x86 BIOSes do not correctly initialize the keyboard, so the
+ * "kbd-reset" command line options can be given to force a reset.
+ * [Ranger]
+ */
+#ifdef __i386__
+ int kbd_startup_reset = 0;
+#else
+ int kbd_startup_reset = 1;
+#endif
+
+/* for "kbd-reset" cmdline param */
+void kbd_reset_setup(char *str, int *ints)
+{
+ kbd_startup_reset = 1;
+}
+
+#define KBD_NO_DATA (-1) /* No data */
+#define KBD_BAD_DATA (-2) /* Parity or other error */
+
+static int kbd_read_data(void)
+{
+ int retval = KBD_NO_DATA;
+ unsigned char status;
+
+ status = kbd_read_status();
+ if (status & KBD_STAT_OBF) {
+ unsigned char data = kbd_read_input();
+
+ retval = data;
+ if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
+ retval = KBD_BAD_DATA;
+ }
+ return retval;
+}
+
+static void kbd_clear_input(void)
+{
+ int maxread = 100; /* Random number */
+
+ do {
+ if (kbd_read_data() == KBD_NO_DATA)
+ break;
+ } while (--maxread);
+}
+
+static int kbd_wait_for_input(void)
+{
+ long timeout = KBD_INIT_TIMEOUT;
+
+ do {
+ int retval = kbd_read_data();
+ if (retval >= 0)
+ return retval;
+ mdelay(1);
+ } while (--timeout);
+ return -1;
+}
+
+static void kbd_write_command_w(int data)
+{
+ kb_wait();
+ kbd_write_command(data);
+}
+
+static void kbd_write_output_w(int data)
+{
+ kb_wait();
+ kbd_write_output(data);
+}
+
+static char * initialize_kbd(void)
+{
+ int status;
+
+ /*
+ * Test the keyboard interface.
+ * This seems to be the only way to get it going.
+ * If the test is successful a x55 is placed in the input buffer.
+ */
+ kbd_write_command_w(KBD_CCMD_SELF_TEST);
+ if (kbd_wait_for_input() != 0x55)
+ return "Keyboard failed self test";
+
+ /*
+ * Perform a keyboard interface test. This causes the controller
+ * to test the keyboard clock and data lines. The results of the
+ * test are placed in the input buffer.
+ */
+ kbd_write_command_w(KBD_CCMD_KBD_TEST);
+ if (kbd_wait_for_input() != 0x00)
+ return "Keyboard interface failed self test";
+
+ /*
+ * Enable the keyboard by allowing the keyboard clock to run.
+ */
+ kbd_write_command_w(KBD_CCMD_KBD_ENABLE);
+
+ /*
+ * Reset keyboard. If the read times out
+ * then the assumption is that no keyboard is
+ * plugged into the machine.
+ * This defaults the keyboard to scan-code set 2.
+ *
+ * Set up to try again if the keyboard asks for RESEND.
+ */
+ do {
+ kbd_write_output_w(KBD_CMD_RESET);
+ status = kbd_wait_for_input();
+ if (status == KBD_REPLY_ACK)
+ break;
+ if (status != KBD_REPLY_RESEND)
+ return "Keyboard reset failed, no ACK";
+ } while (1);
+
+ if (kbd_wait_for_input() != KBD_REPLY_POR)
+ return "Keyboard reset failed, no POR";
+
+ /*
+ * Set keyboard controller mode. During this, the keyboard should be
+ * in the disabled state.
+ *
+ * Set up to try again if the keyboard asks for RESEND.
+ */
+ do {
+ kbd_write_output_w(KBD_CMD_DISABLE);
+ status = kbd_wait_for_input();
+ if (status == KBD_REPLY_ACK)
+ break;
+ if (status != KBD_REPLY_RESEND)
+ return "Disable keyboard: no ACK";
+ } while (1);
+
+ kbd_write_command_w(KBD_CCMD_WRITE_MODE);
+ kbd_write_output_w(KBD_MODE_KBD_INT
+ | KBD_MODE_SYS
+ | KBD_MODE_DISABLE_MOUSE
+ | KBD_MODE_KCC);
+
+ /* ibm powerpc portables need this to use scan-code set 1 -- Cort */
+ kbd_write_command_w(KBD_CCMD_READ_MODE);
+ if (!(kbd_wait_for_input() & KBD_MODE_KCC)) {
+ /*
+ * If the controller does not support conversion,
+ * Set the keyboard to scan-code set 1.
+ */
+ kbd_write_output_w(0xF0);
+ kbd_wait_for_input();
+ kbd_write_output_w(0x01);
+ kbd_wait_for_input();
+ }
+
+
+ kbd_write_output_w(KBD_CMD_ENABLE);
+ if (kbd_wait_for_input() != KBD_REPLY_ACK)
+ return "Enable keyboard: no ACK";
+ /*
+ * Finally, set the typematic rate to maximum.
+ */
+ kbd_write_output_w(KBD_CMD_SET_RATE);
+ if (kbd_wait_for_input() != KBD_REPLY_ACK)
+ return "Set rate: no ACK";
+ kbd_write_output_w(0x00);
+ if (kbd_wait_for_input() != KBD_REPLY_ACK)
+ return "Set rate: no ACK";
+ return NULL;
+}
+
+
+void pckbd_init_hw(void)
+{
+ /* kbd_request_region(); */
+
+ /* Flush any pending input. */
+ kbd_clear_input();
+
+ if (kbd_startup_reset) {
+ char *msg = initialize_kbd();
+ if (msg)
+ printk( "initialize_kbd: %s\n", msg);
+ }
+
+#if defined CONFIG_PSMOUSE
+ psaux_init();
+#endif
+
+ /* Ok, finally allocate the IRQ, and off we go.. */
+#if 0
+ kbd_request_irq( keyboard_interrupt );
+#endif
+
+}
+
+
+char BSP_wait_polled_input( void )
+{
+ int c;
+ cli();
+ while ( ( c= kbd_wait_for_input() ) < 0 )
+ continue;
+ sti();
+ return c;
+}
diff --git a/c/src/lib/libbsp/i386/pc386/console/ps2_drv.h b/c/src/lib/libbsp/i386/pc386/console/ps2_drv.h
new file mode 100644
index 0000000000..adbf3a6485
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/ps2_drv.h
@@ -0,0 +1,80 @@
+#ifndef __paux_drv__
+#define __paux_drv__
+/***************************************************************************
+ *
+ * $Header$
+ *
+ * Copyright (c) 1999 ConnectTel, Inc. All Rights Reserved.
+ *
+ * MODULE DESCRIPTION: Prototype routines for the paux driver.
+ *
+ * by: Rosimildo da Silva:
+ * rdasilva@connecttel.com
+ * http://www.connecttel.com
+ *
+ * MODIFICATION/HISTORY:
+ *
+ * $Log$
+ ****************************************************************************/
+
+/* functions */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* paux prototype entry points */
+rtems_device_driver paux_initialize(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver paux_open(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver paux_control(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver paux_close(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+
+rtems_device_driver paux_read(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver paux_write(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver paux_control(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+#define PAUX_DRIVER_TABLE_ENTRY \
+ { paux_initialize, paux_open, paux_close, \
+ paux_read, paux_write, paux_control }
+
+#ifdef __cplusplus
+}
+#endif
+/* end of include file */
+
+#endif /* __paux_drv__ */
+
+
diff --git a/c/src/lib/libbsp/i386/pc386/console/ps2_mouse.c b/c/src/lib/libbsp/i386/pc386/console/ps2_mouse.c
new file mode 100644
index 0000000000..23e69a933a
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/ps2_mouse.c
@@ -0,0 +1,708 @@
+/*
+ * linux/drivers/char/pc_keyb.c
+ * Separation of the PC low-level part by Geert Uytterhoeven, May 1997
+ * See keyboard.c for the whole history.
+ * Major cleanup by Martin Mares, May 1997
+ * Combined the keyboard and PS/2 mouse handling into one file,
+ * because they share the same hardware.
+ * Johan Myreen <jem@iki.fi> 1998-10-08.
+ * Code fixes to handle mouse ACKs properly.
+ * C. Scott Ananian <cananian@alumni.princeton.edu> 1999-01-29.
+ *
+ * RTEMS port: by Rosimildo da Silva.
+ * This module was ported from Linux.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+
+#include <bsp.h>
+#include <irq.h>
+#include <rtems/libio.h>
+#include <termios.h>
+#include <i386_io.h>
+#include <rtems/mw_uid.h>
+
+#define INITIALIZE_MOUSE
+/* Some configuration switches are present in the include file... */
+#include "ps2_mouse.h"
+#include "mouse_parser.h"
+
+static void kbd_write_command_w(int data);
+static void kbd_write_output_w(int data);
+
+static unsigned char handle_kbd_event(void);
+
+/* used only by send_data - set by keyboard_interrupt */
+static volatile unsigned char reply_expected = 0;
+static volatile unsigned char acknowledge = 0;
+static volatile unsigned char resend = 0;
+
+/*
+ * PS/2 Auxiliary Device
+ */
+static int psaux_init(void);
+
+static struct aux_queue *queue; /* Mouse data buffer. */
+static int aux_count = 0;
+/* used when we send commands to the mouse that expect an ACK. */
+static unsigned char mouse_reply_expected = 0;
+
+#define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT)
+#define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT)
+#define MAX_RETRIES 60 /* some aux operations take long time*/
+
+static void ps2_mouse_interrupt();
+
+static void ( *driver_input_handler_ps2 )( void *, char *, int ) = 0;
+
+/*
+ * This routine sets the handler to handle the characters received
+ * from the serial port.
+ */
+void ps2_set_driver_handler( int port, void ( *handler )( void *, char *, int ) )
+{
+ driver_input_handler_ps2 = handler;
+}
+
+static void mdelay( unsigned long t )
+{
+ Wait_X_ms( t );
+}
+
+
+static void* termios_ttyp_paux = NULL;
+
+static void
+isr_on(const rtems_irq_connect_data *unused)
+{
+ return;
+}
+
+static void
+isr_off(const rtems_irq_connect_data *unused)
+{
+ return;
+}
+
+static int isr_is_on(const rtems_irq_connect_data *irq)
+{
+ return BSP_irq_enabled_at_i8259s( irq->name );
+}
+
+
+static rtems_irq_connect_data ps2_isr_data = { AUX_IRQ,
+ ps2_mouse_interrupt, isr_on, isr_off, isr_is_on };
+
+
+/*
+ * Wait for keyboard controller input buffer to drain.
+ *
+ * Don't use 'jiffies' so that we don't depend on
+ * interrupts..
+ *
+ * Quote from PS/2 System Reference Manual:
+ *
+ * "Address hex 0060 and address hex 0064 should be written only when
+ * the input-buffer-full bit and output-buffer-full bit in the
+ * Controller Status register are set 0."
+ */
+
+static void kb_wait(void)
+{
+ unsigned long timeout = KBC_TIMEOUT;
+
+ do {
+ /*
+ * "handle_kbd_event()" will handle any incoming events
+ * while we wait - keypresses or mouse movement.
+ */
+ unsigned char status = handle_kbd_event();
+
+ if (! (status & KBD_STAT_IBF))
+ return;
+
+ mdelay(1);
+
+ timeout--;
+ } while (timeout);
+#ifdef KBD_REPORT_TIMEOUTS
+ printk( "Keyboard timed out[1]\n");
+#endif
+}
+
+static int do_acknowledge(unsigned char scancode)
+{
+ if (reply_expected) {
+ /* Unfortunately, we must recognise these codes only if we know they
+ * are known to be valid (i.e., after sending a command), because there
+ * are some brain-damaged keyboards (yes, FOCUS 9000 again) which have
+ * keys with such codes :(
+ */
+ if (scancode == KBD_REPLY_ACK) {
+ acknowledge = 1;
+ reply_expected = 0;
+ return 0;
+ } else if (scancode == KBD_REPLY_RESEND) {
+ resend = 1;
+ reply_expected = 0;
+ return 0;
+ }
+ /* Should not happen... */
+#if 0
+ printk( "keyboard reply expected - got %02x\n",
+ scancode);
+#endif
+ }
+ return 1;
+}
+
+
+static inline void handle_mouse_event(unsigned char scancode)
+{
+ if (mouse_reply_expected) {
+ if (scancode == AUX_ACK) {
+ mouse_reply_expected--;
+ return;
+ }
+ mouse_reply_expected = 0;
+ }
+
+ if (aux_count) {
+ int head = queue->head;
+
+ queue->buf[head] = scancode;
+ head = (head + 1) & (AUX_BUF_SIZE-1);
+ if (head != queue->tail) {
+ queue->head = head;
+ }
+ /* if the input queue is active, add to it */
+ if( driver_input_handler_ps2 )
+ {
+ driver_input_handler_ps2( NULL, &scancode, 1 );
+ }
+ else
+ {
+ /* post this byte to termios */
+ rtems_termios_enqueue_raw_characters( termios_ttyp_paux, &scancode, 1 );
+ }
+ }
+}
+
+/*
+ * This reads the keyboard status port, and does the
+ * appropriate action.
+ *
+ * It requires that we hold the keyboard controller
+ * spinlock.
+ */
+static unsigned char handle_kbd_event(void)
+{
+ unsigned char status = kbd_read_status();
+ unsigned int work = 10000;
+
+ while (status & KBD_STAT_OBF) {
+ unsigned char scancode;
+
+ scancode = kbd_read_input();
+
+ if (status & KBD_STAT_MOUSE_OBF) {
+ handle_mouse_event(scancode);
+ } else {
+ do_acknowledge(scancode);
+ printk("pc_keyb: %X ", scancode );
+ }
+ status = kbd_read_status();
+ if(!work--)
+ {
+ printk("pc_keyb: controller jammed (0x%02X).\n",
+ status);
+ break;
+ }
+ }
+
+ return status;
+}
+
+
+static void ps2_mouse_interrupt()
+{
+ handle_kbd_event();
+}
+
+/*
+ * send_data sends a character to the keyboard and waits
+ * for an acknowledge, possibly retrying if asked to. Returns
+ * the success status.
+ *
+ * Don't use 'jiffies', so that we don't depend on interrupts
+ */
+static int send_data(unsigned char data)
+{
+ int retries = 3;
+
+ do {
+ unsigned long timeout = KBD_TIMEOUT;
+
+ acknowledge = 0; /* Set by interrupt routine on receipt of ACK. */
+ resend = 0;
+ reply_expected = 1;
+ kbd_write_output_w(data);
+ for (;;) {
+ if (acknowledge)
+ return 1;
+ if (resend)
+ break;
+ mdelay(1);
+ if (!--timeout) {
+#ifdef KBD_REPORT_TIMEOUTS
+ printk( "Keyboard timeout[2]\n");
+#endif
+ return 0;
+ }
+ }
+ } while (retries-- > 0);
+#ifdef KBD_REPORT_TIMEOUTS
+ printk( "keyboard: Too many NACKs -- noisy kbd cable?\n");
+#endif
+ return 0;
+}
+
+#define KBD_NO_DATA (-1) /* No data */
+#define KBD_BAD_DATA (-2) /* Parity or other error */
+
+static int kbd_read_data(void)
+{
+ int retval = KBD_NO_DATA;
+ unsigned char status;
+
+ status = kbd_read_status();
+ if (status & KBD_STAT_OBF) {
+ unsigned char data = kbd_read_input();
+
+ retval = data;
+ if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
+ retval = KBD_BAD_DATA;
+ }
+ return retval;
+}
+
+static void kbd_clear_input(void)
+{
+ int maxread = 100; /* Random number */
+
+ do {
+ if (kbd_read_data() == KBD_NO_DATA)
+ break;
+ } while (--maxread);
+}
+
+static int kbd_wait_for_input(void)
+{
+ long timeout = KBD_INIT_TIMEOUT;
+
+ do {
+ int retval = kbd_read_data();
+ if (retval >= 0)
+ return retval;
+ mdelay(1);
+ } while (--timeout);
+ return -1;
+}
+
+static void kbd_write_command_w(int data)
+{
+ kb_wait();
+ kbd_write_command(data);
+}
+
+static void kbd_write_output_w(int data)
+{
+ kb_wait();
+ kbd_write_output(data);
+}
+
+static void kbd_write_cmd(int cmd)
+{
+ kb_wait();
+ kbd_write_command(KBD_CCMD_WRITE_MODE);
+ kb_wait();
+ kbd_write_output(cmd);
+}
+
+/*
+ * Check if this is a dual port controller.
+ */
+static int detect_auxiliary_port(void)
+{
+ int loops = 10;
+ int retval = 0;
+
+ /* Put the value 0x5A in the output buffer using the "Write
+ * Auxiliary Device Output Buffer" command (0xD3). Poll the
+ * Status Register for a while to see if the value really
+ * turns up in the Data Register. If the KBD_STAT_MOUSE_OBF
+ * bit is also set to 1 in the Status Register, we assume this
+ * controller has an Auxiliary Port (a.k.a. Mouse Port).
+ */
+ kb_wait();
+ kbd_write_command(KBD_CCMD_WRITE_AUX_OBUF);
+
+ kb_wait();
+ kbd_write_output(0x5a); /* 0x5a is a random dummy value. */
+
+ do {
+ unsigned char status = kbd_read_status();
+
+ if (status & KBD_STAT_OBF) {
+ (void) kbd_read_input();
+ if (status & KBD_STAT_MOUSE_OBF) {
+ printk( "Detected PS/2 Mouse Port.\n");
+ retval = 1;
+ }
+ break;
+ }
+ mdelay(1);
+ } while (--loops);
+ return retval;
+}
+
+/*
+ * Send a byte to the mouse.
+ */
+static void aux_write_dev(int val)
+{
+ kb_wait();
+ kbd_write_command(KBD_CCMD_WRITE_MOUSE);
+ kb_wait();
+ kbd_write_output(val);
+}
+
+/*
+ * Send a byte to the mouse & handle returned ack
+ */
+static void aux_write_ack(int val)
+{
+ kb_wait();
+ kbd_write_command(KBD_CCMD_WRITE_MOUSE);
+ kb_wait();
+ kbd_write_output(val);
+ /* we expect an ACK in response. */
+ mouse_reply_expected++;
+ kb_wait();
+}
+
+static unsigned char get_from_queue(void)
+{
+ unsigned char result;
+ result = queue->buf[queue->tail];
+ queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
+ return result;
+}
+
+
+static int queue_empty(void)
+{
+ return queue->head == queue->tail;
+}
+
+/*
+ * Random magic cookie for the aux device
+ */
+#define AUX_DEV ((void *)queue)
+
+static int release_aux()
+{
+ if (--aux_count)
+ return 0;
+ kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints */
+ kbd_write_command_w(KBD_CCMD_MOUSE_DISABLE);
+
+ BSP_remove_rtems_irq_handler( &ps2_isr_data );
+ return 0;
+}
+/*
+ * Install interrupt handler.
+ * Enable auxiliary device.
+ */
+
+static int open_aux()
+{
+ rtems_status_code status;
+
+ if (aux_count++) {
+ return 0;
+ }
+ queue->head = queue->tail = 0; /* Flush input queue */
+
+
+ status = BSP_install_rtems_irq_handler( &ps2_isr_data );
+ if( !status )
+ {
+ printk("Error installing ps2-mouse interrupt handler!\n" );
+ rtems_fatal_error_occurred( status );
+ }
+
+ kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable the
+ auxiliary port on
+ controller. */
+ aux_write_ack(AUX_ENABLE_DEV); /* Enable aux device */
+ kbd_write_cmd(AUX_INTS_ON); /* Enable controller ints */
+ return 0;
+}
+
+/*
+ * Put bytes from input queue to buffer.
+ */
+size_t read_aux(char * buffer, size_t count )
+{
+ size_t i = count;
+ unsigned char c;
+
+ if (queue_empty())
+ {
+ return 0;
+ }
+ while (i > 0 && !queue_empty())
+ {
+ c = get_from_queue();
+ *buffer++ = c;
+ i--;
+ }
+ return count-i;
+}
+
+/*
+ * Write to the aux device.
+ */
+
+static int write_aux( int minor, const char * buffer, int count )
+{
+ int retval = 0;
+
+ if (count) {
+ int written = 0;
+
+ if (count > 32)
+ count = 32; /* Limit to 32 bytes. */
+ do {
+ char c;
+ c = *buffer++;
+ aux_write_dev(c);
+ written++;
+ } while (--count);
+ retval = -EIO;
+ if (written) {
+ retval = written;
+ }
+ }
+ return retval;
+}
+
+static unsigned int aux_poll()
+{
+ if( !queue_empty() )
+ return 1;
+ return 0;
+}
+
+static int psaux_init( void )
+{
+ if( !detect_auxiliary_port() )
+ {
+ printk( "PS/2 - mouse not found.\n" );
+ return -EIO;
+ }
+
+ queue = (struct aux_queue *)malloc( sizeof(*queue) );
+ memset(queue, 0, sizeof(*queue));
+ queue->head = queue->tail = 0;
+ queue->proc_list = NULL;
+
+#ifdef INITIALIZE_MOUSE
+ kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable Aux. */
+ aux_write_ack(AUX_SET_SAMPLE);
+ aux_write_ack(100); /* 100 samples/sec */
+ aux_write_ack(AUX_SET_RES);
+ aux_write_ack(3); /* 8 counts per mm */
+ aux_write_ack(AUX_SET_SCALE21); /* 2:1 scaling */
+#endif /* INITIALIZE_MOUSE */
+ kbd_write_command(KBD_CCMD_MOUSE_DISABLE); /* Disable aux device. */
+ kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints. */
+ return 0;
+}
+
+void paux_reserve_resources(rtems_configuration_table *conf)
+{
+ rtems_termios_reserve_resources(conf, 1);
+ return;
+}
+
+/*
+ * paux device driver INITIALIZE entry point.
+ */
+rtems_device_driver
+paux_initialize( rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_status_code status;
+
+ /*
+ * Set up TERMIOS
+ */
+ rtems_termios_initialize();
+
+ printk( "PS/2 mouse probe.\n" );
+ if( psaux_init() < 0 )
+ {
+ printk("Error detecting PS/2 mouse --\n");
+
+ /* we might want to finish the application here !!! */
+ }
+ open_aux();
+
+ /*
+ * Register the device
+ */
+ status = rtems_io_register_name ("/dev/mouse", major, 0);
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ printk("Error registering paux device!\n");
+ rtems_fatal_error_occurred (status);
+ }
+ return RTEMS_SUCCESSFUL;
+} /* tty_initialize */
+
+
+static int paux_last_close(int major, int minor, void *arg)
+{
+ release_aux();
+ return 0;
+}
+
+/*
+ * Write to the aux device. This routine is invoked by the
+ * termios framework whenever the "ECHO" feature is on.
+ * It does nothing write now.
+ */
+static int write_aux_echo( int minor, const char * buffer, int count )
+{
+ return 0;
+}
+
+
+/*
+ * Some initialization if necessary
+ */
+static rtems_device_driver
+paux_first_open( rtems_device_minor_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/*
+ * paux device driver OPEN entry point
+ */
+rtems_device_driver
+paux_open(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_status_code status;
+ static rtems_termios_callbacks cb =
+ {
+ NULL, /* firstOpen */
+ paux_last_close, /* lastClose */
+ NULL, /* poll read */
+ write_aux_echo, /* write */
+ NULL, /* setAttributes */
+ NULL, /* stopRemoteTx */
+ NULL, /* startRemoteTx */
+ 0 /* outputUsesInterrupts */
+ };
+
+ status = rtems_termios_open (major, minor, arg, &cb );
+ termios_ttyp_paux = ( (rtems_libio_open_close_args_t *)arg)->iop->data1;
+ return status;
+}
+
+/*
+ * paux device driver CLOSE entry point
+ */
+rtems_device_driver
+paux_close(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ return (rtems_termios_close (arg));
+}
+
+
+/*
+ * paux device driver READ entry point.
+ * Read characters from the PS/2 mouse.
+ */
+rtems_device_driver
+paux_read(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ return rtems_termios_read (arg);
+} /* tty_read */
+
+
+/*
+ * paux device driver WRITE entry point.
+ * Write characters to the PS/2 mouse.
+ */
+rtems_device_driver
+paux_write(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg)
+{
+ rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
+ char *buffer = rw_args->buffer;
+ int maximum = rw_args->count;
+ rw_args->bytes_moved = write_aux( minor, buffer, maximum );
+ return RTEMS_SUCCESSFUL;
+} /* tty_write */
+
+
+/*
+ * Handle ioctl request.
+ */
+rtems_device_driver
+paux_control(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ rtems_libio_ioctl_args_t *args = arg;
+ switch( args->command )
+ {
+ default:
+ return rtems_termios_ioctl (arg);
+ break;
+
+ case MW_UID_REGISTER_DEVICE:
+ printk( "PS2 Mouse: reg=%s\n", args->buffer );
+ register_mou_msg_queue( args->buffer, -1 );
+ break;
+
+ case MW_UID_UNREGISTER_DEVICE:
+ unregister_mou_msg_queue( -1 );
+ break;
+ }
+ args->ioctl_return = 0;
+ return RTEMS_SUCCESSFUL;
+}
+
+
+
diff --git a/c/src/lib/libbsp/i386/pc386/console/ps2_mouse.h b/c/src/lib/libbsp/i386/pc386/console/ps2_mouse.h
new file mode 100644
index 0000000000..fc47ab518d
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/ps2_mouse.h
@@ -0,0 +1,146 @@
+/*
+ * include/linux/pc_keyb.h
+ * PC Keyboard And Keyboard Controller
+ * (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *
+ * RTEMS port: by Rosimildo da Silva.
+ *
+ * This module was ported from Linux.
+ *
+ */
+
+/*
+ * Configuration Switches
+ */
+
+#undef KBD_REPORT_ERR /* Report keyboard errors */
+#define KBD_REPORT_UNKN /* Report unknown scan codes */
+#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */
+#undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */
+#undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */
+
+
+
+#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */
+#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */
+#define KBD_TIMEOUT 1000 /* Timeout in ms for keyboard command acknowledge */
+
+/*
+ * Internal variables of the driver
+ */
+
+extern unsigned char pckbd_read_mask;
+extern unsigned char aux_device_present;
+
+/*
+ * Keyboard Controller Registers on normal PCs.
+ */
+
+#define KBD_STATUS_REG 0x64 /* Status register (R) */
+#define KBD_CNTL_REG 0x64 /* Controller command register (W) */
+#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */
+
+/*
+ * Keyboard Controller Commands
+ */
+
+#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
+#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */
+#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */
+#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */
+#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */
+#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */
+#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */
+#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */
+#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */
+#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */
+#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if
+ initiated by the auxiliary device */
+#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */
+
+/*
+ * Keyboard Commands
+ */
+
+#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
+#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
+#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
+#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */
+#define KBD_CMD_RESET 0xFF /* Reset */
+
+/*
+ * Keyboard Replies
+ */
+
+#define KBD_REPLY_POR 0xAA /* Power on reset */
+#define KBD_REPLY_ACK 0xFA /* Command ACK */
+#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
+
+/*
+ * Status Register Bits
+ */
+
+#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
+#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
+#define KBD_STAT_SELFTEST 0x04 /* Self test successful */
+#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */
+#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */
+#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
+#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */
+#define KBD_STAT_PERR 0x80 /* Parity error */
+
+#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF)
+
+/*
+ * Controller Mode Register Bits
+ */
+
+#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */
+#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */
+#define KBD_MODE_SYS 0x04 /* The system flag (?) */
+#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */
+#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */
+#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */
+#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
+#define KBD_MODE_RFU 0x80
+
+/*
+ * Mouse Commands
+ */
+
+#define AUX_SET_RES 0xE8 /* Set resolution */
+#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
+#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
+#define AUX_GET_SCALE 0xE9 /* Get scaling factor */
+#define AUX_SET_STREAM 0xEA /* Set stream mode */
+#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
+#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
+#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
+#define AUX_RESET 0xFF /* Reset aux device */
+#define AUX_ACK 0xFA /* Command byte ACK. */
+
+#define AUX_BUF_SIZE 512 /* This might be better divisible by
+ three to make overruns stay in sync
+ but then the read function would need
+ a lock etc - ick */
+
+struct aux_queue {
+ unsigned long head;
+ unsigned long tail;
+ struct wait_queue *proc_list;
+ struct fasync_struct *fasync;
+ unsigned char buf[AUX_BUF_SIZE];
+};
+
+/* How to access the keyboard macros on this platform. */
+#define kbd_read_input() inb(KBD_DATA_REG)
+#define kbd_read_status() inb(KBD_STATUS_REG)
+#define kbd_write_output(val) outb(val, KBD_DATA_REG)
+#define kbd_write_command(val) outb(val, KBD_CNTL_REG)
+
+/*
+ * Machine specific bits for the PS/2 driver
+ */
+
+#define AUX_IRQ 12
+
diff --git a/c/src/lib/libbsp/i386/pc386/console/serial_mouse.c b/c/src/lib/libbsp/i386/pc386/console/serial_mouse.c
new file mode 100644
index 0000000000..dbdb7ea14c
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/serial_mouse.c
@@ -0,0 +1,348 @@
+/***************************************************************************
+ *
+ * $Header$
+ *
+ * MODULE DESCRIPTION:
+ * This module implements the RTEMS drivers for the PC serial ports
+ * as /dev/ttyS1 for COM1 and /dev/ttyS2 as COM2. If one of the ports
+ * is used as the console, this driver would fail to initialize.
+ *
+ * This code was based on the console driver. It is based on the
+ * current termios framework. This is just a shell around the
+ * termios support.
+ *
+ * by: Rosimildo da Silva:
+ * rdasilva@connecttel.com
+ * http://www.connecttel.com
+ *
+ * MODIFICATION/HISTORY:
+ *
+ * $Log$
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <bsp.h>
+#include <irq.h>
+#include <rtems/libio.h>
+#include <termios.h>
+#include <uart.h>
+#include <libcpu/cpuModel.h>
+
+int BSP_poll_read(int);
+
+#include <rtems/mw_uid.h>
+#include "serial_mouse.h"
+#include "mouse_parser.h"
+
+/* Internal routines */
+static int serial_mouse_conSetAttr( int minor, const struct termios *t);
+static void isr_on(const rtems_irq_connect_data *);
+static void isr_off(const rtems_irq_connect_data *);
+static int isr_is_on(const rtems_irq_connect_data *);
+
+
+extern BSP_polling_getchar_function_type BSP_poll_char;
+extern int BSPConsolePort;
+
+/* Select Default to be COM1 */
+#if !defined( SERIAL_MOUSE_COM1 ) && !defined( SERIAL_MOUSE_COM2 )
+#define SERIAL_MOUSE_COM1 1
+#endif
+
+/* select which serial port the mouse is connected to */
+#ifdef SERIAL_MOUSE_COM1
+#define BSP_UART_PORT BSP_UART_COM1
+#define BSP_UART_IRQ BSP_UART_COM1_IRQ
+#define BSP_ISR_FUNC BSP_uart_termios_isr_com1
+#define BSP_WRITE_FUNC BSP_uart_termios_write_com1
+#endif
+
+#ifdef SERIAL_MOUSE_COM2
+#define BSP_UART_PORT BSP_UART_COM2
+#define BSP_UART_IRQ BSP_UART_COM2_IRQ
+#define BSP_ISR_FUNC BSP_uart_termios_isr_com2
+#define BSP_WRITE_FUNC BSP_uart_termios_write_com2
+#endif
+
+/*
+ * Interrupt structure for serial_mouse
+ */
+static rtems_irq_connect_data serial_mouse_isr_data =
+{
+ BSP_UART_IRQ,
+ BSP_ISR_FUNC,
+ isr_on,
+ isr_off,
+ isr_is_on};
+
+static void isr_on(const rtems_irq_connect_data *unused)
+{
+ return;
+}
+
+static void isr_off(const rtems_irq_connect_data *unused)
+{
+ return;
+}
+
+static int isr_is_on(const rtems_irq_connect_data *irq)
+{
+ return BSP_irq_enabled_at_i8259s(irq->name);
+}
+
+void serial_mouse_reserve_resources(rtems_configuration_table *conf)
+{
+ rtems_termios_reserve_resources(conf, 1);
+ return;
+}
+
+/*
+ * Serial Mouse - device driver INITIALIZE entry point.
+ */
+rtems_device_driver
+serial_mouse_initialize(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_status_code status;
+
+ /* Check if this port is not been used as console */
+ if( BSPConsolePort == BSP_UART_PORT )
+ {
+ status = -1;
+ printk("SERIAL MOUSE: port selected as console.( %d )\n", BSP_UART_PORT );
+ rtems_fatal_error_occurred( status );
+ }
+
+ /*
+ * Set up TERMIOS
+ */
+ rtems_termios_initialize();
+
+ /*
+ * Do device-specific initialization
+ */
+ /* 9600-8-N-1, without hardware flow control */
+ BSP_uart_init( BSP_UART_PORT, 1200, 0 );
+ status = BSP_install_rtems_irq_handler( &serial_mouse_isr_data );
+ if( !status )
+ {
+ printk("Error installing serial mouse interrupt handler!\n");
+ rtems_fatal_error_occurred(status);
+ }
+ /*
+ * Register the device
+ */
+ status = rtems_io_register_name ("/dev/mouse", major, 0);
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ printk("Error registering /dev/mouse device!\n");
+ rtems_fatal_error_occurred (status);
+ }
+ printk("Device: /dev/mouse on COM%d -- ok \n", BSP_UART_PORT );
+ return RTEMS_SUCCESSFUL;
+} /* tty_initialize */
+
+
+static int serial_mouse_last_close(int major, int minor, void *arg)
+{
+ BSP_remove_rtems_irq_handler( &serial_mouse_isr_data );
+ return 0;
+}
+
+/*
+ * serial_mouse - device driver OPEN entry point
+ */
+rtems_device_driver
+serial_mouse_open(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_status_code status;
+ static rtems_termios_callbacks cb =
+ {
+ NULL, /* firstOpen */
+ serial_mouse_last_close, /* lastClose */
+ NULL, /* poll read */
+ BSP_WRITE_FUNC, /* write */
+ serial_mouse_conSetAttr, /* setAttributes */
+ NULL, /* stopRemoteTx */
+ NULL, /* startRemoteTx */
+ 1 /* outputUsesInterrupts */
+ };
+
+ status = rtems_termios_open( major, minor, arg, &cb );
+ if(status != RTEMS_SUCCESSFUL)
+ {
+ printk("Error openning serial_mouse device\n");
+ return status;
+ }
+
+ /*
+ * Pass data area info down to driver
+ */
+ BSP_uart_termios_set( BSP_UART_PORT,
+ ((rtems_libio_open_close_args_t *)arg)->iop->data1 );
+ /* Enable interrupts on channel */
+ BSP_uart_intr_ctrl( BSP_UART_PORT, BSP_UART_INTR_CTRL_TERMIOS);
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * TTY - device driver CLOSE entry point
+ */
+rtems_device_driver
+serial_mouse_close(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+
+ return (rtems_termios_close (arg));
+
+} /* tty_close */
+
+
+/*
+ * TTY device driver READ entry point.
+ * Read characters from the tty device.
+ */
+rtems_device_driver
+serial_mouse_read(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ return rtems_termios_read (arg);
+} /* tty_read */
+
+
+/*
+ * TTY device driver WRITE entry point.
+ * Write characters to the tty device.
+ */
+rtems_device_driver
+serial_mouse_write(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg)
+{
+ return rtems_termios_write (arg);
+
+} /* tty_write */
+
+/*
+ * Handle ioctl request. This is a generic internal
+ * routine to handle both devices.
+ */
+static rtems_device_driver serial_mouse_control_internal( int port, void *arg )
+{
+ rtems_libio_ioctl_args_t *args = arg;
+ switch( args->command )
+ {
+ default:
+ return rtems_termios_ioctl (arg);
+ break;
+
+ case MW_UID_REGISTER_DEVICE:
+ printk( "SerialMouse: reg=%s\n", args->buffer );
+ register_mou_msg_queue( args->buffer, BSP_UART_PORT );
+ break;
+
+ case MW_UID_UNREGISTER_DEVICE:
+ unregister_mou_msg_queue( BSP_UART_PORT );
+ break;
+
+ }
+ args->ioctl_return = 0;
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * Handle ioctl request for ttyS1.
+ */
+rtems_device_driver
+serial_mouse_control(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return serial_mouse_control_internal( BSP_UART_PORT, arg );
+}
+
+static int
+conSetAttr(int port, int minor, const struct termios *t)
+{
+ int baud;
+
+ switch (t->c_cflag & CBAUD)
+ {
+ case B50:
+ baud = 50;
+ break;
+ case B75:
+ baud = 75;
+ break;
+ case B110:
+ baud = 110;
+ break;
+ case B134:
+ baud = 134;
+ break;
+ case B150:
+ baud = 150;
+ break;
+ case B200:
+ baud = 200;
+ break;
+ case B300:
+ baud = 300;
+ break;
+ case B600:
+ baud = 600;
+ break;
+ case B1200:
+ baud = 1200;
+ break;
+ case B1800:
+ baud = 1800;
+ break;
+ case B2400:
+ baud = 2400;
+ break;
+ case B4800:
+ baud = 4800;
+ break;
+ case B9600:
+ baud = 9600;
+ break;
+ case B19200:
+ baud = 19200;
+ break;
+ case B38400:
+ baud = 38400;
+ break;
+ case B57600:
+ baud = 57600;
+ break;
+ case B115200:
+ baud = 115200;
+ break;
+ default:
+ baud = 0;
+ rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
+ return 0;
+ }
+ printk("Mouse baud, port=%X, baud=%d\n", port, baud );
+ BSP_uart_set_baud( port, baud );
+ return 0;
+}
+
+/*
+ * Handle ioctl request for ttyS2.
+ */
+static int
+serial_mouse_conSetAttr( int minor, const struct termios *t)
+{
+ return conSetAttr( BSP_UART_PORT, minor, t );
+}
diff --git a/c/src/lib/libbsp/i386/pc386/console/serial_mouse.h b/c/src/lib/libbsp/i386/pc386/console/serial_mouse.h
new file mode 100644
index 0000000000..afbf16c9d9
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/serial_mouse.h
@@ -0,0 +1,86 @@
+#ifndef __serial_mouse_drv__
+#define __serial_mouse_drv__
+/***************************************************************************
+ *
+ * $Header$
+ *
+ * Copyright (c) 1999 ConnectTel, Inc. All Rights Reserved.
+ *
+ * MODULE DESCRIPTION: Prototype routines for the /dev/mouse driver.
+ *
+ * by: Rosimildo da Silva:
+ * rdasilva@connecttel.com
+ * http://www.connecttel.com
+ *
+ * MODIFICATION/HISTORY:
+ *
+ * $Log$
+ ****************************************************************************/
+
+/* functions */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* ttyS1 entry points */
+rtems_device_driver serial_mouse_initialize(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver serial_mouse_open(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver serial_mouse_control(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+
+/* serial_mouse entry points */
+rtems_device_driver serial_mouse_close(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+
+rtems_device_driver serial_mouse_read(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver serial_mouse_write(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+
+/* Select the mouse type: "ms","pc","ps2" */
+#define MOUSE_TYPE "ms"
+
+/* Select the serial port for the serial mouse driver */
+#define SERIAL_MOUSE_COM1 1
+/* #define SERIAL_MOUSE_COM2 1 */
+
+
+#define SERIAL_MOUSE_DRIVER_TABLE_ENTRY \
+ { serial_mouse_initialize, serial_mouse_open, serial_mouse_close, \
+ serial_mouse_read, serial_mouse_write, serial_mouse_control }
+
+#ifdef __cplusplus
+}
+#endif
+/* end of include file */
+
+#endif /* __tty_drv__ */
+
+
diff --git a/c/src/lib/libbsp/i386/pc386/console/vgainit.c b/c/src/lib/libbsp/i386/pc386/console/vgainit.c
new file mode 100644
index 0000000000..c91421f807
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/vgainit.c
@@ -0,0 +1,766 @@
+/*
+ * Copyright (c) 1999 Greg Haerr <greg@censoft.com>
+ * Copyright (c) 1991 David I. Bell
+ * Permission is granted to use, distribute, or modify this source,
+ * provided that this copyright notice remains intact.
+ *
+ * Alternate EGA/VGA Screen Driver Init, direct hw programming
+ */
+#include <i386_io.h>
+
+#ifdef __rtems__
+#define ROMFONT 0 /* =0 no bios rom fonts available*/
+#else
+#define ROMFONT 1 /* =1 uses PC rom fonts */
+#endif
+
+/* defines are defined in device.h of the MicroWindows package */
+#define MODE_SET 0 /* draw pixels as given (default) */
+#define MODE_XOR 1 /* draw pixels using XOR */
+#define MODE_OR 2 /* draw pixels using OR (notimp)*/
+#define MODE_AND 3 /* draw pixels using AND (notimp)*/
+#define MODE_MAX 3
+typedef int MODE; /* drawing mode*/
+
+
+/* Define one and only one of the following to be nonzero*/
+#define VGA_ET4000 0 /* TSENG LABS ET4000 chip 800x600*/
+#define VGA_STANDARD 1 /* standard VGA 640x480*/
+#define EGA_STANDARD 0 /* standard EGA 640x350*/
+
+#define DONE 0
+#define IN 1
+#define OUT 2
+
+#define RAM_SCAN_LINES 32 /* number of scan lines in fonts in RAM */
+#define FONT_CHARS 256 /* number of characters in font tables */
+#define CHAR_WIDTH 8 /* number of pixels for character width */
+
+#define PALREG 0x3c0
+#define SEQREG 0x3c4
+#define SEQVAL 0x3c5
+#define GRREG 0x3ce
+#define GRVAL 0x3cf
+#define ATTRREG 0x3da
+#define CRTCREG 0x3d4
+#define CRTCVAL 0x3d5
+
+#define GENREG1 0x3c2
+#define GENREG2 0x3cc
+#define GENREG3 0x3ca
+
+#define DATA_ROTATE 3 /* register number for data rotate */
+
+typedef struct {
+ int action;
+ int port1;
+ int data1;
+ int port2;
+ int data2;
+} REGIO;
+
+/* extern data*/
+#if ROMFONT
+extern FARADDR rom_char_addr; /* address of ROM font*/
+extern int ROM_CHAR_HEIGHT; /* ROM character height*/
+#endif
+
+/* local data*/
+extern REGIO graphics_on[];
+extern REGIO graph_off[];
+
+/* entry points*/
+void ega_hwinit(void);
+void ega_hwterm(void);
+
+/* local routines*/
+static void writeregs(REGIO *rp);
+static void out_word(unsigned int p,unsigned int d);
+static void setmode(MODE mode);
+
+void
+ega_hwinit(void)
+{
+ writeregs(graphics_on);
+}
+
+void
+ega_hwterm(void)
+{
+ setmode(MODE_SET);
+
+ /* Copy character table from ROM back into bit plane 2 before turning
+ * off graphics.
+ */
+ out_word(SEQREG, 0x0100); /* syn reset */
+ out_word(SEQREG, 0x0402); /* cpu writes only to map 2 */
+ out_word(SEQREG, 0x0704); /* sequential addressing */
+ out_word(SEQREG, 0x0300); /* clear synchronous reset */
+
+ out_word(GRREG, 0x0204); /* select map 2 for CPU reads */
+ out_word(GRREG, 0x0005); /* disable odd-even addressing */
+
+#if ROMFONT
+ {
+ FARADDR srcoffset;
+ FARADDR destoffset;
+ int data;
+ int ch;
+ int row;
+
+ srcoffset = rom_char_addr;
+ destoffset = EGA_BASE;
+ for (ch = 0; ch < FONT_CHARS; ch++) {
+ for(row = 0; row < ROM_CHAR_HEIGHT; row++) {
+ data = GETBYTE_FP(srcoffset++);
+ PUTBYTE_FP(destoffset++, data);
+ }
+ destoffset += (RAM_SCAN_LINES - ROM_CHAR_HEIGHT);
+ }
+ }
+#endif
+
+ /* Finally set the registers back for text mode. */
+ writeregs(graph_off);
+}
+
+/* Set the graphics registers as indicated by the given table */
+static void
+writeregs(REGIO *rp)
+{
+ for (; rp->action != DONE; rp++) {
+ switch (rp->action) {
+ case IN:
+ inp(rp->port1);
+ break;
+ case OUT:
+ outp(rp->port1, rp->data1);
+ if (rp->port2)
+ outp(rp->port2, rp->data2);
+ break;
+ }
+ }
+}
+
+/* Output a word to an I/O port. */
+static void
+out_word(unsigned int p,unsigned int d)
+{
+ outp(p, d & 0xff);
+ outp(p + 1, (d >> 8) & 0xff);
+}
+
+
+/* Values for the data rotate register to implement drawing modes. */
+static unsigned char mode_table[MODE_MAX + 1] = {
+ 0x00, 0x18, 0x10, 0x08
+};
+
+/* Set the drawing mode.
+ * This is either SET, OR, AND, or XOR.
+ */
+static void
+setmode(MODE mode)
+{
+ if (mode > MODE_MAX)
+ return;
+ outp(GRREG, DATA_ROTATE);
+ outp(GRVAL, mode_table[mode]);
+}
+
+
+#if VGA_ET4000
+
+/* VGA 800x600 16-color graphics (BIOS mode 0x29).
+ */
+static REGIO graphics_on[] = {
+ /* Reset attr F/F */
+ IN, ATTRREG, 0, 0, 0,
+
+ /* Disable palette */
+ OUT, PALREG, 0, 0, 0,
+
+ /* Reset sequencer regs */
+ OUT, SEQREG, 0, SEQVAL, 0,
+ OUT, SEQREG, 1, SEQVAL, 1,
+ OUT, SEQREG, 2, SEQVAL, 0x0f,
+ OUT, SEQREG, 3, SEQVAL, 0,
+ OUT, SEQREG, 4, SEQVAL, 6,
+
+ /* Misc out reg */
+ OUT, GENREG1, 0xe3, 0, 0,
+
+ /* Sequencer enable */
+ OUT, SEQREG, 0, SEQVAL, 0x03,
+
+ /* Unprotect crtc regs 0-7 */
+ OUT, CRTCREG, 0x11, CRTCVAL, 0,
+
+ /* Crtc */
+ OUT, CRTCREG, 0, CRTCVAL, 0x7a,
+ OUT, CRTCREG, 1, CRTCVAL, 0x63,
+ OUT, CRTCREG, 2, CRTCVAL, 0x64,
+ OUT, CRTCREG, 3, CRTCVAL, 0x1d,
+ OUT, CRTCREG, 4, CRTCVAL, 0x68,
+ OUT, CRTCREG, 5, CRTCVAL, 0x9a,
+ OUT, CRTCREG, 6, CRTCVAL, 0x78,
+ OUT, CRTCREG, 7, CRTCVAL, 0xf0,
+ OUT, CRTCREG, 8, CRTCVAL, 0x00,
+ OUT, CRTCREG, 9, CRTCVAL, 0x60,
+ OUT, CRTCREG, 10, CRTCVAL, 0x00,
+ OUT, CRTCREG, 11, CRTCVAL, 0x00,
+ OUT, CRTCREG, 12, CRTCVAL, 0x00,
+ OUT, CRTCREG, 13, CRTCVAL, 0x00,
+ OUT, CRTCREG, 14, CRTCVAL, 0x00,
+ OUT, CRTCREG, 15, CRTCVAL, 0x00,
+ OUT, CRTCREG, 16, CRTCVAL, 0x5c,
+ OUT, CRTCREG, 17, CRTCVAL, 0x8e,
+ OUT, CRTCREG, 18, CRTCVAL, 0x57,
+ OUT, CRTCREG, 19, CRTCVAL, 0x32,
+ OUT, CRTCREG, 20, CRTCVAL, 0x00,
+ OUT, CRTCREG, 21, CRTCVAL, 0x5b,
+ OUT, CRTCREG, 22, CRTCVAL, 0x75,
+ OUT, CRTCREG, 23, CRTCVAL, 0xc3,
+ OUT, CRTCREG, 24, CRTCVAL, 0xff,
+
+ /* Graphics controller */
+ OUT, GENREG2, 0x00, 0, 0,
+ OUT, GENREG3, 0x01, 0, 0,
+ OUT, GRREG, 0, GRVAL, 0x00,
+ OUT, GRREG, 1, GRVAL, 0x00,
+ OUT, GRREG, 2, GRVAL, 0x00,
+ OUT, GRREG, 3, GRVAL, 0x00,
+ OUT, GRREG, 4, GRVAL, 0x00,
+ OUT, GRREG, 5, GRVAL, 0x00,
+ OUT, GRREG, 6, GRVAL, 0x05,
+ OUT, GRREG, 7, GRVAL, 0x0f,
+ OUT, GRREG, 8, GRVAL, 0xff,
+
+ /* Reset attribute flip/flop */
+ IN, ATTRREG, 0, 0, 0,
+
+ /* Palette */
+ OUT, PALREG, 0, PALREG, 0x00,
+ OUT, PALREG, 1, PALREG, 0x01,
+ OUT, PALREG, 2, PALREG, 0x02,
+ OUT, PALREG, 3, PALREG, 0x03,
+ OUT, PALREG, 4, PALREG, 0x04,
+ OUT, PALREG, 5, PALREG, 0x05,
+ OUT, PALREG, 6, PALREG, 0x06,
+ OUT, PALREG, 7, PALREG, 0x07,
+ OUT, PALREG, 8, PALREG, 0x38,
+ OUT, PALREG, 9, PALREG, 0x39,
+ OUT, PALREG, 10, PALREG, 0x3a,
+ OUT, PALREG, 11, PALREG, 0x3b,
+ OUT, PALREG, 12, PALREG, 0x3c,
+ OUT, PALREG, 13, PALREG, 0x3d,
+ OUT, PALREG, 14, PALREG, 0x3e,
+ OUT, PALREG, 15, PALREG, 0x3f,
+ OUT, PALREG, 16, PALREG, 0x01,
+ OUT, PALREG, 17, PALREG, 0x00,
+ OUT, PALREG, 18, PALREG, 0x0f,
+ OUT, PALREG, 19, PALREG, 0x00,
+
+ /* Enable palette */
+ OUT, PALREG, 0x20, 0, 0,
+
+ /* End of table */
+ DONE, 0, 0, 0, 0
+};
+
+
+/* VGA 80x25 text (BIOS mode 3).
+ */
+static REGIO graph_off[] = {
+ /* Reset attr F/F */
+ IN, ATTRREG, 0, 0, 0,
+
+ /* Disable palette */
+ OUT, PALREG, 0, 0, 0,
+
+ /* Reset sequencer regs */
+ OUT, SEQREG, 0, SEQVAL, 1,
+ OUT, SEQREG, 1, SEQVAL, 1,
+ OUT, SEQREG, 2, SEQVAL, 3,
+ OUT, SEQREG, 3, SEQVAL, 0,
+ OUT, SEQREG, 4, SEQVAL, 2,
+
+ /* Misc out reg */
+ OUT, GENREG1, 0x63, 0, 0,
+
+ /* Sequencer enable */
+ OUT, SEQREG, 0, SEQVAL, 3,
+
+ /* Unprotect crtc regs 0-7 */
+ OUT, CRTCREG, 0x11, CRTCVAL, 0,
+
+ /* Crtc */
+ OUT, CRTCREG, 0, CRTCVAL, 0x5f, /* horiz total */
+ OUT, CRTCREG, 1, CRTCVAL, 0x4f, /* horiz end */
+ OUT, CRTCREG, 2, CRTCVAL, 0x50, /* horiz blank */
+ OUT, CRTCREG, 3, CRTCVAL, 0x82, /* end blank */
+ OUT, CRTCREG, 4, CRTCVAL, 0x55, /* horiz retrace */
+ OUT, CRTCREG, 5, CRTCVAL, 0x81, /* end retrace */
+ OUT, CRTCREG, 6, CRTCVAL, 0xbf, /* vert total */
+ OUT, CRTCREG, 7, CRTCVAL, 0x1f, /* overflows */
+ OUT, CRTCREG, 8, CRTCVAL, 0x00, /* row scan */
+ OUT, CRTCREG, 9, CRTCVAL, 0x4f, /* max scan line */
+ OUT, CRTCREG, 10, CRTCVAL, 0x00, /* cursor start */
+ OUT, CRTCREG, 11, CRTCVAL, 0x0f, /* cursor end */
+ OUT, CRTCREG, 12, CRTCVAL, 0x0e, /* start high addr */
+ OUT, CRTCREG, 13, CRTCVAL, 0xb0, /* low addr */
+ OUT, CRTCREG, 14, CRTCVAL, 0x16, /* cursor high */
+ OUT, CRTCREG, 15, CRTCVAL, 0x30, /* cursor low */
+ OUT, CRTCREG, 16, CRTCVAL, 0x9c, /* vert retrace */
+ OUT, CRTCREG, 17, CRTCVAL, 0x8e, /* retrace end */
+ OUT, CRTCREG, 18, CRTCVAL, 0x8f, /* vert end */
+ OUT, CRTCREG, 19, CRTCVAL, 0x28, /* offset */
+ OUT, CRTCREG, 20, CRTCVAL, 0x1f, /* underline */
+ OUT, CRTCREG, 21, CRTCVAL, 0x96, /* vert blank */
+ OUT, CRTCREG, 22, CRTCVAL, 0xb9, /* end blank */
+ OUT, CRTCREG, 23, CRTCVAL, 0xa3, /* crt mode */
+ OUT, CRTCREG, 24, CRTCVAL, 0xff, /* line compare */
+
+ /* Graphics controller */
+ OUT, GENREG2, 0x00, 0, 0,
+ OUT, GENREG3, 0x01, 0, 0,
+ OUT, GRREG, 0, GRVAL, 0x00,
+ OUT, GRREG, 1, GRVAL, 0x00,
+ OUT, GRREG, 2, GRVAL, 0x00,
+ OUT, GRREG, 3, GRVAL, 0x00,
+ OUT, GRREG, 4, GRVAL, 0x00,
+ OUT, GRREG, 5, GRVAL, 0x10,
+ OUT, GRREG, 6, GRVAL, 0x0e,
+ OUT, GRREG, 7, GRVAL, 0x00,
+ OUT, GRREG, 8, GRVAL, 0xff,
+
+ /* Reset attribute flip/flop */
+ IN, ATTRREG, 0, 0, 0,
+
+ /* Palette */
+ OUT, PALREG, 0, PALREG, 0x00,
+ OUT, PALREG, 1, PALREG, 0x01,
+ OUT, PALREG, 2, PALREG, 0x02,
+ OUT, PALREG, 3, PALREG, 0x03,
+ OUT, PALREG, 4, PALREG, 0x04,
+ OUT, PALREG, 5, PALREG, 0x05,
+ OUT, PALREG, 6, PALREG, 0x06,
+ OUT, PALREG, 7, PALREG, 0x07,
+ OUT, PALREG, 8, PALREG, 0x10,
+ OUT, PALREG, 9, PALREG, 0x11,
+ OUT, PALREG, 10, PALREG, 0x12,
+ OUT, PALREG, 11, PALREG, 0x13,
+ OUT, PALREG, 12, PALREG, 0x14,
+ OUT, PALREG, 13, PALREG, 0x15,
+ OUT, PALREG, 14, PALREG, 0x16,
+ OUT, PALREG, 15, PALREG, 0x17,
+ OUT, PALREG, 16, PALREG, 0x08,
+ OUT, PALREG, 17, PALREG, 0x00,
+ OUT, PALREG, 18, PALREG, 0x0f,
+ OUT, PALREG, 19, PALREG, 0x00,
+
+ /* Enable palette */
+ OUT, PALREG, 0x20, 0, 0,
+
+ /* End of table */
+ DONE, 0, 0, 0, 0
+};
+
+#endif
+
+
+#if VGA_STANDARD
+
+/* VGA 640x480 16-color graphics (BIOS mode 0x12).
+ */
+static REGIO graphics_on[] = {
+ /* Reset attr F/F */
+ IN, ATTRREG, 0, 0, 0,
+
+ /* Disable palette */
+ OUT, PALREG, 0, 0, 0,
+
+ /* Reset sequencer regs */
+ OUT, SEQREG, 0, SEQVAL, 0,
+ OUT, SEQREG, 1, SEQVAL, 1,
+ OUT, SEQREG, 2, SEQVAL, 0x0f,
+ OUT, SEQREG, 3, SEQVAL, 0,
+ OUT, SEQREG, 4, SEQVAL, 6,
+
+ /* Misc out reg */
+ OUT, GENREG1, 0xe3, 0, 0,
+
+ /* Sequencer enable */
+ OUT, SEQREG, 0, SEQVAL, 0x03,
+
+ /* Unprotect crtc regs 0-7 */
+ OUT, CRTCREG, 0x11, CRTCVAL, 0,
+
+ /* Crtc */
+ OUT, CRTCREG, 0, CRTCVAL, 0x5f,
+ OUT, CRTCREG, 1, CRTCVAL, 0x4f,
+ OUT, CRTCREG, 2, CRTCVAL, 0x50,
+ OUT, CRTCREG, 3, CRTCVAL, 0x82,
+ OUT, CRTCREG, 4, CRTCVAL, 0x54,
+ OUT, CRTCREG, 5, CRTCVAL, 0x80,
+ OUT, CRTCREG, 6, CRTCVAL, 0x0b,
+ OUT, CRTCREG, 7, CRTCVAL, 0x3e,
+ OUT, CRTCREG, 8, CRTCVAL, 0x00,
+ OUT, CRTCREG, 9, CRTCVAL, 0x40,
+ OUT, CRTCREG, 10, CRTCVAL, 0x00,
+ OUT, CRTCREG, 11, CRTCVAL, 0x00,
+ OUT, CRTCREG, 12, CRTCVAL, 0x00,
+ OUT, CRTCREG, 13, CRTCVAL, 0x00,
+ OUT, CRTCREG, 14, CRTCVAL, 0x00,
+ OUT, CRTCREG, 15, CRTCVAL, 0x59,
+ OUT, CRTCREG, 16, CRTCVAL, 0xea,
+ OUT, CRTCREG, 17, CRTCVAL, 0x8c,
+ OUT, CRTCREG, 18, CRTCVAL, 0xdf,
+ OUT, CRTCREG, 19, CRTCVAL, 0x28,
+ OUT, CRTCREG, 20, CRTCVAL, 0x00,
+ OUT, CRTCREG, 21, CRTCVAL, 0xe7,
+ OUT, CRTCREG, 22, CRTCVAL, 0x04,
+ OUT, CRTCREG, 23, CRTCVAL, 0xe3,
+ OUT, CRTCREG, 24, CRTCVAL, 0xff,
+
+ /* Graphics controller */
+ OUT, GENREG2, 0x00, 0, 0,
+ OUT, GENREG3, 0x01, 0, 0,
+ OUT, GRREG, 0, GRVAL, 0x00,
+ OUT, GRREG, 1, GRVAL, 0x00,
+ OUT, GRREG, 2, GRVAL, 0x00,
+ OUT, GRREG, 3, GRVAL, 0x00,
+ OUT, GRREG, 4, GRVAL, 0x00,
+ OUT, GRREG, 5, GRVAL, 0x00,
+ OUT, GRREG, 6, GRVAL, 0x05,
+ OUT, GRREG, 7, GRVAL, 0x0f,
+ OUT, GRREG, 8, GRVAL, 0xff,
+
+ /* Reset attribute flip/flop */
+ IN, ATTRREG, 0, 0, 0,
+
+ /* Palette */
+ OUT, PALREG, 0, PALREG, 0x00,
+ OUT, PALREG, 1, PALREG, 0x01,
+ OUT, PALREG, 2, PALREG, 0x02,
+ OUT, PALREG, 3, PALREG, 0x03,
+ OUT, PALREG, 4, PALREG, 0x04,
+ OUT, PALREG, 5, PALREG, 0x05,
+ OUT, PALREG, 6, PALREG, 0x06,
+ OUT, PALREG, 7, PALREG, 0x07,
+ OUT, PALREG, 8, PALREG, 0x38,
+ OUT, PALREG, 9, PALREG, 0x39,
+ OUT, PALREG, 10, PALREG, 0x3a,
+ OUT, PALREG, 11, PALREG, 0x3b,
+ OUT, PALREG, 12, PALREG, 0x3c,
+ OUT, PALREG, 13, PALREG, 0x3d,
+ OUT, PALREG, 14, PALREG, 0x3e,
+ OUT, PALREG, 15, PALREG, 0x3f,
+ OUT, PALREG, 16, PALREG, 0x01,
+ OUT, PALREG, 17, PALREG, 0x00,
+ OUT, PALREG, 18, PALREG, 0x0f,
+ OUT, PALREG, 19, PALREG, 0x00,
+
+ /* Enable palette */
+ OUT, PALREG, 0x20, 0, 0,
+
+ /* End of table */
+ DONE, 0, 0, 0, 0
+};
+
+
+/* VGA 80x25 text (BIOS mode 3).
+ */
+static REGIO graph_off[] = {
+ /* Reset attr F/F */
+ IN, ATTRREG, 0, 0, 0,
+
+ /* Disable palette */
+ OUT, PALREG, 0, 0, 0,
+
+ /* Reset sequencer regs */
+ OUT, SEQREG, 0, SEQVAL, 1,
+ OUT, SEQREG, 1, SEQVAL, 1,
+ OUT, SEQREG, 2, SEQVAL, 3,
+ OUT, SEQREG, 3, SEQVAL, 0,
+ OUT, SEQREG, 4, SEQVAL, 2,
+
+ /* Misc out reg */
+ OUT, GENREG1, 0x63, 0, 0,
+
+ /* Sequencer enable */
+ OUT, SEQREG, 0, SEQVAL, 3,
+
+ /* Unprotect crtc regs 0-7 */
+ OUT, CRTCREG, 0x11, CRTCVAL, 0,
+
+ /* Crtc */
+ OUT, CRTCREG, 0, CRTCVAL, 0x5f, /* horiz total */
+ OUT, CRTCREG, 1, CRTCVAL, 0x4f, /* horiz end */
+ OUT, CRTCREG, 2, CRTCVAL, 0x50, /* horiz blank */
+ OUT, CRTCREG, 3, CRTCVAL, 0x82, /* end blank */
+ OUT, CRTCREG, 4, CRTCVAL, 0x55, /* horiz retrace */
+ OUT, CRTCREG, 5, CRTCVAL, 0x81, /* end retrace */
+ OUT, CRTCREG, 6, CRTCVAL, 0xbf, /* vert total */
+ OUT, CRTCREG, 7, CRTCVAL, 0x1f, /* overflows */
+ OUT, CRTCREG, 8, CRTCVAL, 0x00, /* row scan */
+ OUT, CRTCREG, 9, CRTCVAL, 0x4f, /* max scan line */
+ OUT, CRTCREG, 10, CRTCVAL, 0x00, /* cursor start */
+ OUT, CRTCREG, 11, CRTCVAL, 0x0f, /* cursor end */
+ OUT, CRTCREG, 12, CRTCVAL, 0x0e, /* start high addr */
+ OUT, CRTCREG, 13, CRTCVAL, 0xb0, /* low addr */
+ OUT, CRTCREG, 14, CRTCVAL, 0x16, /* cursor high */
+ OUT, CRTCREG, 15, CRTCVAL, 0x30, /* cursor low */
+ OUT, CRTCREG, 16, CRTCVAL, 0x9c, /* vert retrace */
+ OUT, CRTCREG, 17, CRTCVAL, 0x8e, /* retrace end */
+ OUT, CRTCREG, 18, CRTCVAL, 0x8f, /* vert end */
+ OUT, CRTCREG, 19, CRTCVAL, 0x28, /* offset */
+ OUT, CRTCREG, 20, CRTCVAL, 0x1f, /* underline */
+ OUT, CRTCREG, 21, CRTCVAL, 0x96, /* vert blank */
+ OUT, CRTCREG, 22, CRTCVAL, 0xb9, /* end blank */
+ OUT, CRTCREG, 23, CRTCVAL, 0xa3, /* crt mode */
+ OUT, CRTCREG, 24, CRTCVAL, 0xff, /* line compare */
+
+ /* Graphics controller */
+ OUT, GENREG2, 0x00, 0, 0,
+ OUT, GENREG3, 0x01, 0, 0,
+ OUT, GRREG, 0, GRVAL, 0x00,
+ OUT, GRREG, 1, GRVAL, 0x00,
+ OUT, GRREG, 2, GRVAL, 0x00,
+ OUT, GRREG, 3, GRVAL, 0x00,
+ OUT, GRREG, 4, GRVAL, 0x00,
+ OUT, GRREG, 5, GRVAL, 0x10,
+ OUT, GRREG, 6, GRVAL, 0x0e,
+ OUT, GRREG, 7, GRVAL, 0x00,
+ OUT, GRREG, 8, GRVAL, 0xff,
+
+ /* Reset attribute flip/flop */
+ IN, ATTRREG, 0, 0, 0,
+
+ /* Palette */
+ OUT, PALREG, 0, PALREG, 0x00,
+ OUT, PALREG, 1, PALREG, 0x01,
+ OUT, PALREG, 2, PALREG, 0x02,
+ OUT, PALREG, 3, PALREG, 0x03,
+ OUT, PALREG, 4, PALREG, 0x04,
+ OUT, PALREG, 5, PALREG, 0x05,
+ OUT, PALREG, 6, PALREG, 0x06,
+ OUT, PALREG, 7, PALREG, 0x07,
+ OUT, PALREG, 8, PALREG, 0x10,
+ OUT, PALREG, 9, PALREG, 0x11,
+ OUT, PALREG, 10, PALREG, 0x12,
+ OUT, PALREG, 11, PALREG, 0x13,
+ OUT, PALREG, 12, PALREG, 0x14,
+ OUT, PALREG, 13, PALREG, 0x15,
+ OUT, PALREG, 14, PALREG, 0x16,
+ OUT, PALREG, 15, PALREG, 0x17,
+ OUT, PALREG, 16, PALREG, 0x08,
+ OUT, PALREG, 17, PALREG, 0x00,
+ OUT, PALREG, 18, PALREG, 0x0f,
+ OUT, PALREG, 19, PALREG, 0x00,
+
+ /* Enable palette */
+ OUT, PALREG, 0x20, 0, 0,
+
+ /* End of table */
+ DONE, 0, 0, 0, 0
+};
+
+#endif
+
+
+#if EGA_STANDARD
+
+/* EGA 640x350 16-color graphics (BIOS mode 0x10).
+ */
+static REGIO graphics_on[] = {
+ /* Reset attr F/F */
+ IN, ATTRREG, 0, 0, 0,
+
+ /* Disable palette */
+ OUT, PALREG, 0, 0, 0,
+
+ /* Reset sequencer regs */
+ OUT, SEQREG, 0, SEQVAL, 0,
+ OUT, SEQREG, 1, SEQVAL, 1,
+ OUT, SEQREG, 2, SEQVAL, 0x0f,
+ OUT, SEQREG, 3, SEQVAL, 0,
+ OUT, SEQREG, 4, SEQVAL, 6,
+
+ /* Misc out reg */
+ OUT, GENREG1, 0xa7, 0, 0,
+
+ /* Sequencer enable */
+ OUT, SEQREG, 0, SEQVAL, 0x03,
+
+ /* Unprotect crtc regs 0-7 */
+ OUT, CRTCREG, 0x11, CRTCVAL, 0,
+
+ /* Crtc */
+ OUT, CRTCREG, 0, CRTCVAL, 0x5b,
+ OUT, CRTCREG, 1, CRTCVAL, 0x4f,
+ OUT, CRTCREG, 2, CRTCVAL, 0x53,
+ OUT, CRTCREG, 3, CRTCVAL, 0x37,
+ OUT, CRTCREG, 4, CRTCVAL, 0x52,
+ OUT, CRTCREG, 5, CRTCVAL, 0x00,
+ OUT, CRTCREG, 6, CRTCVAL, 0x6c,
+ OUT, CRTCREG, 7, CRTCVAL, 0x1f,
+ OUT, CRTCREG, 8, CRTCVAL, 0x00,
+ OUT, CRTCREG, 9, CRTCVAL, 0x00,
+ OUT, CRTCREG, 10, CRTCVAL, 0x00,
+ OUT, CRTCREG, 11, CRTCVAL, 0x00,
+ OUT, CRTCREG, 12, CRTCVAL, 0x00,
+ OUT, CRTCREG, 13, CRTCVAL, 0x00,
+ OUT, CRTCREG, 14, CRTCVAL, 0x00,
+ OUT, CRTCREG, 15, CRTCVAL, 0x00,
+ OUT, CRTCREG, 16, CRTCVAL, 0x5e,
+ OUT, CRTCREG, 17, CRTCVAL, 0x2b,
+ OUT, CRTCREG, 18, CRTCVAL, 0x5d,
+ OUT, CRTCREG, 19, CRTCVAL, 0x28,
+ OUT, CRTCREG, 20, CRTCVAL, 0x0f,
+ OUT, CRTCREG, 21, CRTCVAL, 0x5f,
+ OUT, CRTCREG, 22, CRTCVAL, 0x0a,
+ OUT, CRTCREG, 23, CRTCVAL, 0xe3,
+ OUT, CRTCREG, 24, CRTCVAL, 0xff,
+
+ /* Graphics controller */
+ OUT, GENREG2, 0x00, 0, 0,
+ OUT, GENREG3, 0x01, 0, 0,
+ OUT, GRREG, 0, GRVAL, 0x00,
+ OUT, GRREG, 1, GRVAL, 0x00,
+ OUT, GRREG, 2, GRVAL, 0x00,
+ OUT, GRREG, 3, GRVAL, 0x00,
+ OUT, GRREG, 4, GRVAL, 0x00,
+ OUT, GRREG, 5, GRVAL, 0x00,
+ OUT, GRREG, 6, GRVAL, 0x05,
+ OUT, GRREG, 7, GRVAL, 0x0f,
+ OUT, GRREG, 8, GRVAL, 0xff,
+
+ /* Reset attribute flip/flop */
+ IN, ATTRREG, 0, 0, 0,
+
+ /* Palette */
+ OUT, PALREG, 0, PALREG, 0x00,
+ OUT, PALREG, 1, PALREG, 0x01,
+ OUT, PALREG, 2, PALREG, 0x02,
+ OUT, PALREG, 3, PALREG, 0x03,
+ OUT, PALREG, 4, PALREG, 0x04,
+ OUT, PALREG, 5, PALREG, 0x05,
+ OUT, PALREG, 6, PALREG, 0x06,
+ OUT, PALREG, 7, PALREG, 0x07,
+ OUT, PALREG, 8, PALREG, 0x38,
+ OUT, PALREG, 9, PALREG, 0x39,
+ OUT, PALREG, 10, PALREG, 0x3a,
+ OUT, PALREG, 11, PALREG, 0x3b,
+ OUT, PALREG, 12, PALREG, 0x3c,
+ OUT, PALREG, 13, PALREG, 0x3d,
+ OUT, PALREG, 14, PALREG, 0x3e,
+ OUT, PALREG, 15, PALREG, 0x3f,
+ OUT, PALREG, 16, PALREG, 0x01,
+ OUT, PALREG, 17, PALREG, 0x00,
+ OUT, PALREG, 18, PALREG, 0x0f,
+ OUT, PALREG, 19, PALREG, 0x00,
+
+ /* Enable palette */
+ OUT, PALREG, 0x20, 0, 0,
+
+ /* End of table */
+ DONE, 0, 0, 0, 0
+};
+
+
+/* EGA 80x25 text (BIOS mode 3).
+ */
+static REGIO graph_off[] = {
+ /* Reset attr F/F */
+ IN, ATTRREG, 0, 0, 0,
+
+ /* Disable palette */
+ OUT, PALREG, 0, 0, 0,
+
+ /* Reset sequencer regs */
+ OUT, SEQREG, 0, SEQVAL, 1,
+ OUT, SEQREG, 1, SEQVAL, 1,
+ OUT, SEQREG, 2, SEQVAL, 3,
+ OUT, SEQREG, 3, SEQVAL, 0,
+ OUT, SEQREG, 4, SEQVAL, 3,
+
+ /* Misc out reg */
+ OUT, GENREG1, 0xa7, 0, 0,
+
+ /* Sequencer enable */
+ OUT, SEQREG, 0, SEQVAL, 3,
+
+ /* Crtc */
+ OUT, CRTCREG, 0, CRTCVAL, 0x5b, /* horiz total */
+ OUT, CRTCREG, 1, CRTCVAL, 0x4f, /* horiz end */
+ OUT, CRTCREG, 2, CRTCVAL, 0x53, /* horiz blank */
+ OUT, CRTCREG, 3, CRTCVAL, 0x37, /* end blank */
+ OUT, CRTCREG, 4, CRTCVAL, 0x51, /* horiz retrace */
+ OUT, CRTCREG, 5, CRTCVAL, 0x5b, /* end retrace */
+ OUT, CRTCREG, 6, CRTCVAL, 0x6c, /* vert total */
+ OUT, CRTCREG, 7, CRTCVAL, 0x1f, /* overflows */
+ OUT, CRTCREG, 8, CRTCVAL, 0x00, /* row scan */
+ OUT, CRTCREG, 9, CRTCVAL, 0x0d, /* max scan line */
+ OUT, CRTCREG, 10, CRTCVAL, 0x00, /* cursor start */
+ OUT, CRTCREG, 11, CRTCVAL, 0x0f, /* cursor end */
+ OUT, CRTCREG, 12, CRTCVAL, 0x00, /* start high addr */
+ OUT, CRTCREG, 13, CRTCVAL, 0x00, /* low addr */
+ OUT, CRTCREG, 14, CRTCVAL, 0x00, /* cursor high */
+ OUT, CRTCREG, 15, CRTCVAL, 0x00, /* cursor low */
+ OUT, CRTCREG, 16, CRTCVAL, 0x5e, /* vert retrace */
+ OUT, CRTCREG, 17, CRTCVAL, 0x2b, /* retrace end */
+ OUT, CRTCREG, 18, CRTCVAL, 0x5d, /* vert end */
+ OUT, CRTCREG, 19, CRTCVAL, 0x28, /* offset */
+ OUT, CRTCREG, 20, CRTCVAL, 0x0f, /* underline */
+ OUT, CRTCREG, 21, CRTCVAL, 0x5e, /* vert blank */
+ OUT, CRTCREG, 22, CRTCVAL, 0x0a, /* end blank */
+ OUT, CRTCREG, 23, CRTCVAL, 0xa3, /* crt mode */
+ OUT, CRTCREG, 24, CRTCVAL, 0xff, /* line compare */
+
+ /* Graphics controller */
+ OUT, GENREG2, 0x00, 0, 0,
+ OUT, GENREG3, 0x01, 0, 0,
+ OUT, GRREG, 0, GRVAL, 0x00,
+ OUT, GRREG, 1, GRVAL, 0x00,
+ OUT, GRREG, 2, GRVAL, 0x00,
+ OUT, GRREG, 3, GRVAL, 0x00,
+ OUT, GRREG, 4, GRVAL, 0x00,
+ OUT, GRREG, 5, GRVAL, 0x10,
+ OUT, GRREG, 6, GRVAL, 0x0e,
+ OUT, GRREG, 7, GRVAL, 0x00,
+ OUT, GRREG, 8, GRVAL, 0xff,
+
+ /* Reset attribute flip/flop */
+ IN, ATTRREG, 0, 0, 0,
+
+ /* Palette */
+ OUT, PALREG, 0, PALREG, 0x00,
+ OUT, PALREG, 1, PALREG, 0x01,
+ OUT, PALREG, 2, PALREG, 0x02,
+ OUT, PALREG, 3, PALREG, 0x03,
+ OUT, PALREG, 4, PALREG, 0x04,
+ OUT, PALREG, 5, PALREG, 0x05,
+ OUT, PALREG, 6, PALREG, 0x14,
+ OUT, PALREG, 7, PALREG, 0x07,
+ OUT, PALREG, 8, PALREG, 0x38,
+ OUT, PALREG, 9, PALREG, 0x39,
+ OUT, PALREG, 10, PALREG, 0x3a,
+ OUT, PALREG, 11, PALREG, 0x3b,
+ OUT, PALREG, 12, PALREG, 0x3c,
+ OUT, PALREG, 13, PALREG, 0x3d,
+ OUT, PALREG, 14, PALREG, 0x3e,
+ OUT, PALREG, 15, PALREG, 0x3f,
+ OUT, PALREG, 16, PALREG, 0x08,
+ OUT, PALREG, 17, PALREG, 0x00,
+ OUT, PALREG, 18, PALREG, 0x0f,
+ OUT, PALREG, 19, PALREG, 0x00,
+
+ /* Enable palette */
+ OUT, PALREG, 0x20, 0, 0,
+
+ /* End of table */
+ DONE, 0, 0, 0, 0
+};
+
+#endif
diff --git a/c/src/lib/libbsp/i386/pc386/console/vt.c b/c/src/lib/libbsp/i386/pc386/console/vt.c
new file mode 100644
index 0000000000..eb8ec64c76
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/vt.c
@@ -0,0 +1,347 @@
+/*
+ * linux/drivers/char/vt.c
+ *
+ * Copyright (C) 1992 obz under the linux copyright
+ *
+ * Dynamic diacritical handling - aeb@cwi.nl - Dec 1993
+ * Dynamic keymap and string allocation - aeb@cwi.nl - May 1994
+ * Restrict VT switching via ioctl() - grif@cs.ucr.edu - Dec 1995
+ * Some code moved for less code duplication - Andi Kleen - Mar 1997
+ *
+ *
+ * by: Rosimildo da Silva --
+ * Ported to RTEMS to provide the basic interface to the console
+ * driver. Removed all stuff not required, such as VT_, Fonts, etc.
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+
+#include <i386_io.h>
+#include <rtems/kd.h>
+#include <rtems/keyboard.h>
+
+/*
+ * Console (vt and kd) routines, as defined by USL SVR4 manual, and by
+ * experimentation and study of X386 SYSV handling.
+ *
+ * One point of difference: SYSV vt's are /dev/vtX, which X >= 0, and
+ * /dev/console is a separate ttyp. Under Linux, /dev/tty0 is /dev/console,
+ * and the vc start at /dev/ttyX, X >= 1. We maintain that here, so we will
+ * always treat our set of vt as numbered 1..MAX_NR_CONSOLES (corresponding to
+ * ttys 0..MAX_NR_CONSOLES-1). Explicitly naming VT 0 is illegal, but using
+ * /dev/tty0 (fg_console) as a target is legal, since an implicit aliasing
+ * to the current console is done by the main ioctl code.
+ */
+
+struct vt_struct *vt_cons[MAX_NR_CONSOLES];
+
+/* Keyboard type: Default is KB_101, but can be set by machine
+ * specific code.
+ */
+unsigned char keyboard_type = KB_101;
+
+/*
+ * Generates sound of some frequency for some number of clock ticks
+ *
+ * If freq is 0, will turn off sound, else will turn it on for that time.
+ * If msec is 0, will return immediately, else will sleep for msec time, then
+ * turn sound off.
+ *
+ * We also return immediately, which is what was implied within the X
+ * comments - KDMKTONE doesn't put the process to sleep.
+ */
+
+#if defined(__i386__) || defined(__alpha__) || defined(__powerpc__) \
+ || (defined(__mips__) && !defined(CONFIG_SGI))
+
+static void
+kd_nosound(unsigned long ignored)
+{
+ /* disable counter 2 */
+ outb(inb_p(0x61)&0xFC, 0x61);
+ return;
+}
+
+void
+_kd_mksound(unsigned int hz, unsigned int ticks)
+{
+ unsigned int count = 0;
+
+ if (hz > 20 && hz < 32767)
+ count = 1193180 / hz;
+
+ cli();
+/* del_timer(&sound_timer); */
+ if (count) {
+ /* enable counter 2 */
+ outb_p(inb_p(0x61)|3, 0x61);
+ /* set command for counter 2, 2 byte write */
+ outb_p(0xB6, 0x43);
+ /* select desired HZ */
+ outb_p(count & 0xff, 0x42);
+ outb((count >> 8) & 0xff, 0x42);
+
+/*
+ if (ticks) {
+ sound_timer.expires = jiffies+ticks;
+ add_timer(&sound_timer);
+ }
+*/
+ } else
+ kd_nosound(0);
+
+ sti();
+ return;
+}
+
+#else
+
+void
+_kd_mksound(unsigned int hz, unsigned int ticks)
+{
+}
+
+#endif
+
+void (*kd_mksound)(unsigned int hz, unsigned int ticks) = _kd_mksound;
+
+
+#define i (tmp.kb_index)
+#define s (tmp.kb_table)
+#define v (tmp.kb_value)
+static inline int
+do_kdsk_ioctl(int cmd, struct kbentry *user_kbe, int perm, struct kbd_struct *kbd)
+{
+ struct kbentry tmp;
+ ushort *key_map, val;
+
+ tmp = *user_kbe;
+ if (i >= NR_KEYS || s >= MAX_NR_KEYMAPS)
+ return -EINVAL;
+
+ switch (cmd) {
+ case KDGKBENT:
+ key_map = key_maps[s];
+ if (key_map) {
+ val = U(key_map[i]);
+ if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
+ val = K_HOLE;
+ } else
+ val = (i ? K_HOLE : K_NOSUCHMAP);
+ user_kbe->kb_value = val;
+ return 0;
+
+ case KDSKBENT:
+ return -EINVAL;
+ }
+ return 0;
+}
+#undef i
+#undef s
+#undef v
+
+
+#define HZ 100
+
+static inline int
+do_kbkeycode_ioctl(int cmd, struct kbkeycode *user_kbkc, int perm)
+{
+ struct kbkeycode tmp;
+ int kc = 0;
+
+ tmp = *user_kbkc;
+ switch (cmd) {
+ case KDGETKEYCODE:
+ kc = getkeycode(tmp.scancode);
+ if (kc >= 0)
+ user_kbkc->keycode = kc;
+ break;
+ case KDSETKEYCODE:
+ if (!perm)
+ return -EPERM;
+ kc = setkeycode(tmp.scancode, tmp.keycode);
+ break;
+ }
+ return kc;
+}
+
+static inline int
+do_kdgkb_ioctl(int cmd, struct kbsentry *user_kdgkb, int perm)
+{
+ return -EINVAL;
+}
+
+/*
+ * We handle the console-specific ioctl's here. We allow the
+ * capability to modify any console, not just the fg_console.
+ */
+int vt_ioctl( unsigned int cmd, unsigned long arg)
+{
+ int perm;
+ unsigned int console;
+ unsigned char ucval;
+ struct kbd_struct * kbd;
+
+ console = 0;
+ /*
+ * To have permissions to do most of the vt ioctls, we either have
+ * to be the owner of the tty, or super-user.
+ */
+ perm = 1;
+ kbd = kbd_table + console;
+ switch (cmd) {
+ case KIOCSOUND:
+ if (!perm)
+ return -EPERM;
+ if (arg)
+ arg = 1193180 / arg;
+ kd_mksound(arg, 0);
+ return 0;
+
+ case KDMKTONE:
+ if (!perm)
+ return -EPERM;
+ {
+ unsigned int ticks, count;
+
+ /*
+ * Generate the tone for the appropriate number of ticks.
+ * If the time is zero, turn off sound ourselves.
+ */
+ ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
+ count = ticks ? (arg & 0xffff) : 0;
+ if (count)
+ count = 1193180 / count;
+ kd_mksound(count, ticks);
+ return 0;
+ }
+
+ case KDGKBTYPE:
+ /*
+ * this is naive.
+ */
+ ucval = keyboard_type;
+ goto setchar;
+
+ case KDSETMODE:
+ case KDGETMODE:
+ return -EINVAL;
+
+ case KDSKBMODE:
+ if (!perm)
+ return -EPERM;
+ switch(arg) {
+ case K_RAW:
+ kbd->kbdmode = VC_RAW;
+ break;
+ case K_MEDIUMRAW:
+ kbd->kbdmode = VC_MEDIUMRAW;
+ break;
+ case K_XLATE:
+ kbd->kbdmode = VC_XLATE;
+ compute_shiftstate();
+ break;
+ case K_UNICODE:
+ kbd->kbdmode = VC_UNICODE;
+ compute_shiftstate();
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+
+ case KDGKBMODE:
+ ucval = ((kbd->kbdmode == VC_RAW) ? K_RAW :
+ (kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW :
+ (kbd->kbdmode == VC_UNICODE) ? K_UNICODE :
+ K_XLATE);
+ goto setint;
+
+ /* this could be folded into KDSKBMODE, but for compatibility
+ reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */
+ case KDSKBMETA:
+ switch(arg) {
+ case K_METABIT:
+ clr_vc_kbd_mode(kbd, VC_META);
+ break;
+ case K_ESCPREFIX:
+ set_vc_kbd_mode(kbd, VC_META);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+
+ case KDGKBMETA:
+ ucval = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT);
+ setint:
+ *(int *)arg = ucval;
+ return 0;
+
+ case KDGETKEYCODE:
+ case KDSETKEYCODE:
+ return do_kbkeycode_ioctl(cmd, (struct kbkeycode *)arg, perm);
+
+ case KDGKBENT:
+ case KDSKBENT:
+ return do_kdsk_ioctl(cmd, (struct kbentry *)arg, perm, kbd);
+
+ case KDGKBDIACR:
+ {
+ struct kbdiacrs *a = (struct kbdiacrs *)arg;
+ a->kb_cnt = accent_table_size;
+ memcpy( a->kbdiacr, accent_table, accent_table_size*sizeof(struct kbdiacr) );
+ return 0;
+ }
+
+ case KDSKBDIACR:
+ {
+ struct kbdiacrs *a = (struct kbdiacrs *)arg;
+ unsigned int ct;
+
+ if (!perm)
+ return -EPERM;
+ ct = a->kb_cnt;
+ if (ct >= MAX_DIACR)
+ return -EINVAL;
+ accent_table_size = ct;
+ memcpy(accent_table, a->kbdiacr, ct*sizeof(struct kbdiacr));
+ return 0;
+ }
+
+ /* the ioctls below read/set the flags usually shown in the leds */
+ /* don't use them - they will go away without warning */
+ case KDGKBLED:
+ ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4);
+ goto setchar;
+
+ case KDSKBLED:
+ if (!perm)
+ return -EPERM;
+ if (arg & ~0x77)
+ return -EINVAL;
+ kbd->ledflagstate = (arg & 7);
+ kbd->default_ledflagstate = ((arg >> 4) & 7);
+ set_leds();
+ return 0;
+
+ /* the ioctls below only set the lights, not the functions */
+ /* for those, see KDGKBLED and KDSKBLED above */
+ case KDGETLED:
+ ucval = getledstate();
+ setchar:
+ *(char*)arg = ucval;
+ return 0;
+
+ case KDSETLED:
+ if (!perm)
+ return -EPERM;
+ setledstate(kbd, arg);
+ return 0;
+
+ default:
+ return -EINVAL;
+ }
+}
+
diff --git a/c/src/lib/libbsp/i386/pc386/startup/Makefile.am b/c/src/lib/libbsp/i386/pc386/startup/Makefile.am
index a634ef5724..76e66dd9a7 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/Makefile.am
+++ b/c/src/lib/libbsp/i386/pc386/startup/Makefile.am
@@ -10,7 +10,8 @@ PGM = $(ARCH)/startup.rel
C_FILES = bsplibc.c bsppost.c bspstart.c exit.c irq.c irq_init.c bootcard.c \
main.c sbrk.c i386-stub.c i386-stub-glue.c uart.c pcibios.c \
- gnatinstallhandler.c
+ gnatinstallhandler.c gdb_glue.c tty_drv.c
+
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
S_FILES = ldsegs.S irq_asm.S