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

Generated on Sun Dec 3 02:38:03 2006 for UbixOS V2 by  doxygen 1.4.7