Subversion Repositories HelenOS

Rev

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