Subversion Repositories HelenOS

Rev

Rev 2479 | 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. #define KEY_F1 0x504f1b
  62. #define KEY_F2 0x514f1b
  63. #define KEY_F3 0x524f1b
  64. #define KEY_F4 0x534f1b
  65. #define KEY_F5 0x7e35315b1b
  66. #define KEY_F6 0x7e37315b1b
  67. #define KEY_F7 0x7e38315b1b
  68. #define KEY_F8 0x7e39315b1b
  69. #define KEY_F9 0x7e30325b1b
  70. #define KEY_F10 0x7e31325b1b
  71. #define KEY_F11 0x7e33325b1b
  72. #define KEY_F12 0x7e34325b1b
  73.  
  74.  
  75.  
  76.  
  77. #define NSKEY_F1 0x415b5b1b
  78. #define NSKEY_F2 0x425b5b1b
  79. #define NSKEY_F3 0x435b5b1b
  80. #define NSKEY_F4 0x445b5b1b
  81. #define NSKEY_F5 0x455b5b1b
  82. #define NSKEY_F6 0x37315b1b
  83. #define NSKEY_F7 0x38315b1b
  84. #define NSKEY_F8 0x39315b1b
  85. #define NSKEY_F9 0x30325b1b
  86. #define NSKEY_F10 0x31325b1b
  87. #define NSKEY_F11 0x33325b1b
  88. #define NSKEY_F12 0x34325b1b
  89.  
  90.  
  91. #define FUNCTION_KEYS 0x100
  92.  
  93.  
  94. #define KBD_SKI 1
  95. #define KBD_LEGACY 2
  96. #define KBD_NS16550 3
  97.  
  98.  
  99.  
  100.  
  101. /* NS16550 registers */
  102. #define RBR_REG     0   /** Receiver Buffer Register. */
  103. #define IER_REG     1   /** Interrupt Enable Register. */
  104. #define IIR_REG     2   /** Interrupt Ident Register (read). */
  105. #define FCR_REG     2   /** FIFO control register (write). */
  106. #define LCR_REG     3   /** Line Control register. */
  107. #define MCR_REG     4   /** Modem Control Register. */
  108. #define LSR_REG     5   /** Line Status Register. */
  109.  
  110.  
  111.  
  112.  
  113. irq_cmd_t ski_cmds[1] = {
  114.     { CMD_IA64_GETCHAR, 0, 0, 2 }
  115. };
  116.  
  117. irq_code_t ski_kbd = {
  118.     1,
  119.     ski_cmds
  120. };
  121.  
  122.  
  123.  
  124. irq_cmd_t ns16550_cmds[1] = {
  125.     { CMD_PORT_READ_1, 0, 0, 2 },
  126. };
  127.  
  128. irq_code_t ns16550_kbd = {
  129.     1,
  130.     ns16550_cmds
  131. };
  132.  
  133.  
  134. uint16_t ns16550_port;
  135.  
  136. int kbd_type;
  137.  
  138. int kbd_arch_init(void)
  139. {
  140.     if (sysinfo_value("kbd")) {
  141.         kbd_type=sysinfo_value("kbd.type");
  142.         if(kbd_type==KBD_SKI) ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &ski_kbd);
  143.         if(kbd_type==KBD_NS16550) {
  144.             ns16550_kbd.cmds[0].addr= (void *)  (sysinfo_value("kbd.port")+RBR_REG);
  145.             ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &ns16550_kbd);
  146.             iospace_enable(task_get_id(),ns16550_port=sysinfo_value("kbd.port"),8);
  147.         }  
  148.         return 0;
  149.     }  
  150.     return 1;
  151. }
  152.  
  153. /*
  154. * Please preserve this code (it can be used to determine scancodes)
  155. *
  156. int to_hex(int v)
  157. {
  158.     return "0123456789ABCDEF"[v];
  159. }
  160. */
  161. #define LSR_DATA_READY  0x01
  162.  
  163. int kbd_ns16550_process(keybuffer_t *keybuffer, ipc_call_t *call)
  164. {
  165.     static unsigned long buf = 0;
  166.     static int count = 0, esc_count=0; 
  167.  
  168.     int scan_code = IPC_GET_ARG2(*call);
  169.  
  170.     if (scan_code == 0x1b) {
  171.         esc_count++;
  172.         if (esc_count == 3) {
  173.             __SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
  174.         }  
  175.     } else {
  176.         esc_count = 0;
  177.     }
  178.  
  179.     if(scan_code==0x0d) return 1;   //Delete CR
  180.  
  181.     if(scan_code == 0x7e) {
  182.         switch (buf) {
  183.         case NSKEY_F6:
  184.             keybuffer_push(keybuffer,FUNCTION_KEYS | 6);
  185.             buf = count = 0;
  186.             return 1;
  187.         case NSKEY_F7:
  188.             keybuffer_push(keybuffer,FUNCTION_KEYS | 7);
  189.             buf = count = 0;
  190.             return 1;
  191.         case NSKEY_F8:
  192.             keybuffer_push(keybuffer,FUNCTION_KEYS | 8);
  193.             buf = count = 0;
  194.             return 1;
  195.         case NSKEY_F9:
  196.             keybuffer_push(keybuffer,FUNCTION_KEYS | 9);
  197.             buf = count = 0;
  198.             return 1;
  199.         case NSKEY_F10:
  200.             keybuffer_push(keybuffer,FUNCTION_KEYS | 10);
  201.             buf = count = 0;
  202.             return 1;
  203.         case NSKEY_F11:
  204.             keybuffer_push(keybuffer,FUNCTION_KEYS | 11);
  205.             buf = count = 0;
  206.             return 1;
  207.         case NSKEY_F12:
  208.             keybuffer_push(keybuffer,FUNCTION_KEYS | 12);
  209.             buf = count = 0;
  210.             return 1;
  211.         default:
  212.             keybuffer_push(keybuffer, buf & 0xff);
  213.             keybuffer_push(keybuffer, (buf >> 8) &0xff);
  214.             keybuffer_push(keybuffer, (buf >> 16) &0xff);
  215.             keybuffer_push(keybuffer, (buf >> 24) &0xff);
  216.             keybuffer_push(keybuffer, scan_code);
  217.             buf = count = 0;
  218.             return 1;
  219.         }
  220.     }
  221.  
  222.     buf |= ((unsigned long) scan_code)<<(8*(count++));
  223.    
  224.     if((buf & 0xff) != (NSKEY_F1 & 0xff)) {
  225.         keybuffer_push(keybuffer, buf);
  226.         buf = count = 0;
  227.         return 1;
  228.     }
  229.  
  230.     if (count <= 1)
  231.         return 1;
  232.  
  233.     if ((buf & 0xffff) != (NSKEY_F1 & 0xffff))  {
  234.  
  235.         keybuffer_push(keybuffer, buf & 0xff);
  236.         keybuffer_push(keybuffer, (buf >> 8) &0xff);
  237.         buf = count = 0;
  238.         return 1;
  239.     }
  240.  
  241.     if (count <= 2)
  242.         return 1;
  243.  
  244.  
  245.     if ((buf & 0xffffff) != (NSKEY_F1 & 0xffffff)
  246.         && (buf & 0xffffff) != (NSKEY_F6 & 0xffffff)
  247.         && (buf & 0xffffff) != (NSKEY_F9 & 0xffffff) ) {
  248.  
  249.         keybuffer_push(keybuffer, buf & 0xff);
  250.         keybuffer_push(keybuffer, (buf >> 8) &0xff);
  251.         keybuffer_push(keybuffer, (buf >> 16) &0xff);
  252.         buf = count = 0;
  253.         return 1;
  254.     }
  255.  
  256.     if (count <= 3)
  257.         return 1;
  258.  
  259.     switch (buf) {
  260.     case NSKEY_F1:
  261.         keybuffer_push(keybuffer,FUNCTION_KEYS | 1);
  262.         buf = count = 0;
  263.         return 1;
  264.     case NSKEY_F2:
  265.         keybuffer_push(keybuffer,FUNCTION_KEYS | 2);
  266.         buf = count = 0;
  267.         return 1;
  268.     case NSKEY_F3:
  269.         keybuffer_push(keybuffer,FUNCTION_KEYS | 3);
  270.         buf = count = 0;
  271.         return 1;
  272.     case NSKEY_F4:
  273.         keybuffer_push(keybuffer,FUNCTION_KEYS | 4);
  274.         buf = count = 0;
  275.         return 1;
  276.     case NSKEY_F5:
  277.         keybuffer_push(keybuffer,FUNCTION_KEYS | 5);
  278.         buf = count = 0;
  279.         return 1;
  280.     }
  281.  
  282.  
  283.    
  284.     switch (buf) {
  285.     case NSKEY_F6:
  286.     case NSKEY_F7:
  287.     case NSKEY_F8:
  288.     case NSKEY_F9:
  289.     case NSKEY_F10:
  290.     case NSKEY_F11:
  291.     case NSKEY_F12:
  292.         return 1;
  293.     default:
  294.         keybuffer_push(keybuffer, buf & 0xff);
  295.         keybuffer_push(keybuffer, (buf >> 8) &0xff);
  296.         keybuffer_push(keybuffer, (buf >> 16) &0xff);
  297.         keybuffer_push(keybuffer, (buf >> 24) &0xff);
  298.         buf = count = 0;
  299.         return 1;
  300.     }
  301.     return 1;
  302. }
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310. int kbd_ski_process(keybuffer_t *keybuffer, ipc_call_t *call)
  311. {
  312.     static unsigned long long buf = 0;
  313.     static int count = 0;  
  314.     static int esc_count = 0;
  315.     int scan_code = IPC_GET_ARG2(*call);
  316.    
  317.     /*
  318.      * Please preserve this code (it can be used to determine scancodes)
  319.      */
  320.     //keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf));
  321.     //keybuffer_push(keybuffer, to_hex(scan_code&0xf));
  322.     //keybuffer_push(keybuffer, ' ');
  323.     //keybuffer_push(keybuffer, ' ');
  324.     //*/
  325.  
  326.    
  327.     if (scan_code) {
  328.         buf |= (unsigned long long) scan_code<<(8*(count++));
  329.     } else {
  330.        
  331.         if (buf == 0x1b) {
  332.             esc_count++;
  333.             if (esc_count == 3) {
  334.                 __SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
  335.             }  
  336.         } else {
  337.             esc_count = 0;
  338.         }
  339.    
  340.         if (!(buf & 0xff00)) {
  341.             keybuffer_push(keybuffer, buf);
  342.         } else {
  343.             switch (buf) {
  344.             case KEY_F1:
  345.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 1);
  346.                 break;
  347.             case KEY_F2:
  348.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 2);
  349.                 break;
  350.             case KEY_F3:
  351.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 3);
  352.                 break;
  353.             case KEY_F4:
  354.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 4);
  355.                 break;
  356.             case KEY_F5:
  357.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 5);
  358.                 break;
  359.             case KEY_F6:
  360.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 6);
  361.                 break;
  362.             case KEY_F7:
  363.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 7);
  364.                 break;
  365.             case KEY_F8:
  366.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 8);
  367.                 break;
  368.             case KEY_F9:
  369.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 9);
  370.                 break;
  371.             case KEY_F10:
  372.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 10);
  373.                 break;
  374.             case KEY_F11:
  375.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 11);
  376.                 break;
  377.             case KEY_F12:
  378.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 12);
  379.                 break;
  380.             }
  381.         }
  382.         buf = count = 0;
  383.     }
  384.     return  1;
  385. }
  386.  
  387. int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call)
  388. {
  389.     printf("KBD Key pressed: %x(%c)\n",IPC_GET_ARG2(*call),IPC_GET_ARG2(*call));
  390.     if(kbd_type==KBD_SKI) return kbd_ski_process(keybuffer,call);
  391.     if(kbd_type==KBD_NS16550) return kbd_ns16550_process(keybuffer,call);
  392.  
  393.    
  394. }
  395.  
  396.  
  397.  
  398. /**
  399.  * @}
  400.  */
  401.