1
2
/*
* QEMU ADB support
ths
authored
18 years ago
3
*
4
* Copyright ( c ) 2004 Fabrice Bellard
ths
authored
18 years ago
5
*
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the "Software" ), to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED "AS IS" , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE .
*/
24
25
26
# include "hw.h"
# include "ppc_mac.h"
# include "console.h"
27
28
29
30
31
32
33
34
35
36
37
/* debug ADB */
// # define DEBUG_ADB
# ifdef DEBUG_ADB
# define ADB_DPRINTF ( fmt , args ...) \
do { printf ( "ADB: " fmt , ## args ); } while ( 0 )
# else
# define ADB_DPRINTF ( fmt , args ...)
# endif
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/* ADB commands */
# define ADB_BUSRESET 0x00
# define ADB_FLUSH 0x01
# define ADB_WRITEREG 0x08
# define ADB_READREG 0x0c
/* ADB device commands */
# define ADB_CMD_SELF_TEST 0xff
# define ADB_CMD_CHANGE_ID 0xfe
# define ADB_CMD_CHANGE_ID_AND_ACT 0xfd
# define ADB_CMD_CHANGE_ID_AND_ENABLE 0x00
/* ADB default device IDs (upper 4 bits of ADB command byte) */
# define ADB_DONGLE 1
# define ADB_KEYBOARD 2
# define ADB_MOUSE 3
# define ADB_TABLET 4
# define ADB_MODEM 5
# define ADB_MISC 7
58
59
60
/* error codes */
# define ADB_RET_NOTPRESENT ( - 2 )
61
int adb_request ( ADBBusState * s , uint8_t * obuf , const uint8_t * buf , int len )
62
63
64
65
{
ADBDevice * d ;
int devaddr , cmd , i ;
66
cmd = buf [ 0 ] & 0xf ;
67
68
69
70
71
72
73
74
if ( cmd == ADB_BUSRESET ) {
for ( i = 0 ; i < s -> nb_devices ; i ++ ) {
d = & s -> devices [ i ];
if ( d -> devreset ) {
d -> devreset ( d );
}
}
return 0 ;
75
}
76
devaddr = buf [ 0 ] >> 4 ;
77
78
79
for ( i = 0 ; i < s -> nb_devices ; i ++ ) {
d = & s -> devices [ i ];
if ( d -> devaddr == devaddr ) {
80
return d -> devreq ( d , obuf , buf , len );
81
82
}
}
83
return ADB_RET_NOTPRESENT ;
84
85
}
86
/* XXX: move that to cuda ? */
87
88
89
90
int adb_poll ( ADBBusState * s , uint8_t * obuf )
{
ADBDevice * d ;
int olen , i ;
91
uint8_t buf [ 1 ];
92
93
94
95
96
97
olen = 0 ;
for ( i = 0 ; i < s -> nb_devices ; i ++ ) {
if ( s -> poll_index >= s -> nb_devices )
s -> poll_index = 0 ;
d = & s -> devices [ s -> poll_index ];
98
99
100
101
102
103
buf [ 0 ] = ADB_READREG | ( d -> devaddr << 4 );
olen = adb_request ( s , obuf + 1 , buf , 1 );
/* if there is data, we poll again the same device */
if ( olen > 0 ) {
obuf [ 0 ] = buf [ 0 ];
olen ++ ;
104
break ;
105
106
}
s -> poll_index ++ ;
107
108
}
return olen ;
109
110
}
ths
authored
18 years ago
111
112
113
ADBDevice * adb_register_device ( ADBBusState * s , int devaddr ,
ADBDeviceRequest * devreq ,
ADBDeviceReset * devreset ,
114
115
116
117
118
119
120
121
void * opaque )
{
ADBDevice * d ;
if ( s -> nb_devices >= MAX_ADB_DEVICES )
return NULL ;
d = & s -> devices [ s -> nb_devices ++ ];
d -> bus = s ;
d -> devaddr = devaddr ;
122
d -> devreq = devreq ;
123
d -> devreset = devreset ;
124
d -> opaque = opaque ;
125
qemu_register_reset (( QEMUResetHandler * ) devreset , d );
126
d -> devreset ( d );
127
128
129
130
131
132
return d ;
}
/***************************************************************/
/* Keyboard ADB device */
133
134
135
136
137
typedef struct KBDState {
uint8_t data [ 128 ];
int rptr , wptr , count ;
} KBDState ;
138
139
140
141
142
143
static const uint8_t pc_to_adb_keycode [ 256 ] = {
0 , 53 , 18 , 19 , 20 , 21 , 23 , 22 , 26 , 28 , 25 , 29 , 27 , 24 , 51 , 48 ,
12 , 13 , 14 , 15 , 17 , 16 , 32 , 34 , 31 , 35 , 33 , 30 , 36 , 54 , 0 , 1 ,
2 , 3 , 5 , 4 , 38 , 40 , 37 , 41 , 39 , 50 , 56 , 42 , 6 , 7 , 8 , 9 ,
11 , 45 , 46 , 43 , 47 , 44 , 123 , 67 , 58 , 49 , 57 , 122 , 120 , 99 , 118 , 96 ,
97 , 98 , 100 , 101 , 109 , 71 , 107 , 89 , 91 , 92 , 78 , 86 , 87 , 88 , 69 , 83 ,
144
84 , 85 , 82 , 65 , 0 , 0 , 10 , 103 , 111 , 0 , 0 , 110 , 81 , 0 , 0 , 0 ,
145
146
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
147
148
149
150
151
152
0 , 0 , 0 , 94 , 0 , 93 , 0 , 0 , 0 , 0 , 0 , 0 , 104 , 102 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 76 , 125 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 105 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 75 , 0 , 0 , 124 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 115 , 62 , 116 , 0 , 59 , 0 , 60 , 0 , 119 ,
61 , 121 , 114 , 117 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 55 , 126 , 0 , 127 , 0 ,
153
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
154
0 , 0 , 0 , 0 , 0 , 95 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
155
156
157
158
159
};
static void adb_kbd_put_keycode ( void * opaque , int keycode )
{
ADBDevice * d = opaque ;
160
161
162
163
164
165
166
KBDState * s = d -> opaque ;
if ( s -> count < sizeof ( s -> data )) {
s -> data [ s -> wptr ] = keycode ;
if ( ++ s -> wptr == sizeof ( s -> data ))
s -> wptr = 0 ;
s -> count ++ ;
167
168
169
}
}
170
static int adb_kbd_poll ( ADBDevice * d , uint8_t * obuf )
171
{
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
static int ext_keycode ;
KBDState * s = d -> opaque ;
int adb_keycode , keycode ;
int olen ;
olen = 0 ;
for (;;) {
if ( s -> count == 0 )
break ;
keycode = s -> data [ s -> rptr ];
if ( ++ s -> rptr == sizeof ( s -> data ))
s -> rptr = 0 ;
s -> count -- ;
if ( keycode == 0xe0 ) {
ext_keycode = 1 ;
} else {
if ( ext_keycode )
adb_keycode = pc_to_adb_keycode [ keycode | 0x80 ];
else
adb_keycode = pc_to_adb_keycode [ keycode & 0x7f ];
193
194
195
196
obuf [ 0 ] = adb_keycode | ( keycode & 0x80 );
/* NOTE: could put a second keycode if needed */
obuf [ 1 ] = 0xff ;
olen = 2 ;
197
198
199
200
201
202
203
204
205
206
ext_keycode = 0 ;
break ;
}
}
return olen ;
}
static int adb_kbd_request ( ADBDevice * d , uint8_t * obuf ,
const uint8_t * buf , int len )
{
207
KBDState * s = d -> opaque ;
208
209
int cmd , reg , olen ;
210
211
212
213
if (( buf [ 0 ] & 0x0f ) == ADB_FLUSH ) {
/* flush keyboard fifo */
s -> wptr = s -> rptr = s -> count = 0 ;
return 0 ;
214
}
215
216
217
cmd = buf [ 0 ] & 0xc ;
reg = buf [ 0 ] & 0x3 ;
218
olen = 0 ;
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
switch ( cmd ) {
case ADB_WRITEREG :
switch ( reg ) {
case 2 :
/* LED status */
break ;
case 3 :
switch ( buf [ 2 ]) {
case ADB_CMD_SELF_TEST :
break ;
case ADB_CMD_CHANGE_ID :
case ADB_CMD_CHANGE_ID_AND_ACT :
case ADB_CMD_CHANGE_ID_AND_ENABLE :
d -> devaddr = buf [ 1 ] & 0xf ;
break ;
default :
/* XXX: check this */
d -> devaddr = buf [ 1 ] & 0xf ;
d -> handler = buf [ 2 ];
break ;
}
}
break ;
case ADB_READREG :
switch ( reg ) {
244
245
246
case 0 :
olen = adb_kbd_poll ( d , obuf );
break ;
247
248
249
case 1 :
break ;
case 2 :
250
251
252
obuf [ 0 ] = 0x00 ; /* XXX: check this */
obuf [ 1 ] = 0x07 ; /* led status */
olen = 2 ;
253
254
break ;
case 3 :
255
256
257
obuf [ 0 ] = d -> handler ;
obuf [ 1 ] = d -> devaddr ;
olen = 2 ;
258
259
260
261
break ;
}
break ;
}
262
return olen ;
263
264
}
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
static void adb_kbd_save ( QEMUFile * f , void * opaque )
{
KBDState * s = ( KBDState * ) opaque ;
qemu_put_buffer ( f , s -> data , sizeof ( s -> data ));
qemu_put_sbe32s ( f , & s -> rptr );
qemu_put_sbe32s ( f , & s -> wptr );
qemu_put_sbe32s ( f , & s -> count );
}
static int adb_kbd_load ( QEMUFile * f , void * opaque , int version_id )
{
KBDState * s = ( KBDState * ) opaque ;
if ( version_id != 1 )
return - EINVAL ;
qemu_get_buffer ( f , s -> data , sizeof ( s -> data ));
qemu_get_sbe32s ( f , & s -> rptr );
qemu_get_sbe32s ( f , & s -> wptr );
qemu_get_sbe32s ( f , & s -> count );
return 0 ;
}
290
291
292
293
294
295
296
297
298
299
300
static int adb_kbd_reset ( ADBDevice * d )
{
KBDState * s = d -> opaque ;
d -> handler = 1 ;
d -> devaddr = ADB_KEYBOARD ;
memset ( s , 0 , sizeof ( KBDState ));
return 0 ;
}
301
302
303
void adb_kbd_init ( ADBBusState * bus )
{
ADBDevice * d ;
304
305
KBDState * s ;
s = qemu_mallocz ( sizeof ( KBDState ));
306
307
d = adb_register_device ( bus , ADB_KEYBOARD , adb_kbd_request ,
adb_kbd_reset , s );
308
qemu_add_kbd_event_handler ( adb_kbd_put_keycode , d );
309
310
register_savevm ( "adb_kbd" , - 1 , 1 , adb_kbd_save ,
adb_kbd_load , s );
311
312
313
314
315
}
/***************************************************************/
/* Mouse ADB device */
316
317
318
319
320
typedef struct MouseState {
int buttons_state , last_buttons_state ;
int dx , dy , dz ;
} MouseState ;
321
322
323
324
static void adb_mouse_event ( void * opaque ,
int dx1 , int dy1 , int dz1 , int buttons_state )
{
ADBDevice * d = opaque ;
325
326
327
328
329
330
331
332
333
334
335
336
MouseState * s = d -> opaque ;
s -> dx += dx1 ;
s -> dy += dy1 ;
s -> dz += dz1 ;
s -> buttons_state = buttons_state ;
}
static int adb_mouse_poll ( ADBDevice * d , uint8_t * obuf )
{
MouseState * s = d -> opaque ;
337
338
int dx , dy ;
339
340
341
if ( s -> last_buttons_state == s -> buttons_state &&
s -> dx == 0 && s -> dy == 0 )
return 0 ;
ths
authored
18 years ago
342
343
dx = s -> dx ;
344
345
346
347
if ( dx < - 63 )
dx = - 63 ;
else if ( dx > 63 )
dx = 63 ;
ths
authored
18 years ago
348
349
dy = s -> dy ;
350
351
352
353
if ( dy < - 63 )
dy = - 63 ;
else if ( dy > 63 )
dy = 63 ;
ths
authored
18 years ago
354
355
356
357
s -> dx -= dx ;
s -> dy -= dy ;
s -> last_buttons_state = s -> buttons_state ;
ths
authored
18 years ago
358
359
360
dx &= 0x7f ;
dy &= 0x7f ;
ths
authored
18 years ago
361
362
if ( ! ( s -> buttons_state & MOUSE_EVENT_LBUTTON ))
363
dy |= 0x80 ;
364
if ( ! ( s -> buttons_state & MOUSE_EVENT_RBUTTON ))
365
dx |= 0x80 ;
ths
authored
18 years ago
366
367
368
369
obuf [ 0 ] = dy ;
obuf [ 1 ] = dx ;
return 2 ;
370
371
}
372
373
static int adb_mouse_request ( ADBDevice * d , uint8_t * obuf ,
const uint8_t * buf , int len )
374
{
375
MouseState * s = d -> opaque ;
376
int cmd , reg , olen ;
ths
authored
18 years ago
377
378
379
380
381
382
383
384
if (( buf [ 0 ] & 0x0f ) == ADB_FLUSH ) {
/* flush mouse fifo */
s -> buttons_state = s -> last_buttons_state ;
s -> dx = 0 ;
s -> dy = 0 ;
s -> dz = 0 ;
return 0 ;
385
}
386
387
388
cmd = buf [ 0 ] & 0xc ;
reg = buf [ 0 ] & 0x3 ;
389
olen = 0 ;
390
391
switch ( cmd ) {
case ADB_WRITEREG :
392
ADB_DPRINTF ( "write reg %d val 0x%2.2x \n " , reg , buf [ 1 ]);
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
switch ( reg ) {
case 2 :
break ;
case 3 :
switch ( buf [ 2 ]) {
case ADB_CMD_SELF_TEST :
break ;
case ADB_CMD_CHANGE_ID :
case ADB_CMD_CHANGE_ID_AND_ACT :
case ADB_CMD_CHANGE_ID_AND_ENABLE :
d -> devaddr = buf [ 1 ] & 0xf ;
break ;
default :
/* XXX: check this */
d -> devaddr = buf [ 1 ] & 0xf ;
break ;
}
}
break ;
case ADB_READREG :
switch ( reg ) {
414
415
416
case 0 :
olen = adb_mouse_poll ( d , obuf );
break ;
417
418
419
case 1 :
break ;
case 3 :
420
421
422
obuf [ 0 ] = d -> handler ;
obuf [ 1 ] = d -> devaddr ;
olen = 2 ;
423
424
break ;
}
425
426
ADB_DPRINTF ( "read reg %d obuf[0] 0x%2.2x obuf[1] 0x%2.2x \n " , reg ,
obuf [ 0 ], obuf [ 1 ]);
427
428
break ;
}
429
return olen ;
430
431
}
432
433
434
435
436
437
438
439
440
441
442
static int adb_mouse_reset ( ADBDevice * d )
{
MouseState * s = d -> opaque ;
d -> handler = 2 ;
d -> devaddr = ADB_MOUSE ;
memset ( s , 0 , sizeof ( MouseState ));
return 0 ;
}
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
static void adb_mouse_save ( QEMUFile * f , void * opaque )
{
MouseState * s = ( MouseState * ) opaque ;
qemu_put_sbe32s ( f , & s -> buttons_state );
qemu_put_sbe32s ( f , & s -> last_buttons_state );
qemu_put_sbe32s ( f , & s -> dx );
qemu_put_sbe32s ( f , & s -> dy );
qemu_put_sbe32s ( f , & s -> dz );
}
static int adb_mouse_load ( QEMUFile * f , void * opaque , int version_id )
{
MouseState * s = ( MouseState * ) opaque ;
if ( version_id != 1 )
return - EINVAL ;
qemu_get_sbe32s ( f , & s -> buttons_state );
qemu_get_sbe32s ( f , & s -> last_buttons_state );
qemu_get_sbe32s ( f , & s -> dx );
qemu_get_sbe32s ( f , & s -> dy );
qemu_get_sbe32s ( f , & s -> dz );
return 0 ;
}
470
471
472
void adb_mouse_init ( ADBBusState * bus )
{
ADBDevice * d ;
473
MouseState * s ;
474
475
s = qemu_mallocz ( sizeof ( MouseState ));
476
477
d = adb_register_device ( bus , ADB_MOUSE , adb_mouse_request ,
adb_mouse_reset , s );
ths
authored
18 years ago
478
qemu_add_mouse_event_handler ( adb_mouse_event , d , 0 , "QEMU ADB Mouse" );
479
480
register_savevm ( "adb_mouse" , - 1 , 1 , adb_mouse_save ,
adb_mouse_load , s );
481
}