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
RevLine 
[8b1439e]1/*
[df4ed85]2 * Copyright (c) 2006 Martin Decky
[8b1439e]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
[281994b]29/** @addtogroup ppc32
[b45c443]30 * @{
31 */
32/** @file
33 */
34
[8b1439e]35#include <arch/drivers/cuda.h>
[b3f8fb7]36#include <ipc/irq.h>
[8b1439e]37#include <arch/asm.h>
[edc89bd0]38#include <console/console.h>
[ae971b3e]39#include <console/chardev.h>
[982f0fe]40#include <arch/drivers/pic.h>
[732fd3c]41#include <sysinfo/sysinfo.h>
[982f0fe]42#include <interrupt.h>
[afc12d0]43#include <stdarg.h>
44
[f5e39a32]45#define CUDA_IRQ 10
[d667767]46#define SPECIAL '?'
47
[afc12d0]48#define PACKET_ADB 0x00
49#define PACKET_CUDA 0x01
[8b1439e]50
[f74bbaf]51#define CUDA_POWERDOWN 0x0a
52#define CUDA_RESET 0x11
[8b1439e]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
[7f1c620]65static volatile uint8_t *cuda = NULL;
[f5e39a32]66static irq_t cuda_irq; /**< Cuda's IRQ. */
67
[afc12d0]68static char lchars[0x80] = {
[d667767]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 */
[afc12d0]192};
193
194
[7f1c620]195static void receive_packet(uint8_t *kind, index_t count, uint8_t data[])
[afc12d0]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}
[8b1439e]206
[8333801]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
[ae971b3e]229static chardev_t kbrd;
[8333801]230static chardev_operations_t ops = {
231 .suspend = cuda_suspend,
232 .resume = cuda_resume,
233 .read = key_read
234};
235
[afc12d0]236
[d667767]237int cuda_get_scancode(void)
[982f0fe]238{
[7f1c620]239 uint8_t kind;
240 uint8_t data[4];
[afc12d0]241
242 receive_packet(&kind, 4, data);
243
[ae971b3e]244 if ((kind == PACKET_ADB) && (data[0] == 0x40) && (data[1] == 0x2c))
245 return data[2];
246
[d667767]247 return -1;
[ae971b3e]248}
249
[f5e39a32]250static void cuda_irq_handler(irq_t *irq, void *arg, ...)
[ae971b3e]251{
[fb8335c]252 if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox))
[f5e39a32]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 }
[d667767]262 }
[982f0fe]263}
[8b1439e]264
[f5e39a32]265static irq_ownership_t cuda_claim(void)
266{
267 return IRQ_ACCEPT;
268}
269
[afc12d0]270
[281994b]271/** Initialize keyboard and service interrupts using kernel routine */
272void cuda_grab(void)
273{
[3dea17f]274 ipl_t ipl = interrupts_disable();
275 spinlock_lock(&cuda_irq.lock);
[4874c2d]276 cuda_irq.notif_cfg.notify = false;
[3dea17f]277 spinlock_unlock(&cuda_irq.lock);
278 interrupts_restore(ipl);
[281994b]279}
280
281
282/** Resume the former interrupt vector */
283void cuda_release(void)
284{
[3dea17f]285 ipl_t ipl = interrupts_disable();
286 spinlock_lock(&cuda_irq.lock);
[4874c2d]287 if (cuda_irq.notif_cfg.answerbox)
288 cuda_irq.notif_cfg.notify = true;
[3dea17f]289 spinlock_unlock(&cuda_irq.unlock);
290 interrupts_restore(ipl);
[281994b]291}
292
293
[f5e39a32]294void cuda_init(devno_t devno, uintptr_t base, size_t size)
[e4ddfa8]295{
[f5e39a32]296 cuda = (uint8_t *) hw_map(base, size);
[8333801]297
298 chardev_initialize("cuda_kbd", &kbrd, &ops);
299 stdin = &kbrd;
[732fd3c]300
[f5e39a32]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);
[e4ddfa8]314}
315
316
[f74bbaf]317static void send_packet(const uint8_t kind, count_t count, ...)
[ae971b3e]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
[8b1439e]341void cpu_halt(void) {
[f74bbaf]342 asm volatile (
343 "b 0\n"
344 );
345}
346
347void arch_reboot(void) {
348 send_packet(PACKET_CUDA, 1, CUDA_RESET);
[9a68b34d]349 asm volatile (
350 "b 0\n"
351 );
[8b1439e]352}
[b45c443]353
[281994b]354/** @}
[b45c443]355 */
Note: See TracBrowser for help on using the repository browser.