5abbf990f3
a boot string for firmware that can do this, such as the SPARC and the sun3 models. It is currently silently ignored on all other hardware now, however. The MD function "boot()" has been changed to also take a char *.
1535 lines
36 KiB
C
1535 lines
36 KiB
C
/* $NetBSD: kbd.c,v 1.11 1996/08/09 10:30:23 mrg Exp $ */
|
|
|
|
/*
|
|
* Copyright (c) 1994 Mark Brinicombe.
|
|
* Copyright (c) 1994 Brini.
|
|
* All rights reserved.
|
|
*
|
|
* This code is derived from software written for Brini by Mark Brinicombe
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
* must display the following acknowledgement:
|
|
* This product includes software developed by Brini.
|
|
* 4. The name of the company nor the name of the author may be used to
|
|
* endorse or promote products derived from this software without specific
|
|
* prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
* RiscBSD kernel project
|
|
*
|
|
* kbd.c
|
|
*
|
|
* Keyboard driver functions
|
|
*
|
|
* Created : 09/10/94
|
|
*/
|
|
|
|
#include <sys/param.h>
|
|
#include <sys/systm.h>
|
|
#include <sys/kernel.h>
|
|
#include <sys/conf.h>
|
|
#include <sys/proc.h>
|
|
#include <sys/reboot.h>
|
|
#include <sys/device.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/malloc.h>
|
|
#include <sys/tty.h>
|
|
#include <sys/vnode.h>
|
|
#include <sys/select.h>
|
|
#include <sys/fcntl.h>
|
|
#include <sys/signalvar.h>
|
|
#include <sys/time.h>
|
|
|
|
#include <machine/irqhandler.h>
|
|
#include <machine/iomd.h>
|
|
#include <machine/vidc.h>
|
|
#include <machine/katelib.h>
|
|
#include <machine/kbd.h>
|
|
#include <arm32/mainbus/mainbus.h>
|
|
#include "vt.h"
|
|
#include "kbd.h"
|
|
|
|
|
|
/* Define the key_struct structure */
|
|
|
|
typedef struct {
|
|
int base_code; /* Base ASCII code */
|
|
int shift_code; /* Shifted ASCII code */
|
|
int ctrl_code; /* CTRL code */
|
|
int alt_code; /* Alt code */
|
|
int flags; /* Flags field */
|
|
} key_struct;
|
|
|
|
/* Define mappings for each possible code */
|
|
|
|
key_struct keys[256] = {
|
|
/* 0x00 - 0x0f */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x80 },
|
|
{ 0x89, 0x99, 0x00, 0x489, 0x00 },
|
|
{ 0x8a, 0x9a, 0x00, 0x00, 0x00 },
|
|
{ 0x85, 0x95, 0x00, 0x485, 0x00 },
|
|
{ 0x83, 0x93, 0x00, 0x483, 0x00 },
|
|
{ 0x81, 0x91, 0x00, 0x481, 0x00 },
|
|
{ 0x82, 0x92, 0x00, 0x482, 0x00 },
|
|
{ 0x8c, 0x9c, 0x00, 0x48c, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x88, 0x98, 0x00, 0x488, 0x00 },
|
|
{ 0x86, 0x96, 0x00, 0x486, 0x00 },
|
|
{ 0x84, 0x94, 0x00, 0x484, 0x00 },
|
|
{ 0x09, 0x09, 0x09, 0x09, 0x00 },
|
|
#ifdef RC7500
|
|
{ 0x60, 0x7e, 0x00, 0x00, 0x00 },
|
|
#else
|
|
{ 0x60, 0x00, 0x00, 0x00, 0x00 },
|
|
#endif
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0x10 - 0x1f */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x84 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x82 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x81 },
|
|
{ 0x71, 0x51, 0x11, 0x00, 0x40 },
|
|
{ 0x31, 0x21, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x7a, 0x5a, 0x1a, 0x00, 0x40 },
|
|
{ 0x73, 0x53, 0x13, 0x00, 0x40 },
|
|
{ 0x61, 0x41, 0x01, 0x00, 0x40 },
|
|
{ 0x77, 0x57, 0x17, 0x00, 0x40 },
|
|
{ 0x32, 0x22, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0x20 - 0x2f */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x63, 0x43, 0x03, 0x00, 0x40 },
|
|
{ 0x78, 0x58, 0x18, 0x00, 0x40 },
|
|
{ 0x64, 0x44, 0x04, 0x00, 0x40 },
|
|
{ 0x65, 0x45, 0x05, 0x00, 0x40 },
|
|
{ 0x34, 0x24, 0x00, 0x00, 0x00 },
|
|
{ 0x33, 0x23, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x20, 0x20, 0x20, 0x20, 0x00 },
|
|
{ 0x76, 0x56, 0x16, 0x00, 0x40 },
|
|
{ 0x66, 0x46, 0x06, 0x00, 0x40 },
|
|
{ 0x74, 0x54, 0x14, 0x00, 0x40 },
|
|
{ 0x72, 0x52, 0x12, 0x00, 0x40 },
|
|
{ 0x35, 0x25, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0x30 - 0x3f */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x6e, 0x4e, 0x0e, 0x00, 0x40 },
|
|
{ 0x62, 0x42, 0x02, 0x00, 0x40 },
|
|
{ 0x68, 0x48, 0x08, 0x00, 0x40 },
|
|
{ 0x67, 0x47, 0x07, 0x00, 0x40 },
|
|
{ 0x79, 0x59, 0x19, 0x00, 0x40 },
|
|
{ 0x36, 0x5e, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x6d, 0x4d, 0x0d, 0x00, 0x40 },
|
|
{ 0x6a, 0x4a, 0x0a, 0x00, 0x40 },
|
|
{ 0x75, 0x55, 0x15, 0x00, 0x40 },
|
|
{ 0x37, 0x26, 0x00, 0x00, 0x00 },
|
|
{ 0x38, 0x2a, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0x40 - 0x4f */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x2c, 0x3c, 0x00, 0x00, 0x00 },
|
|
{ 0x6b, 0x4b, 0x0b, 0x00, 0x40 },
|
|
{ 0x69, 0x49, 0x09, 0x00, 0x40 },
|
|
{ 0x6f, 0x4f, 0x0f, 0x00, 0x40 },
|
|
{ 0x30, 0x29, 0x00, 0x00, 0x00 },
|
|
{ 0x39, 0x28, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x2e, 0x3e, 0x00, 0x00, 0x00 },
|
|
{ 0x2f, 0x3f, 0x00, 0x00, 0x00 },
|
|
{ 0x6c, 0x4c, 0x0c, 0x00, 0x40 },
|
|
{ 0x3b, 0x3a, 0x00, 0x00, 0x00 },
|
|
{ 0x70, 0x50, 0x10, 0x00, 0x40 },
|
|
{ 0x2d, 0x5f, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0x50 - 0x5f */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
#ifdef RC7500
|
|
{ 0x27, 0x22, 0x00, 0x00, 0x00 },
|
|
#else
|
|
{ 0x27, 0x40, 0x00, 0x00, 0x00 },
|
|
#endif
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x5b, 0x7b, 0x00, 0x00, 0x00 },
|
|
{ 0x3d, 0x2b, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0xa0 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x82 },
|
|
{ 0x0d, 0x0d, 0x0d, 0x00, 0x00 },
|
|
{ 0x5d, 0x7d, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
#ifdef RC7500
|
|
{ 0x5c, 0x7c, 0x00, 0x00, 0x00 },
|
|
#else
|
|
{ 0x23, 0x7e, 0x00, 0x00, 0x00 },
|
|
#endif
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0x60 - 0x6f */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x5c, 0x7c, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x08, 0x7f, 0x08, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x31, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x34, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x37, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0x70 - 0x7f */
|
|
{ 0x30, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x2e, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x32, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x35, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x36, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x38, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x1b, 0x1b, 0x21b, 0x1b, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x90 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x2b, 0x00, 0x00, 0x22b, 0x00 },
|
|
{ 0x33, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x2d, 0x00, 0x00, 0x22d, 0x00 },
|
|
{ 0x2a, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x39, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x88 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0x80 - 0x8f */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x87, 0x97, 0x00, 0x487, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0x90 - 0x9f */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0xa0 - 0xaf */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0xb0 - 0xbf */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0xc0 - 0xcf */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0xd0 - 0xdf */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0xe0 - 0xef */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0xf0 - 0xff */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 }
|
|
};
|
|
|
|
/* Define mappings for each possible code */
|
|
|
|
key_struct E0keys[128] = {
|
|
|
|
/* 0x00 - 0x0f */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0x10 - 0x1f */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x84 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x81 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0x20 - 0x2f */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0x30 - 0x3f */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0x40 - 0x4f */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x2f, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0x50 - 0x5f */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x0d, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0x60 - 0x6f */
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x10b, 0x00, 0x00, 0x20b, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x102, 0x00, 0x00, 0x202, 0x00 },
|
|
{ 0x10a, 0x00, 0x00, 0x20a, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
|
|
/* 0x70 - 0x7f */
|
|
{ 0x108, 0x00, 0x00, 0x208, 0x00 },
|
|
{ 0x109, 0x00, 0x00, 0x209, 0x00 },
|
|
{ 0x101, 0x105, 0x00, 0x201, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x103, 0x00, 0x00, 0x203, 0x00 },
|
|
{ 0x100, 0x104, 0x00, 0x200, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x104, 0x100, 0x00, 0x204, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x105, 0x101, 0x00, 0x205, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
};
|
|
|
|
/* Special keycodes */
|
|
|
|
#define KEYCODE_UP 0x100
|
|
#define KEYCODE_DOWN 0x101
|
|
#define KEYCODE_LEFT 0x102
|
|
#define KEYCODE_RIGHT 0x103
|
|
#define KEYCODE_PGUP 0x104
|
|
#define KEYCODE_PGDN 0x105
|
|
#define KEYCODE_INSERT 0x108
|
|
#define KEYCODE_DELETE 0x109
|
|
#define KEYCODE_HOME 0x10a
|
|
#define KEYCODE_END 0x10b
|
|
|
|
/* Key modifiers flags */
|
|
|
|
#define MODIFIER_CTRL 0x01
|
|
#define MODIFIER_SHIFT 0x02
|
|
#define MODIFIER_ALT 0x04
|
|
#define MODIFIER_MASK 0x07
|
|
|
|
#define MODIFIER_CAPS 0x20
|
|
#define MODIFIER_NUM 0x10
|
|
#define MODIFIER_SCROLL 0x08
|
|
#define MODIFIER_LOCK_MASK 0x38
|
|
|
|
#define MODIFIER_CAPSLOCK 0x40
|
|
#define MODIFIER_NORETURN 0x80
|
|
|
|
/* Keyboard variables */
|
|
|
|
#define RAWKBD_BSIZE 128
|
|
|
|
static int autorepeatkey = -1;
|
|
static struct kbd_autorepeat kbdautorepeat = { 5, 20 };
|
|
static int rawkbd_device = 0;
|
|
int modifiers = 0;
|
|
static int kbd_ack = 0;
|
|
static int kbd_resend = 0;
|
|
|
|
extern int pmap_debug_level;
|
|
|
|
struct kbd_softc {
|
|
struct device sc_device;
|
|
irqhandler_t sc_ih;
|
|
|
|
int sc_state;
|
|
#define RAWKBD_OPEN 0x01
|
|
#define KBD_OPEN 0x02
|
|
#define RAWKBD_ASLEEP 0x04
|
|
int sc_iobase;
|
|
struct clist sc_q;
|
|
struct selinfo sc_rsel;
|
|
struct proc *sc_proc;
|
|
};
|
|
|
|
#define KBDUNIT(u) (minor(u) / 2)
|
|
#define KBDFLAG(u) (minor(u) % 2)
|
|
|
|
#define KBDFLAG_RAWUNIT 0
|
|
#define KBDFLAG_CONUNIT 1
|
|
|
|
/* Local function prototypes */
|
|
|
|
int kbdprobe __P((struct device *, void *, void *));
|
|
void kbdattach __P((struct device *, struct device *, void *));
|
|
|
|
int kbdopen __P((dev_t, int, int, struct proc *));
|
|
int kbdclose __P((dev_t, int, int, struct proc *));
|
|
int kbdread __P((dev_t, struct uio *, int));
|
|
int kbdselect __P((dev_t, int, struct proc *));
|
|
int kbdioctl __P((dev_t, int, caddr_t, int, struct proc *));
|
|
|
|
int kbdreset __P((void));
|
|
void kbd_flush_input __P((void));
|
|
int kbdcmd __P((u_char cmd));
|
|
void kbdsetleds __P((int /*leds*/));
|
|
|
|
int PollKeyboard __P((int));
|
|
int kbddecodekey __P((struct kbd_softc *, int));
|
|
int kbdintr __P((struct kbd_softc *));
|
|
|
|
void autorepeatstart __P((void *));
|
|
void autorepeat __P((void *));
|
|
|
|
extern int physconkbd __P((int key));
|
|
extern void console_switch __P((u_int number));
|
|
extern int console_switchdown __P((void));
|
|
extern int console_switchup __P((void));
|
|
extern int console_unblank __P((void));
|
|
extern int console_scrollback __P((void));
|
|
extern int console_scrollforward __P((void));
|
|
extern void pmap_debug __P((int level));
|
|
|
|
/* Device structures */
|
|
|
|
struct cfattach kbd_ca = {
|
|
sizeof(struct kbd_softc), kbdprobe, kbdattach
|
|
};
|
|
|
|
struct cfdriver kbd_cd = {
|
|
NULL, "kbd", DV_TTY
|
|
};
|
|
|
|
/* keyboard commands */
|
|
|
|
#define KBC_RESET 0xFF /* reset the keyboard */
|
|
#define KBC_RESEND 0xFE /* request the keyboard resend the last byte */
|
|
#define KBC_SET_TMB 0xFA /* What is this one ? */
|
|
#define KBC_SETDEFAULT 0xF6 /* resets keyboard to its power-on defaults */
|
|
#define KBC_DISABLE 0xF5 /* as per KBC_SETDEFAULT, but also disable key scanning */
|
|
#define KBC_ENABLE 0xF4 /* enable key scanning */
|
|
#define KBC_TYPEMATIC 0xF3 /* set typematic rate and delay */
|
|
#define KBC_SETSCANTBL 0xF0 /* set scancode translation table */
|
|
#define KBC_SETLEDS 0xED /* set mode indicators (i.e. LEDs) */
|
|
#define KBC_ECHO 0xEE /* request an echo from the keyboard */
|
|
|
|
#define KBD_SETSCAN_2 0x02
|
|
#define KBD_SETSCAN_3 0x03
|
|
|
|
/* keyboard responses */
|
|
#define KBR_EXTENDED 0xE0 /* extended key sequence */
|
|
#define KBR_RESEND 0xFE /* needs resend of command */
|
|
#define KBR_ACK 0xFA /* received a valid command */
|
|
#define KBR_OVERRUN 0x00 /* flooded */
|
|
#define KBR_FAILURE 0xFD /* diagnosic failure */
|
|
#define KBR_BREAK 0xF0 /* break code prefix - sent on key release */
|
|
#define KBR_RSTDONE 0xAA /* reset complete */
|
|
#define KBR_ECHO 0xEE /* echo response */
|
|
|
|
|
|
int
|
|
kbdprobe(parent, match, aux)
|
|
struct device *parent;
|
|
void *match;
|
|
void *aux;
|
|
{
|
|
int id;
|
|
|
|
/* Make sure we have an IOMD we understand */
|
|
|
|
id = ReadByte(IOMD_ID0) | (ReadByte(IOMD_ID1) << 8);
|
|
|
|
/* So far I only know about this IOMD */
|
|
|
|
switch (id) {
|
|
case RPC600_IOMD_ID:
|
|
case RC7500_IOC_ID:
|
|
return(1);
|
|
break;
|
|
default:
|
|
printf("kbd: Unknown IOMD id=%04x", id);
|
|
break;
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
void
|
|
kbdattach(parent, self, aux)
|
|
struct device *parent;
|
|
struct device *self;
|
|
void *aux;
|
|
{
|
|
struct kbd_softc *sc = (void *)self;
|
|
struct mainbus_attach_args *mb = aux;
|
|
int error;
|
|
|
|
error = kbdreset();
|
|
if (error == 1)
|
|
printf(": Cannot enable keyboard");
|
|
else if (error == 2)
|
|
printf(": No keyboard present");
|
|
|
|
sc->sc_iobase = mb->mb_iobase;
|
|
|
|
sc->sc_ih.ih_func = kbdintr;
|
|
sc->sc_ih.ih_arg = sc;
|
|
sc->sc_ih.ih_level = IPL_TTY;
|
|
sc->sc_ih.ih_name = "kbd rx";
|
|
if (irq_claim(IRQ_KBDRX, &sc->sc_ih))
|
|
panic("Cannot claim IRQ for kbd%d\n", sc->sc_device.dv_unit);
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
|
|
int
|
|
kbdopen(dev, flag, mode, p)
|
|
dev_t dev;
|
|
int flag;
|
|
int mode;
|
|
struct proc *p;
|
|
{
|
|
struct kbd_softc *sc;
|
|
int unit = KBDUNIT(dev);
|
|
|
|
if (unit >= kbd_cd.cd_ndevs)
|
|
return(ENXIO);
|
|
|
|
sc = kbd_cd.cd_devs[unit];
|
|
|
|
if (!sc) return(ENXIO);
|
|
|
|
switch (KBDFLAG(dev)) {
|
|
case KBDFLAG_RAWUNIT :
|
|
if (sc->sc_state & RAWKBD_OPEN)
|
|
return(EBUSY);
|
|
sc->sc_state |= RAWKBD_OPEN;
|
|
if (clalloc(&sc->sc_q, RAWKBD_BSIZE, 0) == -1)
|
|
return(ENOMEM);
|
|
sc->sc_proc = p;
|
|
rawkbd_device = 1;
|
|
break;
|
|
case KBDFLAG_CONUNIT :
|
|
if (sc->sc_state & KBD_OPEN)
|
|
return(EBUSY);
|
|
sc->sc_state |= KBD_OPEN;
|
|
break;
|
|
}
|
|
|
|
/* Kill any active autorepeat */
|
|
|
|
untimeout(autorepeatstart, &autorepeatkey);
|
|
untimeout(autorepeat, &autorepeatkey);
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
int
|
|
kbdclose(dev, flag, mode, p)
|
|
dev_t dev;
|
|
int flag;
|
|
int mode;
|
|
struct proc *p;
|
|
{
|
|
int unit = KBDUNIT(dev);
|
|
struct kbd_softc *sc = kbd_cd.cd_devs[unit];
|
|
|
|
switch (KBDFLAG(dev)) {
|
|
case KBDFLAG_RAWUNIT :
|
|
if (!(sc->sc_state & RAWKBD_OPEN))
|
|
return(EINVAL);
|
|
sc->sc_state &= ~RAWKBD_OPEN;
|
|
clfree(&sc->sc_q);
|
|
sc->sc_proc = NULL;
|
|
rawkbd_device = 0;
|
|
break;
|
|
case KBDFLAG_CONUNIT :
|
|
if (!(sc->sc_state & KBD_OPEN))
|
|
return(EINVAL);
|
|
sc->sc_state &= ~KBD_OPEN;
|
|
break;
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
int
|
|
kbdread(dev, uio, flag)
|
|
dev_t dev;
|
|
struct uio *uio;
|
|
int flag;
|
|
{
|
|
struct kbd_softc *sc = kbd_cd.cd_devs[KBDUNIT(dev)];
|
|
int s;
|
|
int error = 0;
|
|
size_t length;
|
|
u_char buffer[128];
|
|
|
|
if (KBDFLAG(dev) == KBDFLAG_CONUNIT)
|
|
return(ENXIO);
|
|
|
|
/* Block until keyboard activity occured. */
|
|
|
|
s = spltty();
|
|
while (sc->sc_q.c_cc == 0) {
|
|
if (flag & IO_NDELAY) {
|
|
splx(s);
|
|
return EWOULDBLOCK;
|
|
}
|
|
sc->sc_state |= RAWKBD_ASLEEP;
|
|
if ((error = tsleep((caddr_t)sc, PZERO | PCATCH, "kbdread", 0))) {
|
|
sc->sc_state &= (~RAWKBD_ASLEEP);
|
|
splx(s);
|
|
return error;
|
|
}
|
|
}
|
|
splx(s);
|
|
|
|
/* Transfer as many chunks as possible. */
|
|
|
|
while (sc->sc_q.c_cc > 0 && uio->uio_resid > 0) {
|
|
length = min(sc->sc_q.c_cc, uio->uio_resid);
|
|
if (length > sizeof(buffer))
|
|
length = sizeof(buffer);
|
|
|
|
/* Remove a small chunk from the input queue. */
|
|
(void) q_to_b(&sc->sc_q, buffer, length);
|
|
|
|
/* Copy the data to the user process. */
|
|
if ((error = (uiomove(buffer, length, uio))))
|
|
break;
|
|
}
|
|
return error;
|
|
}
|
|
|
|
|
|
int
|
|
kbdselect(dev, rw, p)
|
|
dev_t dev;
|
|
int rw;
|
|
struct proc *p;
|
|
{
|
|
struct kbd_softc *sc = kbd_cd.cd_devs[KBDUNIT(dev)];
|
|
int s;
|
|
int ret;
|
|
|
|
if (KBDFLAG(dev) == KBDFLAG_CONUNIT)
|
|
return(ENXIO);
|
|
|
|
if (rw == FWRITE)
|
|
return 0;
|
|
|
|
s = spltty();
|
|
if (!sc->sc_q.c_cc) {
|
|
selrecord(p, &sc->sc_rsel);
|
|
ret = 0;
|
|
} else
|
|
ret = 1;
|
|
splx(s);
|
|
return ret;
|
|
}
|
|
|
|
|
|
int
|
|
kbdioctl(dev, cmd, data, flag, p)
|
|
dev_t dev;
|
|
int cmd;
|
|
caddr_t data;
|
|
int flag;
|
|
struct proc *p;
|
|
{
|
|
/* struct kbd_softc *sc = kbd_cd.cd_devs[KBDUNIT(dev)];*/
|
|
struct kbd_autorepeat *kbdar = (void *)data;
|
|
int *leds = (int *)data;
|
|
int s;
|
|
|
|
switch (cmd) {
|
|
case KBD_GETAUTOREPEAT:
|
|
/* if (KBDFLAG(dev) == KBDFLAG_RAWUNIT)
|
|
return(EINVAL);*/
|
|
|
|
*kbdar = kbdautorepeat;
|
|
break;
|
|
case KBD_SETAUTOREPEAT:
|
|
/* if (KBDFLAG(dev) == KBDFLAG_RAWUNIT)
|
|
return(EINVAL);*/
|
|
s = spltty();
|
|
kbdautorepeat = *kbdar;
|
|
if (kbdautorepeat.ka_rate < 1)
|
|
kbdautorepeat.ka_rate = 1;
|
|
if (kbdautorepeat.ka_rate > 50)
|
|
kbdautorepeat.ka_rate = 50;
|
|
if (kbdautorepeat.ka_delay > 50)
|
|
kbdautorepeat.ka_delay = 50;
|
|
if (kbdautorepeat.ka_delay < 1)
|
|
kbdautorepeat.ka_delay = 1;
|
|
(void)splx(s);
|
|
break;
|
|
case KBD_SETLEDS:
|
|
kbdsetleds(*leds);
|
|
break;
|
|
default:
|
|
return(ENXIO);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
/* Low level keyboard driver functions */
|
|
|
|
/*
|
|
* kbdcmd
|
|
*
|
|
* Send a command to the keyboard
|
|
* Returns 0 if command succeeded or 1 if it failed.
|
|
*/
|
|
|
|
int
|
|
kbdcmd(cmd)
|
|
u_char cmd;
|
|
{
|
|
u_char c;
|
|
int i = 0;
|
|
int retry;
|
|
|
|
for (retry = 7; retry >= 0; --retry) {
|
|
|
|
/* Wait for empty kbd transmit register */
|
|
|
|
for (i = 1000; i; i--) {
|
|
if (inb(IOMD_KBDCR) & 0x80)
|
|
break;
|
|
delay(200);
|
|
}
|
|
if (i == 0)
|
|
printf("kbd: transmit not ready\n");
|
|
|
|
outb(IOMD_KBDDAT, cmd);
|
|
delay(200);
|
|
|
|
/* Wait for full kbd receive register */
|
|
|
|
for (i = 0; i < 1000; i++) {
|
|
c = inb(IOMD_KBDCR);
|
|
if ((c & 0x20) == 0x20)
|
|
break;
|
|
delay(100);
|
|
}
|
|
|
|
delay(100);
|
|
|
|
/* Get byte from kbd receive register */
|
|
|
|
c = inb(IOMD_KBDDAT);
|
|
if ((c == KBR_ACK) || (c == KBR_ECHO))
|
|
return(0);
|
|
|
|
/* Failed if we have more reties to go flush kbd */
|
|
|
|
if (retry)
|
|
kbd_flush_input();
|
|
}
|
|
printf("kbd: command failed, cmd = %02x, status = %02x\n", cmd, c);
|
|
return(1);
|
|
}
|
|
|
|
|
|
/*
|
|
* kbd_flush_input()
|
|
*
|
|
* Flushes the keyboard input register
|
|
*/
|
|
|
|
void
|
|
kbd_flush_input()
|
|
{
|
|
int i;
|
|
|
|
/* Loop round reading bytes while the receive buffer is not empty */
|
|
|
|
for (i = 0; i < 20; i++) {
|
|
if ((inb(IOMD_KBDCR) & 0x20) == 0)
|
|
break;
|
|
delay(100);
|
|
(void)inb(IOMD_KBDDAT);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* kbdreset()
|
|
*
|
|
* Resets the keyboard.
|
|
* Returns 0 if successful.
|
|
* Returns 1 if keyboard could not be enabled.
|
|
* Returns 2 if keyboard could not be reset.
|
|
*/
|
|
|
|
int
|
|
kbdreset()
|
|
{
|
|
int i;
|
|
u_char c;
|
|
|
|
kbd_flush_input();
|
|
|
|
/* Disable, wait then enable the keyboard interface */
|
|
|
|
outb(IOMD_KBDCR, 0x00);
|
|
delay(100);
|
|
outb(IOMD_KBDCR, 0x08);
|
|
|
|
/* Wait for kdata and kclk to go high */
|
|
|
|
for (i = 1000; i; i--) {
|
|
if ((inb(IOMD_KBDCR) & 0x03) == 0x03)
|
|
break;
|
|
outb(IOMD_KBDCR, 0x03);
|
|
delay(200);
|
|
outb(IOMD_KBDCR, 0x08);
|
|
}
|
|
if (i == 0 || (inb(IOMD_KBDCR) & 0x08) == 0)
|
|
return(1);
|
|
|
|
kbd_flush_input();
|
|
kbdcmd(KBC_DISABLE);
|
|
retry:
|
|
kbdcmd(KBC_RESET);
|
|
delay(100000);
|
|
for (i = 10000; i; i--) {
|
|
c = inb(IOMD_KBDDAT);
|
|
if (c == KBR_RSTDONE)
|
|
break;
|
|
if (c == KBR_RESEND)
|
|
goto retry;
|
|
delay(1000);
|
|
}
|
|
if (i == 0)
|
|
return(2);
|
|
|
|
kbdcmd(KBC_SETSCANTBL);
|
|
kbdcmd(KBD_SETSCAN_2);
|
|
kbdcmd(KBC_ENABLE);
|
|
|
|
modifiers = MODIFIER_NUM;
|
|
kbdsetleds((modifiers >> 3) & 7);
|
|
return(0);
|
|
}
|
|
|
|
|
|
void
|
|
kbdsetleds(leds)
|
|
int leds;
|
|
{
|
|
kbdcmd(KBC_SETLEDS);
|
|
kbdcmd(leds);
|
|
}
|
|
|
|
|
|
void
|
|
kbdsetstate(state)
|
|
int state;
|
|
{
|
|
modifiers = state & MODIFIER_LOCK_MASK;
|
|
kbdsetleds((modifiers >> 3) & 7);
|
|
}
|
|
|
|
|
|
int
|
|
kdbgetstate()
|
|
{
|
|
return(modifiers);
|
|
}
|
|
|
|
|
|
int
|
|
getkey_polled()
|
|
{
|
|
int code;
|
|
int key;
|
|
int up;
|
|
key_struct *ks;
|
|
int s;
|
|
|
|
s = splhigh();
|
|
|
|
key = 0;
|
|
|
|
do {
|
|
while ((ReadByte(IOMD_KBDCR) & (1<<5)) == 0) ;
|
|
delay(10);
|
|
|
|
/* Read the IOMD keyboard register and process the key */
|
|
|
|
code = PollKeyboard(ReadByte(IOMD_KBDDAT));
|
|
|
|
if (code != 0) {
|
|
up = (code & 0x100);
|
|
key = code & 0xff;
|
|
|
|
/* printf("code=%04x mod=%04x\n", code, modifiers);*/
|
|
|
|
/* By default we use the main keycode lookup table */
|
|
|
|
ks = keys;
|
|
|
|
/* If we have an E0 or E1 sqeuence we use the extended table */
|
|
|
|
if (code > 0x1ff)
|
|
ks = E0keys;
|
|
|
|
/* Is the key a temporary modifier ? */
|
|
|
|
if (ks[key].flags & MODIFIER_MASK) {
|
|
if (up)
|
|
modifiers &= ~ks[key].flags;
|
|
else
|
|
modifiers |= ks[key].flags;
|
|
key = 0;
|
|
continue;
|
|
}
|
|
|
|
/* Is the key a locking modifier ? */
|
|
|
|
if (ks[key].flags & MODIFIER_LOCK_MASK) {
|
|
if (!up) {
|
|
modifiers ^= ks[key].flags;
|
|
kbdsetleds((modifiers >> 3) & 7);
|
|
}
|
|
key = 0;
|
|
continue;
|
|
}
|
|
|
|
/* Lookup the correct key code */
|
|
|
|
if (modifiers & 0x01)
|
|
key = ks[key].ctrl_code;
|
|
else if (modifiers & 0x02)
|
|
key = ks[key].shift_code;
|
|
else if (modifiers & 0x04)
|
|
key = ks[key].alt_code;
|
|
else
|
|
key = ks[key].base_code;
|
|
|
|
if (modifiers & MODIFIER_CAPS) {
|
|
if ((key >= 'A' && key <= 'Z') || (key >= 'a' && key <= 'z'))
|
|
key ^= 0x20;
|
|
}
|
|
|
|
if (up)
|
|
key = 0;
|
|
if (!up && key >= 0x200) {
|
|
|
|
#if (NVT > 0)
|
|
if ((key & ~0x0f) == 0x480)
|
|
console_switch((key & 0x0f) - 1);
|
|
else
|
|
#endif
|
|
switch (key) {
|
|
#if (NVT > 0)
|
|
case 0x201:
|
|
console_scrollforward();
|
|
break;
|
|
case 0x200:
|
|
console_scrollback();
|
|
break;
|
|
#endif
|
|
default:
|
|
break;
|
|
}
|
|
key = 0;
|
|
}
|
|
}
|
|
} while (key == 0);
|
|
|
|
if (key == '\r')
|
|
key = '\n';
|
|
|
|
splx(s);
|
|
return(key);
|
|
}
|
|
|
|
|
|
/* Keyboard IRQ handler */
|
|
|
|
int
|
|
kbdintr(sc)
|
|
struct kbd_softc *sc;
|
|
{
|
|
int key;
|
|
|
|
/* Read the IOMD keyboard register and process the key */
|
|
|
|
key = PollKeyboard(ReadByte(IOMD_KBDDAT));
|
|
|
|
/* If we have a raw keycode convert it to an ASCII code */
|
|
|
|
if (key != 0)
|
|
kbddecodekey(sc, key);
|
|
return(1);
|
|
}
|
|
|
|
|
|
/* Flags used to decode the raw keys */
|
|
|
|
#define FLAG_KEYUP 0x01
|
|
#define FLAG_E0 0x02
|
|
#define FLAG_E1 0x04
|
|
|
|
static int flags = 0;
|
|
|
|
/*
|
|
* This function is now misnamed.
|
|
* It processes the raw key codes from the keyboard and generates
|
|
* a unique code that can be decoded with the key translation array.
|
|
*/
|
|
|
|
int
|
|
PollKeyboard(code)
|
|
int code;
|
|
{
|
|
/* printf("%02x.", code);*/
|
|
|
|
/*
|
|
* Set the keyup flag if this is the release code.
|
|
*/
|
|
|
|
if (code == 0xf0) {
|
|
flags |= FLAG_KEYUP;
|
|
return(0);
|
|
}
|
|
|
|
/* If it is a special code ignore it */
|
|
|
|
if (code == 0xff || code == 0x00) {
|
|
flags = 0;
|
|
return(0);
|
|
}
|
|
|
|
/* If it is a resend code note it down */
|
|
|
|
if (code == KBR_RESEND) {
|
|
printf("kbd:resend\n");
|
|
kbd_resend = 1;
|
|
return(0);
|
|
}
|
|
|
|
/* If it is an ack code note it down */
|
|
|
|
if (code == KBR_ACK) {
|
|
/* printf("kbd:ack\n");*/
|
|
kbd_ack = 1;
|
|
return(0);
|
|
}
|
|
|
|
/* Flag the start of an E0 sequence. */
|
|
|
|
if (code == 0xe0) {
|
|
flags |= FLAG_E0;
|
|
return(0);
|
|
}
|
|
|
|
/* Flag the start of an E1 sequence. */
|
|
|
|
if (code == 0xe1) {
|
|
flags |= FLAG_E1;
|
|
return(0);
|
|
}
|
|
|
|
/* Ignore any other invalid codes */
|
|
|
|
if (code > 0x8f) {
|
|
flags = 0;
|
|
return(0);
|
|
}
|
|
|
|
/* printf("%02x:%02x.", code, flags);*/
|
|
|
|
/* Mark the code appropriately if it is part of an E0 sequence */
|
|
|
|
if (flags & FLAG_E0) {
|
|
flags &= ~FLAG_E0;
|
|
if (code == 0x12) {
|
|
flags &= ~FLAG_KEYUP;
|
|
return(0);
|
|
}
|
|
code |= 0x200;
|
|
}
|
|
|
|
/* Mark the key if it is the upcode */
|
|
|
|
if (flags & FLAG_KEYUP) {
|
|
flags &= ~FLAG_KEYUP;
|
|
code |= 0x100;
|
|
}
|
|
|
|
/* Mark the code appropriately if it is part of an E1 sequence */
|
|
|
|
if (flags & FLAG_E1) {
|
|
if ((code & 0xff) == 0x14) {
|
|
return(0);
|
|
}
|
|
flags &= ~FLAG_E1;
|
|
code |= 0x400;
|
|
flags &= ~FLAG_KEYUP;
|
|
}
|
|
|
|
return(code);
|
|
}
|
|
|
|
|
|
/*
|
|
* This routine decodes the unique keycode and generates an ASCII code
|
|
* if necessary.
|
|
*/
|
|
|
|
int
|
|
kbddecodekey(sc, code)
|
|
struct kbd_softc *sc;
|
|
int code;
|
|
{
|
|
key_struct *ks;
|
|
int up;
|
|
int key;
|
|
|
|
console_unblank();
|
|
|
|
/* Do we have the raw kbd device open ... */
|
|
|
|
if (rawkbd_device == 1 && code != 0) {
|
|
struct kbd_data buffer;
|
|
int s;
|
|
|
|
/* Add this event to the queue. */
|
|
|
|
buffer.keycode = code;
|
|
microtime(&buffer.event_time);
|
|
s=spltty();
|
|
(void) b_to_q((char *)&buffer, sizeof(buffer), &sc->sc_q);
|
|
splx(s);
|
|
selwakeup(&sc->sc_rsel);
|
|
|
|
if (sc->sc_state & RAWKBD_ASLEEP) {
|
|
sc->sc_state &= ~RAWKBD_ASLEEP;
|
|
wakeup((caddr_t)sc);
|
|
}
|
|
|
|
psignal(sc->sc_proc, SIGIO);
|
|
return(1);
|
|
}
|
|
|
|
up = (code & 0x100);
|
|
key = code & 0xff;
|
|
|
|
/* By default we use the main keycode lookup table */
|
|
|
|
ks = keys;
|
|
|
|
/* If we have an E0 or E1 sqeuence we use the extended table */
|
|
|
|
if (code > 0x1ff)
|
|
ks = E0keys;
|
|
|
|
/* Is the key a temporary modifier ? */
|
|
|
|
if (ks[key].flags & MODIFIER_MASK) {
|
|
if (up)
|
|
modifiers &= ~ks[key].flags;
|
|
else
|
|
modifiers |= ks[key].flags;
|
|
return(0);
|
|
}
|
|
|
|
/* Is the key a locking modifier ? */
|
|
|
|
if (ks[key].flags & MODIFIER_LOCK_MASK) {
|
|
if (!up) {
|
|
modifiers ^= ks[key].flags;
|
|
kbdsetleds((modifiers >> 3) & 7);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
/* Lookup the correct key code */
|
|
|
|
if (modifiers & 0x01)
|
|
key = ks[key].ctrl_code;
|
|
else if (modifiers & 0x02)
|
|
key = ks[key].shift_code;
|
|
else if (modifiers & 0x04)
|
|
key = ks[key].alt_code;
|
|
else
|
|
key = ks[key].base_code;
|
|
|
|
if (modifiers & MODIFIER_CAPS) {
|
|
if ((key >= 'A' && key <= 'Z') || (key >= 'a' && key <= 'z'))
|
|
key ^= 0x20;
|
|
}
|
|
|
|
/* If no valid code the key is not yet mapped so report error */
|
|
|
|
#ifdef DEBUG_TERM
|
|
/* if (key == 0) {
|
|
char err[80];
|
|
|
|
sprintf(err, "\n\rUnknown keycode %04x\n\r", code);
|
|
dprintf(err);
|
|
|
|
}*/
|
|
#endif
|
|
|
|
/* If we have an ASCII code insert it into the keyboard buffer */
|
|
|
|
if (!up && key != 0) {
|
|
if (key >= 0x200) {
|
|
|
|
untimeout(autorepeatstart, &autorepeatkey);
|
|
untimeout(autorepeat, &autorepeatkey);
|
|
autorepeatkey = -1;
|
|
#if (NVT > 0)
|
|
if ((key & ~0x0f) == 0x480)
|
|
console_switch((key & 0x0f) - 1);
|
|
else
|
|
#endif
|
|
switch (key) {
|
|
case 0x22b:
|
|
pmap_debug(pmap_debug_level + 1);
|
|
break;
|
|
case 0x22d:
|
|
pmap_debug(pmap_debug_level - 1);
|
|
break;
|
|
#if (NVT > 0)
|
|
case 0x201:
|
|
console_scrollforward();
|
|
break;
|
|
case 0x200:
|
|
console_scrollback();
|
|
break;
|
|
case 0x202:
|
|
console_switchdown();
|
|
break;
|
|
case 0x203:
|
|
console_switchup();
|
|
break;
|
|
#endif
|
|
case 0x204:
|
|
--kbdautorepeat.ka_rate;
|
|
if (kbdautorepeat.ka_rate < 1)
|
|
kbdautorepeat.ka_rate = 1;
|
|
break;
|
|
case 0x205:
|
|
++kbdautorepeat.ka_rate;
|
|
if (kbdautorepeat.ka_rate > 50)
|
|
kbdautorepeat.ka_rate = 50;
|
|
break;
|
|
case 0x20a:
|
|
++kbdautorepeat.ka_delay;
|
|
if (kbdautorepeat.ka_delay > 50)
|
|
kbdautorepeat.ka_delay = 50;
|
|
break;
|
|
case 0x20b:
|
|
--kbdautorepeat.ka_delay;
|
|
if (kbdautorepeat.ka_delay < 1)
|
|
kbdautorepeat.ka_delay = 1;
|
|
break;
|
|
#ifdef DDB
|
|
case 0x208:
|
|
Debugger();
|
|
break;
|
|
#endif
|
|
case 0x21b:
|
|
printf("Kernel interruption\n");
|
|
boot(RB_HALT, NULL);
|
|
break;
|
|
case 0x209:
|
|
printf("Kernel interruption - nosync\n");
|
|
boot(RB_NOSYNC | RB_HALT, NULL);
|
|
break;
|
|
|
|
default:
|
|
printf("Special key %04x\n", key);
|
|
break;
|
|
}
|
|
} else {
|
|
/*
|
|
* Check rawkbd_device first, in case we stick in the
|
|
* physconkbd().
|
|
*/
|
|
if (rawkbd_device == 0 && physconkbd(key) == 0) {
|
|
if (autorepeatkey != key) {
|
|
untimeout(autorepeatstart, &autorepeatkey);
|
|
untimeout(autorepeat, &autorepeatkey);
|
|
autorepeatkey = key;
|
|
timeout(autorepeatstart, &autorepeatkey, hz/kbdautorepeat.ka_delay);
|
|
}
|
|
}
|
|
|
|
return(1);
|
|
}
|
|
} else {
|
|
untimeout(autorepeatstart, &autorepeatkey);
|
|
untimeout(autorepeat, &autorepeatkey);
|
|
autorepeatkey = -1;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
void
|
|
autorepeatstart(key)
|
|
void *key;
|
|
{
|
|
physconkbd(*((int *)key));
|
|
timeout(autorepeat, key, hz/kbdautorepeat.ka_rate);
|
|
}
|
|
|
|
|
|
void
|
|
autorepeat(key)
|
|
void *key;
|
|
{
|
|
physconkbd(*((int *)key));
|
|
timeout(autorepeat, key, hz/kbdautorepeat.ka_rate);
|
|
}
|
|
|
|
/* End of kbd.c */
|