sgcn.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008 Pavel Rimsky
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00037 #include <as.h>
00038 #include <ddi.h>
00039 #include <async.h>
00040 #include <kbd.h>
00041 #include <kbd_port.h>
00042 #include <sysinfo.h>
00043 #include <stdio.h>
00044 #include <thread.h>
00045 #include <bool.h>
00046 #include <errno.h>
00047 
00048 #define POLL_INTERVAL  10000
00049 
00054 typedef struct {
00056         char magic[4];
00057         
00059         char unused[8];
00060         
00062         uint32_t in_begin;
00063         
00065         uint32_t in_end;
00066         
00068         uint32_t in_rdptr;
00069         
00071         uint32_t in_wrptr;
00072 } __attribute__ ((packed)) sgcn_buffer_header_t;
00073 
00074 /*
00075  * Returns a pointer to the object of a given type which is placed at the given
00076  * offset from the console buffer beginning.
00077  */
00078 #define SGCN_BUFFER(type, offset) \
00079                 ((type *) (sram_virt_addr + sram_buffer_offset + (offset)))
00080 
00082 #define SGCN_BUFFER_HEADER      (SGCN_BUFFER(sgcn_buffer_header_t, 0))
00083 
00087 static uintptr_t sram_virt_addr;
00088 
00092 static uintptr_t sram_buffer_offset;
00093 
00094 /* polling thread */
00095 static void sgcn_thread_impl(void *arg);
00096 
00097 static volatile bool polling_disabled = false;
00098 
00103 int kbd_port_init(void)
00104 {
00105         sysarg_t sram_paddr;
00106         if (sysinfo_get_value("sram.address.physical", &sram_paddr) != EOK)
00107                 return -1;
00108         
00109         sysarg_t sram_size;
00110         if (sysinfo_get_value("sram.area.size", &sram_size) != EOK)
00111                 return -1;
00112         
00113         if (sysinfo_get_value("sram.buffer.offset", &sram_buffer_offset) != EOK)
00114                 sram_buffer_offset = 0;
00115         
00116         sram_virt_addr = (uintptr_t) as_get_mappable_page(sram_size);
00117         
00118         if (physmem_map((void *) sram_paddr, (void *) sram_virt_addr,
00119             sram_size / PAGE_SIZE, AS_AREA_READ | AS_AREA_WRITE) != 0) {
00120                 printf("SGCN: uspace driver could not map physical memory.");
00121                 return -1;
00122         }
00123         
00124         thread_id_t tid;
00125         int rc = thread_create(sgcn_thread_impl, NULL, "kbd_poll", &tid);
00126         if (rc != 0)
00127                 return rc;
00128         
00129         return 0;
00130 }
00131 
00132 void kbd_port_yield(void)
00133 {
00134         polling_disabled = true;
00135 }
00136 
00137 void kbd_port_reclaim(void)
00138 {
00139         polling_disabled = false;
00140 }
00141 
00142 void kbd_port_write(uint8_t data)
00143 {
00144         (void) data;
00145 }
00146 
00151 static void sgcn_key_pressed(void)
00152 {
00153         char c;
00154         
00155         uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
00156         uint32_t end = SGCN_BUFFER_HEADER->in_end;
00157         uint32_t size = end - begin;
00158         
00159         volatile char *buf_ptr = (volatile char *)
00160                 SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
00161         volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
00162         volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
00163         
00164         while (*in_rdptr_ptr != *in_wrptr_ptr) {
00165                 c = *buf_ptr;
00166                 *in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
00167                 buf_ptr = (volatile char *)
00168                         SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
00169                 kbd_push_scancode(c);
00170         }
00171 }
00172 
00176 static void sgcn_thread_impl(void *arg)
00177 {
00178         (void) arg;
00179 
00180         while (1) {
00181                 if (polling_disabled == false)
00182                         sgcn_key_pressed();
00183                 usleep(POLL_INTERVAL);
00184         }
00185 }
00186 

Generated on Thu Jun 2 07:45:49 2011 for HelenOS/USB by  doxygen 1.4.7