Subversion Repositories HelenOS

Rev

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

Rev Author Line No. Line
982 decky 1
/*
2071 jermar 2
 * Copyright (c) 2006 Martin Decky
982 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>
2089 decky 36
#include <ipc/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
 
2307 hudecek 51
#define CUDA_POWERDOWN  0x0a
52
#define CUDA_RESET      0x11
982 decky 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
 
1780 jermar 65
static volatile uint8_t *cuda = NULL;
1928 decky 66
static irq_t cuda_irq;      /**< Cuda's IRQ. */
982 decky 67
 
1619 decky 68
static char lchars[0x80] = {
1633 decky 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 */
1619 decky 192
};
193
 
194
 
1780 jermar 195
static void receive_packet(uint8_t *kind, index_t count, uint8_t data[])
1619 decky 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
 
1606 decky 208
/* Called from getc(). */
209
static void cuda_resume(chardev_t *d)
210
{
211
}
212
 
213
 
214
/* Called from getc(). */
215
static void cuda_suspend(chardev_t *d)
216
{
217
}
218
 
219
 
220
static char key_read(chardev_t *d)
221
{
222
    char ch;
223
 
224
    ch = 0;
225
    return ch;
226
}
227
 
228
 
1628 decky 229
static chardev_t kbrd;
1606 decky 230
static chardev_operations_t ops = {
231
    .suspend = cuda_suspend,
232
    .resume = cuda_resume,
233
    .read = key_read
234
};
235
 
1619 decky 236
 
1633 decky 237
int cuda_get_scancode(void)
1480 palkovsky 238
{
1780 jermar 239
    uint8_t kind;
240
    uint8_t data[4];
1619 decky 241
 
242
    receive_packet(&kind, 4, data);
243
 
1628 decky 244
    if ((kind == PACKET_ADB) && (data[0] == 0x40) && (data[1] == 0x2c))
245
        return data[2];
246
 
1633 decky 247
    return -1;
1480 palkovsky 248
}
982 decky 249
 
1928 decky 250
static void cuda_irq_handler(irq_t *irq, void *arg, ...)
1628 decky 251
{
1934 decky 252
    if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox))
1928 decky 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
        }
1633 decky 262
    }
1628 decky 263
}
264
 
1928 decky 265
static irq_ownership_t cuda_claim(void)
266
{
267
    return IRQ_ACCEPT;
268
}
1628 decky 269
 
1928 decky 270
 
1734 decky 271
/** Initialize keyboard and service interrupts using kernel routine */
272
void cuda_grab(void)
273
{
1944 jermar 274
    ipl_t ipl = interrupts_disable();
275
    spinlock_lock(&cuda_irq.lock);
1932 jermar 276
    cuda_irq.notif_cfg.notify = false;
1944 jermar 277
    spinlock_unlock(&cuda_irq.lock);
278
    interrupts_restore(ipl);
1734 decky 279
}
280
 
281
 
282
/** Resume the former interrupt vector */
283
void cuda_release(void)
284
{
1944 jermar 285
    ipl_t ipl = interrupts_disable();
286
    spinlock_lock(&cuda_irq.lock);
1932 jermar 287
    if (cuda_irq.notif_cfg.answerbox)
288
        cuda_irq.notif_cfg.notify = true;
1944 jermar 289
    spinlock_unlock(&cuda_irq.unlock);
290
    interrupts_restore(ipl);
1734 decky 291
}
292
 
293
 
1928 decky 294
void cuda_init(devno_t devno, uintptr_t base, size_t size)
990 decky 295
{
1928 decky 296
    cuda = (uint8_t *) hw_map(base, size); 
1619 decky 297
 
1606 decky 298
    chardev_initialize("cuda_kbd", &kbrd, &ops);
299
    stdin = &kbrd;
1625 decky 300
 
1928 decky 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);
990 decky 314
}
315
 
316
 
2307 hudecek 317
static void send_packet(const uint8_t kind, count_t count, ...)
1628 decky 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
 
982 decky 341
void cpu_halt(void) {
1269 decky 342
    asm volatile (
343
        "b 0\n"
344
    );
982 decky 345
}
1702 cejka 346
 
2307 hudecek 347
void arch_reboot(void) {
348
    send_packet(PACKET_CUDA, 1, CUDA_RESET);
349
    asm volatile (
350
        "b 0\n"
351
    );
352
}
353
 
1734 decky 354
/** @}
1702 cejka 355
 */