Rev 893 | Rev 895 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 893 | Rev 894 | ||
|---|---|---|---|
| Line 24... | Line 24... | ||
| 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | */ |
27 | */ |
| 28 | 28 | ||
| 29 | #include <arch/i8042.h> |
29 | #include <genarch/i8042/i8042.h> |
| 30 | #include <arch/i8259.h> |
30 | #include <arch/drivers/i8042.h> |
| 31 | #include <arch/interrupt.h> |
31 | #include <arch/interrupt.h> |
| 32 | #include <cpu.h> |
32 | #include <cpu.h> |
| 33 | #include <arch/asm.h> |
33 | #include <arch/asm.h> |
| 34 | #include <arch.h> |
34 | #include <arch.h> |
| 35 | #include <print.h> |
35 | #include <print.h> |
| Line 43... | Line 43... | ||
| 43 | /** |
43 | /** |
| 44 | * i8042 processor driver. |
44 | * i8042 processor driver. |
| 45 | * It takes care of low-level keyboard functions. |
45 | * It takes care of low-level keyboard functions. |
| 46 | */ |
46 | */ |
| 47 | 47 | ||
| 48 | #define i8042_DATA 0x60 |
- | |
| 49 | #define i8042_STATUS 0x64 |
- | |
| 50 | #define i8042_BUFFER_FULL_MASK 0x01 |
- | |
| 51 | - | ||
| 52 | /** Keyboard commands. */ |
48 | /** Keyboard commands. */ |
| 53 | #define KBD_ENABLE 0xf4 |
49 | #define KBD_ENABLE 0xf4 |
| 54 | #define KBD_DISABLE 0xf5 |
50 | #define KBD_DISABLE 0xf5 |
| 55 | #define KBD_ACK 0xfa |
51 | #define KBD_ACK 0xfa |
| 56 | 52 | ||
| Line 69... | Line 65... | ||
| 69 | * `----------- reserved, should be 0 |
65 | * `----------- reserved, should be 0 |
| 70 | */ |
66 | */ |
| 71 | 67 | ||
| 72 | #define i8042_SET_COMMAND 0x60 |
68 | #define i8042_SET_COMMAND 0x60 |
| 73 | #define i8042_COMMAND 0x49 |
69 | #define i8042_COMMAND 0x49 |
| - | 70 | ||
| - | 71 | #define i8042_BUFFER_FULL_MASK 0x01 |
|
| 74 | #define i8042_WAIT_MASK 0x02 |
72 | #define i8042_WAIT_MASK 0x02 |
| 75 | 73 | ||
| 76 | #define SPECIAL '?' |
74 | #define SPECIAL '?' |
| 77 | #define KEY_RELEASE 0x80 |
75 | #define KEY_RELEASE 0x80 |
| 78 | 76 | ||
| Line 82... | Line 80... | ||
| 82 | 80 | ||
| 83 | #define PRESSED_SHIFT (1<<0) |
81 | #define PRESSED_SHIFT (1<<0) |
| 84 | #define PRESSED_CAPSLOCK (1<<1) |
82 | #define PRESSED_CAPSLOCK (1<<1) |
| 85 | #define LOCKED_CAPSLOCK (1<<0) |
83 | #define LOCKED_CAPSLOCK (1<<0) |
| 86 | 84 | ||
| 87 | #define ACTIVE_READ_BUFF_SIZE 16 /*Must be power of 2*/ |
85 | #define ACTIVE_READ_BUFF_SIZE 16 /* Must be power of 2 */ |
| 88 | 86 | ||
| 89 | __u8 active_read_buff[ACTIVE_READ_BUFF_SIZE]={0}; |
87 | static __u8 active_read_buff[ACTIVE_READ_BUFF_SIZE]; |
| 90 | 88 | ||
| 91 | SPINLOCK_INITIALIZE(keylock); /**< keylock protects keyflags and lockflags. */ |
89 | SPINLOCK_INITIALIZE(keylock); /**< keylock protects keyflags and lockflags. */ |
| 92 | static volatile int keyflags; /**< Tracking of multiple keypresses. */ |
90 | static volatile int keyflags; /**< Tracking of multiple keypresses. */ |
| 93 | static volatile int lockflags; /**< Tracking of multiple keys lockings. */ |
91 | static volatile int lockflags; /**< Tracking of multiple keys lockings. */ |
| 94 | 92 | ||
| Line 266... | Line 264... | ||
| 266 | 264 | ||
| 267 | /** Initialize i8042. */ |
265 | /** Initialize i8042. */ |
| 268 | void i8042_init(void) |
266 | void i8042_init(void) |
| 269 | { |
267 | { |
| 270 | exc_register(VECTOR_KBD, "i8042_interrupt", i8042_interrupt); |
268 | exc_register(VECTOR_KBD, "i8042_interrupt", i8042_interrupt); |
| 271 | while (inb(i8042_STATUS)&i8042_WAIT_MASK) { |
269 | while (i8042_status_read() & i8042_WAIT_MASK) { |
| 272 | /* wait */ |
270 | /* wait */ |
| 273 | } |
271 | } |
| 274 | outb(i8042_STATUS,i8042_SET_COMMAND); |
272 | i8042_command_write(i8042_SET_COMMAND); |
| 275 | while (inb(i8042_STATUS)&i8042_WAIT_MASK) { |
273 | while (i8042_status_read() & i8042_WAIT_MASK) { |
| 276 | /* wait */ |
274 | /* wait */ |
| 277 | } |
275 | } |
| 278 | outb(i8042_DATA,i8042_COMMAND); |
276 | i8042_data_write(i8042_COMMAND); |
| 279 | 277 | ||
| 280 | trap_virtual_enable_irqs(1<<IRQ_KBD); |
278 | trap_virtual_enable_irqs(1<<IRQ_KBD); |
| 281 | chardev_initialize("i8042_kbd", &kbrd, &ops); |
279 | chardev_initialize("i8042_kbd", &kbrd, &ops); |
| 282 | stdin = &kbrd; |
280 | stdin = &kbrd; |
| 283 | } |
281 | } |
| Line 290... | Line 288... | ||
| 290 | void i8042_interrupt(int n, void *stack) |
288 | void i8042_interrupt(int n, void *stack) |
| 291 | { |
289 | { |
| 292 | __u8 x; |
290 | __u8 x; |
| 293 | 291 | ||
| 294 | trap_virtual_eoi(); |
292 | trap_virtual_eoi(); |
| 295 | x = inb(i8042_DATA); |
293 | x = i8042_data_read(); |
| 296 | if (x & KEY_RELEASE) |
294 | if (x & KEY_RELEASE) |
| 297 | key_released(x ^ KEY_RELEASE); |
295 | key_released(x ^ KEY_RELEASE); |
| 298 | else |
296 | else |
| 299 | key_pressed(x); |
297 | key_pressed(x); |
| 300 | } |
298 | } |
| Line 407... | Line 405... | ||
| 407 | } |
405 | } |
| 408 | 406 | ||
| 409 | static __u8 active_read_buff_read(void) |
407 | static __u8 active_read_buff_read(void) |
| 410 | { |
408 | { |
| 411 | static int i=0; |
409 | static int i=0; |
| 412 | i&=(ACTIVE_READ_BUFF_SIZE-1); |
410 | i &= (ACTIVE_READ_BUFF_SIZE-1); |
| 413 | if(!active_read_buff[i]) |
411 | if(!active_read_buff[i]) { |
| 414 | { |
- | |
| 415 | return 0; |
412 | return 0; |
| 416 | } |
413 | } |
| 417 | return active_read_buff[i++]; |
414 | return active_read_buff[i++]; |
| 418 | } |
415 | } |
| 419 | 416 | ||
| 420 | static void active_read_buff_write(__u8 ch) |
417 | static void active_read_buff_write(__u8 ch) |
| 421 | { |
418 | { |
| 422 | static int i=0; |
419 | static int i=0; |
| 423 | active_read_buff[i]=ch; |
420 | active_read_buff[i] = ch; |
| 424 | i++; |
421 | i++; |
| 425 | i&=(ACTIVE_READ_BUFF_SIZE-1); |
422 | i &= (ACTIVE_READ_BUFF_SIZE-1); |
| 426 | active_read_buff[i]=0; |
423 | active_read_buff[i]=0; |
| 427 | } |
424 | } |
| 428 | 425 | ||
| 429 | 426 | ||
| 430 | static void active_read_key_pressed(__u8 sc) |
427 | static void active_read_key_pressed(__u8 sc) |
| Line 498... | Line 495... | ||
| 498 | 495 | ||
| 499 | static char key_read(chardev_t *d) |
496 | static char key_read(chardev_t *d) |
| 500 | { |
497 | { |
| 501 | char ch; |
498 | char ch; |
| 502 | 499 | ||
| 503 | while(!(ch=active_read_buff_read())) |
500 | while(!(ch = active_read_buff_read())) { |
| 504 | { |
- | |
| 505 | __u8 x; |
501 | __u8 x; |
| 506 | while (!((x=inb(i8042_STATUS))&i8042_BUFFER_FULL_MASK)); |
502 | while (!((x=i8042_status_read() & i8042_BUFFER_FULL_MASK))) |
| - | 503 | ; |
|
| 507 | x = inb(i8042_DATA); |
504 | x = i8042_data_read(); |
| 508 | if (x & KEY_RELEASE) |
505 | if (x & KEY_RELEASE) |
| 509 | key_released(x ^ KEY_RELEASE); |
506 | key_released(x ^ KEY_RELEASE); |
| 510 | else |
507 | else |
| 511 | active_read_key_pressed(x); |
508 | active_read_key_pressed(x); |
| 512 | } |
509 | } |