Subversion Repositories HelenOS

Rev

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

  1. /*
  2.  * Copyright (c) 2008 Pavel Rimsky
  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 kbd_port
  30.  * @ingroup  kbd
  31.  * @{
  32.  */
  33. /** @file
  34.  * @brief   SGCN (Serengeti Console) keyboard port driver.
  35.  */
  36.  
  37. #include <as.h>
  38. #include <ddi.h>
  39. #include <async.h>
  40. #include <kbd.h>
  41. #include <kbd_port.h>
  42. #include <sysinfo.h>
  43. #include <stdio.h>
  44. #include <thread.h>
  45. #include <bool.h>
  46.  
  47. #define POLL_INTERVAL       10000
  48.  
  49. /**
  50.  * SGCN buffer header. It is placed at the very beginning of the SGCN
  51.  * buffer.
  52.  */
  53. typedef struct {
  54.     /** hard-wired to "CON" */
  55.     char magic[4];
  56.    
  57.     /** we don't need this */
  58.     char unused[8];
  59.    
  60.     /** offset within the SGCN buffer of the input buffer start */
  61.     uint32_t in_begin;
  62.    
  63.     /** offset within the SGCN buffer of the input buffer end */
  64.     uint32_t in_end;
  65.    
  66.     /** offset within the SGCN buffer of the input buffer read pointer */
  67.     uint32_t in_rdptr;
  68.    
  69.     /** offset within the SGCN buffer of the input buffer write pointer */
  70.     uint32_t in_wrptr;
  71. } __attribute__ ((packed)) sgcn_buffer_header_t;
  72.  
  73. /*
  74.  * Returns a pointer to the object of a given type which is placed at the given
  75.  * offset from the console buffer beginning.
  76.  */
  77. #define SGCN_BUFFER(type, offset) \
  78.         ((type *) (sram_virt_addr + sram_buffer_offset + (offset)))
  79.  
  80. /** Returns a pointer to the console buffer header. */
  81. #define SGCN_BUFFER_HEADER  (SGCN_BUFFER(sgcn_buffer_header_t, 0))
  82.  
  83. /**
  84.  * Virtual address mapped to SRAM.
  85.  */
  86. static uintptr_t sram_virt_addr;
  87.  
  88. /**
  89.  * SGCN buffer offset within SGCN.
  90.  */
  91. static uintptr_t sram_buffer_offset;
  92.  
  93. /* polling thread */
  94. static void *sgcn_thread_impl(void *arg);
  95.  
  96. static volatile bool polling_disabled = false;
  97.  
  98. /**
  99.  * Initializes the SGCN driver.
  100.  * Maps the physical memory (SRAM) and creates the polling thread.
  101.  */
  102. int kbd_port_init(void)
  103. {
  104.     sram_virt_addr = (uintptr_t) as_get_mappable_page(sysinfo_value("sram.area.size"));
  105.     if (physmem_map((void *) sysinfo_value("sram.address.physical"),
  106.         (void *) sram_virt_addr, sysinfo_value("sram.area.size") / PAGE_SIZE,
  107.         AS_AREA_READ | AS_AREA_WRITE) != 0) {
  108.         printf("SGCN: uspace driver could not map physical memory.");
  109.         return -1;
  110.     }
  111.    
  112.     sram_buffer_offset = sysinfo_value("sram.buffer.offset");
  113.  
  114.     thread_id_t tid;
  115.     int rc;
  116.  
  117.     rc = thread_create(sgcn_thread_impl, NULL, "kbd_poll", &tid);
  118.     if (rc != 0) {
  119.         return rc;
  120.     }
  121.  
  122.     return 0;
  123. }
  124.  
  125. void kbd_port_yield(void)
  126. {
  127.     polling_disabled = true;
  128. }
  129.  
  130. void kbd_port_reclaim(void)
  131. {
  132.     polling_disabled = false;
  133. }
  134.  
  135. /**
  136.  * Handler of the "key pressed" event. Reads codes of all the pressed keys from
  137.  * the buffer.
  138.  */
  139. static void sgcn_key_pressed(void)
  140. {
  141.     char c;
  142.    
  143.     uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
  144.     uint32_t end = SGCN_BUFFER_HEADER->in_end;
  145.     uint32_t size = end - begin;
  146.    
  147.     volatile char *buf_ptr = (volatile char *)
  148.         SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
  149.     volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
  150.     volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
  151.    
  152.     while (*in_rdptr_ptr != *in_wrptr_ptr) {
  153.         c = *buf_ptr;
  154.         *in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
  155.         buf_ptr = (volatile char *)
  156.             SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
  157.         kbd_push_scancode(c);
  158.     }
  159. }
  160.  
  161. /**
  162.  * Thread to poll SGCN for keypresses.
  163.  */
  164. static void *sgcn_thread_impl(void *arg)
  165. {
  166.     (void) arg;
  167.  
  168.     while (1) {
  169.         if (polling_disabled == false)
  170.             sgcn_key_pressed();
  171.         usleep(POLL_INTERVAL);
  172.     }
  173. }
  174.  
  175. /** @}
  176.  */
  177.