2000-08-26 Rosimildo da Silva <rdasilva@connecttel.com>

* Major rework of the "/dev/console" driver.
	* Added termios support for stdin ( keyboard ).
	* Added ioctls() to support modes similar to Linux( XLATE,
	RAW, MEDIUMRAW ).
	* Added Keyboard mapping and handling of the keyboard's leds.
	* Added Micro FrameBuffer driver ( "/dev/fb0" ) for bare VGA
	controller ( 16 colors ).
	* Added PS/2 and Serial mouse support for PC386 BSP.
	* console/defkeymap.c: New file.
	* console/fb_vga.c: New file.
	* console/fb_vga.h: New file.
	* console/i386kbd.h: New file.
	* console/kd.h: New file.
	* console/keyboard.c: New file.
	* console/keyboard.h: New file.
	* console/mouse_parser.c: New file.
	* console/mouse_parser.h: New file.
	* console/pc_keyb.c: New file.
	* console/ps2_drv.h: New file.
	* console/ps2_mouse.c: New file.
	* console/ps2_mouse.h: New file.
	* console/serial_mouse.c: New file.
	* console/serial_mouse.h: New file.
	* console/vgainit.c: New file.
	* console/vt.c: New file.
	* console/Makefile.am: Reflect new files.
	* console/console.c, console/inch.c, console/outch.c: Console
	functionality modifications.
	* startup/Makefile.am: Pick up tty_drv.c and gdb_glue.c
This commit is contained in:
Joel Sherrill
2000-08-30 08:15:30 +00:00
parent fe602cfef0
commit 3cbb63ac77
23 changed files with 6184 additions and 353 deletions

View File

@@ -1,3 +1,35 @@
2000-08-26 Rosimildo da Silva <rdasilva@connecttel.com>
* Major rework of the "/dev/console" driver.
* Added termios support for stdin ( keyboard ).
* Added ioctls() to support modes similar to Linux( XLATE,
RAW, MEDIUMRAW ).
* Added Keyboard mapping and handling of the keyboard's leds.
* Added Micro FrameBuffer driver ( "/dev/fb0" ) for bare VGA
controller ( 16 colors ).
* Added PS/2 and Serial mouse support for PC386 BSP.
* console/defkeymap.c: New file.
* console/fb_vga.c: New file.
* console/fb_vga.h: New file.
* console/i386kbd.h: New file.
* console/kd.h: New file.
* console/keyboard.c: New file.
* console/keyboard.h: New file.
* console/mouse_parser.c: New file.
* console/mouse_parser.h: New file.
* console/pc_keyb.c: New file.
* console/ps2_drv.h: New file.
* console/ps2_mouse.c: New file.
* console/ps2_mouse.h: New file.
* console/serial_mouse.c: New file.
* console/serial_mouse.h: New file.
* console/vgainit.c: New file.
* console/vt.c: New file.
* console/Makefile.am: Reflect new files.
* console/console.c, console/inch.c, console/outch.c: Console
functionality modifications.
* startup/Makefile.am: Pick up tty_drv.c and gdb_glue.c
2000-08-10 Joel Sherrill <joel@OARcorp.com>
* ChangeLog: New file.

View File

@@ -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

View File

