From 3cbb63ac774a21e13f5f75271810754b70ff311d Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Wed, 30 Aug 2000 08:15:30 +0000 Subject: 2000-08-26 Rosimildo da Silva * 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 --- c/src/lib/libbsp/i386/pc386/ChangeLog | 32 + c/src/lib/libbsp/i386/pc386/console/Makefile.am | 19 +- c/src/lib/libbsp/i386/pc386/console/console.c | 187 +++-- c/src/lib/libbsp/i386/pc386/console/defkeymap.c | 263 ++++++ c/src/lib/libbsp/i386/pc386/console/fb_vga.c | 245 ++++++ c/src/lib/libbsp/i386/pc386/console/fb_vga.h | 81 ++ c/src/lib/libbsp/i386/pc386/console/i386kbd.h | 189 +++++ c/src/lib/libbsp/i386/pc386/console/inch.c | 298 +------ c/src/lib/libbsp/i386/pc386/console/kd.h | 114 +++ c/src/lib/libbsp/i386/pc386/console/keyboard.c | 928 +++++++++++++++++++++ c/src/lib/libbsp/i386/pc386/console/keyboard.h | 588 +++++++++++++ c/src/lib/libbsp/i386/pc386/console/mouse_parser.c | 400 +++++++++ c/src/lib/libbsp/i386/pc386/console/mouse_parser.h | 36 + c/src/lib/libbsp/i386/pc386/console/outch.c | 21 + c/src/lib/libbsp/i386/pc386/console/pc_keyb.c | 648 ++++++++++++++ c/src/lib/libbsp/i386/pc386/console/ps2_drv.h | 80 ++ c/src/lib/libbsp/i386/pc386/console/ps2_mouse.c | 708 ++++++++++++++++ c/src/lib/libbsp/i386/pc386/console/ps2_mouse.h | 146 ++++ c/src/lib/libbsp/i386/pc386/console/serial_mouse.c | 348 ++++++++ c/src/lib/libbsp/i386/pc386/console/serial_mouse.h | 86 ++ c/src/lib/libbsp/i386/pc386/console/vgainit.c | 766 +++++++++++++++++ c/src/lib/libbsp/i386/pc386/console/vt.c | 347 ++++++++ c/src/lib/libbsp/i386/pc386/startup/Makefile.am | 3 +- 23 files changed, 6182 insertions(+), 351 deletions(-) create mode 100644 c/src/lib/libbsp/i386/pc386/console/defkeymap.c create mode 100644 c/src/lib/libbsp/i386/pc386/console/fb_vga.c create mode 100644 c/src/lib/libbsp/i386/pc386/console/fb_vga.h create mode 100644 c/src/lib/libbsp/i386/pc386/console/i386kbd.h create mode 100644 c/src/lib/libbsp/i386/pc386/console/kd.h create mode 100644 c/src/lib/libbsp/i386/pc386/console/keyboard.c create mode 100644 c/src/lib/libbsp/i386/pc386/console/keyboard.h create mode 100644 c/src/lib/libbsp/i386/pc386/console/mouse_parser.c create mode 100644 c/src/lib/libbsp/i386/pc386/console/mouse_parser.h create mode 100644 c/src/lib/libbsp/i386/pc386/console/pc_keyb.c create mode 100644 c/src/lib/libbsp/i386/pc386/console/ps2_drv.h create mode 100644 c/src/lib/libbsp/i386/pc386/console/ps2_mouse.c create mode 100644 c/src/lib/libbsp/i386/pc386/console/ps2_mouse.h create mode 100644 c/src/lib/libbsp/i386/pc386/console/serial_mouse.c create mode 100644 c/src/lib/libbsp/i386/pc386/console/serial_mouse.h create mode 100644 c/src/lib/libbsp/i386/pc386/console/vgainit.c create mode 100644 c/src/lib/libbsp/i386/pc386/console/vt.c 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 + + * 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 * 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 #include +#include +#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); @@ -171,33 +222,26 @@ 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 +#include +#include + +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 +#include +#include +#include + +#include +#include +#include + +#include + +/* 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 + +#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 + */ + +/* + * 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 + +/* 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 +#include +#include "i386kbd.h" +#include +#include + +#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<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; jledmode = 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 + * 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 +#include +#include +#include +#include + +#include +#include +#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 + +#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 1998-10-08. + * + * Code fixes to handle mouse ACKs properly. + * C. Scott Ananian 1999-01-29. + * + * Ported to RTEMS by Rosimildo da Silva + */ + +#include +#include +#include + +#include +#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 1998-10-08. + * Code fixes to handle mouse ACKs properly. + * C. Scott Ananian 1999-01-29. + * + * RTEMS port: by Rosimildo da Silva. + * This module was ported from Linux. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#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 + * + * 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 +#include +#include + +#include +#include +#include +#include +#include +#include + +int BSP_poll_read(int); + +#include +#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 + * 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 + +#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 +#include + +#include +#include +#include + +/* + * 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 -- cgit v1.2.3