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

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

start shutdown infrastructure

  • Property mode set to 100644
File size: 6.6 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 <ipc/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#define CUDA_RESET 0x11
53
54#define RS 0x200
55#define B (0 * RS)
56#define A (1 * RS)
57#define SR (10 * RS)
58#define ACR (11 * RS)
59
60#define SR_OUT 0x10
61#define TACK 0x10
62#define TIP 0x20
63
64
65static volatile uint8_t *cuda = NULL;
66static irq_t cuda_irq; /**< Cuda's IRQ. */
67
68static char lchars[0x80] = {
69 'a',
70 's',
71 'd',
72 'f',
73 'h',
74 'g',
75 'z',
76 'x',
77 'c',
78 'v',
79 SPECIAL,
80 'b',
81 'q',
82 'w',
83 'e',
84 'r',
85 'y',
86 't',
87 '1',
88 '2',
89 '3',
90 '4',
91 '6',
92 '5',
93 '=',
94 '9',
95 '7',
96 '-',
97 '8',
98 '0',
99 ']',
100 'o',
101 'u',
102 '[',
103 'i',
104 'p',
105 '\n', /* Enter */
106 'l',
107 'j',
108 '\'',
109 'k',
110 ';',
111 '\\',
112 ',',
113 '/',
114 'n',
115 'm',
116 '.',
117 '\t', /* Tab */
118 ' ',
119 '`',
120 '\b', /* Backspace */
121 SPECIAL,
122 SPECIAL, /* Escape */
123 SPECIAL, /* Ctrl */
124 SPECIAL, /* Alt */
125 SPECIAL, /* Shift */
126 SPECIAL, /* Caps-Lock */
127 SPECIAL, /* RAlt */
128 SPECIAL, /* Left */
129 SPECIAL, /* Right */
130 SPECIAL, /* Down */
131 SPECIAL, /* Up */
132 SPECIAL,
133 SPECIAL,
134 '.', /* Keypad . */
135 SPECIAL,
136 '*', /* Keypad * */
137 SPECIAL,
138 '+', /* Keypad + */
139 SPECIAL,
140 SPECIAL, /* NumLock */
141 SPECIAL,
142 SPECIAL,
143 SPECIAL,
144 '/', /* Keypad / */
145 '\n', /* Keypad Enter */
146 SPECIAL,
147 '-', /* Keypad - */
148 SPECIAL,
149 SPECIAL,
150 SPECIAL,
151 '0', /* Keypad 0 */
152 '1', /* Keypad 1 */
153 '2', /* Keypad 2 */
154 '3', /* Keypad 3 */
155 '4', /* Keypad 4 */
156 '5', /* Keypad 5 */
157 '6', /* Keypad 6 */
158 '7', /* Keypad 7 */
159 SPECIAL,
160 '8', /* Keypad 8 */
161 '9', /* Keypad 9 */
162 SPECIAL,
163 SPECIAL,
164 SPECIAL,
165 SPECIAL, /* F5 */
166 SPECIAL, /* F6 */
167 SPECIAL, /* F7 */
168 SPECIAL, /* F3 */
169 SPECIAL, /* F8 */
170 SPECIAL, /* F9 */
171 SPECIAL,
172 SPECIAL, /* F11 */
173 SPECIAL,
174 SPECIAL, /* F13 */
175 SPECIAL,
176 SPECIAL, /* ScrollLock */
177 SPECIAL,
178 SPECIAL, /* F10 */
179 SPECIAL,
180 SPECIAL, /* F12 */
181 SPECIAL,
182 SPECIAL, /* Pause */
183 SPECIAL, /* Insert */
184 SPECIAL, /* Home */
185 SPECIAL, /* PageUp */
186 SPECIAL, /* Delete */
187 SPECIAL, /* F4 */
188 SPECIAL, /* End */
189 SPECIAL, /* F2 */
190 SPECIAL, /* PageDown */
191 SPECIAL /* F1 */
192};
193
194
195static void receive_packet(uint8_t *kind, index_t count, uint8_t data[])
196{
197 cuda[B] = cuda[B] & ~TIP;
198 *kind = cuda[SR];
199
200 index_t i;
201 for (i = 0; i < count; i++)
202 data[i] = cuda[SR];
203
204 cuda[B] = cuda[B] | TIP;
205}
206
207
208/* Called from getc(). */
209static void cuda_resume(chardev_t *d)
210{
211}
212
213
214/* Called from getc(). */
215static void cuda_suspend(chardev_t *d)
216{
217}
218
219
220static char key_read(chardev_t *d)
221{
222 char ch;
223
224 ch = 0;
225 return ch;
226}
227
228
229static chardev_t kbrd;
230static chardev_operations_t ops = {
231 .suspend = cuda_suspend,
232 .resume = cuda_resume,
233 .read = key_read
234};
235
236
237int cuda_get_scancode(void)
238{
239 uint8_t kind;
240 uint8_t data[4];
241
242 receive_packet(&kind, 4, data);
243
244 if ((kind == PACKET_ADB) && (data[0] == 0x40) && (data[1] == 0x2c))
245 return data[2];
246
247 return -1;
248}
249
250static void cuda_irq_handler(irq_t *irq, void *arg, ...)
251{
252 if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox))
253 ipc_irq_send_notif(irq);
254 else {
255 int scan_code = cuda_get_scancode();
256
257 if (scan_code != -1) {
258 uint8_t scancode = (uint8_t) scan_code;
259 if ((scancode & 0x80) != 0x80)
260 chardev_push_character(&kbrd, lchars[scancode & 0x7f]);
261 }
262 }
263}
264
265static irq_ownership_t cuda_claim(void)
266{
267 return IRQ_ACCEPT;
268}
269
270
271/** Initialize keyboard and service interrupts using kernel routine */
272void cuda_grab(void)
273{
274 ipl_t ipl = interrupts_disable();
275 spinlock_lock(&cuda_irq.lock);
276 cuda_irq.notif_cfg.notify = false;
277 spinlock_unlock(&cuda_irq.lock);
278 interrupts_restore(ipl);
279}
280
281
282/** Resume the former interrupt vector */
283void cuda_release(void)
284{
285 ipl_t ipl = interrupts_disable();
286 spinlock_lock(&cuda_irq.lock);
287 if (cuda_irq.notif_cfg.answerbox)
288 cuda_irq.notif_cfg.notify = true;
289 spinlock_unlock(&cuda_irq.unlock);
290 interrupts_restore(ipl);
291}
292
293
294void cuda_init(devno_t devno, uintptr_t base, size_t size)
295{
296 cuda = (uint8_t *) hw_map(base, size);
297
298 chardev_initialize("cuda_kbd", &kbrd, &ops);
299 stdin = &kbrd;
300
301 irq_initialize(&cuda_irq);
302 cuda_irq.devno = devno;
303 cuda_irq.inr = CUDA_IRQ;
304 cuda_irq.claim = cuda_claim;
305 cuda_irq.handler = cuda_irq_handler;
306 irq_register(&cuda_irq);
307
308 pic_enable_interrupt(CUDA_IRQ);
309
310 sysinfo_set_item_val("kbd", NULL, true);
311 sysinfo_set_item_val("kbd.devno", NULL, devno);
312 sysinfo_set_item_val("kbd.inr", NULL, CUDA_IRQ);
313 sysinfo_set_item_val("kbd.address.virtual", NULL, base);
314}
315
316
317static void send_packet(const uint8_t kind, count_t count, ...)
318{
319 index_t i;
320 va_list va;
321
322 cuda[B] = cuda[B] | TIP;
323 cuda[ACR] = cuda[ACR] | SR_OUT;
324 cuda[SR] = kind;
325 cuda[B] = cuda[B] & ~TIP;
326
327 va_start(va, count);
328
329 for (i = 0; i < count; i++) {
330 cuda[ACR] = cuda[ACR] | SR_OUT;
331 cuda[SR] = va_arg(va, int);
332 cuda[B] = cuda[B] | TACK;
333 }
334
335 va_end(va);
336
337 cuda[B] = cuda[B] | TIP;
338}
339
340
341void cpu_halt(void) {
342 asm volatile (
343 "b 0\n"
344 );
345}
346
347void arch_reboot(void) {
348 send_packet(PACKET_CUDA, 1, CUDA_RESET);
349 asm volatile (
350 "b 0\n"
351 );
352}
353
354/** @}
355 */
Note: See TracBrowser for help on using the repository browser.