Subversion Repositories HelenOS

Rev

Rev 1932 | 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
 
1619 decky 67
static char lchars[0x80] = {
1633 decky 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 */
1619 decky 191
};
192
 
193
 
1780 jermar 194
void send_packet(const uint8_t kind, index_t count, ...);
1619 decky 195
 
196
 
1780 jermar 197
static void receive_packet(uint8_t *kind, index_t count, uint8_t data[])
1619 decky 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
 
1606 decky 210
/* Called from getc(). */
211
static void cuda_resume(chardev_t *d)
212
{
213
}
214
 
215
 
216
/* Called from getc(). */
217
static void cuda_suspend(chardev_t *d)
218
{
219
}
220
 
221
 
222
static char key_read(chardev_t *d)
223
{
224
    char ch;
225
 
226
    ch = 0;
227
    return ch;
228
}
229
 
230
 
1628 decky 231
static chardev_t kbrd;
1606 decky 232
static chardev_operations_t ops = {
233
    .suspend = cuda_suspend,
234
    .resume = cuda_resume,
235
    .read = key_read
236
};
237
 
1619 decky 238
 
1633 decky 239
int cuda_get_scancode(void)
1480 palkovsky 240
{
1780 jermar 241
    uint8_t kind;
242
    uint8_t data[4];
1619 decky 243
 
244
    receive_packet(&kind, 4, data);
245
 
1628 decky 246
    if ((kind == PACKET_ADB) && (data[0] == 0x40) && (data[1] == 0x2c))
247
        return data[2];
248
 
1633 decky 249
    return -1;
1480 palkovsky 250
}
982 decky 251
 
1928 decky 252
static void cuda_irq_handler(irq_t *irq, void *arg, ...)
1628 decky 253
{
1934 decky 254
    if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox))
1928 decky 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
        }
1633 decky 264
    }
1628 decky 265
}
266
 
1928 decky 267
static irq_ownership_t cuda_claim(void)
268
{
269
    return IRQ_ACCEPT;
270
}
1628 decky 271
 
1928 decky 272
 
1734 decky 273
/** Initialize keyboard and service interrupts using kernel routine */
274
void cuda_grab(void)
275
{
1932 jermar 276
    cuda_irq.notif_cfg.notify = false;
1734 decky 277
}
278
 
279
 
280
/** Resume the former interrupt vector */
281
void cuda_release(void)
282
{
1932 jermar 283
    if (cuda_irq.notif_cfg.answerbox)
284
        cuda_irq.notif_cfg.notify = true;
1734 decky 285
}
286
 
287
 
1928 decky 288
void cuda_init(devno_t devno, uintptr_t base, size_t size)
990 decky 289
{
1928 decky 290
    cuda = (uint8_t *) hw_map(base, size); 
1619 decky 291
 
1606 decky 292
    chardev_initialize("cuda_kbd", &kbrd, &ops);
293
    stdin = &kbrd;
1625 decky 294
 
1928 decky 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);
990 decky 308
}
309
 
310
 
1780 jermar 311
void send_packet(const uint8_t kind, index_t count, ...)
1628 decky 312
{
313
    index_t i;
314
    va_list va;
315
 
316
    cuda[B] = cuda[B] | TIP;
317
    cuda[ACR] = cuda[ACR] | SR_OUT;
318
    cuda[SR] = kind;
319
    cuda[B] = cuda[B] & ~TIP;
320
 
321
    va_start(va, count);
322
 
323
    for (i = 0; i < count; i++) {
324
        cuda[ACR] = cuda[ACR] | SR_OUT;
325
        cuda[SR] = va_arg(va, int);
326
        cuda[B] = cuda[B] | TACK;
327
    }
328
 
329
    va_end(va);
330
 
331
    cuda[B] = cuda[B] | TIP;
332
}
333
 
334
 
982 decky 335
void cpu_halt(void) {
1004 decky 336
#ifdef CONFIG_POWEROFF
1619 decky 337
    send_packet(PACKET_CUDA, 1, CUDA_POWERDOWN);
338
#endif
1269 decky 339
    asm volatile (
340
        "b 0\n"
341
    );
982 decky 342
}
1702 cejka 343
 
1734 decky 344
/** @}
1702 cejka 345
 */