UbixOS V2  2.0
atkbd.c
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2002-2018 The UbixOS Project.
3  * All rights reserved.
4  *
5  * This was developed by Christopher W. Olsen for the UbixOS Project.
6  *
7  * Redistribution and use in source and binary forms, with or without modification, are permitted
8  * provided that the following conditions are met:
9  *
10  * 1) Redistributions of source code must retain the above copyright notice, this list of
11  * conditions, the following disclaimer and the list of authors.
12  * 2) Redistributions in binary form must reproduce the above copyright notice, this list of
13  * conditions, the following disclaimer and the list of authors in the documentation and/or
14  * other materials provided with the distribution.
15  * 3) Neither the name of the UbixOS Project nor the names of its contributors may be used to
16  * endorse or promote products derived from this software without specific prior written
17  * permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <isa/atkbd.h>
30 #include <isa/8259.h>
31 #include <sys/video.h>
32 #include <sys/idt.h>
33 #include <sys/gdt.h>
34 #include <sys/io.h>
35 #include <lib/kmalloc.h>
36 #include <lib/kprintf.h>
37 #include <ubixos/sched.h>
38 #include <ubixos/endtask.h>
39 #include <ubixos/tty.h>
40 #include <ubixos/spinlock.h>
41 #include <ubixos/kpanic.h>
42 #include <ubixos/vitals.h>
43 
44 static int atkbd_scan();
45 
46 static unsigned int keyMap = 0x0;
47 static unsigned int ledStatus = 0x0;
48 static char stdinBuffer[512];
49 static uInt16 stdinSize;
50 static uInt32 controlKeys = 0x0;
51 
52 static struct spinLock atkbdSpinLock = SPIN_LOCK_INITIALIZER;
53 
54 static unsigned int keyboardMap[255][8] = {
55 /* Ascii, Shift, Ctrl, Alt, Num, Caps, Shift Caps, Shift Num */
56 { 0, 0, 0, 0, 0, 0, 0, 0 },
57 /* ESC */{ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B },
58 /* 1,! */{ 0x31, 0x21, 0, 0, 0x31, 0x31, 0x21, 0x21 },
59 /* 2,@ */{ 0x32, 0x40, 0, 0, 0x32, 0x32, 0x40, 0x40 },
60 /* 3,# */{ 0x33, 0x23, 0, 0, 0x33, 0x33, 0x23, 0x23 },
61 /* 4,$ */{ 0x34, 0x24, 0, 0, 0x34, 0x34, 0x24, 0x24 },
62 /* 5,% */{ 0x35, 0x25, 0, 0, 0x35, 0x35, 0x25, 0x25 },
63 /* 6,^ */{ 0x36, 0x5E, 0, 0, 0x36, 0x36, 0x5E, 0x5E },
64 /* 7,& */{ 0x37, 0x26, 0, 0, 0x37, 0x37, 0x26, 0x26 },
65 /* 8,* */{ 0x38, 0x2A, 0, 0, 0x38, 0x38, 0x2A, 0x2A },
66 /* 9.( */{ 0x39, 0x28, 0, 0, 0x39, 0x39, 0x28, 0x28 },
67 /* 0,) */{ 0x30, 0x29, 0, 0, 0x30, 0x30, 0x29, 0x29 },
68 /* -,_ */{ 0x2D, 0x5F, 0, 0, 0x2D, 0x2D, 0x5F, 0x5F },
69 /* =,+ */{ 0x3D, 0x2B, 0, 0, 0x3D, 0x3D, 0x2B, 0x2B },
70 /* 14 */{ 0x08, 0x08, 0x8, 0x8, 0x08, 0x08, 0x08, 0x08 },
71 /* 15 */{ 0x09, 0, 0, 0, 0, 0, 0, 0 },
72 /* */{ 0x71, 0x51, 0, 0, 0, 0, 0, 0 },
73 /* */{ 0x77, 0x57, 0, 0, 0, 0, 0, 0 },
74 /* e,E */{ 0x65, 0x45, 0x05, 0, 0, 0, 0, 0 },
75 /* */{ 0x72, 0x52, 0, 0, 0, 0, 0, 0 },
76 /* */{ 0x74, 0x54, 0, 0, 0, 0, 0, 0 },
77 /* */{ 0x79, 0x59, 0, 0, 0, 0, 0, 0 },
78 /* */{ 0x75, 0x55, 0, 0, 0, 0, 0, 0 },
79 /* */{ 0x69, 0x49, 0, 0, 0, 0, 0, 0 },
80 /* */{ 0x6F, 0x4F, 0, 0, 0, 0, 0, 0 },
81 /* */{ 0x70, 0x50, 0, 0, 0, 0, 0, 0 },
82 /* */{ 0x5B, 0x7B, 0, 0, 0, 0, 0, 0 },
83 /* */{ 0x5D, 0x7D, 0, 0, 0, 0, 0, 0 },
84 /* */{ 0x0A, 0, 0, 0, 0, 0, 0, 0 },
85 /* */{ 0, 0, 0, 0, 0, 0, 0, 0 },
86 /* a,A */{ 0x61, 0x41, 0x01, 0, 0, 0, 0, 0 },
87 /* */{ 0x73, 0x53, 0, 0, 0, 0, 0, 0 },
88 /* d,D */{ 0x64, 0x44, 0x04, 0, 0, 0, 0, 0 },
89 /* f,F */{ 0x66, 0x46, 0x06, 0, 0, 0, 0, 0 },
90 /* g,G */{ 0x67, 0x47, 0x07, 0, 0, 0, 0, 0 },
91 /* h,H */{ 0x68, 0x48, 0x08, 0, 0, 0, 0, 0 },
92 /* */{ 0x6A, 0x4A, 0, 0, 0, 0, 0, 0 },
93 /* */{ 0x6B, 0x4B, 0, 0, 0, 0, 0, 0 },
94 /* */{ 0x6C, 0x4C, 0, 0, 0, 0, 0, 0 },
95 /* */{ 0x3B, 0x3A, 0, 0, 0, 0, 0, 0 },
96 /* */{ 0x27, 0x22, 0, 0, 0, 0, 0, 0 },
97 /* */{ 0x60, 0x7E, 0, 0, 0, 0, 0, 0 },
98 /* */{ 0x2A, 0x0, 0, 0, 0, 0, 0, 0 },
99 /* */{ 0x5C, 0x3C, 0, 0, 0, 0, 0, 0 },
100 /* */{ 0x7A, 0x5A, 0, 0, 0, 0, 0, 0 },
101 /* x,X */{ 0x78, 0x58, 0x18, 0, 0, 0, 0, 0 },
102 /* c,C */{ 0x63, 0x43, 0x03, 0x9, 0, 0, 0, 0 },
103 /* */{ 0x76, 0x56, 0, 0, 0, 0, 0, 0 },
104 /* b,B */{ 0x62, 0x42, 0x02, 0, 0, 0, 0, 0 },
105 /* */{ 0x6E, 0x4E, 0, 0, 0, 0, 0, 0 },
106 /* */{ 0x6D, 0x4D, 0, 0, 0, 0, 0, 0 },
107 /* */{ 0x2C, 0x3C, 0, 0, 0, 0, 0, 0 },
108 /* */{ 0x2E, 0x3E, 0, 0, 0, 0, 0, 0 },
109 /* */{ 0x2F, 0x3F, 0, 0, 0, 0, 0, 0 },
110 /* */{ 0, 0, 0, 0, 0, 0, 0, 0 },
111 /* */{ 0, 0, 0, 0, 0, 0, 0, 0 },
112 /* */{ 0, 0, 0, 0, 0, 0, 0, 0 },
113 /* */{ 0x20, 0, 0, 0, 0, 0, 0, 0 },
114 /* */{ 0, 0, 0, 0, 0, 0, 0, 0 },
115 /* F1 */{ 0x3000, 0, 0, 0x3000, 0, 0, 0, 0 },
116 /* */{ 0x3001, 0, 0, 0x3001, 0, 0, 0, 0 },
117 /* */{ 0x3002, 0, 0, 0x3002, 0, 0, 0, 0 },
118 /* */{ 0x3003, 0, 0, 0x3003, 0, 0, 0, 0 },
119 /* */{ 0x3004, 0, 0, 0x3004, 0, 0, 0, 0 },
120 /* */{ 0x4000, 0, 0, 0, 0, 0, 0, 0 },
121 /* */{ 0x4100, 0, 0, 0, 0, 0, 0, 0 },
122 /* */{ 0x4200, 0, 0, 0, 0, 0, 0, 0 },
123 /* */{ 0x4300, 0, 0, 0, 0, 0, 0, 0 },
124 /* */{ 0x4400, 0, 0, 0, 0, 0, 0, 0 },
125 /* */{ 0, 0, 0, 0, 0, 0, 0, 0 },
126 /* */{ 0, 0, 0, 0, 0, 0, 0, 0 },
127 /* */{ 0x4700, 0, 0, 0, 0, 0, 0, 0 },
128 /* */{ 0x4800, 0, 0, 0, 0, 0, 0, 0 },
129 /* */{ 0x4900, 0, 0, 0, 0, 0, 0, 0 },
130 /* */{ 0x2D, 0, 0, 0, 0, 0, 0, 0 },
131 /* */{ 0x4B00, 0, 0, 0, 0, 0, 0, 0 },
132 /* */{ 0x4C00, 0, 0, 0, 0, 0, 0, 0 },
133 /* */{ 0x4D00, 0, 0, 0, 0, 0, 0, 0 },
134 /* */{ 0x2B, 0, 0, 0, 0, 0, 0, 0 },
135 /* */{ 0x4F00, 0, 0, 0, 0, 0, 0, 0 },
136 /* */{ 0x5000, 0, 0, 0, 0, 0, 0, 0 },
137 /* */{ 0x5100, 0, 0, 0, 0, 0, 0, 0 },
138 /* */{ 0x5200, 0, 0, 0, 0, 0, 0, 0 },
139 /* */{ 0x5300, 0, 0, 0, 0, 0, 0, 0 },
140 /* */{ 0, 0, 0, 0, 0, 0, 0, 0 },
141 /* */{ 0, 0, 0, 0, 0, 0, 0, 0 } };
142 
143 /************************************************************************
144 
145  Function: int atkbd_init
146 
147  Description: This function is used to turn on the keyboard
148 
149  Notes:
150 
151  02/20/2004 - Approved for quality
152 
153  ************************************************************************/
154 int atkbd_init() {
155 
156  /* Insert the IDT vector for the keyboard handler */
157  setVector(&atkbd_isr, mVec + 0x1, dPresent + dInt + dDpl0);
158 
159  /* Set the LEDS to their defaults */
160  setLED();
161 
162  /* Clear Keyboard */
163  atkbd_scan();
164 
165  /* Turn on the keyboard vector */
166  irqEnable(0x1);
167 
168  /* Print out information on keyboard */
169  kprintf("atkbd0 - Address: [0x%X], Keyboard Buffer: [0x%X], Buffer Size [%i]\n", &atkbd_isr, &stdinBuffer, 512);
170 
171  /* Return so we know everything went well */
172  return (0x0);
173 }
174 
175 /*
176  * 2-23-2004 mji I think the pusha/popa should be pushal/popal
177  */
178 
179 asm(
180  ".globl atkbd_isr \n"
181  "atkbd_isr: \n"
182  "push $0x80\n"
183  "push $0x80\n"
184  " pusha \n" /* Save all registers */
185  " push %ds \n"
186  " push %es \n"
187  " push %fs \n"
188  " push %gs \n"
189  " push %esp \n"
190  " call keyboardHandler \n"
191  " add $0x4,%esp\n"
192  " mov $0x20,%dx \n"
193  " mov $0x20,%ax \n"
194  " outb %al,%dx \n"
195  " pop %gs \n"
196  " pop %fs \n"
197  " pop %es \n"
198  " pop %ds \n"
199  " popa \n"
200  " add $0x8,%esp\n"
201  " iret \n" /* Exit interrupt */
202 );
203 
204 static int atkbd_scan() {
205  int code = 0x0;
206  int val = 0x0;
207 
208  code = inportByte(0x60);
209  val = inportByte(0x61);
210 
211  outportByte(0x61, val | 0x80);
212  outportByte(0x61, val);
213 
214  return (code);
215 }
216 
217 void keyboardHandler(struct trapframe *frame) {
218  int key = 0x0;
219 
220  if (spinTryLock(&atkbdSpinLock))
221  return;
222 
223  key = atkbd_scan();
224 
225  if (key > 255)
226  return;
227 
228 
229  /* Control Key */
230  if (key == 0x1D && !(controlKeys & controlKey)) {
231  controlKeys |= controlKey;
232  }
233  if (key == 0x80 + 0x1D) {
234  controlKeys &= (0xFF - controlKey);
235  }
236  /* ALT Key */
237  if (key == 0x38 && !(controlKeys & altKey)) {
238  controlKeys |= altKey;
239  }
240  if (key == 0x80 + 0x38) {
241  controlKeys &= (0xFF - altKey);
242  }
243  /* Shift Key */
244  if ((key == 0x2A || key == 0x36) && !(controlKeys & shiftKey)) {
245  controlKeys |= shiftKey;
246  }
247  if ((key == 0x80 + 0x2A) || (key == 0x80 + 0x36)) {
248  controlKeys &= (0xFF - shiftKey);
249  }
250  /* Caps Lock */
251  if (key == 0x3A) {
252  ledStatus ^= ledCapslock;
253  setLED();
254  }
255  /* Num Lock */
256  if (key == 0x45) {
257  ledStatus ^= ledNumlock;
258  setLED();
259  }
260  /* Scroll Lock */
261  if (key == 0x46) {
262  ledStatus ^= ledScrolllock;
263  setLED();
264  }
265  /* Pick Which Key Map */
266  if (controlKeys == 0) {
267  keyMap = 0;
268  }
269  else if (controlKeys == 1) {
270  keyMap = 1;
271  }
272  else if (controlKeys == 2) {
273  keyMap = 2;
274  }
275  else if (controlKeys == 4) {
276  keyMap = 3;
277  }
278  /* If Key Is Not Null Add It To Handler */
279  if (((uInt) (keyboardMap[key][keyMap]) > 0) && ((uInt32) (keyboardMap[key][keyMap]) < 0xFF)) {
280  switch ((uInt32) keyboardMap[key][keyMap]) {
281  case 8:
282  backSpace();
283  if (tty_foreground == 0x0) {
284  stdinBuffer[stdinSize] = keyboardMap[key][keyMap];
285  stdinSize++;
286  }
287  else {
288  tty_foreground->stdin[tty_foreground->stdinSize] = keyboardMap[key][keyMap];
290  }
291  break;
292  case 0x3:
293  //if (tty_foreground != 0x0)
294  // endTask(tty_foreground->owner);
295  //K_PANIC( "CTRL-C pressed\n" );
296  kprintf("FreePages: [0x%X]\n", systemVitals->freePages);
298  break;
299  case 0x9:
300  kprintf("REBOOTING");
301  while (inportByte(0x64) & 0x02)
302  ;
303  outportByte(0x64, 0xFE);
304  break;
305  case 0x18:
306  if (tty_foreground->owner == _current->id)
307  die_if_kernel("CTRL-X", frame, frame->tf_eax);
308  break;
309  default:
310  if (tty_foreground == 0x0) {
311  stdinBuffer[stdinSize] = keyboardMap[key][keyMap];
312  stdinSize++;
313  }
314  else {
315  tty_foreground->stdin[tty_foreground->stdinSize] = keyboardMap[key][keyMap];
317  }
318  break;
319  }
320  }
321  else {
322  switch ((keyboardMap[key][keyMap] >> 8)) {
323  case 0x30:
324  tty_change(keyboardMap[key][keyMap] & 0xFF);
325  //kprintf("Changing Consoles[0x%X:0x%X]\n",_current->id,_current);
326  break;
327  default:
328  break;
329  }
330  }
331 
332  /* Return */
333  spinUnlock(&atkbdSpinLock);
334  return;
335 }
336 
337 void setLED() {
338  outportByte(0x60, 0xED);
339  while (inportByte(0x64) & 2)
340  ;
341  outportByte(0x60, ledStatus);
342  while (inportByte(0x64) & 2)
343  ;
344 }
345 
346 /* Temp */
347 int getchar() {
348  //uInt8 retKey = 0x0;
349  int retKey = 0x0;
350  uInt32 i = 0x0;
351 
352  /*
353  if ((stdinSize <= 0) && (tty_foreground == 0x0)) {
354  sched_yield();
355  }
356  if ((tty_foreground != 0x0) && (tty_foreground->stdinSize <= 0x0)) {
357  sched_yield();
358  }
359  */
360 
361  /*
362  if (spinTryLock(&atkbdSpinLock))
363  return(0x0);
364  */
365 
366  if (tty_foreground == 0x0) {
367  if (stdinSize == 0x0) {
368  // spinUnlock(&atkbdSpinLock);
369  return (0x0);
370  }
371 
372  retKey = stdinBuffer[0];
373  stdinSize--;
374 
375  for (i = 0x0; i < stdinSize; i++) {
376  stdinBuffer[i] = stdinBuffer[i + 0x1];
377  }
378  }
379  else {
380  if (tty_foreground->stdinSize == 0x0) {
381  // spinUnlock(&atkbdSpinLock);
382  return (0x0);
383  }
384 
385  retKey = tty_foreground->stdin[0];
387 
388  for (i = 0x0; i < tty_foreground->stdinSize; i++) {
389  tty_foreground->stdin[i] = tty_foreground->stdin[i + 0x1];
390  }
391  }
392  //spinUnlock(&atkbdSpinLock);
393  return (retKey);
394 }
8259.h
controlKey
#define controlKey
Definition: atkbd.h:33
spinlock.h
ledNumlock
#define ledNumlock
Definition: atkbd.h:35
gdt.h
uInt32
unsigned long int uInt32
Definition: objgfx30.h:49
dPresent
#define dPresent
Definition: gdt.h:54
uInt
unsigned int uInt
Definition: types.h:65
backSpace
void backSpace()
Definition: video.c:37
idt.h
uInt16
unsigned short int uInt16
Definition: objgfx30.h:48
video.h
outportByte
void outportByte(unsigned int, unsigned char)
outputut one byte to specified port
Definition: io.c:72
spinUnlock
void spinUnlock(spinLock_t *lock)
Definition: spinlock.c:36
endtask.h
atkbd_init
int atkbd_init()
Definition: atkbd.c:153
SPIN_LOCK_INITIALIZER
#define SPIN_LOCK_INITIALIZER
Definition: spinlock.h:36
ledScrolllock
#define ledScrolllock
Definition: atkbd.h:36
sched.h
tty_change
int tty_change(uInt16)
Definition: tty.c:84
getchar
int getchar()
Definition: atkbd.c:346
inportByte
unsigned char inportByte(unsigned int)
input one byte from specified port
Definition: io.c:38
kpanic.h
taskStruct::id
pidType id
Definition: sched.h:63
tty_termNode::stdinSize
int stdinSize
Definition: tty.h:44
systemVitals
vitalsNode * systemVitals
Definition: vitals.c:35
trapframe::tf_eax
int tf_eax
Definition: trap.h:46
kprintf.h
atkbd.h
vitals.h
tty.h
shiftKey
#define shiftKey
Definition: atkbd.h:32
trapframe
Definition: trap.h:34
DEAD
Definition: sched.h:47
_current
kTask_t * _current
Definition: sched.c:50
sched_setStatus
int sched_setStatus(pidType pid, tState state)
Definition: sched.c:265
dInt
#define dInt
Definition: gdt.h:43
altKey
#define altKey
Definition: atkbd.h:34
mVec
#define mVec
Definition: 8259.h:41
vitalsStruct::freePages
uint32_t freePages
Definition: vitals.h:43
tty_foreground
tty_term * tty_foreground
Definition: tty.c:38
spinLock
Definition: spinlock.h:41
setVector
void setVector(void *handler, unsigned char interrupt, unsigned short controlMajor)
Definition: idt.c:208
io.h
die_if_kernel
void die_if_kernel(char *str, struct trapframe *regs, long err)
Definition: trap.c:59
tty_termNode::stdin
char stdin[512]
Definition: tty.h:43
keyboardHandler
void keyboardHandler(struct trapframe *frame)
Definition: atkbd.c:216
irqEnable
void irqEnable(uInt16 irqNo)
atkbd_isr
void atkbd_isr()
kprintf
int kprintf(const char *,...)
Definition: kprintf.c:259
ledCapslock
#define ledCapslock
Definition: atkbd.h:37
setLED
void setLED()
Definition: atkbd.c:336
tty_termNode::owner
pidType owner
Definition: tty.h:42
dDpl0
#define dDpl0
Definition: gdt.h:53
spinTryLock
int spinTryLock(spinLock_t *lock)
Definition: spinlock.c:47
kmalloc.h