Subversion Repositories HelenOS

Rev

Rev 3674 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2006 Josef Cejka
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  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
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup kbdia64 ia64
  30.  * @brief   HelenOS ia64 arch dependent parts of uspace keyboard handler.
  31.  * @ingroup  kbd
  32.  * @{
  33.  */
  34. /** @file
  35.  */
  36.  
  37. #include <arch/kbd.h>
  38. #include <ipc/ipc.h>
  39. #include <sysinfo.h>
  40. #include <kbd.h>
  41. #include <keys.h>
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44.  
  45. #include <unistd.h>
  46. #include <align.h>
  47. #include <async.h>
  48. #include <ipc/ipc.h>
  49. #include <errno.h>
  50. #include <stdio.h>
  51. #include <ddi.h>
  52. #include <sysinfo.h>
  53. #include <as.h>
  54. #include <ipc/fb.h>
  55. #include <ipc/ipc.h>
  56. #include <ipc/ns.h>
  57. #include <ipc/services.h>
  58. #include <libarch/ddi.h>
  59.  
  60.  
  61. extern int lkbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call);
  62. extern int lkbd_arch_init(void);
  63.  
  64.  
  65.  
  66. #define KEY_F1 0x504f1b
  67. #define KEY_F2 0x514f1b
  68. #define KEY_F3 0x524f1b
  69. #define KEY_F4 0x534f1b
  70. #define KEY_F5 0x7e35315b1b
  71. #define KEY_F6 0x7e37315b1b
  72. #define KEY_F7 0x7e38315b1b
  73. #define KEY_F8 0x7e39315b1b
  74. #define KEY_F9 0x7e30325b1b
  75. #define KEY_F10 0x7e31325b1b
  76. #define KEY_F11 0x7e33325b1b
  77. #define KEY_F12 0x7e34325b1b
  78.  
  79.  
  80.  
  81.  
  82. #define NSKEY_F1 0x415b5b1b
  83. #define NSKEY_F2 0x425b5b1b
  84. #define NSKEY_F3 0x435b5b1b
  85. #define NSKEY_F4 0x445b5b1b
  86. #define NSKEY_F5 0x455b5b1b
  87. #define NSKEY_F6 0x37315b1b
  88. #define NSKEY_F7 0x38315b1b
  89. #define NSKEY_F8 0x39315b1b
  90. #define NSKEY_F9 0x30325b1b
  91. #define NSKEY_F10 0x31325b1b
  92. #define NSKEY_F11 0x33325b1b
  93. #define NSKEY_F12 0x34325b1b
  94.  
  95.  
  96. #define FUNCTION_KEYS 0x100
  97.  
  98.  
  99. #define KBD_SKI 1
  100. #define KBD_LEGACY 2
  101. #define KBD_NS16550 3
  102.  
  103.  
  104.  
  105.  
  106. /* NS16550 registers */
  107. #define RBR_REG     0   /** Receiver Buffer Register. */
  108. #define IER_REG     1   /** Interrupt Enable Register. */
  109. #define IIR_REG     2   /** Interrupt Ident Register (read). */
  110. #define FCR_REG     2   /** FIFO control register (write). */
  111. #define LCR_REG     3   /** Line Control register. */
  112. #define MCR_REG     4   /** Modem Control Register. */
  113. #define LSR_REG     5   /** Line Status Register. */
  114.  
  115.  
  116.  
  117. irq_cmd_t ns16550_cmds[1] = {
  118.     { CMD_PORT_READ_1, 0, 0, 2 },
  119. };
  120.  
  121. irq_code_t ns16550_kbd = {
  122.     1,
  123.     ns16550_cmds
  124. };
  125.  
  126.  
  127. uint16_t ns16550_port;
  128.  
  129. int kbd_type;
  130.  
  131. int kbd_arch_init(void)
  132. {
  133.     if (sysinfo_value("kbd")) {
  134.         kbd_type=sysinfo_value("kbd.type");
  135.         if (kbd_type == KBD_LEGACY)
  136.             return lkbd_arch_init();
  137.         if (kbd_type == KBD_NS16550) {
  138.             ns16550_kbd.cmds[0].addr = (void *) (sysinfo_value("kbd.port") + RBR_REG);
  139.             ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &ns16550_kbd);
  140.             iospace_enable(task_get_id(), ns16550_port = sysinfo_value("kbd.port"), 8);
  141.         }
  142.         return 0;
  143.     }
  144.     return 1;
  145. }
  146.  
  147. /*
  148. * Please preserve this code (it can be used to determine scancodes)
  149. *
  150. int to_hex(int v)
  151. {
  152.     return "0123456789ABCDEF"[v];
  153. }
  154. */
  155. #define LSR_DATA_READY  0x01
  156.  
  157. int kbd_ns16550_process(keybuffer_t *keybuffer, ipc_call_t *call)
  158. {
  159.     static unsigned long buf = 0;
  160.     static int count = 0, esc_count=0; 
  161.    
  162.     int scan_code = IPC_GET_ARG2(*call);
  163.    
  164.     if (scan_code == 0x1b) {
  165.         esc_count++;
  166.         if (esc_count == 3) {
  167.             __SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
  168.         }  
  169.     } else {
  170.         esc_count = 0;
  171.     }
  172.    
  173.     if (scan_code == 0x0d)
  174.         return 1;        /* Delete CR */
  175.     if (scan_code == 0x7f)
  176.         scan_code='\b';  /* Convert backspace */
  177.    
  178.     if(scan_code == 0x7e) {
  179.         switch (buf) {
  180.         case NSKEY_F6:
  181.             keybuffer_push(keybuffer,FUNCTION_KEYS | 6);
  182.             buf = count = 0;
  183.             return 1;
  184.         case NSKEY_F7:
  185.             keybuffer_push(keybuffer,FUNCTION_KEYS | 7);
  186.             buf = count = 0;
  187.             return 1;
  188.         case NSKEY_F8:
  189.             keybuffer_push(keybuffer,FUNCTION_KEYS | 8);
  190.             buf = count = 0;
  191.             return 1;
  192.         case NSKEY_F9:
  193.             keybuffer_push(keybuffer,FUNCTION_KEYS | 9);
  194.             buf = count = 0;
  195.             return 1;
  196.         case NSKEY_F10:
  197.             keybuffer_push(keybuffer,FUNCTION_KEYS | 10);
  198.             buf = count = 0;
  199.             return 1;
  200.         case NSKEY_F11:
  201.             keybuffer_push(keybuffer,FUNCTION_KEYS | 11);
  202.             buf = count = 0;
  203.             return 1;
  204.         case NSKEY_F12:
  205.             keybuffer_push(keybuffer,FUNCTION_KEYS | 12);
  206.             buf = count = 0;
  207.             return 1;
  208.         default:
  209.             keybuffer_push(keybuffer, buf & 0xff);
  210.             keybuffer_push(keybuffer, (buf >> 8) &0xff);
  211.             keybuffer_push(keybuffer, (buf >> 16) &0xff);
  212.             keybuffer_push(keybuffer, (buf >> 24) &0xff);
  213.             keybuffer_push(keybuffer, scan_code);
  214.             buf = count = 0;
  215.             return 1;
  216.         }
  217.     }
  218.  
  219.     buf |= ((unsigned long) scan_code)<<(8*(count++));
  220.    
  221.     if((buf & 0xff) != (NSKEY_F1 & 0xff)) {
  222.         keybuffer_push(keybuffer, buf);
  223.         buf = count = 0;
  224.         return 1;
  225.     }
  226.  
  227.     if (count <= 1)
  228.         return 1;
  229.  
  230.     if ((buf & 0xffff) != (NSKEY_F1 & 0xffff))  {
  231.  
  232.         keybuffer_push(keybuffer, buf & 0xff);
  233.         keybuffer_push(keybuffer, (buf >> 8) &0xff);
  234.         buf = count = 0;
  235.         return 1;
  236.     }
  237.  
  238.     if (count <= 2)
  239.         return 1;
  240.  
  241.  
  242.     if ((buf & 0xffffff) != (NSKEY_F1 & 0xffffff)
  243.         && (buf & 0xffffff) != (NSKEY_F6 & 0xffffff)
  244.         && (buf & 0xffffff) != (NSKEY_F9 & 0xffffff) ) {
  245.  
  246.         keybuffer_push(keybuffer, buf & 0xff);
  247.         keybuffer_push(keybuffer, (buf >> 8) &0xff);
  248.         keybuffer_push(keybuffer, (buf >> 16) &0xff);
  249.         buf = count = 0;
  250.         return 1;
  251.     }
  252.  
  253.     if (count <= 3)
  254.         return 1;
  255.  
  256.     switch (buf) {
  257.     case NSKEY_F1:
  258.         keybuffer_push(keybuffer,FUNCTION_KEYS | 1);
  259.         buf = count = 0;
  260.         return 1;
  261.     case NSKEY_F2:
  262.         keybuffer_push(keybuffer,FUNCTION_KEYS | 2);
  263.         buf = count = 0;
  264.         return 1;
  265.     case NSKEY_F3:
  266.         keybuffer_push(keybuffer,FUNCTION_KEYS | 3);
  267.         buf = count = 0;
  268.         return 1;
  269.     case NSKEY_F4:
  270.         keybuffer_push(keybuffer,FUNCTION_KEYS | 4);
  271.         buf = count = 0;
  272.         return 1;
  273.     case NSKEY_F5:
  274.         keybuffer_push(keybuffer,FUNCTION_KEYS | 5);
  275.         buf = count = 0;
  276.         return 1;
  277.     }
  278.  
  279.  
  280.    
  281.     switch (buf) {
  282.     case NSKEY_F6:
  283.     case NSKEY_F7:
  284.     case NSKEY_F8:
  285.     case NSKEY_F9:
  286.     case NSKEY_F10:
  287.     case NSKEY_F11:
  288.     case NSKEY_F12:
  289.         return 1;
  290.     default:
  291.         keybuffer_push(keybuffer, buf & 0xff);
  292.         keybuffer_push(keybuffer, (buf >> 8) &0xff);
  293.         keybuffer_push(keybuffer, (buf >> 16) &0xff);
  294.         keybuffer_push(keybuffer, (buf >> 24) &0xff);
  295.         buf = count = 0;
  296.         return 1;
  297.     }
  298.     return 1;
  299. }
  300.  
  301. int kbd_ski_process(keybuffer_t *keybuffer, ipc_call_t *call)
  302. {
  303.     static unsigned long long buf = 0;
  304.     static int count = 0;  
  305.     static int esc_count = 0;
  306.     int scan_code = IPC_GET_ARG2(*call);
  307.    
  308.     /*
  309.      * Please preserve this code (it can be used to determine scancodes)
  310.      */
  311.     //keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf));
  312.     //keybuffer_push(keybuffer, to_hex(scan_code&0xf));
  313.     //keybuffer_push(keybuffer, ' ');
  314.     //keybuffer_push(keybuffer, ' ');
  315.     //*/
  316.    
  317.     if (scan_code) {
  318.         buf |= (unsigned long long) scan_code<<(8*(count++));
  319.     } else {
  320.        
  321.         if (buf == 0x1b) {
  322.             esc_count++;
  323.             if (esc_count == 3) {
  324.                 __SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
  325.             }  
  326.         } else {
  327.             esc_count = 0;
  328.         }
  329.    
  330.         if (!(buf & 0xff00)) {
  331.             keybuffer_push(keybuffer, buf);
  332.         } else {
  333.             switch (buf) {
  334.             case KEY_F1:
  335.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 1);
  336.                 break;
  337.             case KEY_F2:
  338.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 2);
  339.                 break;
  340.             case KEY_F3:
  341.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 3);
  342.                 break;
  343.             case KEY_F4:
  344.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 4);
  345.                 break;
  346.             case KEY_F5:
  347.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 5);
  348.                 break;
  349.             case KEY_F6:
  350.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 6);
  351.                 break;
  352.             case KEY_F7:
  353.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 7);
  354.                 break;
  355.             case KEY_F8:
  356.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 8);
  357.                 break;
  358.             case KEY_F9:
  359.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 9);
  360.                 break;
  361.             case KEY_F10:
  362.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 10);
  363.                 break;
  364.             case KEY_F11:
  365.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 11);
  366.                 break;
  367.             case KEY_F12:
  368.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 12);
  369.                 break;
  370.             }
  371.         }
  372.         buf = count = 0;
  373.     }
  374.     return  1;
  375. }
  376.  
  377. int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call)
  378. {
  379.     printf("KBD Key pressed: %x(%c)\n",IPC_GET_ARG2(*call),IPC_GET_ARG2(*call));
  380.     if (kbd_type == KBD_SKI)
  381.         return kbd_ski_process(keybuffer, call);
  382.     if (kbd_type == KBD_NS16550)
  383.         return kbd_ns16550_process(keybuffer,call);
  384.     if (kbd_type == KBD_LEGACY)
  385.         return lkbd_arch_process(keybuffer,call);
  386. }
  387.  
  388.  
  389.  
  390. /**
  391.  * @}
  392.  */