Subversion Repositories HelenOS

Rev

Rev 4311 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2005 Jakub Jermar
  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 ia64
  30.  * @{
  31.  */
  32. /** @file
  33.  */
  34.  
  35. #include <arch/drivers/ski.h>
  36. #include <console/console.h>
  37. #include <console/chardev.h>
  38. #include <sysinfo/sysinfo.h>
  39. #include <arch/types.h>
  40. #include <proc/thread.h>
  41. #include <synch/spinlock.h>
  42. #include <arch/asm.h>
  43. #include <arch/drivers/kbd.h>
  44. #include <string.h>
  45. #include <arch.h>
  46.  
  47. #define POLL_INTERVAL  10000  /* 10 ms */
  48.  
  49. #define SKI_INIT_CONSOLE  20
  50. #define SKI_GETCHAR       21
  51. #define SKI_PUTCHAR       31
  52.  
  53. static void ski_putchar(outdev_t *, const wchar_t, bool);
  54.  
  55. static outdev_operations_t skiout_ops = {
  56.     .write = ski_putchar
  57. };
  58.  
  59. static outdev_t skiout;            /**< Ski output device. */
  60. static bool initialized = false;
  61. static bool kbd_disabled = false;
  62.  
  63. /** Initialize debug console
  64.  *
  65.  * Issue SSC (Simulator System Call) to
  66.  * to open debug console.
  67.  *
  68.  */
  69. static void ski_init(void)
  70. {
  71.     if (initialized)
  72.         return;
  73.    
  74.     asm volatile (
  75.         "mov r15 = %0\n"
  76.         "break 0x80000\n"
  77.         :
  78.         : "i" (SKI_INIT_CONSOLE)
  79.         : "r15", "r8"
  80.     );
  81.    
  82.     initialized = true;
  83. }
  84.  
  85. static void ski_do_putchar(const wchar_t ch)
  86. {
  87.     asm volatile (
  88.         "mov r15 = %[cmd]\n"
  89.         "mov r32 = %[ch]\n"   /* r32 is in0 */
  90.         "break 0x80000\n"     /* modifies r8 */
  91.         :
  92.         : [cmd] "i" (SKI_PUTCHAR), [ch] "r" (ch)
  93.         : "r15", "in0", "r8"
  94.     );
  95. }
  96.  
  97. /** Display character on debug console
  98.  *
  99.  * Use SSC (Simulator System Call) to
  100.  * display character on debug console.
  101.  *
  102.  * @param dev    Character device.
  103.  * @param ch     Character to be printed.
  104.  * @param silent Whether the output should be silenced.
  105.  *
  106.  */
  107. static void ski_putchar(outdev_t *dev, const wchar_t ch, bool silent)
  108. {
  109.     if (!silent) {
  110.         if (ascii_check(ch)) {
  111.             if (ch == '\n')
  112.                 ski_do_putchar('\r');
  113.            
  114.             ski_do_putchar(ch);
  115.         } else
  116.             ski_do_putchar(U_SPECIAL);
  117.     }
  118. }
  119.  
  120. void skiout_init(void)
  121. {
  122.     ski_init();
  123.    
  124.     outdev_initialize("skiout", &skiout, &skiout_ops);
  125.     stdout = &skiout;
  126.    
  127.     sysinfo_set_item_val("fb", NULL, false);
  128. }
  129.  
  130. /** Ask debug console if a key was pressed.
  131.  *
  132.  * Use SSC (Simulator System Call) to
  133.  * get character from debug console.
  134.  *
  135.  * This call is non-blocking.
  136.  *
  137.  * @return ASCII code of pressed key or 0 if no key pressed.
  138.  *
  139.  */
  140. static wchar_t ski_getchar(void)
  141. {
  142.     uint64_t ch;
  143.    
  144.     asm volatile (
  145.         "mov r15 = %1\n"
  146.         "break 0x80000;;\n"  /* modifies r8 */
  147.         "mov %0 = r8;;\n"
  148.        
  149.         : "=r" (ch)
  150.         : "i" (SKI_GETCHAR)
  151.         : "r15", "r8"
  152.     );
  153.    
  154.     return (wchar_t) ch;
  155. }
  156.  
  157. /** Ask keyboard if a key was pressed. */
  158. static void poll_keyboard(ski_instance_t *instance)
  159. {
  160.     if (kbd_disabled)
  161.         return;
  162.    
  163.     wchar_t ch = ski_getchar();
  164.    
  165.     if (ch != 0)
  166.         indev_push_character(instance->srlnin, ch);
  167. }
  168.  
  169. /** Kernel thread for polling keyboard. */
  170. static void kskipoll(void *arg)
  171. {
  172.     ski_instance_t *instance = (ski_instance_t *) arg;
  173.    
  174.     while (true) {
  175.         if (!silent)
  176.             poll_keyboard(instance);
  177.        
  178.         thread_usleep(POLL_INTERVAL);
  179.     }
  180. }
  181.  
  182. ski_instance_t *skiin_init(void)
  183. {
  184.     ski_init();
  185.    
  186.     ski_instance_t *instance =
  187.         malloc(sizeof(ski_instance_t), FRAME_ATOMIC);
  188.    
  189.     if (instance) {
  190.         instance->thread = thread_create(kskipoll, instance, TASK, 0,
  191.             "kskipoll", true);
  192.        
  193.         if (!instance->thread) {
  194.             free(instance);
  195.             return NULL;
  196.         }
  197.        
  198.         instance->srlnin = NULL;
  199.     }
  200.    
  201.     return instance;
  202. }
  203.  
  204. void skiin_wire(ski_instance_t *instance, indev_t *srlnin)
  205. {
  206.     ASSERT(instance);
  207.     ASSERT(srlnin);
  208.    
  209.     instance->srlnin = srlnin;
  210.     thread_ready(instance->thread);
  211.    
  212.     sysinfo_set_item_val("kbd", NULL, true);
  213.     sysinfo_set_item_val("kbd.type", NULL, KBD_SKI);
  214. }
  215.  
  216. void ski_kbd_grab(void)
  217. {
  218.     kbd_disabled = true;
  219. }
  220.  
  221. void ski_kbd_release(void)
  222. {
  223.     kbd_disabled = false;
  224. }
  225.  
  226. /** @}
  227.  */
  228.