Subversion Repositories HelenOS

Rev

Rev 4263 | 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 genericconsole
  30.  * @{
  31.  */
  32. /** @file
  33.  */
  34.  
  35. #include <console/chardev.h>
  36. #include <synch/waitq.h>
  37. #include <synch/spinlock.h>
  38. #include <print.h>
  39. #include <func.h>
  40. #include <arch.h>
  41.  
  42. /** Initialize input character device.
  43.  *
  44.  * @param indev Input character device.
  45.  * @param op    Implementation of input character device operations.
  46.  *
  47.  */
  48. void indev_initialize(char *name, indev_t *indev,
  49.     indev_operations_t *op)
  50. {
  51.     indev->name = name;
  52.     waitq_initialize(&indev->wq);
  53.     spinlock_initialize(&indev->lock, "indev");
  54.     indev->counter = 0;
  55.     indev->index = 0;
  56.     indev->op = op;
  57. }
  58.  
  59. /** Push character read from input character device.
  60.  *
  61.  * @param indev Input character device.
  62.  * @param ch    Character being pushed.
  63.  *
  64.  */
  65. void indev_push_character(indev_t *indev, wchar_t ch)
  66. {
  67.     ASSERT(indev);
  68.    
  69.     spinlock_lock(&indev->lock);
  70.     if (indev->counter == INDEV_BUFLEN - 1) {
  71.         /* Buffer full */
  72.         spinlock_unlock(&indev->lock);
  73.         return;
  74.     }
  75.    
  76.     indev->counter++;
  77.     indev->buffer[indev->index++] = ch;
  78.    
  79.     /* Index modulo size of buffer */
  80.     indev->index = indev->index % INDEV_BUFLEN;
  81.     waitq_wakeup(&indev->wq, WAKEUP_FIRST);
  82.     spinlock_unlock(&indev->lock);
  83. }
  84.  
  85. /** Pop character from input character device.
  86.  *
  87.  * @param indev Input character device.
  88.  *
  89.  * @return Character read.
  90.  *
  91.  */
  92. wchar_t indev_pop_character(indev_t *indev)
  93. {
  94.     if (atomic_get(&haltstate)) {
  95.         /* If we are here, we are hopefully on the processor that
  96.          * issued the 'halt' command, so proceed to read the character
  97.          * directly from input
  98.          */
  99.         if (check_poll(indev))
  100.             return indev->op->poll(indev);
  101.        
  102.         /* No other way of interacting with user */
  103.         interrupts_disable();
  104.        
  105.         if (CPU)
  106.             printf("cpu%u: ", CPU->id);
  107.         else
  108.             printf("cpu: ");
  109.        
  110.         printf("halted (no polling input)\n");
  111.         cpu_halt();
  112.     }
  113.    
  114.     waitq_sleep(&indev->wq);
  115.     ipl_t ipl = interrupts_disable();
  116.     spinlock_lock(&indev->lock);
  117.     wchar_t ch = indev->buffer[(indev->index - indev->counter) % INDEV_BUFLEN];
  118.     indev->counter--;
  119.     spinlock_unlock(&indev->lock);
  120.     interrupts_restore(ipl);
  121.    
  122.     return ch;
  123. }
  124.  
  125. /** Initialize output character device.
  126.  *
  127.  * @param outdev Output character device.
  128.  * @param op     Implementation of output character device operations.
  129.  *
  130.  */
  131. void outdev_initialize(char *name, outdev_t *outdev,
  132.     outdev_operations_t *op)
  133. {
  134.     outdev->name = name;
  135.     spinlock_initialize(&outdev->lock, "outdev");
  136.     outdev->op = op;
  137. }
  138.  
  139. bool check_poll(indev_t *indev)
  140. {
  141.     if (indev == NULL)
  142.         return false;
  143.    
  144.     if (indev->op == NULL)
  145.         return false;
  146.    
  147.     return (indev->op->poll != NULL);
  148. }
  149.  
  150. /** @}
  151.  */
  152.