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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 4874c2d was 4874c2d, checked in by Jakub Jermar <jakub@…>, 19 years ago

Do not copy notification config out of the IRQ structure.
Add the notify member, that toggles notifications on and off instead.
This is good for preventing other tasks from registering the notification
while the notification config is stored outside the IRQ structure.
It should also help to implement the cleanup code.

  • 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 cuda_grab();
310}
311
312
313void send_packet(const uint8_t kind, index_t count, ...)
314{
315 index_t i;
316 va_list va;
317
318 cuda[B] = cuda[B] | TIP;
319 cuda[ACR] = cuda[ACR] | SR_OUT;
320 cuda[SR] = kind;
321 cuda[B] = cuda[B] & ~TIP;
322
323 va_start(va, count);
324
325 for (i = 0; i < count; i++) {
326 cuda[ACR] = cuda[ACR] | SR_OUT;
327 cuda[SR] = va_arg(va, int);
328 cuda[B] = cuda[B] | TACK;
329 }
330
331 va_end(va);
332
333 cuda[B] = cuda[B] | TIP;
334}
335
336
337void cpu_halt(void) {
338#ifdef CONFIG_POWEROFF
339 send_packet(PACKET_CUDA, 1, CUDA_POWERDOWN);
340#endif
341 asm volatile (
342 "b 0\n"
343 );
344}
345
346/** @}
347 */
Note: See TracBrowser for help on using the repository browser.