Subversion Repositories HelenOS

Rev

Rev 1787 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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