@@ -44,6 +44,9 @@ void __assert (const char *file, int line, const char *msg);
#include <uart.h>
#include <libcpu/cpuModel.h>
#include <rtems/mw_uid.h>
#include "mouse_parser.h"
/*
* Possible value for console input/output :
* BSP_CONSOLE_PORT_CONSOLE
@@ -65,12 +68,13 @@ int BSPPrintkPort = BSP_CONSOLE_PORT_CONSOLE;
int BSPBaseBaud = 115200;
extern BSP_polling_getchar_function_type BSP_poll_char;
extern int getch( void );
extern void kbd_init( void );
/*-------------------------------------------------------------------------+
| External Prototypes
+--------------------------------------------------------------------------*/
extern void _IBMPC_keyboard_isr(void);
extern rtems_boolean _IBMPC_scankey(char *); /* defined in 'inch.c' */
extern void keyboard_interrupt(void);
extern char BSP_wait_polled_input(void);
extern void _IBMPC_initVideo(void);
@@ -79,9 +83,10 @@ static void isr_on(const rtems_irq_connect_data *);
static void isr_off(const rtems_irq_connect_data *);
static int isr_is_on(const rtems_irq_connect_data *);
extern int rtems_kbpoll( void );
static rtems_irq_connect_data console_isr_data = {BSP_KEYBOARD,
_IBMPC_keyboard_isr,
keyboard_interrupt,
isr_on,
isr_off,
isr_is_on};
@@ -104,6 +109,44 @@ isr_is_on(const rtems_irq_connect_data *irq)
return BSP_irq_enabled_at_i8259s(irq->name);
}
extern char _IBMPC_inch(void);
extern int rtems_kbpoll( void );
static int
ibmpc_console_write(int minor, const char *buf, int len)
{
int count;
for (count = 0; count < len; count++)
{
_IBMPC_outch( buf[ count ] );
if( buf[ count ] == '\n')
_IBMPC_outch( '\r' ); /* LF = LF + CR */
}
return 0;
}
int kbd_poll_read( int minor )
{
if( rtems_kbpoll() )
{
int c = getch();
return c;
}
return -1;
}
/*
static void* termios_ttyp_console = NULL;
void enq_key( char key )
{
if( termios_ttyp_console )
{
rtems_termios_enqueue_raw_characters(termios_ttyp_console, &key,1 );
}
}
*/
void __assert (const char *file, int line, const char *msg)
{
static char exit_msg[] = "EXECUTIVE SHUTDOWN! Any key to reboot...";
@@ -144,12 +187,20 @@ 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 */
@@ -171,15 +222,9 @@ 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);
@@ -197,7 +242,6 @@ console_initialize(rtems_device_major_number major,
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){
@@ -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,11 +430,24 @@ console_control(rtems_device_major_number major,
void * arg
)
{
if(BSPConsolePort != BSP_CONSOLE_PORT_CONSOLE)
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;
}

View File

@@ -0,0 +1,263 @@
/* Do not edit this file! It was automatically generated by */
/* loadkeys --mktable defkeymap.map > defkeymap.c */
#include <sys/types.h>
#include <rtems/keyboard.h>
#include <rtems/kd.h>
u_short plain_map[NR_KEYS] = {
0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036,
0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009,
0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73,
0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b,
0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76,
0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c,
0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307,
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a,
0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short shift_map[NR_KEYS] = {
0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e,
0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009,
0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49,
0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53,
0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a,
0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56,
0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c,
0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e,
0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf213, 0xf203, 0xf307,
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a,
0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short altgr_map[NR_KEYS] = {
0xf200, 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200,
0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200,
0xfb71, 0xfb77, 0xf918, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
0xfb6f, 0xfb70, 0xf200, 0xf07e, 0xf201, 0xf702, 0xf914, 0xfb73,
0xf917, 0xf919, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf200,
0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xf916, 0xfb76,
0xf915, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
0xf703, 0xf200, 0xf207, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510,
0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf202, 0xf911,
0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b,
0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516,
0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short ctrl_map[NR_KEYS] = {
0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e,
0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf200,
0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf702, 0xf001, 0xf013,
0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016,
0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c,
0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf204, 0xf307,
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf10a,
0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short shift_ctrl_map[NR_KEYS] = {
0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200,
0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013,
0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016,
0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307,
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short alt_map[NR_KEYS] = {
0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836,
0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809,
0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869,
0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873,
0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b,
0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876,
0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c,
0xf703, 0xf820, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf907,
0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901,
0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a,
0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short ctrl_alt_map[NR_KEYS] = {
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809,
0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813,
0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200,
0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816,
0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
0xf703, 0xf200, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf200, 0xf307,
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf50a,
0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
ushort *key_maps[MAX_NR_KEYMAPS] = {
plain_map, shift_map, altgr_map, 0,
ctrl_map, shift_ctrl_map, 0, 0,
alt_map, 0, 0, 0,
ctrl_alt_map, 0
};
unsigned int keymap_count = 7;
/*
* Philosophy: most people do not define more strings, but they who do
* often want quite a lot of string space. So, we statically allocate
* the default and allocate dynamically in chunks of 512 bytes.
*/
char func_buf[] = {
'\033', '[', '[', 'A', 0,
'\033', '[', '[', 'B', 0,
'\033', '[', '[', 'C', 0,
'\033', '[', '[', 'D', 0,
'\033', '[', '[', 'E', 0,
'\033', '[', '1', '7', '~', 0,
'\033', '[', '1', '8', '~', 0,
'\033', '[', '1', '9', '~', 0,
'\033', '[', '2', '0', '~', 0,
'\033', '[', '2', '1', '~', 0,
'\033', '[', '2', '3', '~', 0,
'\033', '[', '2', '4', '~', 0,
'\033', '[', '2', '5', '~', 0,
'\033', '[', '2', '6', '~', 0,
'\033', '[', '2', '8', '~', 0,
'\033', '[', '2', '9', '~', 0,
'\033', '[', '3', '1', '~', 0,
'\033', '[', '3', '2', '~', 0,
'\033', '[', '3', '3', '~', 0,
'\033', '[', '3', '4', '~', 0,
'\033', '[', '1', '~', 0,
'\033', '[', '2', '~', 0,
'\033', '[', '3', '~', 0,
'\033', '[', '4', '~', 0,
'\033', '[', '5', '~', 0,
'\033', '[', '6', '~', 0,
'\033', '[', 'M', 0,
'\033', '[', 'P', 0,
};
char *funcbufptr = func_buf;
int funcbufsize = sizeof(func_buf);
int funcbufleft = 0; /* space left */
char *func_table[MAX_NR_FUNC] = {
func_buf + 0,
func_buf + 5,
func_buf + 10,
func_buf + 15,
func_buf + 20,
func_buf + 25,
func_buf + 31,
func_buf + 37,
func_buf + 43,
func_buf + 49,
func_buf + 55,
func_buf + 61,
func_buf + 67,
func_buf + 73,
func_buf + 79,
func_buf + 85,
func_buf + 91,
func_buf + 97,
func_buf + 103,
func_buf + 109,
func_buf + 115,
func_buf + 120,
func_buf + 125,
func_buf + 130,
func_buf + 135,
func_buf + 140,
func_buf + 145,
0,
0,
func_buf + 149,
0,
};
struct kbdiacr accent_table[MAX_DIACR] = {
{'`', 'A', '\300'}, {'`', 'a', '\340'},
{'\'', 'A', '\301'}, {'\'', 'a', '\341'},
{'^', 'A', '\302'}, {'^', 'a', '\342'},
{'~', 'A', '\303'}, {'~', 'a', '\343'},
{'"', 'A', '\304'}, {'"', 'a', '\344'},
{'O', 'A', '\305'}, {'o', 'a', '\345'},
{'0', 'A', '\305'}, {'0', 'a', '\345'},
{'A', 'A', '\305'}, {'a', 'a', '\345'},
{'A', 'E', '\306'}, {'a', 'e', '\346'},
{',', 'C', '\307'}, {',', 'c', '\347'},
{'`', 'E', '\310'}, {'`', 'e', '\350'},
{'\'', 'E', '\311'}, {'\'', 'e', '\351'},
{'^', 'E', '\312'}, {'^', 'e', '\352'},
{'"', 'E', '\313'}, {'"', 'e', '\353'},
{'`', 'I', '\314'}, {'`', 'i', '\354'},
{'\'', 'I', '\315'}, {'\'', 'i', '\355'},
{'^', 'I', '\316'}, {'^', 'i', '\356'},
{'"', 'I', '\317'}, {'"', 'i', '\357'},
{'-', 'D', '\320'}, {'-', 'd', '\360'},
{'~', 'N', '\321'}, {'~', 'n', '\361'},
{'`', 'O', '\322'}, {'`', 'o', '\362'},
{'\'', 'O', '\323'}, {'\'', 'o', '\363'},
{'^', 'O', '\324'}, {'^', 'o', '\364'},
{'~', 'O', '\325'}, {'~', 'o', '\365'},
{'"', 'O', '\326'}, {'"', 'o', '\366'},
{'/', 'O', '\330'}, {'/', 'o', '\370'},
{'`', 'U', '\331'}, {'`', 'u', '\371'},
{'\'', 'U', '\332'}, {'\'', 'u', '\372'},
{'^', 'U', '\333'}, {'^', 'u', '\373'},
{'"', 'U', '\334'}, {'"', 'u', '\374'},
{'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
{'T', 'H', '\336'}, {'t', 'h', '\376'},
{'s', 's', '\337'}, {'"', 'y', '\377'},
{'s', 'z', '\337'}, {'i', 'j', '\377'},
};
unsigned int accent_table_size = 68;

View File

@@ -0,0 +1,245 @@
/*
/////////////////////////////////////////////////////////////////////////////
// $Header$
//
// Copyright (c) 2000 - Rosimildo da Silva ( rdasilva@connecttel.com )
//
// MODULE DESCRIPTION:
// This module implements the micro FB driver for "Bare VGA". It uses the
// routines for "bare hardware" that comes with MicroWindows.
//
// MODIFICATION/HISTORY:
//
// $Log$
//
/////////////////////////////////////////////////////////////////////////////
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <bsp.h>
#include <irq.h>
#include <rtems/libio.h>
#include <rtems/mw_fb.h>
/* these routines are defined in the microwindows code. This
driver is here more as an example of how to implement and
use the micro FB interface
*/
extern void ega_hwinit( void );
extern void ega_hwterm( void );
/* screen information for the VGA driver */
static struct fb_screeninfo fb_info =
{
640, 480, /* screen size x, y */
4, /* bits per pixel */
80, /* chars per line */
(volatile char *)0xA0000, /* buffer pointer */
0x10000, /* buffer size */
FB_TYPE_VGA_PLANES, /* type of dsplay */
FB_VISUAL_PSEUDOCOLOR /* color scheme used */
};
static __u16 red16[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa,
0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff
};
static __u16 green16[] = {
0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa,
0x5555, 0x5555, 0xffff, 0xffff, 0x5555, 0x5555, 0xffff, 0xffff
};
static __u16 blue16[] = {
0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa,
0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff
};
/*
* fbvga device driver INITIALIZE entry point.
*/
rtems_device_driver
fbvga_initialize( rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_status_code status;
printk( "FBVGA -- driver initializing..\n" );
/*
* Register the device
*/
status = rtems_io_register_name ("/dev/fb0", major, 0);
if (status != RTEMS_SUCCESSFUL)
{
printk("Error registering FBVGA device!\n");
rtems_fatal_error_occurred( status );
}
return RTEMS_SUCCESSFUL;
}
/*
* fbvga device driver OPEN entry point
*/
rtems_device_driver
fbvga_open( rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
/* rtems_status_code status; */
printk( "FBVGA open called.\n" );
return RTEMS_SUCCESSFUL;
}
/*
* fbvga device driver CLOSE entry point
*/
rtems_device_driver
fbvga_close(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
printk( "FBVGA close called.\n" );
return RTEMS_SUCCESSFUL;
}
/*
* fbvga device driver READ entry point.
* Read characters from the PS/2 mouse.
*/
rtems_device_driver
fbvga_read( rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
printk( "FBVGA read called.\n" );
rw_args->bytes_moved = 0;
return RTEMS_SUCCESSFUL;
}
/*
* fbvga device driver WRITE entry point.
* Write characters to the PS/2 mouse.
*/
rtems_device_driver
fbvga_write( rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
printk( "FBVGA write called.\n" );
rw_args->bytes_moved = 0;
return RTEMS_SUCCESSFUL;
}
static int get_screen_info( struct fb_screeninfo *info )
{
*info = fb_info;
return 0;
}
static int get_palette( struct fb_cmap *cmap )
{
__u32 i;
if( cmap->start + cmap->len >= 16 )
return 1;
for( i = 0; i < cmap->len; i++ )
{
cmap->red[ cmap->start + i ] = red16[ cmap->start + i ];
cmap->green[ cmap->start + i ] = green16[ cmap->start + i ];
cmap->blue[ cmap->start + i ] = blue16[ cmap->start + i ];
}
return 0;
}
static int set_palette( struct fb_cmap *cmap )
{
__u32 i;
if( cmap->start + cmap->len >= 16 )
return 1;
for( i = 0; i < cmap->len; i++ )
{
red16[ cmap->start + i ] = cmap->red[ cmap->start + i ];
green16[ cmap->start + i ] = cmap->green[ cmap->start + i ];
blue16[ cmap->start + i ] = cmap->blue[ cmap->start + i ];
}
return 0;
}
/*
* IOCTL entry point -- This method is called to carry
* all services of this interface.
*/
rtems_device_driver
fbvga_control( rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
rtems_libio_ioctl_args_t *args = arg;
printk( "FBVGA ioctl called, cmd=%x\n", args->command );
switch( args->command )
{
case FB_SCREENINFO:
args->ioctl_return = get_screen_info( args->buffer );
break;
case FB_GETPALETTE:
args->ioctl_return = get_palette( args->buffer );
break;
case FB_SETPALETTE:
args->ioctl_return = set_palette( args->buffer );
break;
/* this function would execute one of the routines of the
* interface based on the operation requested
*/
case FB_EXEC_FUNCTION:
{
struct fb_exec_function *env = args->buffer;
switch( env->func_no )
{
case FB_FUNC_ENTER_GRAPHICS:
/* enter graphics mode*/
ega_hwinit();
break;
case FB_FUNC_EXIT_GRAPHICS:
/* leave graphics mode*/
ega_hwterm();
break;
case FB_FUNC_IS_DIRTY:
break;
case FB_FUNC_GET_MODE:
break;
default:
break;
}
}
/* no break on purpose */
default:
args->ioctl_return = 0;
break;
}
return RTEMS_SUCCESSFUL;
}

View File

@@ -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__ */

View File

@@ -0,0 +1,189 @@
/*
* linux/include/asm-i386/keyboard.h
*
* Created 3 Nov 1996 by Geert Uytterhoeven
*/
/*
* This file contains the i386 architecture specific keyboard definitions
*/
#ifndef _I386_KEYBOARD_H
#define _I386_KEYBOARD_H
#include <i386_io.h>
#define KEYBOARD_IRQ 1
#define DISABLE_KBD_DURING_INTERRUPTS 0
extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
extern int pckbd_getkeycode(unsigned int scancode);
extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
char raw_mode);
extern char pckbd_unexpected_up(unsigned char keycode);
extern void pckbd_leds(unsigned char leds);
extern void pckbd_init_hw(void);
extern unsigned char pckbd_sysrq_xlate[128];
#define kbd_setkeycode pckbd_setkeycode
#define kbd_getkeycode pckbd_getkeycode
#define kbd_translate pckbd_translate
#define kbd_unexpected_up pckbd_unexpected_up
#define kbd_leds pckbd_leds
#define kbd_init_hw pckbd_init_hw
#define kbd_sysrq_xlate pckbd_sysrq_xlate
#define SYSRQ_KEY 0x54
/* resource allocation */
#define kbd_request_region() /* request_region(0x60, 16, "keyboard") */
#define kbd_request_irq(handler) /* request_irq(KEYBOARD_IRQ, handler, 0, "keyboard", NULL) */
/* How to access the keyboard macros on this platform. */
#define kbd_read_input() inb(KBD_DATA_REG)
#define kbd_read_status() inb(KBD_STATUS_REG)
#define kbd_write_output(val) outb(val, KBD_DATA_REG)
#define kbd_write_command(val) outb(val, KBD_CNTL_REG)
/* Some stoneage hardware needs delays after some operations. */
#define kbd_pause() do { } while(0)
/*
* Machine specific bits for the PS/2 driver
*/
#define AUX_IRQ 12
#define aux_request_irq(hand, dev_id) /* request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id) */
#define aux_free_irq(dev_id) /* free_irq(AUX_IRQ, dev_id) */
/*
* include/linux/pc_keyb.h
*
* PC Keyboard And Keyboard Controller
*
* (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
*/
/*
* Configuration Switches
*/
#undef KBD_REPORT_ERR /* Report keyboard errors */
#define KBD_REPORT_UNKN /* Report unknown scan codes */
#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */
#undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */
#undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */
#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */
#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */
#define KBD_TIMEOUT 1000 /* Timeout in ms for keyboard command acknowledge */
/*
* Internal variables of the driver
*/
extern unsigned char pckbd_read_mask;
extern unsigned char aux_device_present;
/*
* Keyboard Controller Registers on normal PCs.
*/
#define KBD_STATUS_REG 0x64 /* Status register (R) */
#define KBD_CNTL_REG 0x64 /* Controller command register (W) */
#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */
/*
* Keyboard Controller Commands
*/
#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */
#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */
#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */
#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */
#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */
#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */
#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */
#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */
#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */
#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if
initiated by the auxiliary device */
#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */
/*
* Keyboard Commands
*/
#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */
#define KBD_CMD_RESET 0xFF /* Reset */
/*
* Keyboard Replies
*/
#define KBD_REPLY_POR 0xAA /* Power on reset */
#define KBD_REPLY_ACK 0xFA /* Command ACK */
#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
/*
* Status Register Bits
*/
#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
#define KBD_STAT_SELFTEST 0x04 /* Self test successful */
#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */
#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */
#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */
#define KBD_STAT_PERR 0x80 /* Parity error */
#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF)
/*
* Controller Mode Register Bits
*/
#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */
#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */
#define KBD_MODE_SYS 0x04 /* The system flag (?) */
#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */
#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */
#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */
#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
#define KBD_MODE_RFU 0x80
/*
* Mouse Commands
*/
#define AUX_SET_RES 0xE8 /* Set resolution */
#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
#define AUX_GET_SCALE 0xE9 /* Get scaling factor */
#define AUX_SET_STREAM 0xEA /* Set stream mode */
#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
#define AUX_RESET 0xFF /* Reset aux device */
#define AUX_ACK 0xFA /* Command byte ACK. */
#define AUX_BUF_SIZE 2048 /* This might be better divisible by
three to make overruns stay in sync
but then the read function would need
a lock etc - ick */
#define mark_bh(x)
#endif /* _I386_KEYBOARD_H */

View File

@@ -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
/*-------------------------------------------------------------------------+
| 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
#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.
*/
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()
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;
int rc;
disable;
rc = ( kbd_first != kbd_last ) ? TRUE : FALSE;
enable;
return rc;
}
if (next != kbd_first)
{
kbd_last = next;
}
}
} /* _IBMPC_keyboard_isr */
/*-------------------------------------------------------------------------+
| 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];
rtems_task_wake_after( 10 );
}
c = kbd_buffer[ kbd_first ];
kbd_first = (kbd_first + 1) % KBD_BUF_SIZE;
return TRUE;
}
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;
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(;;)
unsigned int next;
kbd_buffer[ kbd_last ] = b;
next = (kbd_last == kbd_end) ? 0 : kbd_last + 1;
if( next != kbd_first )
{
if(_IBMPC_chrdy(&c))
{
return c;
kbd_last = next;
}
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 */
}

View File

@@ -0,0 +1,114 @@
/*
/////////////////////////////////////////////////////////////////////////////
// $Header$
//
// MODULE DESCRIPTION:
//
// This module was based on the Linux version kd.h
//
// by: Rosimildo da Silva: rdasilva@connecttel.com
//
// MODIFICATION/HISTORY:
// $Log$
//
/////////////////////////////////////////////////////////////////////////////
*/
#ifndef _LINUX_KD_H
#define _LINUX_KD_H
#include <sys/types.h>
/* 0x4B is 'K', to avoid collision with termios and vt */
#define KIOCSOUND 0x4B2F /* start sound generation (0 for off) */
#define KDMKTONE 0x4B30 /* generate tone */
#define KDGETLED 0x4B31 /* return current led state */
#define KDSETLED 0x4B32 /* set led state [lights, not flags] */
#define LED_SCR 0x01 /* scroll lock led */
#define LED_CAP 0x04 /* caps lock led */
#define LED_NUM 0x02 /* num lock led */
#define KDGKBTYPE 0x4B33 /* get keyboard type */
#define KB_84 0x01
#define KB_101 0x02 /* this is what we always answer */
#define KB_OTHER 0x03
#define KDSETMODE 0x4B3A /* set text/graphics mode */
#define KD_TEXT 0x00
#define KD_GRAPHICS 0x01
#define KD_TEXT0 0x02 /* obsolete */
#define KD_TEXT1 0x03 /* obsolete */
#define KDGETMODE 0x4B3B /* get current mode */
#define K_RAW 0x00
#define K_XLATE 0x01
#define K_MEDIUMRAW 0x02
#define K_UNICODE 0x03
#define KDGKBMODE 0x4B44 /* gets current keyboard mode */
#define KDSKBMODE 0x4B45 /* sets current keyboard mode */
#define K_METABIT 0x03
#define K_ESCPREFIX 0x04
#define KDGKBMETA 0x4B62 /* gets meta key handling mode */
#define KDSKBMETA 0x4B63 /* sets meta key handling mode */
#define K_SCROLLLOCK 0x01
#define K_CAPSLOCK 0x02
#define K_NUMLOCK 0x04
#define KDGKBLED 0x4B64 /* get led flags (not lights) */
#define KDSKBLED 0x4B65 /* set led flags (not lights) */
struct kbentry {
unsigned char kb_table;
unsigned char kb_index;
unsigned short kb_value;
};
#define K_NORMTAB 0x00
#define K_SHIFTTAB 0x01
#define K_ALTTAB 0x02
#define K_ALTSHIFTTAB 0x03
#define KDGKBENT 0x4B46 /* gets one entry in translation table */
#define KDSKBENT 0x4B47 /* sets one entry in translation table */
struct kbsentry {
unsigned char kb_func;
unsigned char kb_string[512];
};
struct kbdiacr {
unsigned char diacr, base, result;
};
struct kbdiacrs {
unsigned int kb_cnt; /* number of entries in following array */
struct kbdiacr kbdiacr[256]; /* MAX_DIACR from keyboard.h */
};
#define KDGKBDIACR 0x4B4A /* read kernel accent table */
#define KDSKBDIACR 0x4B4B /* write kernel accent table */
struct kbkeycode {
unsigned int scancode, keycode;
};
#define KDGETKEYCODE 0x4B4C /* read kernel keycode table entry */
#define KDSETKEYCODE 0x4B4D /* write kernel keycode table entry */
#define KDSIGACCEPT 0x4B4E /* accept kbd generated signals */
#define KDGHWCLK 0x4B50 /* get hardware clock */
#define KDSHWCLK 0x4B51 /* set hardware clock */
struct kbd_repeat {
int delay; /* in msec; <= 0: don't change */
int rate; /* in msec; <= 0: don't change */
};
#define KDKBDREP 0x4B52 /* set keyboard delay/repeat rate;
* actually used values are returned */
/* note: 0x4B00-0x4B4E all have had a value at some time;
don't reuse for the time being */
/* note: 0x4B60-0x4B6D, 0x4B70-0x4B72 used above */
#endif /* _LINUX_KD_H */

View File

@@ -0,0 +1,928 @@
/*
* linux/drivers/char/keyboard.c
*
* Written for linux by Johan Myreen as a translation from
* the assembly version by Linus (with diacriticals added)
*
* Some additional features added by Christoph Niemann (ChN), March 1993
*
* Loadable keymaps by Risto Kankkunen, May 1993
*
* Diacriticals redone & other small changes, aeb@cwi.nl, June 1993
* Added decr/incr_console, dynamic keymaps, Unicode support,
* dynamic function/string keys, led setting, Sept 1994
* `Sticky' modifier keys, 951006.
*
* 11-11-96: SAK should now work in the raw mode (Martin Mares)
*
* Modified to provide 'generic' keyboard support by Hamish Macdonald
* Merge with the m68k keyboard driver and split-off of the PC low-level
* parts by Geert Uytterhoeven, May 1997
*
* 27-05-97: Added support for the Magic SysRq Key (Martin Mares)
* 30-07-98: Dead keys redone, aeb@cwi.nl.
* -------------------------------------------------------------------
* End of Linux - Copyright notes...
*
* Ported to RTEMS to provide the basic fuctionality to the console driver.
* by: Rosimildo da Silva: rdasilva@connecttel.com
*
*/
#include <sys/types.h>
#include <rtems/keyboard.h>
#include "i386kbd.h"
#include <rtems/kd.h>
#include <bsp.h>
#define SIZE(x) (sizeof(x)/sizeof((x)[0]))
#ifndef KBD_DEFMODE
#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
#endif
#ifndef KBD_DEFLEDS
/*
* Some laptops take the 789uiojklm,. keys as number pad when NumLock
* is on. This seems a good reason to start with NumLock off.
*/
#define KBD_DEFLEDS 0
#endif
#ifndef KBD_DEFLOCK
#define KBD_DEFLOCK 0
#endif
extern void add_to_queue( unsigned short );
extern void rtemsReboot( void );
int set_bit(int nr, unsigned long * addr)
{
int mask, retval;
addr += nr >> 5;
mask = 1 << (nr & 0x1f);
cli();
retval = (mask & *addr) != 0;
*addr |= mask;
sti();
return retval;
}
int clear_bit(int nr, unsigned long * addr)
{
int mask, retval;
addr += nr >> 5;
mask = 1 << (nr & 0x1f);
cli();
retval = (mask & *addr) != 0;
*addr &= ~mask;
sti();
return retval;
}
int test_bit(int nr, unsigned long * addr)
{
int mask;
addr += nr >> 5;
mask = 1 << (nr & 0x1f);
return ((mask & *addr) != 0);
}
#define test_and_set_bit(x,y) set_bit(x,y)
#define test_and_clear_bit(x,y) clear_bit(x,y)
/*
* global state includes the following, and various static variables
* in this module: prev_scancode, shift_state, diacr, npadch, dead_key_next.
* (last_console is now a global variable)
*/
#define BITS_PER_LONG 32
/* shift state counters.. */
static unsigned char k_down[NR_SHIFT] = {0, };
/* keyboard key bitmap */
static unsigned long key_down[256/BITS_PER_LONG] = { 0, };
static int dead_key_next = 0;
/*
* In order to retrieve the shift_state (for the mouse server), either
* the variable must be global, or a new procedure must be created to
* return the value. I chose the former way.
*/
int shift_state = 0;
static int npadch = -1; /* -1 or number assembled on pad */
static unsigned char diacr = 0;
static char rep = 0; /* flag telling character repeat */
/* default console for RTEMS */
static int fg_console = 0;
struct kbd_struct kbd_table[MAX_NR_CONSOLES];
static struct kbd_struct * kbd = kbd_table;
void compute_shiftstate(void);
typedef void (*k_hand)(unsigned char value, char up_flag);
typedef void (k_handfn)(unsigned char value, char up_flag);
static k_handfn
do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2,
do_ignore;
static k_hand key_handler[16] = {
do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_dead2,
do_ignore, do_ignore
};
/* Key types processed even in raw modes */
#define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT))
typedef void (*void_fnp)(void);
typedef void (void_fn)(void);
static void show_mem(void)
{
}
static void show_state(void)
{
}
static void_fn do_null, enter, show_ptregs, send_intr, lastcons, caps_toggle,
num, hold, scroll_forw, scroll_back, boot_it, caps_on, compose,
SAK, decr_console, incr_console, spawn_console, bare_num;
static void_fnp spec_fn_table[] = {
do_null, enter, show_ptregs, show_mem,
show_state, send_intr, lastcons, caps_toggle,
num, hold, scroll_forw, scroll_back,
boot_it, caps_on, compose, SAK,
decr_console, incr_console, spawn_console, bare_num
};
#define SPECIALS_ALLOWED_IN_RAW_MODE (1 << KVAL(K_SAK))
/* maximum values each key_handler can handle */
const int max_vals[] = {
255, SIZE(func_table) - 1, SIZE(spec_fn_table) - 1, NR_PAD - 1,
NR_DEAD - 1, 255, 3, NR_SHIFT - 1,
255, NR_ASCII - 1, NR_LOCK - 1, 255,
NR_LOCK - 1, 255
};
const int NR_TYPES = SIZE(max_vals);
/* N.B. drivers/macintosh/mac_keyb.c needs to call put_queue */
static void put_queue(int);
static unsigned char handle_diacr(unsigned char);
#ifdef CONFIG_MAGIC_SYSRQ
static int sysrq_pressed;
#endif
/*
* Many other routines do put_queue, but I think either
* they produce ASCII, or they produce some user-assigned
* string, and in both cases we might assume that it is
* in utf-8 already.
*/
void to_utf8(ushort c) {
if (c < 0x80)
put_queue(c); /* 0******* */
else if (c < 0x800) {
put_queue(0xc0 | (c >> 6)); /* 110***** 10****** */
put_queue(0x80 | (c & 0x3f));
} else {
put_queue(0xe0 | (c >> 12)); /* 1110**** 10****** 10****** */
put_queue(0x80 | ((c >> 6) & 0x3f));
put_queue(0x80 | (c & 0x3f));
}
/* UTF-8 is defined for words of up to 31 bits,
but we need only 16 bits here */
}
/*
* Translation of escaped scancodes to keycodes.
* This is now user-settable (for machines were it makes sense).
*/
int setkeycode(unsigned int scancode, unsigned int keycode)
{
return kbd_setkeycode(scancode, keycode);
}
int getkeycode(unsigned int scancode)
{
return kbd_getkeycode(scancode);
}
void handle_scancode(unsigned char scancode, int down)
{
unsigned char keycode;
char up_flag = down ? 0 : 0200;
char raw_mode;
mark_bh(CONSOLE_BH);
#if 0
tty = ttytab? ttytab[fg_console]: NULL;
if (tty && (!tty->driver_data)) {
/*
* We touch the tty structure via the the ttytab array
* without knowing whether or not tty is open, which
* is inherently dangerous. We currently rely on that
* fact that console_open sets tty->driver_data when
* it opens it, and clears it when it closes it.
*/
tty = NULL;
}
#endif
kbd = kbd_table + fg_console;
if ((raw_mode = (kbd->kbdmode == VC_RAW))) {
put_queue(scancode | up_flag);
/* we do not return yet, because we want to maintain
the key_down array, so that we have the correct
values when finishing RAW mode or when changing VT's */
}
/*
* Convert scancode to keycode
*/
if (!kbd_translate(scancode, &keycode, raw_mode))
return;
/*
* At this point the variable `keycode' contains the keycode.
* Note: the keycode must not be 0 (++Geert: on m68k 0 is valid).
* We keep track of the up/down status of the key, and
* return the keycode if in MEDIUMRAW mode.
*/
if (up_flag) {
rep = 0;
if(!test_and_clear_bit(keycode, key_down))
up_flag = kbd_unexpected_up(keycode);
} else
rep = test_and_set_bit(keycode, key_down);
#ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */
if (keycode == SYSRQ_KEY) {
sysrq_pressed = !up_flag;
return;
} else if (sysrq_pressed) {
if (!up_flag && sysrq_enabled)
handle_sysrq(kbd_sysrq_xlate[keycode], kbd_pt_regs, kbd, tty);
return;
}
#endif
if (kbd->kbdmode == VC_MEDIUMRAW) {
/* soon keycodes will require more than one byte */
put_queue(keycode + up_flag);
raw_mode = 1; /* Most key classes will be ignored */
}
/*
* Small change in philosophy: earlier we defined repetition by
* rep = keycode == prev_keycode;
* prev_keycode = keycode;
* but now by the fact that the depressed key was down already.
* Does this ever make a difference? Yes.
*/
/*
* Repeat a key only if the input buffers are empty or the
* characters get echoed locally. This makes key repeat usable
* with slow applications and under heavy loads.
*/
if (!rep || vc_kbd_mode(kbd,VC_REPEAT) ) {
/*
|| (vc_kbd_mode(kbd,VC_REPEAT) && tty &&
(L_ECHO(tty) || (tty->driver.chars_in_buffer(tty) == 0)))) {
*/
u_short keysym;
u_char type;
/* the XOR below used to be an OR */
int shift_final = shift_state ^ kbd->lockstate ^ kbd->slockstate;
ushort *key_map = key_maps[shift_final];
if (key_map != NULL) {
keysym = key_map[keycode];
type = KTYP(keysym);
if (type >= 0xf0) {
type -= 0xf0;
if (raw_mode && ! (TYPES_ALLOWED_IN_RAW_MODE & (1 << type)))
return;
if (type == KT_LETTER) {
type = KT_LATIN;
if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
key_map = key_maps[shift_final ^ (1<<KG_SHIFT)];
if (key_map)
keysym = key_map[keycode];
}
}
(*key_handler[type])(keysym & 0xff, up_flag);
if (type != KT_SLOCK)
kbd->slockstate = 0;
} else {
/* maybe only if (kbd->kbdmode == VC_UNICODE) ? */
if (!up_flag && !raw_mode)
to_utf8(keysym);
}
} else {
/* maybe beep? */
/* we have at least to update shift_state */
#if 1 /* how? two almost equivalent choices follow */
compute_shiftstate();
#else
keysym = U(plain_map[keycode]);
type = KTYP(keysym);
if (type == KT_SHIFT)
(*key_handler[type])(keysym & 0xff, up_flag);
#endif
}
}
}
static void ( *driver_input_handler_kbd )( void *, unsigned short, unsigned long ) = 0;
/*
*/
void kbd_set_driver_handler( void ( *handler )( void *, unsigned short, unsigned long ) )
{
driver_input_handler_kbd = handler;
}
static void put_queue(int ch)
{
if( driver_input_handler_kbd )
{
driver_input_handler_kbd( ( void *)kbd, (unsigned short)ch, 0 );
}
else
{
add_to_queue( ch );
}
}
static void puts_queue(char *cp)
{
while (*cp) {
put_queue( *cp );
cp++;
}
}
static void applkey(int key, char mode)
{
static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
buf[1] = (mode ? 'O' : '[');
buf[2] = key;
puts_queue(buf);
}
static void enter(void)
{
if (diacr) {
put_queue(diacr);
diacr = 0;
}
put_queue(13);
if (vc_kbd_mode(kbd,VC_CRLF))
put_queue(10);
}
static void caps_toggle(void)
{
if (rep)
return;
chg_vc_kbd_led(kbd, VC_CAPSLOCK);
}
static void caps_on(void)
{
if (rep)
return;
set_vc_kbd_led(kbd, VC_CAPSLOCK);
}
static void show_ptregs(void)
{
}
static void hold(void)
{
if (rep )
return;
chg_vc_kbd_led(kbd, VC_SCROLLOCK );
}
static void num(void)
{
if (vc_kbd_mode(kbd,VC_APPLIC))
applkey('P', 1);
else
bare_num();
}
/*
* Bind this to Shift-NumLock if you work in application keypad mode
* but want to be able to change the NumLock flag.
* Bind this to NumLock if you prefer that the NumLock key always
* changes the NumLock flag.
*/
static void bare_num(void)
{
if (!rep)
chg_vc_kbd_led(kbd,VC_NUMLOCK);
}
static void lastcons(void)
{
}
static void decr_console(void)
{
}
static void incr_console(void)
{
}
static void send_intr(void)
{
}
static void scroll_forw(void)
{
}
static void scroll_back(void)
{
}
static void boot_it(void)
{
printk( "boot_it() " );
rtemsReboot();
}
static void compose(void)
{
dead_key_next = 1;
}
int spawnpid, spawnsig;
static void spawn_console(void)
{
}
static void SAK(void)
{
}
static void do_ignore(unsigned char value, char up_flag)
{
}
static void do_null()
{
compute_shiftstate();
}
static void do_spec(unsigned char value, char up_flag)
{
if (up_flag)
return;
if (value >= SIZE(spec_fn_table))
return;
if ((kbd->kbdmode == VC_RAW || kbd->kbdmode == VC_MEDIUMRAW) &&
!(SPECIALS_ALLOWED_IN_RAW_MODE & (1 << value)))
return;
spec_fn_table[value]();
}
static void do_lowercase(unsigned char value, char up_flag)
{
}
static void do_self(unsigned char value, char up_flag)
{
if (up_flag)
return; /* no action, if this is a key release */
if (diacr)
value = handle_diacr(value);
if (dead_key_next) {
dead_key_next = 0;
diacr = value;
return;
}
put_queue(value);
}
#define A_GRAVE '`'
#define A_ACUTE '\''
#define A_CFLEX '^'
#define A_TILDE '~'
#define A_DIAER '"'
#define A_CEDIL ','
static unsigned char ret_diacr[NR_DEAD] =
{A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER, A_CEDIL };
/* Obsolete - for backwards compatibility only */
static void do_dead(unsigned char value, char up_flag)
{
value = ret_diacr[value];
printk( " do_dead( %X ) ", value );
do_dead2(value,up_flag);
}
/*
* Handle dead key. Note that we now may have several
* dead keys modifying the same character. Very useful
* for Vietnamese.
*/
static void do_dead2(unsigned char value, char up_flag)
{
if (up_flag)
return;
diacr = (diacr ? handle_diacr(value) : value);
}
/*
* We have a combining character DIACR here, followed by the character CH.
* If the combination occurs in the table, return the corresponding value.
* Otherwise, if CH is a space or equals DIACR, return DIACR.
* Otherwise, conclude that DIACR was not combining after all,
* queue it and return CH.
*/
unsigned char handle_diacr(unsigned char ch)
{
int d = diacr;
int i;
diacr = 0;
for (i = 0; i < accent_table_size; i++) {
if (accent_table[i].diacr == d && accent_table[i].base == ch)
return accent_table[i].result;
}
if (ch == ' ' || ch == d)
return d;
put_queue(d);
return ch;
}
static void do_cons(unsigned char value, char up_flag)
{
if (up_flag)
return;
}
static void do_fn(unsigned char value, char up_flag)
{
if (up_flag)
return;
if (value < SIZE(func_table)) {
if (func_table[value])
puts_queue(func_table[value]);
} else
printk( "do_fn called with value=%d\n", value);
}
static void do_pad(unsigned char value, char up_flag)
{
static const char *pad_chars = "0123456789+-*/\015,.?()";
static const char *app_map = "pqrstuvwxylSRQMnnmPQ";
if (up_flag)
return; /* no action, if this is a key release */
/* kludge... shift forces cursor/number keys */
if (vc_kbd_mode(kbd,VC_APPLIC) && !k_down[KG_SHIFT]) {
applkey(app_map[value], 1);
return;
}
if (!vc_kbd_led(kbd,VC_NUMLOCK))
switch (value) {
case KVAL(K_PCOMMA):
case KVAL(K_PDOT):
do_fn(KVAL(K_REMOVE), 0);
return;
case KVAL(K_P0):
do_fn(KVAL(K_INSERT), 0);
return;
case KVAL(K_P1):
do_fn(KVAL(K_SELECT), 0);
return;
case KVAL(K_P2):
do_cur(KVAL(K_DOWN), 0);
return;
case KVAL(K_P3):
do_fn(KVAL(K_PGDN), 0);
return;
case KVAL(K_P4):
do_cur(KVAL(K_LEFT), 0);
return;
case KVAL(K_P6):
do_cur(KVAL(K_RIGHT), 0);
return;
case KVAL(K_P7):
do_fn(KVAL(K_FIND), 0);
return;
case KVAL(K_P8):
do_cur(KVAL(K_UP), 0);
return;
case KVAL(K_P9):
do_fn(KVAL(K_PGUP), 0);
return;
case KVAL(K_P5):
applkey('G', vc_kbd_mode(kbd, VC_APPLIC));
return;
}
put_queue(pad_chars[value]);
if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
put_queue(10);
}
static void do_cur(unsigned char value, char up_flag)
{
static const char *cur_chars = "BDCA";
if (up_flag)
return;
applkey(cur_chars[value], vc_kbd_mode(kbd,VC_CKMODE));
}
static void do_shift(unsigned char value, char up_flag)
{
int old_state = shift_state;
if (rep)
return;
/* Mimic typewriter:
a CapsShift key acts like Shift but undoes CapsLock */
if (value == KVAL(K_CAPSSHIFT)) {
value = KVAL(K_SHIFT);
if (!up_flag)
clr_vc_kbd_led(kbd, VC_CAPSLOCK);
}
if (up_flag) {
/* handle the case that two shift or control
keys are depressed simultaneously */
if (k_down[value])
k_down[value]--;
} else
k_down[value]++;
if (k_down[value])
shift_state |= (1 << value);
else
shift_state &= ~ (1 << value);
/* kludge */
if (up_flag && shift_state != old_state && npadch != -1) {
if (kbd->kbdmode == VC_UNICODE)
to_utf8(npadch & 0xffff);
else
put_queue(npadch & 0xff);
npadch = -1;
}
}
/* called after returning from RAW mode or when changing consoles -
recompute k_down[] and shift_state from key_down[] */
/* maybe called when keymap is undefined, so that shiftkey release is seen */
void compute_shiftstate(void)
{
int i, j, k, sym, val;
shift_state = 0;
for(i=0; i < SIZE(k_down); i++)
k_down[i] = 0;
for(i=0; i < SIZE(key_down); i++)
if(key_down[i]) { /* skip this word if not a single bit on */
k = i*BITS_PER_LONG;
for(j=0; j<BITS_PER_LONG; j++,k++)
if(test_bit(k, key_down)) {
sym = U(plain_map[k]);
if(KTYP(sym) == KT_SHIFT) {
val = KVAL(sym);
if (val == KVAL(K_CAPSSHIFT))
val = KVAL(K_SHIFT);
k_down[val]++;
shift_state |= (1<<val);
}
}
}
}
static void do_meta(unsigned char value, char up_flag)
{
if (up_flag)
return;
if (vc_kbd_mode(kbd, VC_META)) {
put_queue('\033');
put_queue(value);
} else
put_queue(value | 0x80);
}
static void do_ascii(unsigned char value, char up_flag)
{
int base;
if (up_flag)
return;
if (value < 10) /* decimal input of code, while Alt depressed */
base = 10;
else { /* hexadecimal input of code, while AltGr depressed */
value -= 10;
base = 16;
}
if (npadch == -1)
npadch = value;
else
npadch = npadch * base + value;
}
static void do_lock(unsigned char value, char up_flag)
{
if (up_flag || rep)
return;
chg_vc_kbd_lock(kbd, value);
}
static void do_slock(unsigned char value, char up_flag)
{
if (up_flag || rep)
return;
chg_vc_kbd_slock(kbd, value);
}
/*
* The leds display either (i) the status of NumLock, CapsLock, ScrollLock,
* or (ii) whatever pattern of lights people want to show using KDSETLED,
* or (iii) specified bits of specified words in kernel memory.
*/
static unsigned char ledstate = 0xff; /* undefined */
static unsigned char ledioctl;
unsigned char getledstate(void) {
return ledstate;
}
void setledstate(struct kbd_struct *kbd, unsigned int led) {
if (!(led & ~7)) {
ledioctl = led;
kbd->ledmode = LED_SHOW_IOCTL;
} else
;
kbd->ledmode = LED_SHOW_FLAGS;
set_leds();
}
static struct ledptr {
unsigned int *addr;
unsigned int mask;
unsigned char valid:1;
} ledptrs[3];
void register_leds(int console, unsigned int led,
unsigned int *addr, unsigned int mask) {
struct kbd_struct *kbd = kbd_table + console;
if (led < 3) {
ledptrs[led].addr = addr;
ledptrs[led].mask = mask;
ledptrs[led].valid = 1;
kbd->ledmode = LED_SHOW_MEM;
} else
kbd->ledmode = LED_SHOW_FLAGS;
}
static inline unsigned char getleds(void){
struct kbd_struct *kbd = kbd_table + fg_console;
unsigned char leds;
if (kbd->ledmode == LED_SHOW_IOCTL)
return ledioctl;
leds = kbd->ledflagstate;
if (kbd->ledmode == LED_SHOW_MEM) {
if (ledptrs[0].valid) {
if (*ledptrs[0].addr & ledptrs[0].mask)
leds |= 1;
else
leds &= ~1;
}
if (ledptrs[1].valid) {
if (*ledptrs[1].addr & ledptrs[1].mask)
leds |= 2;
else
leds &= ~2;
}
if (ledptrs[2].valid) {
if (*ledptrs[2].addr & ledptrs[2].mask)
leds |= 4;
else
leds &= ~4;
}
}
return leds;
}
/*
* This routine is the bottom half of the keyboard interrupt
* routine, and runs with all interrupts enabled. It does
* console changing, led setting and copy_to_cooked, which can
* take a reasonably long time.
*
* Aside from timing (which isn't really that important for
* keyboard interrupts as they happen often), using the software
* interrupt routines for this thing allows us to easily mask
* this when we don't want any of the above to happen. Not yet
* used, but this allows for easy and efficient race-condition
* prevention later on.
*/
static void kbd_bh(void)
{
unsigned char leds = getleds();
if (leds != ledstate) {
ledstate = leds;
kbd_leds(leds);
}
}
void set_leds(void)
{
kbd_bh();
}
int kbd_init(void)
{
int i;
struct kbd_struct kbd0;
kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS;
kbd0.ledmode = LED_SHOW_MEM;
kbd0.lockstate = KBD_DEFLOCK;
kbd0.slockstate = 0;
kbd0.modeflags = KBD_DEFMODE;
kbd0.kbdmode = VC_XLATE;
for (i = 0 ; i < MAX_NR_CONSOLES ; i++)
kbd_table[i] = kbd0;
kbd_init_hw();
mark_bh(KEYBOARD_BH);
return 0;
}

View File

@@ -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

View File

@@ -0,0 +1,400 @@
/*
* Copyright (c) 1999 Greg Haerr <greg@censoft.com>
* Portions Copyright (c) 1991 David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
* UNIX Serial Port Mouse Driver
*
* This driver opens a serial port directly, and interprets serial data.
* Microsoft, PC, Logitech and PS/2 mice are supported.
* The PS/2 mouse is only supported if the OS runs the mouse
* byte codes through the serial port.
*
* The following environment variables control the mouse type expected
* and the serial port to open.
*
* Environment Var Default Allowed
* MOUSE_TYPE pc ms, pc, logi, ps2
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <rtems.h>
#include <bsp.h>
#include "keyboard.h"
#include "mouse_parser.h"
#include "serial_mouse.h"
/* NOTE NOTE NOTE NOTE:
Select here the mouse type !!!!!
*/
#ifndef MOUSE_TYPE
#define MOUSE_TYPE "ms" /* default mouse type "ms","pc","ps2" */
#endif
/* states for the mouse*/
#define IDLE 0 /* start of byte sequence */
#define XSET 1 /* setting x delta */
#define YSET 2 /* setting y delta */
#define XADD 3 /* adjusting x delta */
#define YADD 4 /* adjusting y delta */
/* values in the bytes returned by the mouse for the buttons*/
#define PC_LEFT_BUTTON 4
#define PC_MIDDLE_BUTTON 2
#define PC_RIGHT_BUTTON 1
#define MS_LEFT_BUTTON 2
#define MS_RIGHT_BUTTON 1
#define PS2_CTRL_BYTE 0x08
#define PS2_LEFT_BUTTON 1
#define PS2_RIGHT_BUTTON 2
/* Bit fields in the bytes sent by the mouse.*/
#define TOP_FIVE_BITS 0xf8
#define BOTTOM_THREE_BITS 0x07
#define TOP_BIT 0x80
#define SIXTH_BIT 0x40
#define BOTTOM_TWO_BITS 0x03
#define THIRD_FOURTH_BITS 0x0c
#define BOTTOM_SIX_BITS 0x3f
/* local data*/
static int state; /* IDLE, XSET, ... */
static BUTTON buttons; /* current mouse buttons pressed*/
static BUTTON availbuttons; /* which buttons are available */
static COORD xd; /* change in x */
static COORD yd; /* change in y */
static int left; /* because the button values change */
static int middle; /* between mice, the buttons are */
static int right; /* redefined */
static int (*parse)( int ); /* parse routine */
/* local routines*/
static int ParsePC(int); /* routine to interpret PC mouse */
static int ParseMS(int); /* routine to interpret MS mouse */
static int ParsePS2(int); /* routine to interpret PS/2 mouse */
extern void uart_set_driver_handler( int port, void ( *handler )( void *, char *, int ) );
extern void kbd_set_driver_handler( void ( *handler )( void *, unsigned short, unsigned long ) );
extern void ps2_set_driver_handler( int port, void ( *handler )( void *, char *, int ) );
/*
* Open up the mouse device.
* Returns the fd if successful, or negative if unsuccessful.
*/
int MOU_Init()
{
char *type;
/* get mouse type and port*/
type = MOUSE_TYPE;
/* set button bits and parse procedure*/
if(!strcmp(type, "pc") || !strcmp(type, "logi")) {
/* pc or logitech mouse*/
left = PC_LEFT_BUTTON;
middle = PC_MIDDLE_BUTTON;
right = PC_RIGHT_BUTTON;
parse = ParsePC;
} else if (strcmp(type, "ms") == 0) {
/* microsoft mouse*/
left = MS_LEFT_BUTTON;
right = MS_RIGHT_BUTTON;
middle = 0;
parse = ParseMS;
} else if (strcmp(type, "ps2") == 0) {
/* PS/2 mouse*/
left = PS2_LEFT_BUTTON;
right = PS2_RIGHT_BUTTON;
middle = 0;
parse = ParsePS2;
} else
return -1;
printk("Device: /dev/mouse -- mouse type is: %s\n", MOUSE_TYPE );
/* initialize data*/
availbuttons = left | middle | right;
state = IDLE;
buttons = 0;
xd = 0;
yd = 0;
return 0;
}
/*
* Attempt to read bytes from the mouse and interpret them.
* Returns -1 on error, 0 if either no bytes were read or not enough
* was read for a complete state, or 1 if the new state was read.
* When a new state is read, the current buttons and x and y deltas
* are returned. This routine does not block.
*/
int MOU_Data( int ch, COORD *dx, COORD *dy, COORD *dz, BUTTON *bptr)
{
int b;
/*
* Loop over all the bytes read in the buffer, parsing them.
* When a complete state has been read, return the results,
* leaving further bytes in the buffer for later calls.
*/
if( (*parse)( ch ) )
{
*dx = xd;
*dy = yd;
*dz = 0;
b = 0;
if(buttons & left)
b |= LBUTTON;
if(buttons & right)
b |= RBUTTON;
if(buttons & middle)
b |= MBUTTON;
*bptr = b;
return 1;
}
return 0;
}
/*
* Input routine for PC mouse.
* Returns nonzero when a new mouse state has been completed.
*/
static int ParsePC(int byte)
{
int sign; /* sign of movement */
switch (state) {
case IDLE:
if ((byte & TOP_FIVE_BITS) == TOP_BIT) {
buttons = ~byte & BOTTOM_THREE_BITS;
state = XSET;
}
break;
case XSET:
sign = 1;
if (byte > 127) {
byte = 256 - byte;
sign = -1;
}
xd = byte * sign;
state = YSET;
break;
case YSET:
sign = 1;
if (byte > 127) {
byte = 256 - byte;
sign = -1;
}
yd = -byte * sign;
state = XADD;
break;
case XADD:
sign = 1;
if (byte > 127) {
byte = 256 - byte;
sign = -1;
}
xd += byte * sign;
state = YADD;
break;
case YADD:
sign = 1;
if (byte > 127) {
byte = 256 - byte;
sign = -1;
}
yd -= byte * sign;
state = IDLE;
return 1;
}
return 0;
}
/*
* Input routine for Microsoft mouse.
* Returns nonzero when a new mouse state has been completed.
*/
static int ParseMS(int byte)
{
switch (state) {
case IDLE:
if (byte & SIXTH_BIT) {
buttons = (byte >> 4) & BOTTOM_TWO_BITS;
yd = ((byte & THIRD_FOURTH_BITS) << 4);
xd = ((byte & BOTTOM_TWO_BITS) << 6);
state = XADD;
}
break;
case XADD:
xd |= (byte & BOTTOM_SIX_BITS);
state = YADD;
break;
case YADD:
yd |= (byte & BOTTOM_SIX_BITS);
state = IDLE;
if (xd > 127)
xd -= 256;
if (yd > 127)
yd -= 256;
return 1;
}
return 0;
}
/*
* Input routine for PS/2 mouse.
* Returns nonzero when a new mouse state has been completed.
*/
static int ParsePS2(int byte)
{
switch (state) {
case IDLE:
if (byte & PS2_CTRL_BYTE) {
buttons = byte &
(PS2_LEFT_BUTTON|PS2_RIGHT_BUTTON);
state = XSET;
}
break;
case XSET:
if(byte > 127)
byte -= 256;
xd = byte;
state = YSET;
break;
case YSET:
if(byte > 127)
byte -= 256;
yd = -byte;
state = IDLE;
return 1;
}
return 0;
}
static rtems_id queue_id = 0;
/* generic keyboard parser */
static void mouse_parser( void *ptr, char *buffer, int size )
{
COORD dx;
COORD dy;
COORD dz;
BUTTON bptr;
while( size-- )
{
if( MOU_Data( *buffer++, &dx, &dy, &dz, &bptr ) )
{
struct MW_UID_MESSAGE m;
m.type = MV_UID_REL_POS;
/* buttons definitons have been selected to match */
m.m.pos.btns = bptr;
m.m.pos.x = dx;
m.m.pos.y = dy;
m.m.pos.z = dz;
/* printk( "Mouse: msg: dx=%d, dy=%d, btn=%X\n", dx, dy, bptr ); */
rtems_message_queue_send( queue_id, ( void * )&m, sizeof( struct MW_UID_MESSAGE ) );
}
}
}
/* enable the mouse to add messages to the queue */
void register_mou_msg_queue( char * q_name, int port )
{
rtems_name queue_name;
rtems_status_code status;
queue_name = rtems_build_name( q_name[0],
q_name[1],
q_name[2],
q_name[3] );
status = rtems_message_queue_ident( queue_name, RTEMS_LOCAL, &queue_id );
if( status != RTEMS_SUCCESSFUL )
{
printk( "UID_Queue: error open queue: %d\n", status );
return;
}
MOU_Init();
if( port == -1 )
{
/* we know the mouse type in this case, let's initialize everything */
left = PS2_LEFT_BUTTON;
right = PS2_RIGHT_BUTTON;
middle = 0;
parse = ParsePS2;
ps2_set_driver_handler( port, mouse_parser );
}
else
{
uart_set_driver_handler( port, mouse_parser );
}
}
/* stop the mouse from adding messages to the queue */
void unregister_mou_msg_queue( int port )
{
if( port == -1 )
{
ps2_set_driver_handler( port, NULL );
}
else
{
uart_set_driver_handler( port, NULL );
}
}
/* adds a kbd message to the queue */
static void kbd_parser( void *ptr, unsigned short keycode, unsigned long mods )
{
struct MW_UID_MESSAGE m;
struct kbd_struct * kbd = ( struct kbd_struct *)ptr;
m.type = MV_UID_KBD;
m.m.kbd.code = keycode;
m.m.kbd.modifiers = kbd->ledflagstate;
m.m.kbd.mode = kbd->kbdmode;
/* printk( "kbd: msg: keycode=%X, mod=%X\n", keycode, mods ); */
rtems_message_queue_send( queue_id, ( void * )&m,
sizeof( struct MW_UID_MESSAGE ) );
}
void register_kbd_msg_queue( char *q_name, int port )
{
rtems_name queue_name;
rtems_status_code status;
queue_name = rtems_build_name( q_name[0],
q_name[1],
q_name[2],
q_name[3] );
status = rtems_message_queue_ident( queue_name, RTEMS_LOCAL, &queue_id );
if( status != RTEMS_SUCCESSFUL )
{
printk( "UID_Queue: error open queue: %d\n", status );
return;
}
kbd_set_driver_handler( kbd_parser );
}
void unregister_kbd_msg_queue( int port )
{
kbd_set_driver_handler( NULL );
}

View File

@@ -0,0 +1,36 @@
#ifndef __mouse_parser_h__
#define __mouse_parser_h__
#include <rtems/mw_uid.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Use the same definitions as the user interface */
#define RBUTTON MV_BUTTON_RIGHT
#define MBUTTON MV_BUTTON_CENTER
#define LBUTTON MV_BUTTON_LEFT
typedef int COORD; /* device coordinates*/
typedef unsigned int BUTTON; /* mouse button mask*/
/* local routines */
int MOU_Init();
int MOU_Data( int ch, COORD *dx, COORD *dy, COORD *dz, BUTTON *bptr );
/* Mouse Interface */
void register_mou_msg_queue( char * qname, int port );
void unregister_mou_msg_queue( int port );
/* KBD Interface */
void register_kbd_msg_queue( char *qname, int port );
void unregister_kbd_msg_queue( int port );
#ifdef __cplusplus
}
#endif
#endif /* __mouse_parser_h__ */

View File

@@ -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;
}

View File

@@ -0,0 +1,648 @@
/*
* linux/drivers/char/pc_keyb.c
*
* Separation of the PC low-level part by Geert Uytterhoeven, May 1997
* See keyboard.c for the whole history.
*
* Major cleanup by Martin Mares, May 1997
*
* Combined the keyboard and PS/2 mouse handling into one file,
* because they share the same hardware.
* Johan Myreen <jem@iki.fi> 1998-10-08.
*
* Code fixes to handle mouse ACKs properly.
* C. Scott Ananian <cananian@alumni.princeton.edu> 1999-01-29.
*
* Ported to RTEMS by Rosimildo da Silva
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <bsp.h>
#include "i386kbd.h"
/* keyboard.c */
extern void handle_scancode(unsigned char scancode, int down);
static unsigned char handle_kbd_event(void);
static void kbd_write_command_w(int data);
static void kbd_write_output_w(int data);
/* Some configuration switches are present in the include file... */
/* Simple translation table for the SysRq keys */
#ifdef CONFIG_MAGIC_SYSRQ
unsigned char pckbd_sysrq_xlate[128] =
"\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
"qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
"dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
"bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
"\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
"230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
"\r\000/"; /* 0x60 - 0x6f */
#endif
/* used only by send_data - set by keyboard_interrupt */
static volatile unsigned char reply_expected = 0;
static volatile unsigned char acknowledge = 0;
static volatile unsigned char resend = 0;
/*
* Translation of escaped scancodes to keycodes.
* This is now user-settable.
* The keycodes 1-88,96-111,119 are fairly standard, and
* should probably not be changed - changing might confuse X.
* X also interprets scancode 0x5d (KEY_Begin).
*
* For 1-88 keycode equals scancode.
*/
#define E0_KPENTER 96
#define E0_RCTRL 97
#define E0_KPSLASH 98
#define E0_PRSCR 99
#define E0_RALT 100
#define E0_BREAK 101 /* (control-pause) */
#define E0_HOME 102
#define E0_UP 103
#define E0_PGUP 104
#define E0_LEFT 105
#define E0_RIGHT 106
#define E0_END 107
#define E0_DOWN 108
#define E0_PGDN 109
#define E0_INS 110
#define E0_DEL 111
#define E1_PAUSE 119
/*
* The keycodes below are randomly located in 89-95,112-118,120-127.
* They could be thrown away (and all occurrences below replaced by 0),
* but that would force many users to use the `setkeycodes' utility, where
* they needed not before. It does not matter that there are duplicates, as
* long as no duplication occurs for any single keyboard.
*/
#define SC_LIM 89
#define FOCUS_PF1 85 /* actual code! */
#define FOCUS_PF2 89
#define FOCUS_PF3 90
#define FOCUS_PF4 91
#define FOCUS_PF5 92
#define FOCUS_PF6 93
#define FOCUS_PF7 94
#define FOCUS_PF8 95
#define FOCUS_PF9 120
#define FOCUS_PF10 121
#define FOCUS_PF11 122
#define FOCUS_PF12 123
#define JAP_86 124
/* tfj@olivia.ping.dk:
* The four keys are located over the numeric keypad, and are
* labelled A1-A4. It's an rc930 keyboard, from
* Regnecentralen/RC International, Now ICL.
* Scancodes: 59, 5a, 5b, 5c.
*/
#define RGN1 124
#define RGN2 125
#define RGN3 126
#define RGN4 127
static unsigned char high_keys[128 - SC_LIM] = {
RGN1, RGN2, RGN3, RGN4, 0, 0, 0, /* 0x59-0x5f */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12, /* 0x68-0x6f */
0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3, /* 0x70-0x77 */
FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7, /* 0x78-0x7b */
FOCUS_PF8, JAP_86, FOCUS_PF10, 0 /* 0x7c-0x7f */
};
/* BTC */
#define E0_MACRO 112
/* LK450 */
#define E0_F13 113
#define E0_F14 114
#define E0_HELP 115
#define E0_DO 116
#define E0_F17 117
#define E0_KPMINPLUS 118
/*
* My OmniKey generates e0 4c for the "OMNI" key and the
* right alt key does nada. [kkoller@nyx10.cs.du.edu]
*/
#define E0_OK 124
/*
* New microsoft keyboard is rumoured to have
* e0 5b (left window button), e0 5c (right window button),
* e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
* [or: Windows_L, Windows_R, TaskMan]
*/
#define E0_MSLW 125
#define E0_MSRW 126
#define E0_MSTM 127
static unsigned char e0_keys[128] = {
0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x07 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x08-0x0f */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */
0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0, /* 0x18-0x1f */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */
0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR, /* 0x30-0x37 */
E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP, /* 0x38-0x3f */
E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME, /* 0x40-0x47 */
E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0, /* 0x50-0x57 */
0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0, /* 0x58-0x5f */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
0, 0, 0, 0, 0, 0, 0, E0_MACRO, /* 0x68-0x6f */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */
0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7f */
};
static void mdelay( unsigned long t )
{
Wait_X_ms( t );
}
int pckbd_setkeycode(unsigned int scancode, unsigned int keycode)
{
if (scancode < SC_LIM || scancode > 255 || keycode > 127)
return -EINVAL;
if (scancode < 128)
high_keys[scancode - SC_LIM] = keycode;
else
e0_keys[scancode - 128] = keycode;
return 0;
}
int pckbd_getkeycode(unsigned int scancode)
{
return
(scancode < SC_LIM || scancode > 255) ? -EINVAL :
(scancode < 128) ? high_keys[scancode - SC_LIM] :
e0_keys[scancode - 128];
}
static int do_acknowledge(unsigned char scancode)
{
if (reply_expected) {
/* Unfortunately, we must recognise these codes only if we know they
* are known to be valid (i.e., after sending a command), because there
* are some brain-damaged keyboards (yes, FOCUS 9000 again) which have
* keys with such codes :(
*/
if (scancode == KBD_REPLY_ACK) {
acknowledge = 1;
reply_expected = 0;
return 0;
} else if (scancode == KBD_REPLY_RESEND) {
resend = 1;
reply_expected = 0;
return 0;
}
/* Should not happen... */
printk( "keyboard reply expected - got %02x\n", scancode);
}
return 1;
}
int pckbd_translate(unsigned char scancode, unsigned char *keycode,
char raw_mode)
{
static int prev_scancode = 0;
/* special prefix scancodes.. */
if (scancode == 0xe0 || scancode == 0xe1) {
prev_scancode = scancode;
return 0;
}
/* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */
if (scancode == 0x00 || scancode == 0xff) {
prev_scancode = 0;
return 0;
}
scancode &= 0x7f;
if (prev_scancode) {
/*
* usually it will be 0xe0, but a Pause key generates
* e1 1d 45 e1 9d c5 when pressed, and nothing when released
*/
if (prev_scancode != 0xe0) {
if (prev_scancode == 0xe1 && scancode == 0x1d) {
prev_scancode = 0x100;
return 0;
} else if (prev_scancode == 0x100 && scancode == 0x45) {
*keycode = E1_PAUSE;
prev_scancode = 0;
} else {
#ifdef KBD_REPORT_UNKN
if (!raw_mode)
printk("keyboard: unknown e1 escape sequence\n");
#endif
prev_scancode = 0;
return 0;
}
} else {
prev_scancode = 0;
/*
* The keyboard maintains its own internal caps lock and
* num lock statuses. In caps lock mode E0 AA precedes make
* code and E0 2A follows break code. In num lock mode,
* E0 2A precedes make code and E0 AA follows break code.
* We do our own book-keeping, so we will just ignore these.
*/
/*
* For my keyboard there is no caps lock mode, but there are
* both Shift-L and Shift-R modes. The former mode generates
* E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs.
* So, we should also ignore the latter. - aeb@cwi.nl
*/
if (scancode == 0x2a || scancode == 0x36)
return 0;
if (e0_keys[scancode])
*keycode = e0_keys[scancode];
else {
#ifdef KBD_REPORT_UNKN
if (!raw_mode)
printk( "keyboard: unknown scancode e0 %02x\n",
scancode);
#endif
return 0;
}
}
} else if (scancode >= SC_LIM) {
/* This happens with the FOCUS 9000 keyboard
Its keys PF1..PF12 are reported to generate
55 73 77 78 79 7a 7b 7c 74 7e 6d 6f
Moreover, unless repeated, they do not generate
key-down events, so we have to zero up_flag below */
/* Also, Japanese 86/106 keyboards are reported to
generate 0x73 and 0x7d for \ - and \ | respectively. */
/* Also, some Brazilian keyboard is reported to produce
0x73 and 0x7e for \ ? and KP-dot, respectively. */
*keycode = high_keys[scancode - SC_LIM];
if (!*keycode) {
if (!raw_mode) {
#ifdef KBD_REPORT_UNKN
printk( "keyboard: unrecognized scancode (%02x)"
" - ignored\n", scancode);
#endif
}
return 0;
}
} else
*keycode = scancode;
return 1;
}
char pckbd_unexpected_up(unsigned char keycode)
{
/* unexpected, but this can happen: maybe this was a key release for a
FOCUS 9000 PF key; if we want to see it, we have to clear up_flag */
if (keycode >= SC_LIM || keycode == 85)
return 0;
else
return 0200;
}
static void kb_wait(void)
{
unsigned long timeout = KBC_TIMEOUT;
do {
/*
* "handle_kbd_event()" will handle any incoming events
* while we wait - keypresses or mouse movement.
*/
unsigned char status = handle_kbd_event();
if (! (status & KBD_STAT_IBF))
return;
mdelay(1);
timeout--;
} while (timeout);
#ifdef KBD_REPORT_TIMEOUTS
printk( "Keyboard timed out[1]\n");
#endif
}
/*
* This reads the keyboard status port, and does the
* appropriate action.
*
* It requires that we hold the keyboard controller
* spinlock.
*/
static unsigned char handle_kbd_event(void)
{
unsigned char status = kbd_read_status();
unsigned int work = 10000;
while (status & KBD_STAT_OBF) {
unsigned char scancode;
scancode = kbd_read_input();
if (status & KBD_STAT_MOUSE_OBF) {
#if 0
handle_mouse_event(scancode);
#endif
} else {
if (do_acknowledge(scancode))
handle_scancode(scancode, !(scancode & 0x80));
mark_bh(KEYBOARD_BH);
}
status = kbd_read_status();
if(!work--)
{
printk( "pc_keyb: controller jammed (0x%02X).\n", status);
break;
}
return status;
}
/*
* the commands to set the leds for some reason, returns 0x14, 0x16
* and I am intepreting as an ACK, because the original code from
* Linux was timeing out here...
*/
acknowledge = 1;
reply_expected = 0;
resend = 0;
return status;
}
void keyboard_interrupt( void )
{
handle_kbd_event();
}
/*
* send_data sends a character to the keyboard and waits
* for an acknowledge, possibly retrying if asked to. Returns
* the success status.
*
* Don't use 'jiffies', so that we don't depend on interrupts
*/
static int send_data(unsigned char data)
{
int retries = 3;
do {
unsigned long timeout = KBD_TIMEOUT;
acknowledge = 0; /* Set by interrupt routine on receipt of ACK. */
resend = 0;
reply_expected = 1;
kbd_write_output_w(data);
for (;;) {
if (acknowledge)
return 1;
if (resend)
break;
mdelay(1);
if (!--timeout) {
#ifdef KBD_REPORT_TIMEOUTS
printk("Keyboard timeout[2]\n");
#endif
return 0;
}
}
} while (retries-- > 0);
#ifdef KBD_REPORT_TIMEOUTS
printk( "keyboard: Too many NACKs -- noisy kbd cable?\n");
#endif
return 0;
}
void pckbd_leds(unsigned char leds)
{
if (!send_data(KBD_CMD_SET_LEDS) || !send_data(leds))
send_data(KBD_CMD_ENABLE); /* re-enable kbd if any errors */
}
/*
* In case we run on a non-x86 hardware we need to initialize both the
* keyboard controller and the keyboard. On a x86, the BIOS will
* already have initialized them.
*
* Some x86 BIOSes do not correctly initialize the keyboard, so the
* "kbd-reset" command line options can be given to force a reset.
* [Ranger]
*/
#ifdef __i386__
int kbd_startup_reset = 0;
#else
int kbd_startup_reset = 1;
#endif
/* for "kbd-reset" cmdline param */
void kbd_reset_setup(char *str, int *ints)
{
kbd_startup_reset = 1;
}
#define KBD_NO_DATA (-1) /* No data */
#define KBD_BAD_DATA (-2) /* Parity or other error */
static int kbd_read_data(void)
{
int retval = KBD_NO_DATA;
unsigned char status;
status = kbd_read_status();
if (status & KBD_STAT_OBF) {
unsigned char data = kbd_read_input();
retval = data;
if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
retval = KBD_BAD_DATA;
}
return retval;
}
static void kbd_clear_input(void)
{
int maxread = 100; /* Random number */
do {
if (kbd_read_data() == KBD_NO_DATA)
break;
} while (--maxread);
}
static int kbd_wait_for_input(void)
{
long timeout = KBD_INIT_TIMEOUT;
do {
int retval = kbd_read_data();
if (retval >= 0)
return retval;
mdelay(1);
} while (--timeout);
return -1;
}
static void kbd_write_command_w(int data)
{
kb_wait();
kbd_write_command(data);
}
static void kbd_write_output_w(int data)
{
kb_wait();
kbd_write_output(data);
}
static char * initialize_kbd(void)
{
int status;
/*
* Test the keyboard interface.
* This seems to be the only way to get it going.
* If the test is successful a x55 is placed in the input buffer.
*/
kbd_write_command_w(KBD_CCMD_SELF_TEST);
if (kbd_wait_for_input() != 0x55)
return "Keyboard failed self test";
/*
* Perform a keyboard interface test. This causes the controller
* to test the keyboard clock and data lines. The results of the
* test are placed in the input buffer.
*/
kbd_write_command_w(KBD_CCMD_KBD_TEST);
if (kbd_wait_for_input() != 0x00)
return "Keyboard interface failed self test";
/*
* Enable the keyboard by allowing the keyboard clock to run.
*/
kbd_write_command_w(KBD_CCMD_KBD_ENABLE);
/*
* Reset keyboard. If the read times out
* then the assumption is that no keyboard is
* plugged into the machine.
* This defaults the keyboard to scan-code set 2.
*
* Set up to try again if the keyboard asks for RESEND.
*/
do {
kbd_write_output_w(KBD_CMD_RESET);
status = kbd_wait_for_input();
if (status == KBD_REPLY_ACK)
break;
if (status != KBD_REPLY_RESEND)
return "Keyboard reset failed, no ACK";
} while (1);
if (kbd_wait_for_input() != KBD_REPLY_POR)
return "Keyboard reset failed, no POR";
/*
* Set keyboard controller mode. During this, the keyboard should be
* in the disabled state.
*
* Set up to try again if the keyboard asks for RESEND.
*/
do {
kbd_write_output_w(KBD_CMD_DISABLE);
status = kbd_wait_for_input();
if (status == KBD_REPLY_ACK)
break;
if (status != KBD_REPLY_RESEND)
return "Disable keyboard: no ACK";
} while (1);
kbd_write_command_w(KBD_CCMD_WRITE_MODE);
kbd_write_output_w(KBD_MODE_KBD_INT
| KBD_MODE_SYS
| KBD_MODE_DISABLE_MOUSE
| KBD_MODE_KCC);
/* ibm powerpc portables need this to use scan-code set 1 -- Cort */
kbd_write_command_w(KBD_CCMD_READ_MODE);
if (!(kbd_wait_for_input() & KBD_MODE_KCC)) {
/*
* If the controller does not support conversion,
* Set the keyboard to scan-code set 1.
*/
kbd_write_output_w(0xF0);
kbd_wait_for_input();
kbd_write_output_w(0x01);
kbd_wait_for_input();
}
kbd_write_output_w(KBD_CMD_ENABLE);
if (kbd_wait_for_input() != KBD_REPLY_ACK)
return "Enable keyboard: no ACK";
/*
* Finally, set the typematic rate to maximum.
*/
kbd_write_output_w(KBD_CMD_SET_RATE);
if (kbd_wait_for_input() != KBD_REPLY_ACK)
return "Set rate: no ACK";
kbd_write_output_w(0x00);
if (kbd_wait_for_input() != KBD_REPLY_ACK)
return "Set rate: no ACK";
return NULL;
}
void pckbd_init_hw(void)
{
/* kbd_request_region(); */
/* Flush any pending input. */
kbd_clear_input();
if (kbd_startup_reset) {
char *msg = initialize_kbd();
if (msg)
printk( "initialize_kbd: %s\n", msg);
}
#if defined CONFIG_PSMOUSE
psaux_init();
#endif
/* Ok, finally allocate the IRQ, and off we go.. */
#if 0
kbd_request_irq( keyboard_interrupt );
#endif
}
char BSP_wait_polled_input( void )
{
int c;
cli();
while ( ( c= kbd_wait_for_input() ) < 0 )
continue;
sti();
return c;
}

View File

@@ -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__ */

View File

@@ -0,0 +1,708 @@
/*
* linux/drivers/char/pc_keyb.c
* Separation of the PC low-level part by Geert Uytterhoeven, May 1997
* See keyboard.c for the whole history.
* Major cleanup by Martin Mares, May 1997
* Combined the keyboard and PS/2 mouse handling into one file,
* because they share the same hardware.
* Johan Myreen <jem@iki.fi> 1998-10-08.
* Code fixes to handle mouse ACKs properly.
* C. Scott Ananian <cananian@alumni.princeton.edu> 1999-01-29.
*
* RTEMS port: by Rosimildo da Silva.
* This module was ported from Linux.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <bsp.h>
#include <irq.h>
#include <rtems/libio.h>
#include <termios.h>
#include <i386_io.h>
#include <rtems/mw_uid.h>
#define INITIALIZE_MOUSE
/* Some configuration switches are present in the include file... */
#include "ps2_mouse.h"
#include "mouse_parser.h"
static void kbd_write_command_w(int data);
static void kbd_write_output_w(int data);
static unsigned char handle_kbd_event(void);
/* used only by send_data - set by keyboard_interrupt */
static volatile unsigned char reply_expected = 0;
static volatile unsigned char acknowledge = 0;
static volatile unsigned char resend = 0;
/*
* PS/2 Auxiliary Device
*/
static int psaux_init(void);
static struct aux_queue *queue; /* Mouse data buffer. */
static int aux_count = 0;
/* used when we send commands to the mouse that expect an ACK. */
static unsigned char mouse_reply_expected = 0;
#define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT)
#define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT)
#define MAX_RETRIES 60 /* some aux operations take long time*/
static void ps2_mouse_interrupt();
static void ( *driver_input_handler_ps2 )( void *, char *, int ) = 0;
/*
* This routine sets the handler to handle the characters received
* from the serial port.
*/
void ps2_set_driver_handler( int port, void ( *handler )( void *, char *, int ) )
{
driver_input_handler_ps2 = handler;
}
static void mdelay( unsigned long t )
{
Wait_X_ms( t );
}
static void* termios_ttyp_paux = NULL;
static void
isr_on(const rtems_irq_connect_data *unused)
{
return;
}
static void
isr_off(const rtems_irq_connect_data *unused)
{
return;
}
static int isr_is_on(const rtems_irq_connect_data *irq)
{
return BSP_irq_enabled_at_i8259s( irq->name );
}
static rtems_irq_connect_data ps2_isr_data = { AUX_IRQ,
ps2_mouse_interrupt, isr_on, isr_off, isr_is_on };
/*
* Wait for keyboard controller input buffer to drain.
*
* Don't use 'jiffies' so that we don't depend on
* interrupts..
*
* Quote from PS/2 System Reference Manual:
*
* "Address hex 0060 and address hex 0064 should be written only when
* the input-buffer-full bit and output-buffer-full bit in the
* Controller Status register are set 0."
*/
static void kb_wait(void)
{
unsigned long timeout = KBC_TIMEOUT;
do {
/*
* "handle_kbd_event()" will handle any incoming events
* while we wait - keypresses or mouse movement.
*/
unsigned char status = handle_kbd_event();
if (! (status & KBD_STAT_IBF))
return;
mdelay(1);
timeout--;
} while (timeout);
#ifdef KBD_REPORT_TIMEOUTS
printk( "Keyboard timed out[1]\n");
#endif
}
static int do_acknowledge(unsigned char scancode)
{
if (reply_expected) {
/* Unfortunately, we must recognise these codes only if we know they
* are known to be valid (i.e., after sending a command), because there
* are some brain-damaged keyboards (yes, FOCUS 9000 again) which have
* keys with such codes :(
*/
if (scancode == KBD_REPLY_ACK) {
acknowledge = 1;
reply_expected = 0;
return 0;
} else if (scancode == KBD_REPLY_RESEND) {
resend = 1;
reply_expected = 0;
return 0;
}
/* Should not happen... */
#if 0
printk( "keyboard reply expected - got %02x\n",
scancode);
#endif
}
return 1;
}
static inline void handle_mouse_event(unsigned char scancode)
{
if (mouse_reply_expected) {
if (scancode == AUX_ACK) {
mouse_reply_expected--;
return;
}
mouse_reply_expected = 0;
}
if (aux_count) {
int head = queue->head;
queue->buf[head] = scancode;
head = (head + 1) & (AUX_BUF_SIZE-1);
if (head != queue->tail) {
queue->head = head;
}
/* if the input queue is active, add to it */
if( driver_input_handler_ps2 )
{
driver_input_handler_ps2( NULL, &scancode, 1 );
}
else
{
/* post this byte to termios */
rtems_termios_enqueue_raw_characters( termios_ttyp_paux, &scancode, 1 );
}
}
}
/*
* This reads the keyboard status port, and does the
* appropriate action.
*
* It requires that we hold the keyboard controller
* spinlock.
*/
static unsigned char handle_kbd_event(void)
{
unsigned char status = kbd_read_status();
unsigned int work = 10000;
while (status & KBD_STAT_OBF) {
unsigned char scancode;
scancode = kbd_read_input();
if (status & KBD_STAT_MOUSE_OBF) {
handle_mouse_event(scancode);
} else {
do_acknowledge(scancode);
printk("pc_keyb: %X ", scancode );
}
status = kbd_read_status();
if(!work--)
{
printk("pc_keyb: controller jammed (0x%02X).\n",
status);
break;
}
}
return status;
}
static void ps2_mouse_interrupt()
{
handle_kbd_event();
}
/*
* send_data sends a character to the keyboard and waits
* for an acknowledge, possibly retrying if asked to. Returns
* the success status.
*
* Don't use 'jiffies', so that we don't depend on interrupts
*/
static int send_data(unsigned char data)
{
int retries = 3;
do {
unsigned long timeout = KBD_TIMEOUT;
acknowledge = 0; /* Set by interrupt routine on receipt of ACK. */
resend = 0;
reply_expected = 1;
kbd_write_output_w(data);
for (;;) {
if (acknowledge)
return 1;
if (resend)
break;
mdelay(1);
if (!--timeout) {
#ifdef KBD_REPORT_TIMEOUTS
printk( "Keyboard timeout[2]\n");
#endif
return 0;
}
}
} while (retries-- > 0);
#ifdef KBD_REPORT_TIMEOUTS
printk( "keyboard: Too many NACKs -- noisy kbd cable?\n");
#endif
return 0;
}
#define KBD_NO_DATA (-1) /* No data */
#define KBD_BAD_DATA (-2) /* Parity or other error */
static int kbd_read_data(void)
{
int retval = KBD_NO_DATA;
unsigned char status;
status = kbd_read_status();
if (status & KBD_STAT_OBF) {
unsigned char data = kbd_read_input();
retval = data;
if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
retval = KBD_BAD_DATA;
}
return retval;
}
static void kbd_clear_input(void)
{
int maxread = 100; /* Random number */
do {
if (kbd_read_data() == KBD_NO_DATA)
break;
} while (--maxread);
}
static int kbd_wait_for_input(void)
{
long timeout = KBD_INIT_TIMEOUT;
do {
int retval = kbd_read_data();
if (retval >= 0)
return retval;
mdelay(1);
} while (--timeout);
return -1;
}
static void kbd_write_command_w(int data)
{
kb_wait();
kbd_write_command(data);
}
static void kbd_write_output_w(int data)
{
kb_wait();
kbd_write_output(data);
}
static void kbd_write_cmd(int cmd)
{
kb_wait();
kbd_write_command(KBD_CCMD_WRITE_MODE);
kb_wait();
kbd_write_output(cmd);
}
/*
* Check if this is a dual port controller.
*/
static int detect_auxiliary_port(void)
{
int loops = 10;
int retval = 0;
/* Put the value 0x5A in the output buffer using the "Write
* Auxiliary Device Output Buffer" command (0xD3). Poll the
* Status Register for a while to see if the value really
* turns up in the Data Register. If the KBD_STAT_MOUSE_OBF
* bit is also set to 1 in the Status Register, we assume this
* controller has an Auxiliary Port (a.k.a. Mouse Port).
*/
kb_wait();
kbd_write_command(KBD_CCMD_WRITE_AUX_OBUF);
kb_wait();
kbd_write_output(0x5a); /* 0x5a is a random dummy value. */
do {
unsigned char status = kbd_read_status();
if (status & KBD_STAT_OBF) {
(void) kbd_read_input();
if (status & KBD_STAT_MOUSE_OBF) {
printk( "Detected PS/2 Mouse Port.\n");
retval = 1;
}
break;
}
mdelay(1);
} while (--loops);
return retval;
}
/*
* Send a byte to the mouse.
*/
static void aux_write_dev(int val)
{
kb_wait();
kbd_write_command(KBD_CCMD_WRITE_MOUSE);
kb_wait();
kbd_write_output(val);
}
/*
* Send a byte to the mouse & handle returned ack
*/
static void aux_write_ack(int val)
{
kb_wait();
kbd_write_command(KBD_CCMD_WRITE_MOUSE);
kb_wait();
kbd_write_output(val);
/* we expect an ACK in response. */
mouse_reply_expected++;
kb_wait();
}
static unsigned char get_from_queue(void)
{
unsigned char result;
result = queue->buf[queue->tail];
queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
return result;
}
static int queue_empty(void)
{
return queue->head == queue->tail;
}
/*
* Random magic cookie for the aux device
*/
#define AUX_DEV ((void *)queue)
static int release_aux()
{
if (--aux_count)
return 0;
kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints */
kbd_write_command_w(KBD_CCMD_MOUSE_DISABLE);
BSP_remove_rtems_irq_handler( &ps2_isr_data );
return 0;
}
/*
* Install interrupt handler.
* Enable auxiliary device.
*/
static int open_aux()
{
rtems_status_code status;
if (aux_count++) {
return 0;
}
queue->head = queue->tail = 0; /* Flush input queue */
status = BSP_install_rtems_irq_handler( &ps2_isr_data );
if( !status )
{
printk("Error installing ps2-mouse interrupt handler!\n" );
rtems_fatal_error_occurred( status );
}
kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable the
auxiliary port on
controller. */
aux_write_ack(AUX_ENABLE_DEV); /* Enable aux device */
kbd_write_cmd(AUX_INTS_ON); /* Enable controller ints */
return 0;
}
/*
* Put bytes from input queue to buffer.
*/
size_t read_aux(char * buffer, size_t count )
{
size_t i = count;
unsigned char c;
if (queue_empty())
{
return 0;
}
while (i > 0 && !queue_empty())
{
c = get_from_queue();
*buffer++ = c;
i--;
}
return count-i;
}
/*
* Write to the aux device.
*/
static int write_aux( int minor, const char * buffer, int count )
{
int retval = 0;
if (count) {
int written = 0;
if (count > 32)
count = 32; /* Limit to 32 bytes. */
do {
char c;
c = *buffer++;
aux_write_dev(c);
written++;
} while (--count);
retval = -EIO;
if (written) {
retval = written;
}
}
return retval;
}
static unsigned int aux_poll()
{
if( !queue_empty() )
return 1;
return 0;
}
static int psaux_init( void )
{
if( !detect_auxiliary_port() )
{
printk( "PS/2 - mouse not found.\n" );
return -EIO;
}
queue = (struct aux_queue *)malloc( sizeof(*queue) );
memset(queue, 0, sizeof(*queue));
queue->head = queue->tail = 0;
queue->proc_list = NULL;
#ifdef INITIALIZE_MOUSE
kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable Aux. */
aux_write_ack(AUX_SET_SAMPLE);
aux_write_ack(100); /* 100 samples/sec */
aux_write_ack(AUX_SET_RES);
aux_write_ack(3); /* 8 counts per mm */
aux_write_ack(AUX_SET_SCALE21); /* 2:1 scaling */
#endif /* INITIALIZE_MOUSE */
kbd_write_command(KBD_CCMD_MOUSE_DISABLE); /* Disable aux device. */
kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints. */
return 0;
}
void paux_reserve_resources(rtems_configuration_table *conf)
{
rtems_termios_reserve_resources(conf, 1);
return;
}
/*
* paux device driver INITIALIZE entry point.
*/
rtems_device_driver
paux_initialize( rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_status_code status;
/*
* Set up TERMIOS
*/
rtems_termios_initialize();
printk( "PS/2 mouse probe.\n" );
if( psaux_init() < 0 )
{
printk("Error detecting PS/2 mouse --\n");
/* we might want to finish the application here !!! */
}
open_aux();
/*
* Register the device
*/
status = rtems_io_register_name ("/dev/mouse", major, 0);
if (status != RTEMS_SUCCESSFUL)
{
printk("Error registering paux device!\n");
rtems_fatal_error_occurred (status);
}
return RTEMS_SUCCESSFUL;
} /* tty_initialize */
static int paux_last_close(int major, int minor, void *arg)
{
release_aux();
return 0;
}
/*
* Write to the aux device. This routine is invoked by the
* termios framework whenever the "ECHO" feature is on.
* It does nothing write now.
*/
static int write_aux_echo( int minor, const char * buffer, int count )
{
return 0;
}
/*
* Some initialization if necessary
*/
static rtems_device_driver
paux_first_open( rtems_device_minor_number major,
rtems_device_minor_number minor,
void *arg)
{
return RTEMS_SUCCESSFUL;
}
/*
* paux device driver OPEN entry point
*/
rtems_device_driver
paux_open(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_status_code status;
static rtems_termios_callbacks cb =
{
NULL, /* firstOpen */
paux_last_close, /* lastClose */
NULL, /* poll read */
write_aux_echo, /* write */
NULL, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
0 /* outputUsesInterrupts */
};
status = rtems_termios_open (major, minor, arg, &cb );
termios_ttyp_paux = ( (rtems_libio_open_close_args_t *)arg)->iop->data1;
return status;
}
/*
* paux device driver CLOSE entry point
*/
rtems_device_driver
paux_close(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
return (rtems_termios_close (arg));
}
/*
* paux device driver READ entry point.
* Read characters from the PS/2 mouse.
*/
rtems_device_driver
paux_read(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
return rtems_termios_read (arg);
} /* tty_read */
/*
* paux device driver WRITE entry point.
* Write characters to the PS/2 mouse.
*/
rtems_device_driver
paux_write(rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg)
{
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
char *buffer = rw_args->buffer;
int maximum = rw_args->count;
rw_args->bytes_moved = write_aux( minor, buffer, maximum );
return RTEMS_SUCCESSFUL;
} /* tty_write */
/*
* Handle ioctl request.
*/
rtems_device_driver
paux_control(rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
rtems_libio_ioctl_args_t *args = arg;
switch( args->command )
{
default:
return rtems_termios_ioctl (arg);
break;
case MW_UID_REGISTER_DEVICE:
printk( "PS2 Mouse: reg=%s\n", args->buffer );
register_mou_msg_queue( args->buffer, -1 );
break;
case MW_UID_UNREGISTER_DEVICE:
unregister_mou_msg_queue( -1 );
break;
}
args->ioctl_return = 0;
return RTEMS_SUCCESSFUL;
}

View File

@@ -0,0 +1,146 @@
/*
* include/linux/pc_keyb.h
* PC Keyboard And Keyboard Controller
* (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
*
* RTEMS port: by Rosimildo da Silva.
*
* This module was ported from Linux.
*
*/
/*
* Configuration Switches
*/
#undef KBD_REPORT_ERR /* Report keyboard errors */
#define KBD_REPORT_UNKN /* Report unknown scan codes */
#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */
#undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */
#undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */
#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */
#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */
#define KBD_TIMEOUT 1000 /* Timeout in ms for keyboard command acknowledge */
/*
* Internal variables of the driver
*/
extern unsigned char pckbd_read_mask;
extern unsigned char aux_device_present;
/*
* Keyboard Controller Registers on normal PCs.
*/
#define KBD_STATUS_REG 0x64 /* Status register (R) */
#define KBD_CNTL_REG 0x64 /* Controller command register (W) */
#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */
/*
* Keyboard Controller Commands
*/
#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */
#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */
#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */
#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */
#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */
#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */
#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */
#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */
#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */
#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if
initiated by the auxiliary device */
#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */
/*
* Keyboard Commands
*/
#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */
#define KBD_CMD_RESET 0xFF /* Reset */
/*
* Keyboard Replies
*/
#define KBD_REPLY_POR 0xAA /* Power on reset */
#define KBD_REPLY_ACK 0xFA /* Command ACK */
#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
/*
* Status Register Bits
*/
#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
#define KBD_STAT_SELFTEST 0x04 /* Self test successful */
#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */
#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */
#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */
#define KBD_STAT_PERR 0x80 /* Parity error */
#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF)
/*
* Controller Mode Register Bits
*/
#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */
#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */
#define KBD_MODE_SYS 0x04 /* The system flag (?) */
#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */
#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */
#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */
#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
#define KBD_MODE_RFU 0x80
/*
* Mouse Commands
*/
#define AUX_SET_RES 0xE8 /* Set resolution */
#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
#define AUX_GET_SCALE 0xE9 /* Get scaling factor */
#define AUX_SET_STREAM 0xEA /* Set stream mode */
#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
#define AUX_RESET 0xFF /* Reset aux device */
#define AUX_ACK 0xFA /* Command byte ACK. */
#define AUX_BUF_SIZE 512 /* This might be better divisible by
three to make overruns stay in sync
but then the read function would need
a lock etc - ick */
struct aux_queue {
unsigned long head;
unsigned long tail;
struct wait_queue *proc_list;
struct fasync_struct *fasync;
unsigned char buf[AUX_BUF_SIZE];
};
/* How to access the keyboard macros on this platform. */
#define kbd_read_input() inb(KBD_DATA_REG)
#define kbd_read_status() inb(KBD_STATUS_REG)
#define kbd_write_output(val) outb(val, KBD_DATA_REG)
#define kbd_write_command(val) outb(val, KBD_CNTL_REG)
/*
* Machine specific bits for the PS/2 driver
*/
#define AUX_IRQ 12

View File

@@ -0,0 +1,348 @@
/***************************************************************************
*
* $Header$
*
* MODULE DESCRIPTION:
* This module implements the RTEMS drivers for the PC serial ports
* as /dev/ttyS1 for COM1 and /dev/ttyS2 as COM2. If one of the ports
* is used as the console, this driver would fail to initialize.
*
* This code was based on the console driver. It is based on the
* current termios framework. This is just a shell around the
* termios support.
*
* by: Rosimildo da Silva:
* rdasilva@connecttel.com
* http://www.connecttel.com
*
* MODIFICATION/HISTORY:
*
* $Log$
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <bsp.h>
#include <irq.h>
#include <rtems/libio.h>
#include <termios.h>
#include <uart.h>
#include <libcpu/cpuModel.h>
int BSP_poll_read(int);
#include <rtems/mw_uid.h>
#include "serial_mouse.h"
#include "mouse_parser.h"
/* Internal routines */
static int serial_mouse_conSetAttr( int minor, const struct termios *t);
static void isr_on(const rtems_irq_connect_data *);
static void isr_off(const rtems_irq_connect_data *);
static int isr_is_on(const rtems_irq_connect_data *);
extern BSP_polling_getchar_function_type BSP_poll_char;
extern int BSPConsolePort;
/* Select Default to be COM1 */
#if !defined( SERIAL_MOUSE_COM1 ) && !defined( SERIAL_MOUSE_COM2 )
#define SERIAL_MOUSE_COM1 1
#endif
/* select which serial port the mouse is connected to */
#ifdef SERIAL_MOUSE_COM1
#define BSP_UART_PORT BSP_UART_COM1
#define BSP_UART_IRQ BSP_UART_COM1_IRQ
#define BSP_ISR_FUNC BSP_uart_termios_isr_com1
#define BSP_WRITE_FUNC BSP_uart_termios_write_com1
#endif
#ifdef SERIAL_MOUSE_COM2
#define BSP_UART_PORT BSP_UART_COM2
#define BSP_UART_IRQ BSP_UART_COM2_IRQ
#define BSP_ISR_FUNC BSP_uart_termios_isr_com2
#define BSP_WRITE_FUNC BSP_uart_termios_write_com2
#endif
/*
* Interrupt structure for serial_mouse
*/
static rtems_irq_connect_data serial_mouse_isr_data =
{
BSP_UART_IRQ,
BSP_ISR_FUNC,
isr_on,
isr_off,
isr_is_on};
static void isr_on(const rtems_irq_connect_data *unused)
{
return;
}
static void isr_off(const rtems_irq_connect_data *unused)
{
return;
}
static int isr_is_on(const rtems_irq_connect_data *irq)
{
return BSP_irq_enabled_at_i8259s(irq->name);
}
void serial_mouse_reserve_resources(rtems_configuration_table *conf)
{
rtems_termios_reserve_resources(conf, 1);
return;
}
/*
* Serial Mouse - device driver INITIALIZE entry point.
*/
rtems_device_driver
serial_mouse_initialize(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_status_code status;
/* Check if this port is not been used as console */
if( BSPConsolePort == BSP_UART_PORT )
{
status = -1;
printk("SERIAL MOUSE: port selected as console.( %d )\n", BSP_UART_PORT );
rtems_fatal_error_occurred( status );
}
/*
* Set up TERMIOS
*/
rtems_termios_initialize();
/*
* Do device-specific initialization
*/
/* 9600-8-N-1, without hardware flow control */
BSP_uart_init( BSP_UART_PORT, 1200, 0 );
status = BSP_install_rtems_irq_handler( &serial_mouse_isr_data );
if( !status )
{
printk("Error installing serial mouse interrupt handler!\n");
rtems_fatal_error_occurred(status);
}
/*
* Register the device
*/
status = rtems_io_register_name ("/dev/mouse", major, 0);
if (status != RTEMS_SUCCESSFUL)
{
printk("Error registering /dev/mouse device!\n");
rtems_fatal_error_occurred (status);
}
printk("Device: /dev/mouse on COM%d -- ok \n", BSP_UART_PORT );
return RTEMS_SUCCESSFUL;
} /* tty_initialize */
static int serial_mouse_last_close(int major, int minor, void *arg)
{
BSP_remove_rtems_irq_handler( &serial_mouse_isr_data );
return 0;
}
/*
* serial_mouse - device driver OPEN entry point
*/
rtems_device_driver
serial_mouse_open(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_status_code status;
static rtems_termios_callbacks cb =
{
NULL, /* firstOpen */
serial_mouse_last_close, /* lastClose */
NULL, /* poll read */
BSP_WRITE_FUNC, /* write */
serial_mouse_conSetAttr, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
1 /* outputUsesInterrupts */
};
status = rtems_termios_open( major, minor, arg, &cb );
if(status != RTEMS_SUCCESSFUL)
{
printk("Error openning serial_mouse device\n");
return status;
}
/*
* Pass data area info down to driver
*/
BSP_uart_termios_set( BSP_UART_PORT,
((rtems_libio_open_close_args_t *)arg)->iop->data1 );
/* Enable interrupts on channel */
BSP_uart_intr_ctrl( BSP_UART_PORT, BSP_UART_INTR_CTRL_TERMIOS);
return RTEMS_SUCCESSFUL;
}
/*
* TTY - device driver CLOSE entry point
*/
rtems_device_driver
serial_mouse_close(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
return (rtems_termios_close (arg));
} /* tty_close */
/*
* TTY device driver READ entry point.
* Read characters from the tty device.
*/
rtems_device_driver
serial_mouse_read(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
return rtems_termios_read (arg);
} /* tty_read */
/*
* TTY device driver WRITE entry point.
* Write characters to the tty device.
*/
rtems_device_driver
serial_mouse_write(rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg)
{
return rtems_termios_write (arg);
} /* tty_write */
/*
* Handle ioctl request. This is a generic internal
* routine to handle both devices.
*/
static rtems_device_driver serial_mouse_control_internal( int port, void *arg )
{
rtems_libio_ioctl_args_t *args = arg;
switch( args->command )
{
default:
return rtems_termios_ioctl (arg);
break;
case MW_UID_REGISTER_DEVICE:
printk( "SerialMouse: reg=%s\n", args->buffer );
register_mou_msg_queue( args->buffer, BSP_UART_PORT );
break;
case MW_UID_UNREGISTER_DEVICE:
unregister_mou_msg_queue( BSP_UART_PORT );
break;
}
args->ioctl_return = 0;
return RTEMS_SUCCESSFUL;
}
/*
* Handle ioctl request for ttyS1.
*/
rtems_device_driver
serial_mouse_control(rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
return serial_mouse_control_internal( BSP_UART_PORT, arg );
}
static int
conSetAttr(int port, int minor, const struct termios *t)
{
int baud;
switch (t->c_cflag & CBAUD)
{
case B50:
baud = 50;
break;
case B75:
baud = 75;
break;
case B110:
baud = 110;
break;
case B134:
baud = 134;
break;
case B150:
baud = 150;
break;
case B200:
baud = 200;
break;
case B300:
baud = 300;
break;
case B600:
baud = 600;
break;
case B1200:
baud = 1200;
break;
case B1800:
baud = 1800;
break;
case B2400:
baud = 2400;
break;
case B4800:
baud = 4800;
break;
case B9600:
baud = 9600;
break;
case B19200:
baud = 19200;
break;
case B38400:
baud = 38400;
break;
case B57600:
baud = 57600;
break;
case B115200:
baud = 115200;
break;
default:
baud = 0;
rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
return 0;
}
printk("Mouse baud, port=%X, baud=%d\n", port, baud );
BSP_uart_set_baud( port, baud );
return 0;
}
/*
* Handle ioctl request for ttyS2.
*/
static int
serial_mouse_conSetAttr( int minor, const struct termios *t)
{
return conSetAttr( BSP_UART_PORT, minor, t );
}

View File

@@ -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__ */

View File

@@ -0,0 +1,766 @@
/*
* Copyright (c) 1999 Greg Haerr <greg@censoft.com>
* Copyright (c) 1991 David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
* Alternate EGA/VGA Screen Driver Init, direct hw programming
*/
#include <i386_io.h>
#ifdef __rtems__
#define ROMFONT 0 /* =0 no bios rom fonts available*/
#else
#define ROMFONT 1 /* =1 uses PC rom fonts */
#endif
/* defines are defined in device.h of the MicroWindows package */
#define MODE_SET 0 /* draw pixels as given (default) */
#define MODE_XOR 1 /* draw pixels using XOR */
#define MODE_OR 2 /* draw pixels using OR (notimp)*/
#define MODE_AND 3 /* draw pixels using AND (notimp)*/
#define MODE_MAX 3
typedef int MODE; /* drawing mode*/
/* Define one and only one of the following to be nonzero*/
#define VGA_ET4000 0 /* TSENG LABS ET4000 chip 800x600*/
#define VGA_STANDARD 1 /* standard VGA 640x480*/
#define EGA_STANDARD 0 /* standard EGA 640x350*/
#define DONE 0
#define IN 1
#define OUT 2
#define RAM_SCAN_LINES 32 /* number of scan lines in fonts in RAM */
#define FONT_CHARS 256 /* number of characters in font tables */
#define CHAR_WIDTH 8 /* number of pixels for character width */
#define PALREG 0x3c0
#define SEQREG 0x3c4
#define SEQVAL 0x3c5
#define GRREG 0x3ce
#define GRVAL 0x3cf
#define ATTRREG 0x3da
#define CRTCREG 0x3d4
#define CRTCVAL 0x3d5
#define GENREG1 0x3c2
#define GENREG2 0x3cc
#define GENREG3 0x3ca
#define DATA_ROTATE 3 /* register number for data rotate */
typedef struct {
int action;
int port1;
int data1;
int port2;
int data2;
} REGIO;
/* extern data*/
#if ROMFONT
extern FARADDR rom_char_addr; /* address of ROM font*/
extern int ROM_CHAR_HEIGHT; /* ROM character height*/
#endif
/* local data*/
extern REGIO graphics_on[];
extern REGIO graph_off[];
/* entry points*/
void ega_hwinit(void);
void ega_hwterm(void);
/* local routines*/
static void writeregs(REGIO *rp);
static void out_word(unsigned int p,unsigned int d);
static void setmode(MODE mode);
void
ega_hwinit(void)
{
writeregs(graphics_on);
}
void
ega_hwterm(void)
{
setmode(MODE_SET);
/* Copy character table from ROM back into bit plane 2 before turning
* off graphics.
*/
out_word(SEQREG, 0x0100); /* syn reset */
out_word(SEQREG, 0x0402); /* cpu writes only to map 2 */
out_word(SEQREG, 0x0704); /* sequential addressing */
out_word(SEQREG, 0x0300); /* clear synchronous reset */
out_word(GRREG, 0x0204); /* select map 2 for CPU reads */
out_word(GRREG, 0x0005); /* disable odd-even addressing */
#if ROMFONT
{
FARADDR srcoffset;
FARADDR destoffset;
int data;
int ch;
int row;
srcoffset = rom_char_addr;
destoffset = EGA_BASE;
for (ch = 0; ch < FONT_CHARS; ch++) {
for(row = 0; row < ROM_CHAR_HEIGHT; row++) {
data = GETBYTE_FP(srcoffset++);
PUTBYTE_FP(destoffset++, data);
}
destoffset += (RAM_SCAN_LINES - ROM_CHAR_HEIGHT);
}
}
#endif
/* Finally set the registers back for text mode. */
writeregs(graph_off);
}
/* Set the graphics registers as indicated by the given table */
static void
writeregs(REGIO *rp)
{
for (; rp->action != DONE; rp++) {
switch (rp->action) {
case IN:
inp(rp->port1);
break;
case OUT:
outp(rp->port1, rp->data1);
if (rp->port2)
outp(rp->port2, rp->data2);
break;
}
}
}
/* Output a word to an I/O port. */
static void
out_word(unsigned int p,unsigned int d)
{
outp(p, d & 0xff);
outp(p + 1, (d >> 8) & 0xff);
}
/* Values for the data rotate register to implement drawing modes. */
static unsigned char mode_table[MODE_MAX + 1] = {
0x00, 0x18, 0x10, 0x08
};
/* Set the drawing mode.
* This is either SET, OR, AND, or XOR.
*/
static void
setmode(MODE mode)
{
if (mode > MODE_MAX)
return;
outp(GRREG, DATA_ROTATE);
outp(GRVAL, mode_table[mode]);
}
#if VGA_ET4000
/* VGA 800x600 16-color graphics (BIOS mode 0x29).
*/
static REGIO graphics_on[] = {
/* Reset attr F/F */
IN, ATTRREG, 0, 0, 0,
/* Disable palette */
OUT, PALREG, 0, 0, 0,
/* Reset sequencer regs */
OUT, SEQREG, 0, SEQVAL, 0,
OUT, SEQREG, 1, SEQVAL, 1,
OUT, SEQREG, 2, SEQVAL, 0x0f,
OUT, SEQREG, 3, SEQVAL, 0,
OUT, SEQREG, 4, SEQVAL, 6,
/* Misc out reg */
OUT, GENREG1, 0xe3, 0, 0,
/* Sequencer enable */
OUT, SEQREG, 0, SEQVAL, 0x03,
/* Unprotect crtc regs 0-7 */
OUT, CRTCREG, 0x11, CRTCVAL, 0,
/* Crtc */
OUT, CRTCREG, 0, CRTCVAL, 0x7a,
OUT, CRTCREG, 1, CRTCVAL, 0x63,
OUT, CRTCREG, 2, CRTCVAL, 0x64,
OUT, CRTCREG, 3, CRTCVAL, 0x1d,
OUT, CRTCREG, 4, CRTCVAL, 0x68,
OUT, CRTCREG, 5, CRTCVAL, 0x9a,
OUT, CRTCREG, 6, CRTCVAL, 0x78,
OUT, CRTCREG, 7, CRTCVAL, 0xf0,
OUT, CRTCREG, 8, CRTCVAL, 0x00,
OUT, CRTCREG, 9, CRTCVAL, 0x60,
OUT, CRTCREG, 10, CRTCVAL, 0x00,
OUT, CRTCREG, 11, CRTCVAL, 0x00,
OUT, CRTCREG, 12, CRTCVAL, 0x00,
OUT, CRTCREG, 13, CRTCVAL, 0x00,
OUT, CRTCREG, 14, CRTCVAL, 0x00,
OUT, CRTCREG, 15, CRTCVAL, 0x00,
OUT, CRTCREG, 16, CRTCVAL, 0x5c,
OUT, CRTCREG, 17, CRTCVAL, 0x8e,
OUT, CRTCREG, 18, CRTCVAL, 0x57,
OUT, CRTCREG, 19, CRTCVAL, 0x32,
OUT, CRTCREG, 20, CRTCVAL, 0x00,
OUT, CRTCREG, 21, CRTCVAL, 0x5b,
OUT, CRTCREG, 22, CRTCVAL, 0x75,
OUT, CRTCREG, 23, CRTCVAL, 0xc3,
OUT, CRTCREG, 24, CRTCVAL, 0xff,
/* Graphics controller */
OUT, GENREG2, 0x00, 0, 0,
OUT, GENREG3, 0x01, 0, 0,
OUT, GRREG, 0, GRVAL, 0x00,
OUT, GRREG, 1, GRVAL, 0x00,
OUT, GRREG, 2, GRVAL, 0x00,
OUT, GRREG, 3, GRVAL, 0x00,
OUT, GRREG, 4, GRVAL, 0x00,
OUT, GRREG, 5, GRVAL, 0x00,
OUT, GRREG, 6, GRVAL, 0x05,
OUT, GRREG, 7, GRVAL, 0x0f,
OUT, GRREG, 8, GRVAL, 0xff,
/* Reset attribute flip/flop */
IN, ATTRREG, 0, 0, 0,
/* Palette */
OUT, PALREG, 0, PALREG, 0x00,
OUT, PALREG, 1, PALREG, 0x01,
OUT, PALREG, 2, PALREG, 0x02,
OUT, PALREG, 3, PALREG, 0x03,
OUT, PALREG, 4, PALREG, 0x04,
OUT, PALREG, 5, PALREG, 0x05,
OUT, PALREG, 6, PALREG, 0x06,
OUT, PALREG, 7, PALREG, 0x07,
OUT, PALREG, 8, PALREG, 0x38,
OUT, PALREG, 9, PALREG, 0x39,
OUT, PALREG, 10, PALREG, 0x3a,
OUT, PALREG, 11, PALREG, 0x3b,
OUT, PALREG, 12, PALREG, 0x3c,
OUT, PALREG, 13, PALREG, 0x3d,
OUT, PALREG, 14, PALREG, 0x3e,
OUT, PALREG, 15, PALREG, 0x3f,
OUT, PALREG, 16, PALREG, 0x01,
OUT, PALREG, 17, PALREG, 0x00,
OUT, PALREG, 18, PALREG, 0x0f,
OUT, PALREG, 19, PALREG, 0x00,
/* Enable palette */
OUT, PALREG, 0x20, 0, 0,
/* End of table */
DONE, 0, 0, 0, 0
};
/* VGA 80x25 text (BIOS mode 3).
*/
static REGIO graph_off[] = {
/* Reset attr F/F */
IN, ATTRREG, 0, 0, 0,
/* Disable palette */
OUT, PALREG, 0, 0, 0,
/* Reset sequencer regs */
OUT, SEQREG, 0, SEQVAL, 1,
OUT, SEQREG, 1, SEQVAL, 1,
OUT, SEQREG, 2, SEQVAL, 3,
OUT, SEQREG, 3, SEQVAL, 0,
OUT, SEQREG, 4, SEQVAL, 2,
/* Misc out reg */
OUT, GENREG1, 0x63, 0, 0,
/* Sequencer enable */
OUT, SEQREG, 0, SEQVAL, 3,
/* Unprotect crtc regs 0-7 */
OUT, CRTCREG, 0x11, CRTCVAL, 0,
/* Crtc */
OUT, CRTCREG, 0, CRTCVAL, 0x5f, /* horiz total */
OUT, CRTCREG, 1, CRTCVAL, 0x4f, /* horiz end */
OUT, CRTCREG, 2, CRTCVAL, 0x50, /* horiz blank */
OUT, CRTCREG, 3, CRTCVAL, 0x82, /* end blank */
OUT, CRTCREG, 4, CRTCVAL, 0x55, /* horiz retrace */
OUT, CRTCREG, 5, CRTCVAL, 0x81, /* end retrace */
OUT, CRTCREG, 6, CRTCVAL, 0xbf, /* vert total */
OUT, CRTCREG, 7, CRTCVAL, 0x1f, /* overflows */
OUT, CRTCREG, 8, CRTCVAL, 0x00, /* row scan */
OUT, CRTCREG, 9, CRTCVAL, 0x4f, /* max scan line */
OUT, CRTCREG, 10, CRTCVAL, 0x00, /* cursor start */
OUT, CRTCREG, 11, CRTCVAL, 0x0f, /* cursor end */
OUT, CRTCREG, 12, CRTCVAL, 0x0e, /* start high addr */
OUT, CRTCREG, 13, CRTCVAL, 0xb0, /* low addr */
OUT, CRTCREG, 14, CRTCVAL, 0x16, /* cursor high */
OUT, CRTCREG, 15, CRTCVAL, 0x30, /* cursor low */
OUT, CRTCREG, 16, CRTCVAL, 0x9c, /* vert retrace */
OUT, CRTCREG, 17, CRTCVAL, 0x8e, /* retrace end */
OUT, CRTCREG, 18, CRTCVAL, 0x8f, /* vert end */
OUT, CRTCREG, 19, CRTCVAL, 0x28, /* offset */
OUT, CRTCREG, 20, CRTCVAL, 0x1f, /* underline */
OUT, CRTCREG, 21, CRTCVAL, 0x96, /* vert blank */
OUT, CRTCREG, 22, CRTCVAL, 0xb9, /* end blank */
OUT, CRTCREG, 23, CRTCVAL, 0xa3, /* crt mode */
OUT, CRTCREG, 24, CRTCVAL, 0xff, /* line compare */
/* Graphics controller */
OUT, GENREG2, 0x00, 0, 0,
OUT, GENREG3, 0x01, 0, 0,
OUT, GRREG, 0, GRVAL, 0x00,
OUT, GRREG, 1, GRVAL, 0x00,
OUT, GRREG, 2, GRVAL, 0x00,
OUT, GRREG, 3, GRVAL, 0x00,
OUT, GRREG, 4, GRVAL, 0x00,
OUT, GRREG, 5, GRVAL, 0x10,
OUT, GRREG, 6, GRVAL, 0x0e,
OUT, GRREG, 7, GRVAL, 0x00,
OUT, GRREG, 8, GRVAL, 0xff,
/* Reset attribute flip/flop */
IN, ATTRREG, 0, 0, 0,
/* Palette */
OUT, PALREG, 0, PALREG, 0x00,
OUT, PALREG, 1, PALREG, 0x01,
OUT, PALREG, 2, PALREG, 0x02,
OUT, PALREG, 3, PALREG, 0x03,
OUT, PALREG, 4, PALREG, 0x04,
OUT, PALREG, 5, PALREG, 0x05,
OUT, PALREG, 6, PALREG, 0x06,
OUT, PALREG, 7, PALREG, 0x07,
OUT, PALREG, 8, PALREG, 0x10,
OUT, PALREG, 9, PALREG, 0x11,
OUT, PALREG, 10, PALREG, 0x12,
OUT, PALREG, 11, PALREG, 0x13,
OUT, PALREG, 12, PALREG, 0x14,
OUT, PALREG, 13, PALREG, 0x15,
OUT, PALREG, 14, PALREG, 0x16,
OUT, PALREG, 15, PALREG, 0x17,
OUT, PALREG, 16, PALREG, 0x08,
OUT, PALREG, 17, PALREG, 0x00,
OUT, PALREG, 18, PALREG, 0x0f,
OUT, PALREG, 19, PALREG, 0x00,
/* Enable palette */
OUT, PALREG, 0x20, 0, 0,
/* End of table */
DONE, 0, 0, 0, 0
};
#endif
#if VGA_STANDARD
/* VGA 640x480 16-color graphics (BIOS mode 0x12).
*/
static REGIO graphics_on[] = {
/* Reset attr F/F */
IN, ATTRREG, 0, 0, 0,
/* Disable palette */
OUT, PALREG, 0, 0, 0,
/* Reset sequencer regs */
OUT, SEQREG, 0, SEQVAL, 0,
OUT, SEQREG, 1, SEQVAL, 1,
OUT, SEQREG, 2, SEQVAL, 0x0f,
OUT, SEQREG, 3, SEQVAL, 0,
OUT, SEQREG, 4, SEQVAL, 6,
/* Misc out reg */
OUT, GENREG1, 0xe3, 0, 0,
/* Sequencer enable */
OUT, SEQREG, 0, SEQVAL, 0x03,
/* Unprotect crtc regs 0-7 */
OUT, CRTCREG, 0x11, CRTCVAL, 0,
/* Crtc */
OUT, CRTCREG, 0, CRTCVAL, 0x5f,
OUT, CRTCREG, 1, CRTCVAL, 0x4f,
OUT, CRTCREG, 2, CRTCVAL, 0x50,
OUT, CRTCREG, 3, CRTCVAL, 0x82,
OUT, CRTCREG, 4, CRTCVAL, 0x54,
OUT, CRTCREG, 5, CRTCVAL, 0x80,
OUT, CRTCREG, 6, CRTCVAL, 0x0b,
OUT, CRTCREG, 7, CRTCVAL, 0x3e,
OUT, CRTCREG, 8, CRTCVAL, 0x00,
OUT, CRTCREG, 9, CRTCVAL, 0x40,
OUT, CRTCREG, 10, CRTCVAL, 0x00,
OUT, CRTCREG, 11, CRTCVAL, 0x00,
OUT, CRTCREG, 12, CRTCVAL, 0x00,
OUT, CRTCREG, 13, CRTCVAL, 0x00,
OUT, CRTCREG, 14, CRTCVAL, 0x00,
OUT, CRTCREG, 15, CRTCVAL, 0x59,
OUT, CRTCREG, 16, CRTCVAL, 0xea,
OUT, CRTCREG, 17, CRTCVAL, 0x8c,
OUT, CRTCREG, 18, CRTCVAL, 0xdf,
OUT, CRTCREG, 19, CRTCVAL, 0x28,
OUT, CRTCREG, 20, CRTCVAL, 0x00,
OUT, CRTCREG, 21, CRTCVAL, 0xe7,
OUT, CRTCREG, 22, CRTCVAL, 0x04,
OUT, CRTCREG, 23, CRTCVAL, 0xe3,
OUT, CRTCREG, 24, CRTCVAL, 0xff,
/* Graphics controller */
OUT, GENREG2, 0x00, 0, 0,
OUT, GENREG3, 0x01, 0, 0,
OUT, GRREG, 0, GRVAL, 0x00,
OUT, GRREG, 1, GRVAL, 0x00,
OUT, GRREG, 2, GRVAL, 0x00,
OUT, GRREG, 3, GRVAL, 0x00,
OUT, GRREG, 4, GRVAL, 0x00,
OUT, GRREG, 5, GRVAL, 0x00,
OUT, GRREG, 6, GRVAL, 0x05,
OUT, GRREG, 7, GRVAL, 0x0f,
OUT, GRREG, 8, GRVAL, 0xff,
/* Reset attribute flip/flop */
IN, ATTRREG, 0, 0, 0,
/* Palette */
OUT, PALREG, 0, PALREG, 0x00,
OUT, PALREG, 1, PALREG, 0x01,
OUT, PALREG, 2, PALREG, 0x02,
OUT, PALREG, 3, PALREG, 0x03,
OUT, PALREG, 4, PALREG, 0x04,
OUT, PALREG, 5, PALREG, 0x05,
OUT, PALREG, 6, PALREG, 0x06,
OUT, PALREG, 7, PALREG, 0x07,
OUT, PALREG, 8, PALREG, 0x38,
OUT, PALREG, 9, PALREG, 0x39,
OUT, PALREG, 10, PALREG, 0x3a,
OUT, PALREG, 11, PALREG, 0x3b,
OUT, PALREG, 12, PALREG, 0x3c,
OUT, PALREG, 13, PALREG, 0x3d,
OUT, PALREG, 14, PALREG, 0x3e,
OUT, PALREG, 15, PALREG, 0x3f,
OUT, PALREG, 16, PALREG, 0x01,
OUT, PALREG, 17, PALREG, 0x00,
OUT, PALREG, 18, PALREG, 0x0f,
OUT, PALREG, 19, PALREG, 0x00,
/* Enable palette */
OUT, PALREG, 0x20, 0, 0,
/* End of table */
DONE, 0, 0, 0, 0
};
/* VGA 80x25 text (BIOS mode 3).
*/
static REGIO graph_off[] = {
/* Reset attr F/F */
IN, ATTRREG, 0, 0, 0,
/* Disable palette */
OUT, PALREG, 0, 0, 0,
/* Reset sequencer regs */
OUT, SEQREG, 0, SEQVAL, 1,
OUT, SEQREG, 1, SEQVAL, 1,
OUT, SEQREG, 2, SEQVAL, 3,
OUT, SEQREG, 3, SEQVAL, 0,
OUT, SEQREG, 4, SEQVAL, 2,
/* Misc out reg */
OUT, GENREG1, 0x63, 0, 0,
/* Sequencer enable */
OUT, SEQREG, 0, SEQVAL, 3,
/* Unprotect crtc regs 0-7 */
OUT, CRTCREG, 0x11, CRTCVAL, 0,
/* Crtc */
OUT, CRTCREG, 0, CRTCVAL, 0x5f, /* horiz total */
OUT, CRTCREG, 1, CRTCVAL, 0x4f, /* horiz end */
OUT, CRTCREG, 2, CRTCVAL, 0x50, /* horiz blank */
OUT, CRTCREG, 3, CRTCVAL, 0x82, /* end blank */
OUT, CRTCREG, 4, CRTCVAL, 0x55, /* horiz retrace */
OUT, CRTCREG, 5, CRTCVAL, 0x81, /* end retrace */
OUT, CRTCREG, 6, CRTCVAL, 0xbf, /* vert total */
OUT, CRTCREG, 7, CRTCVAL, 0x1f, /* overflows */
OUT, CRTCREG, 8, CRTCVAL, 0x00, /* row scan */
OUT, CRTCREG, 9, CRTCVAL, 0x4f, /* max scan line */
OUT, CRTCREG, 10, CRTCVAL, 0x00, /* cursor start */
OUT, CRTCREG, 11, CRTCVAL, 0x0f, /* cursor end */
OUT, CRTCREG, 12, CRTCVAL, 0x0e, /* start high addr */
OUT, CRTCREG, 13, CRTCVAL, 0xb0, /* low addr */
OUT, CRTCREG, 14, CRTCVAL, 0x16, /* cursor high */
OUT, CRTCREG, 15, CRTCVAL, 0x30, /* cursor low */
OUT, CRTCREG, 16, CRTCVAL, 0x9c, /* vert retrace */
OUT, CRTCREG, 17, CRTCVAL, 0x8e, /* retrace end */
OUT, CRTCREG, 18, CRTCVAL, 0x8f, /* vert end */
OUT, CRTCREG, 19, CRTCVAL, 0x28, /* offset */
OUT, CRTCREG, 20, CRTCVAL, 0x1f, /* underline */
OUT, CRTCREG, 21, CRTCVAL, 0x96, /* vert blank */
OUT, CRTCREG, 22, CRTCVAL, 0xb9, /* end blank */
OUT, CRTCREG, 23, CRTCVAL, 0xa3, /* crt mode */
OUT, CRTCREG, 24, CRTCVAL, 0xff, /* line compare */
/* Graphics controller */
OUT, GENREG2, 0x00, 0, 0,
OUT, GENREG3, 0x01, 0, 0,
OUT, GRREG, 0, GRVAL, 0x00,
OUT, GRREG, 1, GRVAL, 0x00,
OUT, GRREG, 2, GRVAL, 0x00,
OUT, GRREG, 3, GRVAL, 0x00,
OUT, GRREG, 4, GRVAL, 0x00,
OUT, GRREG, 5, GRVAL, 0x10,
OUT, GRREG, 6, GRVAL, 0x0e,
OUT, GRREG, 7, GRVAL, 0x00,
OUT, GRREG, 8, GRVAL, 0xff,
/* Reset attribute flip/flop */
IN, ATTRREG, 0, 0, 0,
/* Palette */
OUT, PALREG, 0, PALREG, 0x00,
OUT, PALREG, 1, PALREG, 0x01,
OUT, PALREG, 2, PALREG, 0x02,
OUT, PALREG, 3, PALREG, 0x03,
OUT, PALREG, 4, PALREG, 0x04,
OUT, PALREG, 5, PALREG, 0x05,
OUT, PALREG, 6, PALREG, 0x06,
OUT, PALREG, 7, PALREG, 0x07,
OUT, PALREG, 8, PALREG, 0x10,
OUT, PALREG, 9, PALREG, 0x11,
OUT, PALREG, 10, PALREG, 0x12,
OUT, PALREG, 11, PALREG, 0x13,
OUT, PALREG, 12, PALREG, 0x14,
OUT, PALREG, 13, PALREG, 0x15,
OUT, PALREG, 14, PALREG, 0x16,
OUT, PALREG, 15, PALREG, 0x17,
OUT, PALREG, 16, PALREG, 0x08,
OUT, PALREG, 17, PALREG, 0x00,
OUT, PALREG, 18, PALREG, 0x0f,
OUT, PALREG, 19, PALREG, 0x00,
/* Enable palette */
OUT, PALREG, 0x20, 0, 0,
/* End of table */
DONE, 0, 0, 0, 0
};
#endif
#if EGA_STANDARD
/* EGA 640x350 16-color graphics (BIOS mode 0x10).
*/
static REGIO graphics_on[] = {
/* Reset attr F/F */
IN, ATTRREG, 0, 0, 0,
/* Disable palette */
OUT, PALREG, 0, 0, 0,
/* Reset sequencer regs */
OUT, SEQREG, 0, SEQVAL, 0,
OUT, SEQREG, 1, SEQVAL, 1,
OUT, SEQREG, 2, SEQVAL, 0x0f,
OUT, SEQREG, 3, SEQVAL, 0,
OUT, SEQREG, 4, SEQVAL, 6,
/* Misc out reg */
OUT, GENREG1, 0xa7, 0, 0,
/* Sequencer enable */
OUT, SEQREG, 0, SEQVAL, 0x03,
/* Unprotect crtc regs 0-7 */
OUT, CRTCREG, 0x11, CRTCVAL, 0,
/* Crtc */
OUT, CRTCREG, 0, CRTCVAL, 0x5b,
OUT, CRTCREG, 1, CRTCVAL, 0x4f,
OUT, CRTCREG, 2, CRTCVAL, 0x53,
OUT, CRTCREG, 3, CRTCVAL, 0x37,
OUT, CRTCREG, 4, CRTCVAL, 0x52,
OUT, CRTCREG, 5, CRTCVAL, 0x00,
OUT, CRTCREG, 6, CRTCVAL, 0x6c,
OUT, CRTCREG, 7, CRTCVAL, 0x1f,
OUT, CRTCREG, 8, CRTCVAL, 0x00,
OUT, CRTCREG, 9, CRTCVAL, 0x00,
OUT, CRTCREG, 10, CRTCVAL, 0x00,
OUT, CRTCREG, 11, CRTCVAL, 0x00,
OUT, CRTCREG, 12, CRTCVAL, 0x00,
OUT, CRTCREG, 13, CRTCVAL, 0x00,
OUT, CRTCREG, 14, CRTCVAL, 0x00,
OUT, CRTCREG, 15, CRTCVAL, 0x00,
OUT, CRTCREG, 16, CRTCVAL, 0x5e,
OUT, CRTCREG, 17, CRTCVAL, 0x2b,
OUT, CRTCREG, 18, CRTCVAL, 0x5d,
OUT, CRTCREG, 19, CRTCVAL, 0x28,
OUT, CRTCREG, 20, CRTCVAL, 0x0f,
OUT, CRTCREG, 21, CRTCVAL, 0x5f,
OUT, CRTCREG, 22, CRTCVAL, 0x0a,
OUT, CRTCREG, 23, CRTCVAL, 0xe3,
OUT, CRTCREG, 24, CRTCVAL, 0xff,
/* Graphics controller */
OUT, GENREG2, 0x00, 0, 0,
OUT, GENREG3, 0x01, 0, 0,
OUT, GRREG, 0, GRVAL, 0x00,
OUT, GRREG, 1, GRVAL, 0x00,
OUT, GRREG, 2, GRVAL, 0x00,
OUT, GRREG, 3, GRVAL, 0x00,
OUT, GRREG, 4, GRVAL, 0x00,
OUT, GRREG, 5, GRVAL, 0x00,
OUT, GRREG, 6, GRVAL, 0x05,
OUT, GRREG, 7, GRVAL, 0x0f,
OUT, GRREG, 8, GRVAL, 0xff,
/* Reset attribute flip/flop */
IN, ATTRREG, 0, 0, 0,
/* Palette */
OUT, PALREG, 0, PALREG, 0x00,
OUT, PALREG, 1, PALREG, 0x01,
OUT, PALREG, 2, PALREG, 0x02,
OUT, PALREG, 3, PALREG, 0x03,
OUT, PALREG, 4, PALREG, 0x04,
OUT, PALREG, 5, PALREG, 0x05,
OUT, PALREG, 6, PALREG, 0x06,
OUT, PALREG, 7, PALREG, 0x07,
OUT, PALREG, 8, PALREG, 0x38,
OUT, PALREG, 9, PALREG, 0x39,
OUT, PALREG, 10, PALREG, 0x3a,
OUT, PALREG, 11, PALREG, 0x3b,
OUT, PALREG, 12, PALREG, 0x3c,
OUT, PALREG, 13, PALREG, 0x3d,
OUT, PALREG, 14, PALREG, 0x3e,
OUT, PALREG, 15, PALREG, 0x3f,
OUT, PALREG, 16, PALREG, 0x01,
OUT, PALREG, 17, PALREG, 0x00,
OUT, PALREG, 18, PALREG, 0x0f,
OUT, PALREG, 19, PALREG, 0x00,
/* Enable palette */
OUT, PALREG, 0x20, 0, 0,
/* End of table */
DONE, 0, 0, 0, 0
};
/* EGA 80x25 text (BIOS mode 3).
*/
static REGIO graph_off[] = {
/* Reset attr F/F */
IN, ATTRREG, 0, 0, 0,
/* Disable palette */
OUT, PALREG, 0, 0, 0,
/* Reset sequencer regs */
OUT, SEQREG, 0, SEQVAL, 1,
OUT, SEQREG, 1, SEQVAL, 1,
OUT, SEQREG, 2, SEQVAL, 3,
OUT, SEQREG, 3, SEQVAL, 0,
OUT, SEQREG, 4, SEQVAL, 3,
/* Misc out reg */
OUT, GENREG1, 0xa7, 0, 0,
/* Sequencer enable */
OUT, SEQREG, 0, SEQVAL, 3,
/* Crtc */
OUT, CRTCREG, 0, CRTCVAL, 0x5b, /* horiz total */
OUT, CRTCREG, 1, CRTCVAL, 0x4f, /* horiz end */
OUT, CRTCREG, 2, CRTCVAL, 0x53, /* horiz blank */
OUT, CRTCREG, 3, CRTCVAL, 0x37, /* end blank */
OUT, CRTCREG, 4, CRTCVAL, 0x51, /* horiz retrace */
OUT, CRTCREG, 5, CRTCVAL, 0x5b, /* end retrace */
OUT, CRTCREG, 6, CRTCVAL, 0x6c, /* vert total */
OUT, CRTCREG, 7, CRTCVAL, 0x1f, /* overflows */
OUT, CRTCREG, 8, CRTCVAL, 0x00, /* row scan */
OUT, CRTCREG, 9, CRTCVAL, 0x0d, /* max scan line */
OUT, CRTCREG, 10, CRTCVAL, 0x00, /* cursor start */
OUT, CRTCREG, 11, CRTCVAL, 0x0f, /* cursor end */
OUT, CRTCREG, 12, CRTCVAL, 0x00, /* start high addr */
OUT, CRTCREG, 13, CRTCVAL, 0x00, /* low addr */
OUT, CRTCREG, 14, CRTCVAL, 0x00, /* cursor high */
OUT, CRTCREG, 15, CRTCVAL, 0x00, /* cursor low */
OUT, CRTCREG, 16, CRTCVAL, 0x5e, /* vert retrace */
OUT, CRTCREG, 17, CRTCVAL, 0x2b, /* retrace end */
OUT, CRTCREG, 18, CRTCVAL, 0x5d, /* vert end */
OUT, CRTCREG, 19, CRTCVAL, 0x28, /* offset */
OUT, CRTCREG, 20, CRTCVAL, 0x0f, /* underline */
OUT, CRTCREG, 21, CRTCVAL, 0x5e, /* vert blank */
OUT, CRTCREG, 22, CRTCVAL, 0x0a, /* end blank */
OUT, CRTCREG, 23, CRTCVAL, 0xa3, /* crt mode */
OUT, CRTCREG, 24, CRTCVAL, 0xff, /* line compare */
/* Graphics controller */
OUT, GENREG2, 0x00, 0, 0,
OUT, GENREG3, 0x01, 0, 0,
OUT, GRREG, 0, GRVAL, 0x00,
OUT, GRREG, 1, GRVAL, 0x00,
OUT, GRREG, 2, GRVAL, 0x00,
OUT, GRREG, 3, GRVAL, 0x00,
OUT, GRREG, 4, GRVAL, 0x00,
OUT, GRREG, 5, GRVAL, 0x10,
OUT, GRREG, 6, GRVAL, 0x0e,
OUT, GRREG, 7, GRVAL, 0x00,
OUT, GRREG, 8, GRVAL, 0xff,
/* Reset attribute flip/flop */
IN, ATTRREG, 0, 0, 0,
/* Palette */
OUT, PALREG, 0, PALREG, 0x00,
OUT, PALREG, 1, PALREG, 0x01,
OUT, PALREG, 2, PALREG, 0x02,
OUT, PALREG, 3, PALREG, 0x03,
OUT, PALREG, 4, PALREG, 0x04,
OUT, PALREG, 5, PALREG, 0x05,
OUT, PALREG, 6, PALREG, 0x14,
OUT, PALREG, 7, PALREG, 0x07,
OUT, PALREG, 8, PALREG, 0x38,
OUT, PALREG, 9, PALREG, 0x39,
OUT, PALREG, 10, PALREG, 0x3a,
OUT, PALREG, 11, PALREG, 0x3b,
OUT, PALREG, 12, PALREG, 0x3c,
OUT, PALREG, 13, PALREG, 0x3d,
OUT, PALREG, 14, PALREG, 0x3e,
OUT, PALREG, 15, PALREG, 0x3f,
OUT, PALREG, 16, PALREG, 0x08,
OUT, PALREG, 17, PALREG, 0x00,
OUT, PALREG, 18, PALREG, 0x0f,
OUT, PALREG, 19, PALREG, 0x00,
/* Enable palette */
OUT, PALREG, 0x20, 0, 0,
/* End of table */
DONE, 0, 0, 0, 0
};
#endif

View File

@@ -0,0 +1,347 @@
/*
* linux/drivers/char/vt.c
*
* Copyright (C) 1992 obz under the linux copyright
*
* Dynamic diacritical handling - aeb@cwi.nl - Dec 1993
* Dynamic keymap and string allocation - aeb@cwi.nl - May 1994
* Restrict VT switching via ioctl() - grif@cs.ucr.edu - Dec 1995
* Some code moved for less code duplication - Andi Kleen - Mar 1997
*
*
* by: Rosimildo da Silva --
* Ported to RTEMS to provide the basic interface to the console
* driver. Removed all stuff not required, such as VT_, Fonts, etc.
*/
#include <sys/types.h>
#include <errno.h>
#include <i386_io.h>
#include <rtems/kd.h>
#include <rtems/keyboard.h>
/*
* Console (vt and kd) routines, as defined by USL SVR4 manual, and by
* experimentation and study of X386 SYSV handling.
*
* One point of difference: SYSV vt's are /dev/vtX, which X >= 0, and
* /dev/console is a separate ttyp. Under Linux, /dev/tty0 is /dev/console,
* and the vc start at /dev/ttyX, X >= 1. We maintain that here, so we will
* always treat our set of vt as numbered 1..MAX_NR_CONSOLES (corresponding to
* ttys 0..MAX_NR_CONSOLES-1). Explicitly naming VT 0 is illegal, but using
* /dev/tty0 (fg_console) as a target is legal, since an implicit aliasing
* to the current console is done by the main ioctl code.
*/
struct vt_struct *vt_cons[MAX_NR_CONSOLES];
/* Keyboard type: Default is KB_101, but can be set by machine
* specific code.
*/
unsigned char keyboard_type = KB_101;
/*
* Generates sound of some frequency for some number of clock ticks
*
* If freq is 0, will turn off sound, else will turn it on for that time.
* If msec is 0, will return immediately, else will sleep for msec time, then
* turn sound off.
*
* We also return immediately, which is what was implied within the X
* comments - KDMKTONE doesn't put the process to sleep.
*/
#if defined(__i386__) || defined(__alpha__) || defined(__powerpc__) \
|| (defined(__mips__) && !defined(CONFIG_SGI))
static void
kd_nosound(unsigned long ignored)
{
/* disable counter 2 */
outb(inb_p(0x61)&0xFC, 0x61);
return;
}
void
_kd_mksound(unsigned int hz, unsigned int ticks)
{
unsigned int count = 0;
if (hz > 20 && hz < 32767)
count = 1193180 / hz;
cli();
/* del_timer(&sound_timer); */
if (count) {
/* enable counter 2 */
outb_p(inb_p(0x61)|3, 0x61);
/* set command for counter 2, 2 byte write */
outb_p(0xB6, 0x43);
/* select desired HZ */
outb_p(count & 0xff, 0x42);
outb((count >> 8) & 0xff, 0x42);
/*
if (ticks) {
sound_timer.expires = jiffies+ticks;
add_timer(&sound_timer);
}
*/
} else
kd_nosound(0);
sti();
return;
}
#else
void
_kd_mksound(unsigned int hz, unsigned int ticks)
{
}
#endif
void (*kd_mksound)(unsigned int hz, unsigned int ticks) = _kd_mksound;
#define i (tmp.kb_index)
#define s (tmp.kb_table)
#define v (tmp.kb_value)
static inline int
do_kdsk_ioctl(int cmd, struct kbentry *user_kbe, int perm, struct kbd_struct *kbd)
{
struct kbentry tmp;
ushort *key_map, val;
tmp = *user_kbe;
if (i >= NR_KEYS || s >= MAX_NR_KEYMAPS)
return -EINVAL;
switch (cmd) {
case KDGKBENT:
key_map = key_maps[s];
if (key_map) {
val = U(key_map[i]);
if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
val = K_HOLE;
} else
val = (i ? K_HOLE : K_NOSUCHMAP);
user_kbe->kb_value = val;
return 0;
case KDSKBENT:
return -EINVAL;
}
return 0;
}
#undef i
#undef s
#undef v
#define HZ 100
static inline int
do_kbkeycode_ioctl(int cmd, struct kbkeycode *user_kbkc, int perm)
{
struct kbkeycode tmp;
int kc = 0;
tmp = *user_kbkc;
switch (cmd) {
case KDGETKEYCODE:
kc = getkeycode(tmp.scancode);
if (kc >= 0)
user_kbkc->keycode = kc;
break;
case KDSETKEYCODE:
if (!perm)
return -EPERM;
kc = setkeycode(tmp.scancode, tmp.keycode);
break;
}
return kc;
}
static inline int
do_kdgkb_ioctl(int cmd, struct kbsentry *user_kdgkb, int perm)
{
return -EINVAL;
}
/*
* We handle the console-specific ioctl's here. We allow the
* capability to modify any console, not just the fg_console.
*/
int vt_ioctl( unsigned int cmd, unsigned long arg)
{
int perm;
unsigned int console;
unsigned char ucval;
struct kbd_struct * kbd;
console = 0;
/*
* To have permissions to do most of the vt ioctls, we either have
* to be the owner of the tty, or super-user.
*/
perm = 1;
kbd = kbd_table + console;
switch (cmd) {
case KIOCSOUND:
if (!perm)
return -EPERM;
if (arg)
arg = 1193180 / arg;
kd_mksound(arg, 0);
return 0;
case KDMKTONE:
if (!perm)
return -EPERM;
{
unsigned int ticks, count;
/*
* Generate the tone for the appropriate number of ticks.
* If the time is zero, turn off sound ourselves.
*/
ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
count = ticks ? (arg & 0xffff) : 0;
if (count)
count = 1193180 / count;
kd_mksound(count, ticks);
return 0;
}
case KDGKBTYPE:
/*
* this is naive.
*/
ucval = keyboard_type;
goto setchar;
case KDSETMODE:
case KDGETMODE:
return -EINVAL;
case KDSKBMODE:
if (!perm)
return -EPERM;
switch(arg) {
case K_RAW:
kbd->kbdmode = VC_RAW;
break;
case K_MEDIUMRAW:
kbd->kbdmode = VC_MEDIUMRAW;
break;
case K_XLATE:
kbd->kbdmode = VC_XLATE;
compute_shiftstate();
break;
case K_UNICODE:
kbd->kbdmode = VC_UNICODE;
compute_shiftstate();
break;
default:
return -EINVAL;
}
return 0;
case KDGKBMODE:
ucval = ((kbd->kbdmode == VC_RAW) ? K_RAW :
(kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW :
(kbd->kbdmode == VC_UNICODE) ? K_UNICODE :
K_XLATE);
goto setint;
/* this could be folded into KDSKBMODE, but for compatibility
reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */
case KDSKBMETA:
switch(arg) {
case K_METABIT:
clr_vc_kbd_mode(kbd, VC_META);
break;
case K_ESCPREFIX:
set_vc_kbd_mode(kbd, VC_META);
break;
default:
return -EINVAL;
}
return 0;
case KDGKBMETA:
ucval = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT);
setint:
*(int *)arg = ucval;
return 0;
case KDGETKEYCODE:
case KDSETKEYCODE:
return do_kbkeycode_ioctl(cmd, (struct kbkeycode *)arg, perm);
case KDGKBENT:
case KDSKBENT:
return do_kdsk_ioctl(cmd, (struct kbentry *)arg, perm, kbd);
case KDGKBDIACR:
{
struct kbdiacrs *a = (struct kbdiacrs *)arg;
a->kb_cnt = accent_table_size;
memcpy( a->kbdiacr, accent_table, accent_table_size*sizeof(struct kbdiacr) );
return 0;
}
case KDSKBDIACR:
{
struct kbdiacrs *a = (struct kbdiacrs *)arg;
unsigned int ct;
if (!perm)
return -EPERM;
ct = a->kb_cnt;
if (ct >= MAX_DIACR)
return -EINVAL;
accent_table_size = ct;
memcpy(accent_table, a->kbdiacr, ct*sizeof(struct kbdiacr));
return 0;
}
/* the ioctls below read/set the flags usually shown in the leds */
/* don't use them - they will go away without warning */
case KDGKBLED:
ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4);
goto setchar;
case KDSKBLED:
if (!perm)
return -EPERM;
if (arg & ~0x77)
return -EINVAL;
kbd->ledflagstate = (arg & 7);
kbd->default_ledflagstate = ((arg >> 4) & 7);
set_leds();
return 0;
/* the ioctls below only set the lights, not the functions */
/* for those, see KDGKBLED and KDSKBLED above */
case KDGETLED:
ucval = getledstate();
setchar:
*(char*)arg = ucval;
return 0;
case KDSETLED:
if (!perm)
return -EPERM;
setledstate(kbd, arg);
return 0;
default:
return -EINVAL;
}
}

View File

@@ -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