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

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

represent special keystrokes (cursor arrows, page up/down, delete, etc.) as appropriate Unicode characters
do not parse ANSI control sequences in kconsole, but in serial line driver

  • Property mode set to 100644
File size: 6.1 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 <arch/asm.h>
37#include <console/console.h>
38#include <console/chardev.h>
39#include <arch/drivers/pic.h>
40#include <sysinfo/sysinfo.h>
41#include <interrupt.h>
42#include <stdarg.h>
43#include <ddi/device.h>
44#include <string.h>
45
46#define CUDA_IRQ 10
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#define SCANCODES 128
65
66static volatile uint8_t *cuda = NULL;
67static irq_t cuda_irq; /**< Cuda's IRQ. */
68
69static wchar_t lchars[SCANCODES] = {
70 'a', 's', 'd', 'f', 'h', 'g', 'z', 'x', 'c', 'v',
71 U_SPECIAL,
72 'b', 'q', 'w', 'e', 'r', 'y', 't', '1', '2', '3', '4', '6', '5',
73 '=', '9', '7', '-', '8', '0', ']', 'o', 'u', '[', 'i', 'p',
74 '\n', /* Enter */
75 'l', 'j', '\'', 'k', ';', '\\', ',', '/', 'n', 'm', '.',
76 '\t', /* Tab */
77 ' ', '`',
78 '\b', /* Backspace */
79 U_SPECIAL,
80 U_ESCAPE, /* Escape */
81 U_SPECIAL, /* Ctrl */
82 U_SPECIAL, /* Alt */
83 U_SPECIAL, /* Shift */
84 U_SPECIAL, /* CapsLock */
85 U_SPECIAL, /* Right Alt */
86 U_LEFT_ARROW, /* Left */
87 U_RIGHT_ARROW, /* Right */
88 U_DOWN_ARROW, /* Down */
89 U_UP_ARROW, /* Up */
90 U_SPECIAL,
91 U_SPECIAL,
92 '.', /* Keypad . */
93 U_SPECIAL,
94 '*', /* Keypad * */
95 U_SPECIAL,
96 '+', /* Keypad + */
97 U_SPECIAL,
98 U_SPECIAL, /* NumLock */
99 U_SPECIAL,
100 U_SPECIAL,
101 U_SPECIAL,
102 '/', /* Keypad / */
103 '\n', /* Keypad Enter */
104 U_SPECIAL,
105 '-', /* Keypad - */
106 U_SPECIAL,
107 U_SPECIAL,
108 U_SPECIAL,
109 '0', /* Keypad 0 */
110 '1', /* Keypad 1 */
111 '2', /* Keypad 2 */
112 '3', /* Keypad 3 */
113 '4', /* Keypad 4 */
114 '5', /* Keypad 5 */
115 '6', /* Keypad 6 */
116 '7', /* Keypad 7 */
117 U_SPECIAL,
118 '8', /* Keypad 8 */
119 '9', /* Keypad 9 */
120 U_SPECIAL,
121 U_SPECIAL,
122 U_SPECIAL,
123 U_SPECIAL, /* F5 */
124 U_SPECIAL, /* F6 */
125 U_SPECIAL, /* F7 */
126 U_SPECIAL, /* F3 */
127 U_SPECIAL, /* F8 */
128 U_SPECIAL, /* F9 */
129 U_SPECIAL,
130 U_SPECIAL, /* F11 */
131 U_SPECIAL,
132 U_SPECIAL, /* F13 */
133 U_SPECIAL,
134 U_SPECIAL, /* ScrollLock */
135 U_SPECIAL,
136 U_SPECIAL, /* F10 */
137 U_SPECIAL,
138 U_SPECIAL, /* F12 */
139 U_SPECIAL,
140 U_SPECIAL, /* Pause */
141 U_SPECIAL, /* Insert */
142 U_HOME_ARROW, /* Home */
143 U_PAGE_UP, /* Page Up */
144 U_DELETE, /* Delete */
145 U_SPECIAL, /* F4 */
146 U_END_ARROW, /* End */
147 U_SPECIAL, /* F2 */
148 U_PAGE_DOWN, /* Page Down */
149 U_SPECIAL /* F1 */
150};
151
152static void receive_packet(uint8_t *kind, index_t count, uint8_t data[])
153{
154 cuda[B] = cuda[B] & ~TIP;
155 *kind = cuda[SR];
156
157 index_t i;
158 for (i = 0; i < count; i++)
159 data[i] = cuda[SR];
160
161 cuda[B] = cuda[B] | TIP;
162}
163
164static indev_t kbrd;
165static indev_operations_t ops = {
166 .poll = NULL
167};
168
169int cuda_get_scancode(void)
170{
171 if (cuda) {
172 uint8_t kind;
173 uint8_t data[4];
174
175 receive_packet(&kind, 4, data);
176
177 if ((kind == PACKET_ADB) && (data[0] == 0x40) && (data[1] == 0x2c))
178 return data[2];
179 }
180
181 return -1;
182}
183
184static void cuda_irq_handler(irq_t *irq)
185{
186 int scan_code = cuda_get_scancode();
187
188 if (scan_code != -1) {
189 uint8_t scancode = (uint8_t) scan_code;
190 if ((scancode & 0x80) != 0x80)
191 indev_push_character(&kbrd, lchars[scancode & 0x7f]);
192 }
193}
194
195static irq_ownership_t cuda_claim(irq_t *irq)
196{
197 return IRQ_ACCEPT;
198}
199
200void cuda_init(uintptr_t base, size_t size)
201{
202 cuda = (uint8_t *) hw_map(base, size);
203
204 indev_initialize("cuda_kbd", &kbrd, &ops);
205 stdin = &kbrd;
206
207 irq_initialize(&cuda_irq);
208 cuda_irq.devno = device_assign_devno();
209 cuda_irq.inr = CUDA_IRQ;
210 cuda_irq.claim = cuda_claim;
211 cuda_irq.handler = cuda_irq_handler;
212 irq_register(&cuda_irq);
213
214 pic_enable_interrupt(CUDA_IRQ);
215
216 sysinfo_set_item_val("kbd", NULL, true);
217 sysinfo_set_item_val("kbd.inr", NULL, CUDA_IRQ);
218 sysinfo_set_item_val("kbd.address.virtual", NULL, base);
219}
220
221static void send_packet(const uint8_t kind, count_t count, ...)
222{
223 index_t i;
224 va_list va;
225
226 cuda[B] = cuda[B] | TIP;
227 cuda[ACR] = cuda[ACR] | SR_OUT;
228 cuda[SR] = kind;
229 cuda[B] = cuda[B] & ~TIP;
230
231 va_start(va, count);
232
233 for (i = 0; i < count; i++) {
234 cuda[ACR] = cuda[ACR] | SR_OUT;
235 cuda[SR] = va_arg(va, int);
236 cuda[B] = cuda[B] | TACK;
237 }
238
239 va_end(va);
240
241 cuda[B] = cuda[B] | TIP;
242}
243
244void cpu_halt(void) {
245 asm volatile (
246 "b 0\n"
247 );
248}
249
250void arch_reboot(void) {
251 if (cuda)
252 send_packet(PACKET_CUDA, 1, CUDA_RESET);
253
254 asm volatile (
255 "b 0\n"
256 );
257}
258
259/** @}
260 */
Note: See TracBrowser for help on using the repository browser.