cuda.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006 Martin Decky
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 
00035 #include <arch/drivers/cuda.h>
00036 #include <arch/asm.h>
00037 #include <console/console.h>
00038 #include <console/chardev.h>
00039 #include <arch/drivers/pic.h>
00040 #include <sysinfo/sysinfo.h>
00041 #include <interrupt.h>
00042 #include <stdarg.h>
00043 
00044 #define SPECIAL         '?'
00045 
00046 #define PACKET_ADB  0x00
00047 #define PACKET_CUDA 0x01
00048 
00049 #define CUDA_POWERDOWN 0x0a
00050 
00051 #define RS 0x200
00052 #define B (0 * RS)
00053 #define A (1 * RS)
00054 #define SR (10 * RS)
00055 #define ACR (11 * RS)
00056 
00057 #define SR_OUT 0x10
00058 #define TACK 0x10
00059 #define TIP 0x20
00060 
00061 
00062 static volatile __u8 *cuda = NULL;
00063 static iroutine vector;
00064 
00065 
00066 static char lchars[0x80] = {
00067         'a',
00068         's',
00069         'd',
00070         'f',
00071         'h',
00072         'g',
00073         'z',
00074         'x',
00075         'c',
00076         'v', 
00077         SPECIAL,
00078         'b',
00079         'q',
00080         'w',
00081         'e',
00082         'r',
00083         'y',
00084         't',
00085         '1',
00086         '2',
00087         '3',
00088         '4',
00089         '6',
00090         '5',
00091         '=',
00092         '9',
00093         '7',
00094         '-',
00095         '8',
00096         '0',
00097         ']',
00098         'o',
00099         'u',
00100         '[',
00101         'i', 
00102         'p',
00103         '\n',    /* Enter */
00104         'l',
00105         'j',
00106         '\'',
00107         'k',
00108         ';',
00109         '\\',
00110         ',',
00111         '/',
00112         'n',
00113         'm',
00114         '.',
00115         '\t',    /* Tab */
00116         ' ',
00117         '`',
00118         '\b',    /* Backspace */
00119         SPECIAL,
00120         SPECIAL, /* Escape */
00121         SPECIAL, /* Ctrl */
00122         SPECIAL, /* Alt */
00123         SPECIAL, /* Shift */
00124         SPECIAL, /* Caps-Lock */
00125         SPECIAL, /* RAlt */
00126         SPECIAL, /* Left */
00127         SPECIAL, /* Right */
00128         SPECIAL, /* Down */
00129         SPECIAL, /* Up */
00130         SPECIAL, 
00131         SPECIAL,
00132         '.',     /* Keypad . */
00133         SPECIAL, 
00134         '*',     /* Keypad * */
00135         SPECIAL,
00136         '+',     /* Keypad + */
00137         SPECIAL,
00138         SPECIAL, /* NumLock */
00139         SPECIAL,
00140         SPECIAL,
00141         SPECIAL,
00142         '/',     /* Keypad / */
00143         '\n',    /* Keypad Enter */
00144         SPECIAL,
00145         '-',     /* Keypad - */
00146         SPECIAL,
00147         SPECIAL,
00148         SPECIAL,
00149         '0',     /* Keypad 0 */
00150         '1',     /* Keypad 1 */
00151         '2',     /* Keypad 2 */
00152         '3',     /* Keypad 3 */
00153         '4',     /* Keypad 4 */
00154         '5',     /* Keypad 5 */
00155         '6',     /* Keypad 6 */
00156         '7',     /* Keypad 7 */
00157         SPECIAL,
00158         '8',     /* Keypad 8 */
00159         '9',     /* Keypad 9 */
00160         SPECIAL,
00161         SPECIAL,
00162         SPECIAL,
00163         SPECIAL, /* F5 */
00164         SPECIAL, /* F6 */
00165         SPECIAL, /* F7 */
00166         SPECIAL, /* F3 */
00167         SPECIAL, /* F8 */
00168         SPECIAL, /* F9 */
00169         SPECIAL,
00170         SPECIAL, /* F11 */
00171         SPECIAL,
00172         SPECIAL, /* F13 */
00173         SPECIAL,
00174         SPECIAL, /* ScrollLock */
00175         SPECIAL,
00176         SPECIAL, /* F10 */
00177         SPECIAL,
00178         SPECIAL, /* F12 */
00179         SPECIAL,
00180         SPECIAL, /* Pause */
00181         SPECIAL, /* Insert */
00182         SPECIAL, /* Home */
00183         SPECIAL, /* PageUp */
00184         SPECIAL, /* Delete */
00185         SPECIAL, /* F4 */
00186         SPECIAL, /* End */
00187         SPECIAL, /* F2 */
00188         SPECIAL, /* PageDown */
00189         SPECIAL  /* F1 */
00190 };
00191 
00192 
00193 void send_packet(const __u8 kind, index_t count, ...);
00194 
00195 
00196 static void receive_packet(__u8 *kind, index_t count, __u8 data[])
00197 {
00198         cuda[B] = cuda[B] & ~TIP;
00199         *kind = cuda[SR];
00200         
00201         index_t i;
00202         for (i = 0; i < count; i++)
00203                 data[i] = cuda[SR];
00204         
00205         cuda[B] = cuda[B] | TIP;
00206 }
00207 
00208 
00209 /* Called from getc(). */
00210 static void cuda_resume(chardev_t *d)
00211 {
00212 }
00213 
00214 
00215 /* Called from getc(). */
00216 static void cuda_suspend(chardev_t *d)
00217 {
00218 }
00219 
00220 
00221 static char key_read(chardev_t *d)
00222 {
00223         char ch;
00224         
00225         ch = 0;
00226         return ch;
00227 }
00228 
00229 
00230 static chardev_t kbrd;
00231 static chardev_operations_t ops = {
00232         .suspend = cuda_suspend,
00233         .resume = cuda_resume,
00234         .read = key_read
00235 };
00236 
00237 
00238 int cuda_get_scancode(void)
00239 {
00240         __u8 kind;
00241         __u8 data[4];
00242         
00243         receive_packet(&kind, 4, data);
00244         
00245         if ((kind == PACKET_ADB) && (data[0] == 0x40) && (data[1] == 0x2c))
00246                 return data[2];
00247         
00248         return -1;
00249 }
00250 
00251 static void cuda_irq(int n, istate_t *istate)
00252 {
00253         int scan_code = cuda_get_scancode();
00254         
00255         if (scan_code != -1) {
00256                 __u8 scancode = (__u8) scan_code;
00257                 if ((scancode & 0x80) != 0x80)
00258                         chardev_push_character(&kbrd, lchars[scancode & 0x7f]);
00259         }
00260 }
00261 
00262 
00264 void cuda_grab(void)
00265 {
00266         vector = int_register(CUDA_IRQ, "cuda", cuda_irq);
00267 }
00268 
00269 
00271 void cuda_release(void)
00272 {
00273         if (vector)
00274                 int_register(CUDA_IRQ, "user_interrupt", vector);
00275 }
00276 
00277 
00278 void cuda_init(__address base, size_t size)
00279 {
00280         cuda = (__u8 *) hw_map(base, size);
00281         
00282         int_register(CUDA_IRQ, "cuda", cuda_irq);
00283         pic_enable_interrupt(CUDA_IRQ);
00284         
00285         chardev_initialize("cuda_kbd", &kbrd, &ops);
00286         stdin = &kbrd;
00287         
00288         sysinfo_set_item_val("cuda", NULL, true);
00289         sysinfo_set_item_val("cuda.irq", NULL, CUDA_IRQ);
00290 }
00291 
00292 
00293 void send_packet(const __u8 kind, index_t count, ...)
00294 {
00295         index_t i;
00296         va_list va;
00297         
00298         cuda[B] = cuda[B] | TIP;
00299         cuda[ACR] = cuda[ACR] | SR_OUT;
00300         cuda[SR] = kind;
00301         cuda[B] = cuda[B] & ~TIP;
00302         
00303         va_start(va, count);
00304         
00305         for (i = 0; i < count; i++) {
00306                 cuda[ACR] = cuda[ACR] | SR_OUT;
00307                 cuda[SR] = va_arg(va, int);
00308                 cuda[B] = cuda[B] | TACK;
00309         }
00310         
00311         va_end(va);
00312         
00313         cuda[B] = cuda[B] | TIP;
00314 }
00315 
00316 
00317 void cpu_halt(void) {
00318 #ifdef CONFIG_POWEROFF
00319         send_packet(PACKET_CUDA, 1, CUDA_POWERDOWN);
00320 #endif
00321         asm volatile (
00322                 "b 0\n"
00323         );
00324 }
00325 

Generated on Sun Jun 18 17:17:04 2006 for HelenOS Kernel (ppc32) by  doxygen 1.4.6