source: mainline/kernel/arch/ppc32/src/drivers/cuda.c@ fb8335c

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since fb8335c was fb8335c, checked in by Martin Decky <martin@…>, 19 years ago

remove grab (not needed)

  • Property mode set to 100644
File size: 6.3 KB
Line 
1/*
2 * Copyright (C) 2006 Martin Decky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup ppc32
30 * @{
31 */
32/** @file
33 */
34
35#include <arch/drivers/cuda.h>
36#include <ddi/irq.h>
37#include <arch/asm.h>
38#include <console/console.h>
39#include <console/chardev.h>
40#include <arch/drivers/pic.h>
41#include <sysinfo/sysinfo.h>
42#include <interrupt.h>
43#include <stdarg.h>
44
45#define CUDA_IRQ 10
46#define SPECIAL '?'
47
48#define PACKET_ADB 0x00
49#define PACKET_CUDA 0x01
50
51#define CUDA_POWERDOWN 0x0a
52
53#define RS 0x200
54#define B (0 * RS)
55#define A (1 * RS)
56#define SR (10 * RS)
57#define ACR (11 * RS)
58
59#define SR_OUT 0x10
60#define TACK 0x10
61#define TIP 0x20
62
63
64static volatile uint8_t *cuda = NULL;
65static irq_t cuda_irq; /**< Cuda's IRQ. */
66
67static char lchars[0x80] = {
68 'a',
69 's',
70 'd',
71 'f',
72 'h',
73 'g',
74 'z',
75 'x',
76 'c',
77 'v',
78 SPECIAL,
79 'b',
80 'q',
81 'w',
82 'e',
83 'r',
84 'y',
85 't',
86 '1',
87 '2',
88 '3',
89 '4',
90 '6',
91 '5',
92 '=',
93 '9',
94 '7',
95 '-',
96 '8',
97 '0',
98 ']',
99 'o',
100 'u',
101 '[',
102 'i',
103 'p',
104 '\n', /* Enter */
105 'l',
106 'j',
107 '\'',
108 'k',
109 ';',
110 '\\',
111 ',',
112 '/',
113 'n',
114 'm',
115 '.',
116 '\t', /* Tab */
117 ' ',
118 '`',
119 '\b', /* Backspace */
120 SPECIAL,
121 SPECIAL, /* Escape */
122 SPECIAL, /* Ctrl */
123 SPECIAL, /* Alt */
124 SPECIAL, /* Shift */
125 SPECIAL, /* Caps-Lock */
126 SPECIAL, /* RAlt */
127 SPECIAL, /* Left */
128 SPECIAL, /* Right */
129 SPECIAL, /* Down */
130 SPECIAL, /* Up */
131 SPECIAL,
132 SPECIAL,
133 '.', /* Keypad . */
134 SPECIAL,
135 '*', /* Keypad * */
136 SPECIAL,
137 '+', /* Keypad + */
138 SPECIAL,
139 SPECIAL, /* NumLock */
140 SPECIAL,
141 SPECIAL,
142 SPECIAL,
143 '/', /* Keypad / */
144 '\n', /* Keypad Enter */
145 SPECIAL,
146 '-', /* Keypad - */
147 SPECIAL,
148 SPECIAL,
149 SPECIAL,
150 '0', /* Keypad 0 */
151 '1', /* Keypad 1 */
152 '2', /* Keypad 2 */
153 '3', /* Keypad 3 */
154 '4', /* Keypad 4 */
155 '5', /* Keypad 5 */
156 '6', /* Keypad 6 */
157 '7', /* Keypad 7 */
158 SPECIAL,
159 '8', /* Keypad 8 */
160 '9', /* Keypad 9 */
161 SPECIAL,
162 SPECIAL,
163 SPECIAL,
164 SPECIAL, /* F5 */
165 SPECIAL, /* F6 */
166 SPECIAL, /* F7 */
167 SPECIAL, /* F3 */
168 SPECIAL, /* F8 */
169 SPECIAL, /* F9 */
170 SPECIAL,
171 SPECIAL, /* F11 */
172 SPECIAL,
173 SPECIAL, /* F13 */
174 SPECIAL,
175 SPECIAL, /* ScrollLock */
176 SPECIAL,
177 SPECIAL, /* F10 */
178 SPECIAL,
179 SPECIAL, /* F12 */
180 SPECIAL,
181 SPECIAL, /* Pause */
182 SPECIAL, /* Insert */
183 SPECIAL, /* Home */
184 SPECIAL, /* PageUp */
185 SPECIAL, /* Delete */
186 SPECIAL, /* F4 */
187 SPECIAL, /* End */
188 SPECIAL, /* F2 */
189 SPECIAL, /* PageDown */
190 SPECIAL /* F1 */
191};
192
193
194void send_packet(const uint8_t kind, index_t count, ...);
195
196
197static void receive_packet(uint8_t *kind, index_t count, uint8_t data[])
198{
199 cuda[B] = cuda[B] & ~TIP;
200 *kind = cuda[SR];
201
202 index_t i;
203 for (i = 0; i < count; i++)
204 data[i] = cuda[SR];
205
206 cuda[B] = cuda[B] | TIP;
207}
208
209
210/* Called from getc(). */
211static void cuda_resume(chardev_t *d)
212{
213}
214
215
216/* Called from getc(). */
217static void cuda_suspend(chardev_t *d)
218{
219}
220
221
222static char key_read(chardev_t *d)
223{
224 char ch;
225
226 ch = 0;
227 return ch;
228}
229
230
231static chardev_t kbrd;
232static chardev_operations_t ops = {
233 .suspend = cuda_suspend,
234 .resume = cuda_resume,
235 .read = key_read
236};
237
238
239int cuda_get_scancode(void)
240{
241 uint8_t kind;
242 uint8_t data[4];
243
244 receive_packet(&kind, 4, data);
245
246 if ((kind == PACKET_ADB) && (data[0] == 0x40) && (data[1] == 0x2c))
247 return data[2];
248
249 return -1;
250}
251
252static void cuda_irq_handler(irq_t *irq, void *arg, ...)
253{
254 if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox))
255 ipc_irq_send_notif(irq);
256 else {
257 int scan_code = cuda_get_scancode();
258
259 if (scan_code != -1) {
260 uint8_t scancode = (uint8_t) scan_code;
261 if ((scancode & 0x80) != 0x80)
262 chardev_push_character(&kbrd, lchars[scancode & 0x7f]);
263 }
264 }
265}
266
267static irq_ownership_t cuda_claim(void)
268{
269 return IRQ_ACCEPT;
270}
271
272
273/** Initialize keyboard and service interrupts using kernel routine */
274void cuda_grab(void)
275{
276 cuda_irq.notif_cfg.notify = false;
277}
278
279
280/** Resume the former interrupt vector */
281void cuda_release(void)
282{
283 if (cuda_irq.notif_cfg.answerbox)
284 cuda_irq.notif_cfg.notify = true;
285}
286
287
288void cuda_init(devno_t devno, uintptr_t base, size_t size)
289{
290 cuda = (uint8_t *) hw_map(base, size);
291
292 chardev_initialize("cuda_kbd", &kbrd, &ops);
293 stdin = &kbrd;
294
295 irq_initialize(&cuda_irq);
296 cuda_irq.devno = devno;
297 cuda_irq.inr = CUDA_IRQ;
298 cuda_irq.claim = cuda_claim;
299 cuda_irq.handler = cuda_irq_handler;
300 irq_register(&cuda_irq);
301
302 pic_enable_interrupt(CUDA_IRQ);
303
304 sysinfo_set_item_val("kbd", NULL, true);
305 sysinfo_set_item_val("kbd.devno", NULL, devno);
306 sysinfo_set_item_val("kbd.inr", NULL, CUDA_IRQ);
307 sysinfo_set_item_val("kbd.address.virtual", NULL, base);
308}
309
310
311void send_packet(const uint8_t kind, index_t count, ...)
312{
313 index_t i;
314 va_list va;
315
316 cuda[B] = cuda[B] | TIP;
317 cuda[ACR] = cuda[ACR] | SR_OUT;
318 cuda[SR] = kind;
319 cuda[B] = cuda[B] & ~TIP;
320
321 va_start(va, count);
322
323 for (i = 0; i < count; i++) {
324 cuda[ACR] = cuda[ACR] | SR_OUT;
325 cuda[SR] = va_arg(va, int);
326 cuda[B] = cuda[B] | TACK;
327 }
328
329 va_end(va);
330
331 cuda[B] = cuda[B] | TIP;
332}
333
334
335void cpu_halt(void) {
336#ifdef CONFIG_POWEROFF
337 send_packet(PACKET_CUDA, 1, CUDA_POWERDOWN);
338#endif
339 asm volatile (
340 "b 0\n"
341 );
342}
343
344/** @}
345 */
Note: See TracBrowser for help on using the repository browser.