Subversion Repositories HelenOS

Rev

Rev 2927 | 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.     if(scan_code==0x7f) scan_code='\b'; //Convert backspace
  187.  
  188.     if(scan_code == 0x7e) {
  189.         switch (buf) {
  190.         case NSKEY_F6:
  191.             keybuffer_push(keybuffer,FUNCTION_KEYS | 6);
  192.             buf = count = 0;
  193.             return 1;
  194.         case NSKEY_F7:
  195.             keybuffer_push(keybuffer,FUNCTION_KEYS | 7);
  196.             buf = count = 0;
  197.             return 1;
  198.         case NSKEY_F8:
  199.             keybuffer_push(keybuffer,FUNCTION_KEYS | 8);
  200.             buf = count = 0;
  201.             return 1;
  202.         case NSKEY_F9:
  203.             keybuffer_push(keybuffer,FUNCTION_KEYS | 9);
  204.             buf = count = 0;
  205.             return 1;
  206.         case NSKEY_F10:
  207.             keybuffer_push(keybuffer,FUNCTION_KEYS | 10);
  208.             buf = count = 0;
  209.             return 1;
  210.         case NSKEY_F11:
  211.             keybuffer_push(keybuffer,FUNCTION_KEYS | 11);
  212.             buf = count = 0;
  213.             return 1;
  214.         case NSKEY_F12:
  215.             keybuffer_push(keybuffer,FUNCTION_KEYS | 12);
  216.             buf = count = 0;
  217.             return 1;
  218.         default:
  219.             keybuffer_push(keybuffer, buf & 0xff);
  220.             keybuffer_push(keybuffer, (buf >> 8) &0xff);
  221.             keybuffer_push(keybuffer, (buf >> 16) &0xff);
  222.             keybuffer_push(keybuffer, (buf >> 24) &0xff);
  223.             keybuffer_push(keybuffer, scan_code);
  224.             buf = count = 0;
  225.             return 1;
  226.         }
  227.     }
  228.  
  229.     buf |= ((unsigned long) scan_code)<<(8*(count++));
  230.    
  231.     if((buf & 0xff) != (NSKEY_F1 & 0xff)) {
  232.         keybuffer_push(keybuffer, buf);
  233.         buf = count = 0;
  234.         return 1;
  235.     }
  236.  
  237.     if (count <= 1)
  238.         return 1;
  239.  
  240.     if ((buf & 0xffff) != (NSKEY_F1 & 0xffff))  {
  241.  
  242.         keybuffer_push(keybuffer, buf & 0xff);
  243.         keybuffer_push(keybuffer, (buf >> 8) &0xff);
  244.         buf = count = 0;
  245.         return 1;
  246.     }
  247.  
  248.     if (count <= 2)
  249.         return 1;
  250.  
  251.  
  252.     if ((buf & 0xffffff) != (NSKEY_F1 & 0xffffff)
  253.         && (buf & 0xffffff) != (NSKEY_F6 & 0xffffff)
  254.         && (buf & 0xffffff) != (NSKEY_F9 & 0xffffff) ) {
  255.  
  256.         keybuffer_push(keybuffer, buf & 0xff);
  257.         keybuffer_push(keybuffer, (buf >> 8) &0xff);
  258.         keybuffer_push(keybuffer, (buf >> 16) &0xff);
  259.         buf = count = 0;
  260.         return 1;
  261.     }
  262.  
  263.     if (count <= 3)
  264.         return 1;
  265.  
  266.     switch (buf) {
  267.     case NSKEY_F1:
  268.         keybuffer_push(keybuffer,FUNCTION_KEYS | 1);
  269.         buf = count = 0;
  270.         return 1;
  271.     case NSKEY_F2:
  272.         keybuffer_push(keybuffer,FUNCTION_KEYS | 2);
  273.         buf = count = 0;
  274.         return 1;
  275.     case NSKEY_F3:
  276.         keybuffer_push(keybuffer,FUNCTION_KEYS | 3);
  277.         buf = count = 0;
  278.         return 1;
  279.     case NSKEY_F4:
  280.         keybuffer_push(keybuffer,FUNCTION_KEYS | 4);
  281.         buf = count = 0;
  282.         return 1;
  283.     case NSKEY_F5:
  284.         keybuffer_push(keybuffer,FUNCTION_KEYS | 5);
  285.         buf = count = 0;
  286.         return 1;
  287.     }
  288.  
  289.  
  290.    
  291.     switch (buf) {
  292.     case NSKEY_F6:
  293.     case NSKEY_F7:
  294.     case NSKEY_F8:
  295.     case NSKEY_F9:
  296.     case NSKEY_F10:
  297.     case NSKEY_F11:
  298.     case NSKEY_F12:
  299.         return 1;
  300.     default:
  301.         keybuffer_push(keybuffer, buf & 0xff);
  302.         keybuffer_push(keybuffer, (buf >> 8) &0xff);
  303.         keybuffer_push(keybuffer, (buf >> 16) &0xff);
  304.         keybuffer_push(keybuffer, (buf >> 24) &0xff);
  305.         buf = count = 0;
  306.         return 1;
  307.     }
  308.     return 1;
  309. }
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317. int kbd_ski_process(keybuffer_t *keybuffer, ipc_call_t *call)
  318. {
  319.     static unsigned long long buf = 0;
  320.     static int count = 0;  
  321.     static int esc_count = 0;
  322.     int scan_code = IPC_GET_ARG2(*call);
  323.    
  324.     /*
  325.      * Please preserve this code (it can be used to determine scancodes)
  326.      */
  327.     //keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf));
  328.     //keybuffer_push(keybuffer, to_hex(scan_code&0xf));
  329.     //keybuffer_push(keybuffer, ' ');
  330.     //keybuffer_push(keybuffer, ' ');
  331.     //*/
  332.    
  333.     if (scan_code) {
  334.         buf |= (unsigned long long) scan_code<<(8*(count++));
  335.     } else {
  336.        
  337.         if (buf == 0x1b) {
  338.             esc_count++;
  339.             if (esc_count == 3) {
  340.                 __SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
  341.             }  
  342.         } else {
  343.             esc_count = 0;
  344.         }
  345.    
  346.         if (!(buf & 0xff00)) {
  347.             keybuffer_push(keybuffer, buf);
  348.         } else {
  349.             switch (buf) {
  350.             case KEY_F1:
  351.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 1);
  352.                 break;
  353.             case KEY_F2:
  354.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 2);
  355.                 break;
  356.             case KEY_F3:
  357.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 3);
  358.                 break;
  359.             case KEY_F4:
  360.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 4);
  361.                 break;
  362.             case KEY_F5:
  363.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 5);
  364.                 break;
  365.             case KEY_F6:
  366.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 6);
  367.                 break;
  368.             case KEY_F7:
  369.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 7);
  370.                 break;
  371.             case KEY_F8:
  372.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 8);
  373.                 break;
  374.             case KEY_F9:
  375.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 9);
  376.                 break;
  377.             case KEY_F10:
  378.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 10);
  379.                 break;
  380.             case KEY_F11:
  381.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 11);
  382.                 break;
  383.             case KEY_F12:
  384.                 keybuffer_push(keybuffer, FUNCTION_KEYS | 12);
  385.                 break;
  386.             }
  387.         }
  388.         buf = count = 0;
  389.     }
  390.     return  1;
  391. }
  392.  
  393. int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call)
  394. {
  395.     printf("KBD Key pressed: %x(%c)\n",IPC_GET_ARG2(*call),IPC_GET_ARG2(*call));
  396.     if(kbd_type==KBD_SKI) return kbd_ski_process(keybuffer,call);
  397.     if(kbd_type==KBD_NS16550) return kbd_ns16550_process(keybuffer,call);
  398.     if(kbd_type==KBD_LEGACY) return lkbd_arch_process(keybuffer,call);
  399.  
  400.    
  401. }
  402.  
  403.  
  404.  
  405. /**
  406.  * @}
  407.  */
  408.