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 | } |