Subversion Repositories HelenOS

Rev

Rev 3657 | 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.  
  118. irq_cmd_t ski_cmds[1] = {
  119.     { CMD_IA64_GETCHAR, 0, 0, 2 }
  120. };
  121.  
  122. irq_code_t ski_kbd = {
  123.     1,
  124.     ski_cmds
  125. };
  126.  
  127.  
  128.  
  129. irq_cmd_t ns16550_cmds[1] = {
  130.     { CMD_PORT_READ_1, 0, 0, 2 },
  131. };
  132.  
  133. irq_code_t ns16550_kbd = {
  134.     1,
  135.     ns16550_cmds
  136. };
  137.  
  138.  
  139. uint16_t ns16550_port;
  140.  
  141. int kbd_type;
  142.  
  143. int kbd_arch_init(void)
  144. {
  145.     if (sysinfo_value("kbd")) {
  146.         kbd_type=sysinfo_value("kbd.type");
  147.         if(kbd_type==KBD_SKI) ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &ski_kbd);
  148.         if(kbd_type==KBD_LEGACY) return lkbd_arch_init();
  149.         if(kbd_type==KBD_NS16550) {
  150.             ns16550_kbd.cmds[0].addr= (void *)  (sysinfo_value("kbd.port")+RBR_REG);
  151.             ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &ns16550_kbd);
  152.             iospace_enable(task_get_id(),ns16550_port=sysinfo_value("kbd.port"),8);
  153.         }  
  154.         return 0;
  155.     }  
  156.     return 1;
  157. }
  158.  
  159. /*
  160. * Please preserve this code (it can be used to determine scancodes)
  161. *
  162. int to_hex(int v)
  163. {
  164.     return "0123456789ABCDEF"[v];
  165. }
  166. */
  167. #define LSR_DATA_READY  0x01
  168.  
  169. int kbd_ns16550_process(keybuffer_t *keybuffer, ipc_call_t *call)
  170. {
  171.     static unsigned long buf = 0;
  172.     static int count = 0, esc_count=0; 
  173.  
  174.     int scan_code = IPC_GET_ARG2(*call);
  175.  
  176.     if (scan_code == 0x1b) {
  177.         esc_count++;
  178.         if (esc_count == 3) {
  179.             __SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
  180.         }  
  181.     } else {
  182.         esc_count = 0;
  183.     }
  184.  
  185.     if(scan_code==0x0d) return 1;   //Delete CR
  186.  
  187.     if(scan_code == 0x7e) {
  188.         switch (buf) {
  189.         case NSKEY_F6:
  190.             keybuffer_push(keybuffer,FUNCTION_KEYS | 6);
  191.             buf = count = 0;
  192.             return 1;
  193.         case NSKEY_F7:
  194.             keybuffer_push(keybuffer,FUNCTION_KEYS | 7);
  195.             buf = count = 0;
  196.             return 1;
  197.         case NSKEY_F8:
  198.             keybuffer_push(keybuffer,FUNCTION_KEYS | 8);
  199.             buf = count = 0;
  200.             return 1;
  201.         case NSKEY_F9:
  202.             keybuffer_push(keybuffer,FUNCTION_KEYS | 9);
  203.             buf = count = 0;
  204.             return 1;
  205.         case NSKEY_F10:
  206.             keybuffer_push(keybuffer,FUNCTION_KEYS | 10);
  207.             buf = count = 0;
  208.             return 1;
  209.         case NSKEY_F11:
  210.             keybuffer_push(keybuffer,FUNCTION_KEYS | 11);
  211.             buf = count = 0;
  212.             return 1;
  213.         case NSKEY_F12:
  214.             keybuffer_push(keybuffer,FUNCTION_KEYS | 12);
  215.             buf = count = 0;
  216.             return 1;
  217.         default:
  218.             keybuffer_push(keybuffer, buf & 0xff);
  219.             keybuffer_push(keybuffer, (buf >> 8) &0xff);
  220.             keybuffer_push(keybuffer, (buf >> 16) &0xff);
  221.             keybuffer_push(keybuffer, (buf >> 24) &0xff);
  222.             keybuffer_push(keybuffer, scan_code);
  223.             buf = count = 0;
  224.             return 1;
  225.         }
  226.     }
  227.  
  228.     buf |= ((unsigned long) scan_code)<<(8*(count++));
  229.    
  230.     if((buf & 0xff) != (NSKEY_F1 & 0xff)) {
  231.         keybuffer_push(keybuffer, buf);
  232.         buf = count = 0;
  233.         return 1;
  234.     }
  235.  
  236.     if (count <= 1)
  237.         return 1;
  238.  
  239.     if ((buf & 0xffff) != (NSKEY_F1 & 0xffff))  {
  240.  
  241.         keybuffer_push(keybuffer, buf & 0xff);
  242.         keybuffer_push(keybuffer, (buf >> 8) &0xff);
  243.         buf = count = 0;
  244.         return 1;
  245.     }
  246.  
  247.     if (count <= 2)
  248.         return 1;
  249.  
  250.  
  251.     if ((buf & 0xffffff) != (NSKEY_F1 & 0xffffff)
  252.         && (buf & 0xffffff) != (NSKEY_F6 & 0xffffff)
  253.         && (buf & 0xffffff) != (NSKEY_F9 & 0xffffff) ) {
  254.  
  255.         keybuffer_push(keybuffer, buf & 0xff);
  256.         keybuffer_push(keybuffer, (buf >> 8) &0xff);
  257.         keybuffer_push(keybuffer, (buf >> 16) &0xff);
  258.         buf = count = 0;
  259.         return 1;
  260.     }
  261.  
  262.     if (count <= 3)
  263.         return 1;
  264.  
  265.     switch (buf) {
  266.     case NSKEY_F1:
  267.         keybuffer_push(keybuffer,FUNCTION_KEYS | 1);
  268.         buf = count = 0;
  269.         return 1;
  270.     case NSKEY_F2:
  271.         keybuffer_push(keybuffer,FUNCTION_KEYS | 2);
  272.         buf = count = 0;
  273.         return 1;
  274.     case NSKEY_F3:
  275.         keybuffer_push(keybuffer,FUNCTION_KEYS | 3);
  276.         buf = count = 0;
  277.         return 1;
  278.     case NSKEY_F4:
  279.         keybuffer_push(keybuffer,FUNCTION_KEYS | 4);
  280.         buf = count = 0;
  281.         return 1;
  282.     case NSKEY_F5:
  283.         keybuffer_push(keybuffer,FUNCTION_KEYS | 5);
  284.         buf = count = 0;
  285.         return 1;
  286.     }
  287.  
  288.  
  289.    
  290.     switch (buf) {
  291.     case NSKEY_F6:
  292.     case NSKEY_F7:
  293.     case NSKEY_F8:
  294.     case NSKEY_F9:
  295.     case NSKEY_F10:
  296.     case NSKEY_F11:
  297.     case NSKEY_F12:
  298.         return 1;
  299.     default:
  300.         keybuffer_push(keybuffer, buf & 0xff);
  301.         keybuffer_push(keybuffer, (buf >> 8) &0xff);
  302.         keybuffer_push(keybuffer, (buf >> 16) &0xff);
  303.         keybuffer_push(keybuffer, (buf >> 24) &0xff);
  304.         buf = count = 0;
  305.         return 1;
  306.     }
  307.     return 1;
  308. }
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316. int kbd_ski_process(keybuffer_t *keybuffer, ipc_call_t *call)
  317. {
  318.     static unsigned long long buf = 0;
  319.     static int count = 0;  
  320.     static int esc_count = 0;
  321.     int scan_code = IPC_GET_ARG2(*call);
  322.    
  323.     /*
  324.      * Please preserve this code (it can be used to determine scancodes)
  325.      */
  326.     //keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf));
  327.     //keybuffer_push(keybuffer, to_hex(scan_code&0xf));
  328.     //keybuffer_push(keybuffer, ' ');
  329.     //keybuffer_push(keybuffer, ' ');
  330.     //*/
  331.    
  332.     if (scan_code) {
  333.         buf |= (unsigned long long) scan_code<<(8*(count++));
  334.     } else {
  335.        
  336.         if (buf == 0x1b) {
  337.             esc_count++;
  338.             if (esc_count == 3) {
  339.                 __SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
  340.             }  
  341.         } else {
  342.             esc_count = 0;
  343.         }
  344.    
  345.         if (!(buf & 0xff00)) {
  346.             keybuffer_push(keybuffer, buf);
  347.         } else {
  348.             switch (buf) {
  349.             case KEY_F1:
  350.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 1);
  351.                 break;
  352.             case KEY_F2:
  353.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 2);
  354.                 break;
  355.             case KEY_F3:
  356.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 3);
  357.                 break;
  358.             case KEY_F4:
  359.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 4);
  360.                 break;
  361.             case KEY_F5:
  362.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 5);
  363.                 break;
  364.             case KEY_F6:
  365.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 6);
  366.                 break;
  367.             case KEY_F7:
  368.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 7);
  369.                 break;
  370.             case KEY_F8:
  371.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 8);
  372.                 break;
  373.             case KEY_F9:
  374.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 9);
  375.                 break;
  376.             case KEY_F10:
  377.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 10);
  378.                 break;
  379.             case KEY_F11:
  380.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 11);
  381.                 break;
  382.             case KEY_F12:
  383.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 12);
  384.                 break;
  385.             }
  386.         }
  387.         buf = count = 0;
  388.     }
  389.     return  1;
  390. }
  391.  
  392. int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call)
  393. {
  394.     printf("KBD Key pressed: %x(%c)\n",IPC_GET_ARG2(*call),IPC_GET_ARG2(*call));
  395.     if(kbd_type==KBD_SKI) return kbd_ski_process(keybuffer,call);
  396.     if(kbd_type==KBD_NS16550) return kbd_ns16550_process(keybuffer,call);
  397.     if(kbd_type==KBD_LEGACY) return lkbd_arch_process(keybuffer,call);
  398.  
  399.    
  400. }
  401.  
  402.  
  403.  
  404. /**
  405.  * @}
  406.  */
  407.