00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
00076
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
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