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

Generated on Tue Dec 5 11:01:15 2006 for UbixOS V2 by  doxygen 1.4.7