Commit e2733d20b2c8fade7e81aebb34e4e1db821d472f
1 parent
637f6cd7
ADB fixes
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@965 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
210 additions
and
108 deletions
hw/adb.c
| ... | ... | @@ -43,53 +43,53 @@ |
| 43 | 43 | #define ADB_MODEM 5 |
| 44 | 44 | #define ADB_MISC 7 |
| 45 | 45 | |
| 46 | -#define ADB_RET_OK 0 | |
| 47 | -#define ADB_RET_INUSE 1 | |
| 48 | -#define ADB_RET_NOTPRESENT 2 | |
| 49 | -#define ADB_RET_TIMEOUT 3 | |
| 50 | -#define ADB_RET_UNEXPECTED_RESULT 4 | |
| 51 | -#define ADB_RET_REQUEST_ERROR 5 | |
| 52 | -#define ADB_RET_BUS_ERROR 6 | |
| 53 | - | |
| 54 | - | |
| 55 | -static void adb_send_packet1(ADBBusState *s, uint8_t reply) | |
| 56 | -{ | |
| 57 | - adb_send_packet(s, &reply, 1); | |
| 58 | -} | |
| 59 | - | |
| 60 | -void adb_receive_packet(ADBBusState *s, const uint8_t *buf, int len) | |
| 46 | +int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len) | |
| 61 | 47 | { |
| 62 | 48 | ADBDevice *d; |
| 63 | 49 | int devaddr, cmd, i; |
| 64 | - uint8_t obuf[4]; | |
| 65 | 50 | |
| 66 | 51 | cmd = buf[0] & 0xf; |
| 67 | 52 | devaddr = buf[0] >> 4; |
| 68 | 53 | if (buf[1] == ADB_BUSRESET) { |
| 69 | 54 | obuf[0] = 0x00; |
| 70 | 55 | obuf[1] = 0x00; |
| 71 | - adb_send_packet(s, obuf, 2); | |
| 72 | - return; | |
| 56 | + return 2; | |
| 73 | 57 | } |
| 74 | 58 | if (cmd == ADB_FLUSH) { |
| 75 | 59 | obuf[0] = 0x00; |
| 76 | 60 | obuf[1] = 0x00; |
| 77 | - adb_send_packet(s, obuf, 2); | |
| 78 | - return; | |
| 61 | + return 2; | |
| 79 | 62 | } |
| 80 | 63 | |
| 81 | 64 | for(i = 0; i < s->nb_devices; i++) { |
| 82 | 65 | d = &s->devices[i]; |
| 83 | 66 | if (d->devaddr == devaddr) { |
| 84 | - d->receive_packet(d, buf, len); | |
| 85 | - return; | |
| 67 | + return d->devreq(d, obuf, buf, len); | |
| 86 | 68 | } |
| 87 | 69 | } |
| 88 | - adb_send_packet1(s, ADB_RET_NOTPRESENT); | |
| 70 | + return 0; | |
| 71 | +} | |
| 72 | + | |
| 73 | +int adb_poll(ADBBusState *s, uint8_t *obuf) | |
| 74 | +{ | |
| 75 | + ADBDevice *d; | |
| 76 | + int olen, i; | |
| 77 | + | |
| 78 | + olen = 0; | |
| 79 | + for(i = 0; i < s->nb_devices; i++) { | |
| 80 | + if (s->poll_index >= s->nb_devices) | |
| 81 | + s->poll_index = 0; | |
| 82 | + d = &s->devices[s->poll_index]; | |
| 83 | + olen = d->devreq(d, obuf, NULL, 0); | |
| 84 | + s->poll_index++; | |
| 85 | + if (olen) | |
| 86 | + break; | |
| 87 | + } | |
| 88 | + return olen; | |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | 91 | ADBDevice *adb_register_device(ADBBusState *s, int devaddr, |
| 92 | - ADBDeviceReceivePacket *receive_packet, | |
| 92 | + ADBDeviceRequest *devreq, | |
| 93 | 93 | void *opaque) |
| 94 | 94 | { |
| 95 | 95 | ADBDevice *d; |
| ... | ... | @@ -98,7 +98,7 @@ ADBDevice *adb_register_device(ADBBusState *s, int devaddr, |
| 98 | 98 | d = &s->devices[s->nb_devices++]; |
| 99 | 99 | d->bus = s; |
| 100 | 100 | d->devaddr = devaddr; |
| 101 | - d->receive_packet = receive_packet; | |
| 101 | + d->devreq = devreq; | |
| 102 | 102 | d->opaque = opaque; |
| 103 | 103 | return d; |
| 104 | 104 | } |
| ... | ... | @@ -106,80 +106,108 @@ ADBDevice *adb_register_device(ADBBusState *s, int devaddr, |
| 106 | 106 | /***************************************************************/ |
| 107 | 107 | /* Keyboard ADB device */ |
| 108 | 108 | |
| 109 | +typedef struct KBDState { | |
| 110 | + uint8_t data[128]; | |
| 111 | + int rptr, wptr, count; | |
| 112 | +} KBDState; | |
| 113 | + | |
| 109 | 114 | static const uint8_t pc_to_adb_keycode[256] = { |
| 110 | 115 | 0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48, |
| 111 | 116 | 12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54, 0, 1, |
| 112 | 117 | 2, 3, 5, 4, 38, 40, 37, 41, 39, 50, 56, 42, 6, 7, 8, 9, |
| 113 | 118 | 11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96, |
| 114 | 119 | 97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83, |
| 115 | - 84, 85, 82, 65, 0, 0, 10,103,111, 0, 0, 0, 0, 0, 0, 0, | |
| 116 | - 76,125, 75,105,124,110,115, 62,116, 59, 60,119, 61,121,114,117, | |
| 117 | - 0, 0, 0, 0,127, 81, 0,113, 0, 0, 0, 0, 95, 55, 0, 0, | |
| 118 | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 119 | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 120 | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 121 | - 0, 0, 0, 0, 0, 94, 0, 93, 0, 0, 0, 0, 0, 0,104,102, | |
| 122 | - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 120 | + 84, 85, 82, 65, 0, 0, 10,103,111, 0, 0,110, 81, 0, 0, 0, | |
| 123 | 121 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 124 | 122 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 123 | + 0, 0, 0, 94, 0, 93, 0, 0, 0, 0, 0, 0,104,102, 0, 0, | |
| 124 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76,125, 0, 0, | |
| 125 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0, 0, 0, | |
| 126 | + 0, 0, 0, 0, 0, 75, 0, 0,124, 0, 0, 0, 0, 0, 0, 0, | |
| 127 | + 0, 0, 0, 0, 0, 0, 0,115, 62,116, 0, 59, 0, 60, 0,119, | |
| 128 | + 61,121,114,117, 0, 0, 0, 0, 0, 0, 0, 55,126, 0,127, 0, | |
| 125 | 129 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 130 | + 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 126 | 131 | }; |
| 127 | 132 | |
| 128 | 133 | static void adb_kbd_put_keycode(void *opaque, int keycode) |
| 129 | 134 | { |
| 130 | - static int ext_keycode; | |
| 131 | 135 | ADBDevice *d = opaque; |
| 132 | - uint8_t buf[4]; | |
| 133 | - int adb_keycode; | |
| 134 | - | |
| 135 | - if (keycode == 0xe0) { | |
| 136 | - ext_keycode = 1; | |
| 137 | - } else { | |
| 138 | - | |
| 139 | - if (ext_keycode) | |
| 140 | - adb_keycode = pc_to_adb_keycode[keycode | 0x80]; | |
| 141 | - else | |
| 142 | - adb_keycode = pc_to_adb_keycode[keycode & 0x7f]; | |
| 143 | - | |
| 144 | - buf[0] = 0x40; | |
| 145 | - buf[1] = (d->devaddr << 4) | 0x0c; | |
| 146 | - buf[2] = adb_keycode | (keycode & 0x80); | |
| 147 | - buf[3] = 0xff; | |
| 148 | - adb_send_packet(d->bus, buf, 4); | |
| 149 | - ext_keycode = 0; | |
| 136 | + KBDState *s = d->opaque; | |
| 137 | + | |
| 138 | + if (s->count < sizeof(s->data)) { | |
| 139 | + s->data[s->wptr] = keycode; | |
| 140 | + if (++s->wptr == sizeof(s->data)) | |
| 141 | + s->wptr = 0; | |
| 142 | + s->count++; | |
| 150 | 143 | } |
| 151 | 144 | } |
| 152 | 145 | |
| 153 | -static void adb_kbd_receive_packet(ADBDevice *d, const uint8_t *buf, int len) | |
| 146 | +static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf) | |
| 154 | 147 | { |
| 155 | - int cmd, reg; | |
| 156 | - uint8_t obuf[4]; | |
| 148 | + static int ext_keycode; | |
| 149 | + KBDState *s = d->opaque; | |
| 150 | + int adb_keycode, keycode; | |
| 151 | + int olen; | |
| 152 | + | |
| 153 | + olen = 0; | |
| 154 | + for(;;) { | |
| 155 | + if (s->count == 0) | |
| 156 | + break; | |
| 157 | + keycode = s->data[s->rptr]; | |
| 158 | + if (++s->rptr == sizeof(s->data)) | |
| 159 | + s->rptr = 0; | |
| 160 | + s->count--; | |
| 161 | + | |
| 162 | + if (keycode == 0xe0) { | |
| 163 | + ext_keycode = 1; | |
| 164 | + } else { | |
| 165 | + if (ext_keycode) | |
| 166 | + adb_keycode = pc_to_adb_keycode[keycode | 0x80]; | |
| 167 | + else | |
| 168 | + adb_keycode = pc_to_adb_keycode[keycode & 0x7f]; | |
| 169 | + obuf[0] = (d->devaddr << 4) | 0x0c; | |
| 170 | + obuf[1] = adb_keycode | (keycode & 0x80); | |
| 171 | + obuf[2] = 0xff; | |
| 172 | + olen = 3; | |
| 173 | + ext_keycode = 0; | |
| 174 | + break; | |
| 175 | + } | |
| 176 | + } | |
| 177 | + return olen; | |
| 178 | +} | |
| 179 | + | |
| 180 | +static int adb_kbd_request(ADBDevice *d, uint8_t *obuf, | |
| 181 | + const uint8_t *buf, int len) | |
| 182 | +{ | |
| 183 | + int cmd, reg, olen; | |
| 184 | + | |
| 185 | + if (!buf) { | |
| 186 | + return adb_kbd_poll(d, obuf); | |
| 187 | + } | |
| 157 | 188 | |
| 158 | 189 | cmd = buf[0] & 0xc; |
| 159 | 190 | reg = buf[0] & 0x3; |
| 191 | + olen = 0; | |
| 160 | 192 | switch(cmd) { |
| 161 | 193 | case ADB_WRITEREG: |
| 162 | 194 | switch(reg) { |
| 163 | 195 | case 2: |
| 164 | 196 | /* LED status */ |
| 165 | - adb_send_packet1(d->bus, ADB_RET_OK); | |
| 166 | 197 | break; |
| 167 | 198 | case 3: |
| 168 | 199 | switch(buf[2]) { |
| 169 | 200 | case ADB_CMD_SELF_TEST: |
| 170 | - adb_send_packet1(d->bus, ADB_RET_OK); | |
| 171 | 201 | break; |
| 172 | 202 | case ADB_CMD_CHANGE_ID: |
| 173 | 203 | case ADB_CMD_CHANGE_ID_AND_ACT: |
| 174 | 204 | case ADB_CMD_CHANGE_ID_AND_ENABLE: |
| 175 | 205 | d->devaddr = buf[1] & 0xf; |
| 176 | - adb_send_packet1(d->bus, ADB_RET_OK); | |
| 177 | 206 | break; |
| 178 | 207 | default: |
| 179 | 208 | /* XXX: check this */ |
| 180 | 209 | d->devaddr = buf[1] & 0xf; |
| 181 | 210 | d->handler = buf[2]; |
| 182 | - adb_send_packet1(d->bus, ADB_RET_OK); | |
| 183 | 211 | break; |
| 184 | 212 | } |
| 185 | 213 | } |
| ... | ... | @@ -187,98 +215,122 @@ static void adb_kbd_receive_packet(ADBDevice *d, const uint8_t *buf, int len) |
| 187 | 215 | case ADB_READREG: |
| 188 | 216 | switch(reg) { |
| 189 | 217 | case 1: |
| 190 | - adb_send_packet1(d->bus, ADB_RET_OK); | |
| 191 | 218 | break; |
| 192 | 219 | case 2: |
| 193 | - obuf[0] = ADB_RET_OK; | |
| 194 | - obuf[1] = 0x00; /* XXX: check this */ | |
| 195 | - obuf[2] = 0x07; /* led status */ | |
| 196 | - adb_send_packet(d->bus, obuf, 3); | |
| 220 | + obuf[0] = 0x00; /* XXX: check this */ | |
| 221 | + obuf[1] = 0x07; /* led status */ | |
| 222 | + olen = 2; | |
| 197 | 223 | break; |
| 198 | 224 | case 3: |
| 199 | - obuf[0] = ADB_RET_OK; | |
| 200 | - obuf[1] = d->handler; | |
| 201 | - obuf[2] = d->devaddr; | |
| 202 | - adb_send_packet(d->bus, obuf, 3); | |
| 225 | + obuf[0] = d->handler; | |
| 226 | + obuf[1] = d->devaddr; | |
| 227 | + olen = 2; | |
| 203 | 228 | break; |
| 204 | 229 | } |
| 205 | 230 | break; |
| 206 | 231 | } |
| 232 | + return olen; | |
| 207 | 233 | } |
| 208 | 234 | |
| 209 | 235 | void adb_kbd_init(ADBBusState *bus) |
| 210 | 236 | { |
| 211 | 237 | ADBDevice *d; |
| 212 | - | |
| 213 | - d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_receive_packet, NULL); | |
| 238 | + KBDState *s; | |
| 239 | + s = qemu_mallocz(sizeof(KBDState)); | |
| 240 | + d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request, s); | |
| 241 | + d->handler = 1; | |
| 214 | 242 | qemu_add_kbd_event_handler(adb_kbd_put_keycode, d); |
| 215 | 243 | } |
| 216 | 244 | |
| 217 | 245 | /***************************************************************/ |
| 218 | 246 | /* Mouse ADB device */ |
| 219 | 247 | |
| 248 | +typedef struct MouseState { | |
| 249 | + int buttons_state, last_buttons_state; | |
| 250 | + int dx, dy, dz; | |
| 251 | +} MouseState; | |
| 252 | + | |
| 220 | 253 | static void adb_mouse_event(void *opaque, |
| 221 | 254 | int dx1, int dy1, int dz1, int buttons_state) |
| 222 | 255 | { |
| 223 | 256 | ADBDevice *d = opaque; |
| 224 | - uint8_t buf[4]; | |
| 257 | + MouseState *s = d->opaque; | |
| 258 | + | |
| 259 | + s->dx += dx1; | |
| 260 | + s->dy += dy1; | |
| 261 | + s->dz += dz1; | |
| 262 | + s->buttons_state = buttons_state; | |
| 263 | +} | |
| 264 | + | |
| 265 | + | |
| 266 | +static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf) | |
| 267 | +{ | |
| 268 | + MouseState *s = d->opaque; | |
| 225 | 269 | int dx, dy; |
| 226 | 270 | |
| 227 | - dx = dx1; | |
| 271 | + if (s->last_buttons_state == s->buttons_state && | |
| 272 | + s->dx == 0 && s->dy == 0) | |
| 273 | + return 0; | |
| 274 | + | |
| 275 | + dx = s->dx; | |
| 228 | 276 | if (dx < -63) |
| 229 | 277 | dx = -63; |
| 230 | 278 | else if (dx > 63) |
| 231 | 279 | dx = 63; |
| 232 | - | |
| 233 | - dy = dy1; | |
| 280 | + | |
| 281 | + dy = s->dy; | |
| 234 | 282 | if (dy < -63) |
| 235 | 283 | dy = -63; |
| 236 | 284 | else if (dy > 63) |
| 237 | 285 | dy = 63; |
| 238 | - | |
| 286 | + | |
| 287 | + s->dx -= dx; | |
| 288 | + s->dy -= dy; | |
| 289 | + s->last_buttons_state = s->buttons_state; | |
| 290 | + | |
| 239 | 291 | dx &= 0x7f; |
| 240 | 292 | dy &= 0x7f; |
| 241 | - | |
| 242 | - if (buttons_state & MOUSE_EVENT_LBUTTON) | |
| 293 | + | |
| 294 | + if (s->buttons_state & MOUSE_EVENT_LBUTTON) | |
| 243 | 295 | dy |= 0x80; |
| 244 | - if (buttons_state & MOUSE_EVENT_RBUTTON) | |
| 296 | + if (s->buttons_state & MOUSE_EVENT_RBUTTON) | |
| 245 | 297 | dx |= 0x80; |
| 246 | - | |
| 247 | - buf[0] = 0x40; | |
| 248 | - buf[1] = (d->devaddr << 4) | 0x0c; | |
| 249 | - buf[2] = dy; | |
| 250 | - buf[3] = dx; | |
| 251 | - adb_send_packet(d->bus, buf, 4); | |
| 298 | + | |
| 299 | + obuf[0] = (d->devaddr << 4) | 0x0c; | |
| 300 | + obuf[1] = dy; | |
| 301 | + obuf[2] = dx; | |
| 302 | + return 3; | |
| 252 | 303 | } |
| 253 | 304 | |
| 254 | -static void adb_mouse_receive_packet(ADBDevice *d, const uint8_t *buf, int len) | |
| 305 | +static int adb_mouse_request(ADBDevice *d, uint8_t *obuf, | |
| 306 | + const uint8_t *buf, int len) | |
| 255 | 307 | { |
| 256 | - int cmd, reg; | |
| 257 | - uint8_t obuf[4]; | |
| 308 | + int cmd, reg, olen; | |
| 309 | + | |
| 310 | + if (!buf) { | |
| 311 | + return adb_mouse_poll(d, obuf); | |
| 312 | + } | |
| 258 | 313 | |
| 259 | 314 | cmd = buf[0] & 0xc; |
| 260 | 315 | reg = buf[0] & 0x3; |
| 316 | + olen = 0; | |
| 261 | 317 | switch(cmd) { |
| 262 | 318 | case ADB_WRITEREG: |
| 263 | 319 | switch(reg) { |
| 264 | 320 | case 2: |
| 265 | - adb_send_packet1(d->bus, ADB_RET_OK); | |
| 266 | 321 | break; |
| 267 | 322 | case 3: |
| 268 | 323 | switch(buf[2]) { |
| 269 | 324 | case ADB_CMD_SELF_TEST: |
| 270 | - adb_send_packet1(d->bus, ADB_RET_OK); | |
| 271 | 325 | break; |
| 272 | 326 | case ADB_CMD_CHANGE_ID: |
| 273 | 327 | case ADB_CMD_CHANGE_ID_AND_ACT: |
| 274 | 328 | case ADB_CMD_CHANGE_ID_AND_ENABLE: |
| 275 | 329 | d->devaddr = buf[1] & 0xf; |
| 276 | - adb_send_packet1(d->bus, ADB_RET_OK); | |
| 277 | 330 | break; |
| 278 | 331 | default: |
| 279 | 332 | /* XXX: check this */ |
| 280 | 333 | d->devaddr = buf[1] & 0xf; |
| 281 | - adb_send_packet1(d->bus, ADB_RET_OK); | |
| 282 | 334 | break; |
| 283 | 335 | } |
| 284 | 336 | } |
| ... | ... | @@ -286,23 +338,25 @@ static void adb_mouse_receive_packet(ADBDevice *d, const uint8_t *buf, int len) |
| 286 | 338 | case ADB_READREG: |
| 287 | 339 | switch(reg) { |
| 288 | 340 | case 1: |
| 289 | - adb_send_packet1(d->bus, ADB_RET_OK); | |
| 290 | 341 | break; |
| 291 | 342 | case 3: |
| 292 | - obuf[0] = ADB_RET_OK; | |
| 293 | - obuf[1] = d->handler; | |
| 294 | - obuf[2] = d->devaddr; | |
| 295 | - adb_send_packet(d->bus, obuf, 3); | |
| 343 | + obuf[0] = d->handler; | |
| 344 | + obuf[1] = d->devaddr; | |
| 345 | + olen = 2; | |
| 296 | 346 | break; |
| 297 | 347 | } |
| 298 | 348 | break; |
| 299 | 349 | } |
| 350 | + return olen; | |
| 300 | 351 | } |
| 301 | 352 | |
| 302 | 353 | void adb_mouse_init(ADBBusState *bus) |
| 303 | 354 | { |
| 304 | 355 | ADBDevice *d; |
| 356 | + MouseState *s; | |
| 305 | 357 | |
| 306 | - d = adb_register_device(bus, ADB_MOUSE, adb_mouse_receive_packet, NULL); | |
| 358 | + s = qemu_mallocz(sizeof(MouseState)); | |
| 359 | + d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request, s); | |
| 360 | + d->handler = 2; | |
| 307 | 361 | qemu_add_mouse_event_handler(adb_mouse_event, d); |
| 308 | 362 | } | ... | ... |
hw/cuda.c
| ... | ... | @@ -85,6 +85,7 @@ |
| 85 | 85 | #define CUDA_COMBINED_FORMAT_IIC 0x25 |
| 86 | 86 | |
| 87 | 87 | #define CUDA_TIMER_FREQ (4700000 / 6) |
| 88 | +#define CUDA_ADB_POLL_FREQ 50 | |
| 88 | 89 | |
| 89 | 90 | typedef struct CUDATimer { |
| 90 | 91 | unsigned int latch; |
| ... | ... | @@ -121,6 +122,7 @@ typedef struct CUDAState { |
| 121 | 122 | uint8_t autopoll; |
| 122 | 123 | uint8_t data_in[128]; |
| 123 | 124 | uint8_t data_out[16]; |
| 125 | + QEMUTimer *adb_poll_timer; | |
| 124 | 126 | } CUDAState; |
| 125 | 127 | |
| 126 | 128 | static CUDAState cuda_state; |
| ... | ... | @@ -469,15 +471,42 @@ void adb_send_packet(ADBBusState *bus, const uint8_t *buf, int len) |
| 469 | 471 | cuda_send_packet_to_host(s, data, len + 1); |
| 470 | 472 | } |
| 471 | 473 | |
| 474 | +void cuda_adb_poll(void *opaque) | |
| 475 | +{ | |
| 476 | + CUDAState *s = opaque; | |
| 477 | + uint8_t obuf[ADB_MAX_OUT_LEN + 2]; | |
| 478 | + int olen; | |
| 479 | + | |
| 480 | + olen = adb_poll(&adb_bus, obuf + 2); | |
| 481 | + if (olen > 0) { | |
| 482 | + obuf[0] = ADB_PACKET; | |
| 483 | + obuf[1] = 0x40; /* polled data */ | |
| 484 | + cuda_send_packet_to_host(s, obuf, olen + 2); | |
| 485 | + } | |
| 486 | + qemu_mod_timer(s->adb_poll_timer, | |
| 487 | + qemu_get_clock(vm_clock) + | |
| 488 | + (ticks_per_sec / CUDA_ADB_POLL_FREQ)); | |
| 489 | +} | |
| 490 | + | |
| 472 | 491 | static void cuda_receive_packet(CUDAState *s, |
| 473 | 492 | const uint8_t *data, int len) |
| 474 | 493 | { |
| 475 | 494 | uint8_t obuf[16]; |
| 476 | - int ti; | |
| 495 | + int ti, autopoll; | |
| 477 | 496 | |
| 478 | 497 | switch(data[0]) { |
| 479 | 498 | case CUDA_AUTOPOLL: |
| 480 | - s->autopoll = data[1]; | |
| 499 | + autopoll = (data[1] != 0); | |
| 500 | + if (autopoll != s->autopoll) { | |
| 501 | + s->autopoll = autopoll; | |
| 502 | + if (autopoll) { | |
| 503 | + qemu_mod_timer(s->adb_poll_timer, | |
| 504 | + qemu_get_clock(vm_clock) + | |
| 505 | + (ticks_per_sec / CUDA_ADB_POLL_FREQ)); | |
| 506 | + } else { | |
| 507 | + qemu_del_timer(s->adb_poll_timer); | |
| 508 | + } | |
| 509 | + } | |
| 481 | 510 | obuf[0] = CUDA_PACKET; |
| 482 | 511 | obuf[1] = data[1]; |
| 483 | 512 | cuda_send_packet_to_host(s, obuf, 2); |
| ... | ... | @@ -522,7 +551,20 @@ static void cuda_receive_packet_from_host(CUDAState *s, |
| 522 | 551 | #endif |
| 523 | 552 | switch(data[0]) { |
| 524 | 553 | case ADB_PACKET: |
| 525 | - adb_receive_packet(&adb_bus, data + 1, len - 1); | |
| 554 | + { | |
| 555 | + uint8_t obuf[ADB_MAX_OUT_LEN + 2]; | |
| 556 | + int olen; | |
| 557 | + olen = adb_request(&adb_bus, obuf + 2, data + 1, len - 1); | |
| 558 | + if (olen != 0) { | |
| 559 | + obuf[0] = ADB_PACKET; | |
| 560 | + obuf[1] = 0x00; | |
| 561 | + } else { | |
| 562 | + /* empty reply */ | |
| 563 | + obuf[0] = ADB_PACKET; | |
| 564 | + obuf[1] = 0x02; | |
| 565 | + } | |
| 566 | + cuda_send_packet_to_host(s, obuf, olen + 2); | |
| 567 | + } | |
| 526 | 568 | break; |
| 527 | 569 | case CUDA_PACKET: |
| 528 | 570 | cuda_receive_packet(s, data + 1, len - 1); |
| ... | ... | @@ -574,6 +616,8 @@ int cuda_init(openpic_t *openpic, int irq) |
| 574 | 616 | s->timers[1].latch = 0x10000; |
| 575 | 617 | s->ier = T1_INT | SR_INT; |
| 576 | 618 | set_counter(s, &s->timers[1], 0xffff); |
| 619 | + | |
| 620 | + s->adb_poll_timer = qemu_new_timer(vm_clock, cuda_adb_poll, s); | |
| 577 | 621 | cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s); |
| 578 | 622 | return cuda_mem_index; |
| 579 | 623 | } | ... | ... |
vl.h
| ... | ... | @@ -528,8 +528,7 @@ PCIBus *pci_pmac_init(void); |
| 528 | 528 | /* openpic.c */ |
| 529 | 529 | typedef struct openpic_t openpic_t; |
| 530 | 530 | void openpic_set_irq (openpic_t *opp, int n_IRQ, int level); |
| 531 | -openpic_t *openpic_init (PCIBus *bus, | |
| 532 | - uint32_t isu_base, uint32_t idu_base, int nb_cpus); | |
| 531 | +openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus); | |
| 533 | 532 | |
| 534 | 533 | /* vga.c */ |
| 535 | 534 | |
| ... | ... | @@ -727,28 +726,33 @@ int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, |
| 727 | 726 | |
| 728 | 727 | #define MAX_ADB_DEVICES 16 |
| 729 | 728 | |
| 730 | -typedef struct ADBDevice ADBDevice; | |
| 729 | +#define ADB_MAX_OUT_LEN 16 | |
| 731 | 730 | |
| 732 | -typedef void ADBDeviceReceivePacket(ADBDevice *d, const uint8_t *buf, int len); | |
| 731 | +typedef struct ADBDevice ADBDevice; | |
| 733 | 732 | |
| 733 | +/* buf = NULL means polling */ | |
| 734 | +typedef int ADBDeviceRequest(ADBDevice *d, uint8_t *buf_out, | |
| 735 | + const uint8_t *buf, int len); | |
| 734 | 736 | struct ADBDevice { |
| 735 | 737 | struct ADBBusState *bus; |
| 736 | 738 | int devaddr; |
| 737 | 739 | int handler; |
| 738 | - ADBDeviceReceivePacket *receive_packet; | |
| 740 | + ADBDeviceRequest *devreq; | |
| 739 | 741 | void *opaque; |
| 740 | 742 | }; |
| 741 | 743 | |
| 742 | 744 | typedef struct ADBBusState { |
| 743 | 745 | ADBDevice devices[MAX_ADB_DEVICES]; |
| 744 | 746 | int nb_devices; |
| 747 | + int poll_index; | |
| 745 | 748 | } ADBBusState; |
| 746 | 749 | |
| 747 | -void adb_receive_packet(ADBBusState *s, const uint8_t *buf, int len); | |
| 748 | -void adb_send_packet(ADBBusState *s, const uint8_t *buf, int len); | |
| 750 | +int adb_request(ADBBusState *s, uint8_t *buf_out, | |
| 751 | + const uint8_t *buf, int len); | |
| 752 | +int adb_poll(ADBBusState *s, uint8_t *buf_out); | |
| 749 | 753 | |
| 750 | 754 | ADBDevice *adb_register_device(ADBBusState *s, int devaddr, |
| 751 | - ADBDeviceReceivePacket *receive_packet, | |
| 755 | + ADBDeviceRequest *devreq, | |
| 752 | 756 | void *opaque); |
| 753 | 757 | void adb_kbd_init(ADBBusState *bus); |
| 754 | 758 | void adb_mouse_init(ADBBusState *bus); | ... | ... |