atkbd.c

Go to the documentation of this file.
00001 /*****************************************************************************************
00002  Copyright (c) 2002-2004 The UbixOS Project
00003  All rights reserved.
00004 
00005  Redistribution and use in source and binary forms, with or without modification, are
00006  permitted provided that the following conditions are met:
00007 
00008  Redistributions of source code must retain the above copyright notice, this list of
00009  conditions, the following disclaimer and the list of authors.  Redistributions in binary
00010  form must reproduce the above copyright notice, this list of conditions, the following
00011  disclaimer and the list of authors in the documentation and/or other materials provided
00012  with the distribution. Neither the name of the UbixOS Project nor the names of its
00013  contributors may be used to endorse or promote products derived from this software
00014  without specific prior written permission.
00015 
00016  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
00017  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00018  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
00019  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00020  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00021  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00022  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
00023  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00024  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025 
00026  $Id: atkbd_8c-source.html 88 2016-01-12 00:11:29Z reddawg $
00027 
00028 *****************************************************************************************/
00029 
00030 #include <isa/atkbd.h>
00031 #include <isa/8259.h>
00032 #include <sys/video.h>
00033 #include <sys/idt.h>
00034 #include <sys/gdt.h>
00035 #include <sys/io.h>
00036 #include <lib/kmalloc.h>
00037 #include <lib/kprintf.h>
00038 #include <ubixos/types.h>
00039 #include <ubixos/sched.h>
00040 #include <ubixos/endtask.h>
00041 #include <ubixos/tty.h>
00042 #include <ubixos/spinlock.h>
00043 #include <ubixos/kpanic.h>
00044 #include <ubixos/vitals.h>
00045 
00046 static int atkbd_scan();
00047 
00048 static unsigned int keyMap = 0x0;
00049 static unsigned int ledStatus = 0x0;
00050 static char   stdinBuffer[512];
00051 static uInt16 stdinSize;
00052 static uInt32 controlKeys = 0x0;
00053 
00054 static spinLock_t atkbdSpinLock = SPIN_LOCK_INITIALIZER;
00055 
00056 static unsigned int keyboardMap[255][8] = {
00057 /*           Ascii,  Shift,   Ctrl,    Alt,    Num,   Caps, Shift Caps, Shift Num */
00058           {      0,      0,      0,      0,      0,      0,          0,         0},
00059 /* ESC */ {   0x1B,   0x1B,   0x1B,   0x1B,   0x1B,   0x1B,       0x1B,      0x1B},
00060 /* 1,! */ {   0x31,   0x21,      0,      0,   0x31,   0x31,       0x21,      0x21},
00061 /* 2,@ */ {   0x32,   0x40,      0,      0,   0x32,   0x32,       0x40,      0x40},
00062 /* 3,# */ {   0x33,   0x23,      0,      0,   0x33,   0x33,       0x23,      0x23},
00063 /* 4,$ */ {   0x34,   0x24,      0,      0,   0x34,   0x34,       0x24,      0x24},
00064 /* 5,% */ {   0x35,   0x25,      0,      0,   0x35,   0x35,       0x25,      0x25},
00065 /* 6,^ */ {   0x36,   0x5E,      0,      0,   0x36,   0x36,       0x5E,      0x5E},
00066 /* 7,& */ {   0x37,   0x26,      0,      0,   0x37,   0x37,       0x26,      0x26},
00067 /* 8,* */ {   0x38,   0x2A,      0,      0,   0x38,   0x38,       0x2A,      0x2A},
00068 /* 9.( */ {   0x39,   0x28,      0,      0,   0x39,   0x39,       0x28,      0x28},
00069 /* 0,) */ {   0x30,   0x29,      0,      0,   0x30,   0x30,       0x29,      0x29},
00070 /* -,_ */ {   0x2D,   0x5F,      0,      0,   0x2D,   0x2D,       0x5F,      0x5F},
00071 /* =,+ */ {   0x3D,   0x2B,      0,      0,   0x3D,   0x3D,       0x2B,      0x2B},
00072 /*  14 */ {   0x08,   0x08,    0x8,    0x8,   0x08,   0x08,       0x08,      0x08},
00073 /*  15 */ {   0x09,      0,      0,      0,      0,      0,          0,         0},
00074 /*     */ {   0x71,   0x51,      0,      0,      0,      0,          0,         0},
00075 /*     */ {   0x77,   0x57,      0,      0,      0,      0,          0,         0},
00076 /*     */ {   0x65,   0x45,      0,      0,      0,      0,          0,         0},
00077 /*     */ {   0x72,   0x52,      0,      0,      0,      0,          0,         0},
00078 /*     */ {   0x74,   0x54,      0,      0,      0,      0,          0,         0},
00079 /*     */ {   0x79,   0x59,      0,      0,      0,      0,          0,         0},
00080 /*     */ {   0x75,   0x55,      0,      0,      0,      0,          0,         0},
00081 /*     */ {   0x69,   0x49,      0,      0,      0,      0,          0,         0},
00082 /*     */ {   0x6F,   0x4F,      0,      0,      0,      0,          0,         0},
00083 /*     */ {   0x70,   0x50,      0,      0,      0,      0,          0,         0},
00084 /*     */ {   0x5B,   0x7B,      0,      0,      0,      0,          0,         0},
00085 /*     */ {   0x5D,   0x7D,      0,      0,      0,      0,          0,         0},
00086 /*     */ {   0x0A,      0,      0,      0,      0,      0,          0,         0},
00087 /*     */ {      0,      0,      0,      0,      0,      0,          0,         0},
00088 /* a,A */ {   0x61,   0x41,   0x41,      0,      0,      0,          0,         0},
00089 /*     */ {   0x73,   0x53,      0,      0,      0,      0,          0,         0},
00090 /*     */ {   0x64,   0x44,      0,      0,      0,      0,          0,         0},
00091 /*     */ {   0x66,   0x46,      0,      0,      0,      0,          0,         0},
00092 /*     */ {   0x67,   0x47,      0,      0,      0,      0,          0,         0},
00093 /*     */ {   0x68,   0x48,      0,      0,      0,      0,          0,         0},
00094 /*     */ {   0x6A,   0x4A,      0,      0,      0,      0,          0,         0},
00095 /*     */ {   0x6B,   0x4B,      0,      0,      0,      0,          0,         0},
00096 /*     */ {   0x6C,   0x4C,      0,      0,      0,      0,          0,         0},
00097 /*     */ {   0x3B,   0x3A,      0,      0,      0,      0,          0,         0},
00098 /*     */ {   0x27,   0x22,      0,      0,      0,      0,          0,         0},
00099 /*     */ {   0x60,   0x7E,      0,      0,      0,      0,          0,         0},
00100 /*     */ {   0x2A,    0x0,      0,      0,      0,      0,          0,         0},
00101 /*     */ {   0x5C,   0x3C,      0,      0,      0,      0,          0,         0},
00102 /*     */ {   0x7A,   0x5A,      0,      0,      0,      0,          0,         0},
00103 /*     */ {   0x78,   0x58,      0,      0,      0,      0,          0,         0},
00104 /* c,C */ {   0x63,   0x43,    0x3,    0x9,      0,      0,          0,         0},
00105 /*     */ {   0x76,   0x56,      0,      0,      0,      0,          0,         0},
00106 /*     */ {   0x62,   0x42,      0,      0,      0,      0,          0,         0},
00107 /*     */ {   0x6E,   0x4E,      0,      0,      0,      0,          0,         0},
00108 /*     */ {   0x6D,   0x4D,      0,      0,      0,      0,          0,         0},
00109 /*     */ {   0x2C,   0x3C,      0,      0,      0,      0,          0,         0},
00110 /*     */ {   0x2E,   0x3E,      0,      0,      0,      0,          0,         0},
00111 /*     */ {   0x2F,   0x3F,      0,      0,      0,      0,          0,         0},
00112 /*     */ {      0,      0,      0,      0,      0,      0,          0,         0},
00113 /*     */ {      0,      0,      0,      0,      0,      0,          0,         0},
00114 /*     */ {      0,      0,      0,      0,      0,      0,          0,         0},
00115 /*     */ {   0x20,      0,      0,      0,      0,      0,          0,         0},
00116 /*     */ {      0,      0,      0,      0,      0,      0,          0,         0},
00117 /* F1  */ { 0x3000,      0,      0, 0x3000,      0,      0,          0,         0},
00118 /*     */ { 0x3001,      0,      0, 0x3001,      0,      0,          0,         0},
00119 /*     */ { 0x3002,      0,      0, 0x3002,      0,      0,          0,         0},
00120 /*     */ { 0x3003,      0,      0, 0x3003,      0,      0,          0,         0},
00121 /*     */ { 0x3004,      0,      0, 0x3004,      0,      0,          0,         0},
00122 /*     */ { 0x4000,      0,      0,      0,      0,      0,          0,         0},
00123 /*     */ { 0x4100,      0,      0,      0,      0,      0,          0,         0},
00124 /*     */ { 0x4200,      0,      0,      0,      0,      0,          0,         0},
00125 /*     */ { 0x4300,      0,      0,      0,      0,      0,          0,         0},
00126 /*     */ { 0x4400,      0,      0,      0,      0,      0,          0,         0},
00127 /*     */ {      0,      0,      0,      0,      0,      0,          0,         0},
00128 /*     */ {      0,      0,      0,      0,      0,      0,          0,         0},
00129 /*     */ { 0x4700,      0,      0,      0,      0,      0,          0,         0},
00130 /*     */ { 0x4800,      0,      0,      0,      0,      0,          0,         0},
00131 /*     */ { 0x4900,      0,      0,      0,      0,      0,          0,         0},
00132 /*     */ {   0x2D,      0,      0,      0,      0,      0,          0,         0},
00133 /*     */ { 0x4B00,      0,      0,      0,      0,      0,          0,         0},
00134 /*     */ { 0x4C00,      0,      0,      0,      0,      0,          0,         0},
00135 /*     */ { 0x4D00,      0,      0,      0,      0,      0,          0,         0},
00136 /*     */ {   0x2B,      0,      0,      0,      0,      0,          0,         0},
00137 /*     */ { 0x4F00,      0,      0,      0,      0,      0,          0,         0},
00138 /*     */ { 0x5000,      0,      0,      0,      0,      0,          0,         0},
00139 /*     */ { 0x5100,      0,      0,      0,      0,      0,          0,         0},
00140 /*     */ { 0x5200,      0,      0,      0,      0,      0,          0,         0},
00141 /*     */ { 0x5300,      0,      0,      0,      0,      0,          0,         0},
00142 /*     */ {      0,      0,      0,      0,      0,      0,          0,         0},
00143 /*     */ {      0,      0,      0,      0,      0,      0,          0,         0}
00144   };
00145 
00146 /************************************************************************
00147 
00148 Function: int atkbd_init
00149 
00150 Description: This function is used to turn on the keyboard
00151 
00152 Notes:
00153 
00154 02/20/2004 - Approved for quality
00155 
00156 ************************************************************************/
00157 int atkbd_init() {
00158   /* Insert the IDT vector for the keyboard handler */
00159   setVector(&atkbd_isr, mVec+0x1, dPresent + dInt + dDpl0);
00160 
00161   /* Set the LEDS to their defaults */
00162   setLED();
00163 
00164   /* Clear Keyboard */
00165   atkbd_scan();
00166 
00167   /* Turn on the keyboard vector */
00168   irqEnable(0x1);
00169 
00170   /* Print out information on keyboard */
00171   kprintf("atkbd0 - Address: [0x%X], Keyboard Buffer: [0x%X], Buffer Size [%i]\n",&atkbd_isr,&stdinBuffer,512);
00172 
00173   /* Return so we know everything went well */
00174   return(0x0);
00175   }
00176 
00177 /*
00178  * 2-23-2004 mji  I think the pusha/popa should be pushal/popal
00179  */
00180 
00181 asm(
00182   ".globl atkbd_isr       \n"
00183   "atkbd_isr:             \n"
00184   "  pusha                \n" /* Save all registers           */
00185   "  push %ss             \n"
00186   "  push %ds             \n"
00187   "  push %es             \n"
00188   "  push %fs             \n"
00189   "  push %gs             \n"  
00190   "  call keyboardHandler \n"
00191   "  mov $0x20,%dx        \n"
00192   "  mov $0x20,%ax        \n"
00193   "  outb %al,%dx         \n"
00194   "  pop %gs              \n"
00195   "  pop %fs              \n" 
00196   "  pop %es              \n"
00197   "  pop %ds              \n"
00198   "  pop %ss              \n"
00199   "  popa                 \n"
00200   "  iret                 \n" /* Exit interrupt                           */
00201   );
00202 
00203 static int atkbd_scan() {
00204   int code = 0x0;
00205   int val  = 0x0;
00206   
00207   code = inportByte(0x60);
00208   val  = inportByte(0x61);
00209   
00210   outportByte(0x61,val | 0x80);
00211   outportByte(0x61,val);
00212   
00213   return(code);
00214   }
00215 
00216 void keyboardHandler() {
00217   int key = 0x0;
00218 
00219   if (!spinTryLock(&atkbdSpinLock))
00220         return;
00221 
00222   key = atkbd_scan();
00223   
00224   if (key > 255) 
00225     return;
00226 
00227   /* Control Key */
00228   if (key == 0x1D && !(controlKeys & controlKey)) {
00229     controlKeys |= controlKey;
00230     }
00231   if (key == 0x80 + 0x1D) {
00232     controlKeys &= (0xFF - controlKey);
00233     }
00234   /* ALT Key */
00235   if (key == 0x38 && !(controlKeys & altKey)) {
00236     controlKeys |= altKey;
00237     }
00238   if (key == 0x80 + 0x38) {
00239     controlKeys &= (0xFF - altKey);
00240     }
00241   /* Shift Key */
00242   if ((key == 0x2A || key == 0x36) && !(controlKeys & shiftKey)) {
00243     controlKeys |= shiftKey;
00244     }
00245   if ((key == 0x80 + 0x2A) || (key == 0x80 + 0x36)) {
00246     controlKeys &= (0xFF - shiftKey);
00247     }
00248   /* Caps Lock */
00249   if (key == 0x3A) {
00250     ledStatus ^= ledCapslock;
00251     setLED();
00252     }
00253   /* Num Lock */
00254   if (key == 0x45) {
00255     ledStatus ^= ledNumlock;
00256     setLED();
00257     }
00258   /* Scroll Lock */
00259   if (key == 0x46) {
00260     ledStatus ^= ledScrolllock;
00261     setLED();
00262     }
00263   /* Pick Which Key Map */
00264   if (controlKeys == 0) { keyMap = 0; }
00265   else if (controlKeys == 1) { keyMap = 1; }
00266   else if (controlKeys == 2) { keyMap = 2; }
00267   else if (controlKeys == 4) { keyMap = 3; }
00268   /* If Key Is Not Null Add It To Handler */
00269   if (((uInt)(keyboardMap[key][keyMap]) > 0) && ((uInt32)(keyboardMap[key][keyMap]) < 0xFF)) {
00270     switch ((uInt32)keyboardMap[key][keyMap]) {
00271       case 8:
00272         backSpace();
00273         if (tty_foreground == 0x0) {
00274           stdinBuffer[stdinSize] = keyboardMap[key][keyMap];
00275           stdinSize++;
00276           }
00277         else {
00278           tty_foreground->stdin[tty_foreground->stdinSize] = keyboardMap[key][keyMap];
00279           tty_foreground->stdinSize++;
00280           }
00281         break;
00282       case 0x3:
00283         //if (tty_foreground != 0x0)
00284         //  endTask(tty_foreground->owner);
00285         K_PANIC("CTRL-C pressed\n");
00286         kprintf("FreePages: [0x%X]\n",systemVitals->freePages);
00287         break;
00288       case 0x9:
00289         kprintf("REBOOTING");
00290         while(inportByte(0x64) & 0x02);
00291         outportByte(0x64, 0xFE);
00292         break;
00293       default:
00294         if (tty_foreground == 0x0) {
00295           stdinBuffer[stdinSize] = keyboardMap[key][keyMap];
00296           stdinSize++;
00297           }
00298         else {
00299           tty_foreground->stdin[tty_foreground->stdinSize] = keyboardMap[key][keyMap];
00300           tty_foreground->stdinSize++;
00301           }
00302         break;
00303       }
00304     }
00305   else {
00306     switch ((keyboardMap[key][keyMap] >> 8)) {
00307       case 0x30:
00308         tty_change(keyboardMap[key][keyMap] & 0xFF);
00309         //kprintf("Changing Consoles[0x%X:0x%X]\n",_current->id,_current);
00310         break;
00311       default:
00312         break;
00313       }
00314     }
00315 
00316   /* Return */
00317   spinUnlock(&atkbdSpinLock);
00318   return;
00319   }
00320 
00321 void setLED() {
00322   outportByte(0x60, 0xED);
00323   while(inportByte(0x64) & 2);
00324   outportByte(0x60, ledStatus);
00325   while(inportByte(0x64) & 2);
00326   }
00327 
00328 /* Temp */
00329 unsigned char getch() {
00330   uInt8   retKey   = 0x0;
00331   uInt32  i        = 0x0;
00332 
00333   /*
00334   if ((stdinSize <= 0) && (tty_foreground == 0x0)) {
00335     sched_yield();
00336     }
00337   if ((tty_foreground != 0x0) && (tty_foreground->stdinSize <= 0x0)) {
00338     sched_yield();
00339     }
00340   */
00341 
00342   /*
00343   if (!spinTryLock(&atkbdSpinLock))
00344         return(0x0);
00345 */
00346 
00347   if (tty_foreground == 0x0) {
00348     if (stdinSize == 0x0) {
00349     //  spinUnlock(&atkbdSpinLock);
00350       return(0x0);
00351       }
00352   
00353     retKey = stdinBuffer[0];
00354     stdinSize--;
00355 
00356     for (i=0x0;i<stdinSize;i++) {
00357       stdinBuffer[i] = stdinBuffer[i+0x1];
00358       }
00359     }
00360   else {
00361     if (tty_foreground->stdinSize == 0x0) {
00362    //   spinUnlock(&atkbdSpinLock);
00363       return(0x0);
00364       }
00365   
00366     retKey = tty_foreground->stdin[0];
00367     tty_foreground->stdinSize--;
00368 
00369     for (i=0x0;i<tty_foreground->stdinSize;i++) {
00370       tty_foreground->stdin[i] = tty_foreground->stdin[i+0x1];
00371       }
00372     }
00373   //spinUnlock(&atkbdSpinLock);
00374   return(retKey);
00375   }
00376 
00377 /***
00378 
00379  $Log: atkbd_8c-source.html,v $
00379  Revision 1.7  2006/12/15 17:47:04  reddawg
00379  Updates
00379 
00380  Revision 1.5  2006/12/05 17:01:15  reddawg
00381  Modified kpanic
00382 
00383  Revision 1.4  2006/12/05 14:10:21  reddawg
00384  Workign Distro
00385 
00386  Revision 1.3  2006/12/01 05:12:35  reddawg
00387  We're almost there... :)
00388 
00389  Revision 1.2  2006/10/19 17:52:17  reddawg
00390  Working On Userland
00391 
00392  Revision 1.1.1.1  2006/06/01 12:46:12  reddawg
00393  ubix2
00394 
00395  Revision 1.2  2005/10/12 00:13:37  reddawg
00396  Removed
00397 
00398  Revision 1.1.1.1  2005/09/26 17:24:01  reddawg
00399  no message
00400 
00401  Revision 1.29  2004/09/11 21:38:00  reddawg
00402  Fixed a few problems
00403 
00404  Revision 1.28  2004/09/08 23:19:58  reddawg
00405  hmm
00406 
00407  Revision 1.27  2004/09/07 21:54:38  reddawg
00408  ok reverted back to old scheduling for now....
00409 
00410  Revision 1.26  2004/09/06 22:18:52  reddawg
00411  ok bed time
00412 
00413  Revision 1.25  2004/09/06 22:11:29  reddawg
00414  tty: now each tty has a stdin....
00415 
00416  Revision 1.24  2004/09/06 15:13:25  reddawg
00417  Last commit before FreeBSD 6.0
00418 
00419  Revision 1.23  2004/08/21 23:47:50  reddawg
00420  *** empty log message ***
00421 
00422  Revision 1.22  2004/08/09 12:58:05  reddawg
00423  let me know when you got the surce
00424 
00425  Revision 1.21  2004/08/06 22:32:16  reddawg
00426  Ubix Works Again
00427 
00428  Revision 1.19  2004/08/03 18:31:19  reddawg
00429  virtual terms
00430 
00431  Revision 1.18  2004/07/29 21:32:16  reddawg
00432  My quick lunchs breaks worth of updates....
00433 
00434  Revision 1.17  2004/07/28 18:45:39  reddawg
00435  movement of files
00436 
00437  Revision 1.16  2004/07/28 17:07:25  reddawg
00438  MPI: moved the syscalls
00439 
00440  Revision 1.15  2004/07/26 19:15:49  reddawg
00441  test code, fixes and the like
00442 
00443  Revision 1.14  2004/07/25 05:32:58  reddawg
00444  fixed
00445 
00446  Revision 1.13  2004/07/25 05:24:39  reddawg
00447  atkbd: removed sti... does it still miss keys
00448 
00449  Revision 1.12  2004/07/24 20:00:51  reddawg
00450  Lots of changes to the vmm subsystem.... Page faults have been adjust to now be blocking on a per thread basis not system wide. This has resulted in no more deadlocks.. also the addition of per thread locking has removed segfaults as a result of COW in which two tasks fault the same COW page and try to modify it.
00451 
00452  Revision 1.11  2004/07/24 15:12:56  reddawg
00453  Now I'm current
00454 
00455  Revision 1.10  2004/07/23 17:49:58  reddawg
00456  atkbd: adjust the timing issue on the driver hopefully it will work fine now
00457 
00458  Revision 1.9  2004/07/23 17:37:35  reddawg
00459  Fix
00460 
00461  Revision 1.8  2004/07/23 09:10:06  reddawg
00462  ubixfs: cleaned up some functions played with the caching a bit
00463  vfs:    renamed a bunch of functions
00464  cleaned up a few misc bugs
00465 
00466  Revision 1.7  2004/07/22 20:53:07  reddawg
00467  atkbd: fixed problem
00468 
00469  Revision 1.6  2004/07/09 13:34:51  reddawg
00470  keyboard: keyboardInit to atkbd_init
00471  Adjusted initialization routines
00472 
00473  Revision 1.5  2004/06/17 14:49:14  reddawg
00474  atkbd: converted some variables to static
00475 
00476  Revision 1.4  2004/06/04 10:19:42  reddawg
00477  notes: we compile again, thank g-d anyways i was about to cry
00478 
00479  Revision 1.3  2004/05/19 04:07:42  reddawg
00480  kmalloc(size,pid) no more it is no kmalloc(size); the way it should of been
00481 
00482  Revision 1.2  2004/05/10 02:23:24  reddawg
00483  Minor Changes To Source Code To Prepare It For Open Source Release
00484 
00485  Revision 1.1.1.1  2004/04/15 12:07:09  reddawg
00486  UbixOS v1.0
00487 
00488  Revision 1.19  2004/04/13 16:36:33  reddawg
00489  Changed our copyright, it is all now under a BSD-Style license
00490 
00491  END
00492  ***/
00493 

Generated on Fri Dec 15 11:18:55 2006 for UbixOS V2 by  doxygen 1.4.7