Subversion Repositories HelenOS

Rev

Rev 4153 | 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
 
4153 mejdrech 29
/** @addtogroup ppc32
1702 cejka 30
 * @{
31
 */
32
/** @file
33
 */
34
 
982 decky 35
#include <arch/drivers/cuda.h>
36
#include <arch/asm.h>
987 decky 37
#include <console/console.h>
1628 decky 38
#include <console/chardev.h>
1480 palkovsky 39
#include <arch/drivers/pic.h>
1625 decky 40
#include <sysinfo/sysinfo.h>
1480 palkovsky 41
#include <interrupt.h>
1619 decky 42
#include <stdarg.h>
4153 mejdrech 43
#include <ddi/device.h>
4263 mejdrech 44
#include <string.h>
982 decky 45
 
1928 decky 46
#define CUDA_IRQ 10
1633 decky 47
 
4263 mejdrech 48
#define PACKET_ADB   0x00
49
#define PACKET_CUDA  0x01
1619 decky 50
 
4263 mejdrech 51
#define CUDA_POWERDOWN  0x0a
52
#define CUDA_RESET      0x11
982 decky 53
 
4263 mejdrech 54
#define RS   0x200
55
#define B    (0 * RS)
56
#define A    (1 * RS)
57
#define SR   (10 * RS)
58
#define ACR  (11 * RS)
982 decky 59
 
4263 mejdrech 60
#define SR_OUT  0x10
61
#define TACK    0x10
62
#define TIP     0x20
982 decky 63
 
4263 mejdrech 64
#define SCANCODES  128
982 decky 65
 
1780 jermar 66
static volatile uint8_t *cuda = NULL;
4263 mejdrech 67
static irq_t cuda_irq;                 /**< Cuda's IRQ. */
982 decky 68
 
4263 mejdrech 69
static 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 */
1619 decky 150
};
151
 
1780 jermar 152
static void receive_packet(uint8_t *kind, index_t count, uint8_t data[])
1619 decky 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
 
4153 mejdrech 164
static indev_t kbrd;
165
static indev_operations_t ops = {
166
    .poll = NULL
1606 decky 167
};
168
 
1633 decky 169
int cuda_get_scancode(void)
1480 palkovsky 170
{
4153 mejdrech 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
    }
1619 decky 180
 
1633 decky 181
    return -1;
1480 palkovsky 182
}
982 decky 183
 
4153 mejdrech 184
static void cuda_irq_handler(irq_t *irq)
1628 decky 185
{
4153 mejdrech 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]);
1633 decky 192
    }
1628 decky 193
}
194
 
4153 mejdrech 195
static irq_ownership_t cuda_claim(irq_t *irq)
1928 decky 196
{
197
    return IRQ_ACCEPT;
198
}
1628 decky 199
 
4153 mejdrech 200
void cuda_init(uintptr_t base, size_t size)
1734 decky 201
{
4153 mejdrech 202
    cuda = (uint8_t *) hw_map(base, size);
1619 decky 203
 
4153 mejdrech 204
    indev_initialize("cuda_kbd", &kbrd, &ops);
1606 decky 205
    stdin = &kbrd;
1625 decky 206
 
1928 decky 207
    irq_initialize(&cuda_irq);
4153 mejdrech 208
    cuda_irq.devno = device_assign_devno();
1928 decky 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);
4153 mejdrech 215
 
1928 decky 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);
990 decky 219
}
220
 
2227 decky 221
static void send_packet(const uint8_t kind, count_t count, ...)
1628 decky 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
 
982 decky 244
void cpu_halt(void) {
1269 decky 245
    asm volatile (
246
        "b 0\n"
247
    );
982 decky 248
}
1702 cejka 249
 
2227 decky 250
void arch_reboot(void) {
4153 mejdrech 251
    if (cuda)
252
        send_packet(PACKET_CUDA, 1, CUDA_RESET);
253
 
2227 decky 254
    asm volatile (
255
        "b 0\n"
256
    );
257
}
258
 
1734 decky 259
/** @}
1702 cejka 260
 */