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 00053 static uintptr_t input_buffer_addr; 00054 00055 /* 00056 * Kernel counterpart of the driver pushes characters (it has read) here. 00057 * Keep in sync with the definition from 00058 * kernel/arch/sparc64/src/drivers/niagara.c. 00059 */ 00060 #define INPUT_BUFFER_SIZE ((PAGE_SIZE) - 2 * 8) 00061 00062 typedef volatile struct { 00063 uint64_t write_ptr; 00064 uint64_t read_ptr; 00065 char data[INPUT_BUFFER_SIZE]; 00066 } 00067 __attribute__ ((packed)) 00068 __attribute__ ((aligned(PAGE_SIZE))) 00069 *input_buffer_t; 00070 00071 /* virtual address of the shared buffer */ 00072 input_buffer_t input_buffer; 00073 00074 static volatile bool polling_disabled = false; 00075 static void niagara_thread_impl(void *arg); 00076 00081 int kbd_port_init(void) 00082 { 00083 sysarg_t paddr; 00084 if (sysinfo_get_value("niagara.inbuf.address", &paddr) != EOK) 00085 return -1; 00086 00087 input_buffer_addr = (uintptr_t) as_get_mappable_page(PAGE_SIZE); 00088 int rc = physmem_map((void *) paddr, (void *) input_buffer_addr, 00089 1, AS_AREA_READ | AS_AREA_WRITE); 00090 00091 if (rc != 0) { 00092 printf("Niagara: uspace driver couldn't map physical memory: %d\n", 00093 rc); 00094 return rc; 00095 } 00096 00097 input_buffer = (input_buffer_t) input_buffer_addr; 00098 00099 thread_id_t tid; 00100 rc = thread_create(niagara_thread_impl, NULL, "kbd_poll", &tid); 00101 if (rc != 0) 00102 return rc; 00103 00104 return 0; 00105 } 00106 00107 void kbd_port_yield(void) 00108 { 00109 polling_disabled = true; 00110 } 00111 00112 void kbd_port_reclaim(void) 00113 { 00114 polling_disabled = false; 00115 } 00116 00117 void kbd_port_write(uint8_t data) 00118 { 00119 (void) data; 00120 } 00121 00126 static void niagara_key_pressed(void) 00127 { 00128 char c; 00129 00130 while (input_buffer->read_ptr != input_buffer->write_ptr) { 00131 c = input_buffer->data[input_buffer->read_ptr]; 00132 input_buffer->read_ptr = 00133 ((input_buffer->read_ptr) + 1) % INPUT_BUFFER_SIZE; 00134 kbd_push_scancode(c); 00135 } 00136 } 00137 00141 static void niagara_thread_impl(void *arg) 00142 { 00143 (void) arg; 00144 00145 while (1) { 00146 if (polling_disabled == false) 00147 niagara_key_pressed(); 00148 usleep(POLL_INTERVAL); 00149 } 00150 }