Subversion Repositories HelenOS

Rev

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