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
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',
00104 'l',
00105 'j',
00106 '\'',
00107 'k',
00108 ';',
00109 '\\',
00110 ',',
00111 '/',
00112 'n',
00113 'm',
00114 '.',
00115 '\t',
00116 ' ',
00117 '`',
00118 '\b',
00119 SPECIAL,
00120 SPECIAL,
00121 SPECIAL,
00122 SPECIAL,
00123 SPECIAL,
00124 SPECIAL,
00125 SPECIAL,
00126 SPECIAL,
00127 SPECIAL,
00128 SPECIAL,
00129 SPECIAL,
00130 SPECIAL,
00131 SPECIAL,
00132 '.',
00133 SPECIAL,
00134 '*',
00135 SPECIAL,
00136 '+',
00137 SPECIAL,
00138 SPECIAL,
00139 SPECIAL,
00140 SPECIAL,
00141 SPECIAL,
00142 '/',
00143 '\n',
00144 SPECIAL,
00145 '-',
00146 SPECIAL,
00147 SPECIAL,
00148 SPECIAL,
00149 '0',
00150 '1',
00151 '2',
00152 '3',
00153 '4',
00154 '5',
00155 '6',
00156 '7',
00157 SPECIAL,
00158 '8',
00159 '9',
00160 SPECIAL,
00161 SPECIAL,
00162 SPECIAL,
00163 SPECIAL,
00164 SPECIAL,
00165 SPECIAL,
00166 SPECIAL,
00167 SPECIAL,
00168 SPECIAL,
00169 SPECIAL,
00170 SPECIAL,
00171 SPECIAL,
00172 SPECIAL,
00173 SPECIAL,
00174 SPECIAL,
00175 SPECIAL,
00176 SPECIAL,
00177 SPECIAL,
00178 SPECIAL,
00179 SPECIAL,
00180 SPECIAL,
00181 SPECIAL,
00182 SPECIAL,
00183 SPECIAL,
00184 SPECIAL,
00185 SPECIAL,
00186 SPECIAL,
00187 SPECIAL,
00188 SPECIAL,
00189 SPECIAL
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
00210 static void cuda_resume(chardev_t *d)
00211 {
00212 }
00213
00214
00215
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