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,53 +43,53 @@ | ||
| 43 | #define ADB_MODEM 5 | 43 | #define ADB_MODEM 5 |
| 44 | #define ADB_MISC 7 | 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 | ADBDevice *d; | 48 | ADBDevice *d; |
| 63 | int devaddr, cmd, i; | 49 | int devaddr, cmd, i; |
| 64 | - uint8_t obuf[4]; | ||
| 65 | 50 | ||
| 66 | cmd = buf[0] & 0xf; | 51 | cmd = buf[0] & 0xf; |
| 67 | devaddr = buf[0] >> 4; | 52 | devaddr = buf[0] >> 4; |
| 68 | if (buf[1] == ADB_BUSRESET) { | 53 | if (buf[1] == ADB_BUSRESET) { |
| 69 | obuf[0] = 0x00; | 54 | obuf[0] = 0x00; |
| 70 | obuf[1] = 0x00; | 55 | obuf[1] = 0x00; |
| 71 | - adb_send_packet(s, obuf, 2); | ||
| 72 | - return; | 56 | + return 2; |
| 73 | } | 57 | } |
| 74 | if (cmd == ADB_FLUSH) { | 58 | if (cmd == ADB_FLUSH) { |
| 75 | obuf[0] = 0x00; | 59 | obuf[0] = 0x00; |
| 76 | obuf[1] = 0x00; | 60 | obuf[1] = 0x00; |
| 77 | - adb_send_packet(s, obuf, 2); | ||
| 78 | - return; | 61 | + return 2; |
| 79 | } | 62 | } |
| 80 | 63 | ||
| 81 | for(i = 0; i < s->nb_devices; i++) { | 64 | for(i = 0; i < s->nb_devices; i++) { |
| 82 | d = &s->devices[i]; | 65 | d = &s->devices[i]; |
| 83 | if (d->devaddr == devaddr) { | 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 | ADBDevice *adb_register_device(ADBBusState *s, int devaddr, | 91 | ADBDevice *adb_register_device(ADBBusState *s, int devaddr, |
| 92 | - ADBDeviceReceivePacket *receive_packet, | 92 | + ADBDeviceRequest *devreq, |
| 93 | void *opaque) | 93 | void *opaque) |
| 94 | { | 94 | { |
| 95 | ADBDevice *d; | 95 | ADBDevice *d; |
| @@ -98,7 +98,7 @@ ADBDevice *adb_register_device(ADBBusState *s, int devaddr, | @@ -98,7 +98,7 @@ ADBDevice *adb_register_device(ADBBusState *s, int devaddr, | ||
| 98 | d = &s->devices[s->nb_devices++]; | 98 | d = &s->devices[s->nb_devices++]; |
| 99 | d->bus = s; | 99 | d->bus = s; |
| 100 | d->devaddr = devaddr; | 100 | d->devaddr = devaddr; |
| 101 | - d->receive_packet = receive_packet; | 101 | + d->devreq = devreq; |
| 102 | d->opaque = opaque; | 102 | d->opaque = opaque; |
| 103 | return d; | 103 | return d; |
| 104 | } | 104 | } |
| @@ -106,80 +106,108 @@ ADBDevice *adb_register_device(ADBBusState *s, int devaddr, | @@ -106,80 +106,108 @@ ADBDevice *adb_register_device(ADBBusState *s, int devaddr, | ||
| 106 | /***************************************************************/ | 106 | /***************************************************************/ |
| 107 | /* Keyboard ADB device */ | 107 | /* Keyboard ADB device */ |
| 108 | 108 | ||
| 109 | +typedef struct KBDState { | ||
| 110 | + uint8_t data[128]; | ||
| 111 | + int rptr, wptr, count; | ||
| 112 | +} KBDState; | ||
| 113 | + | ||
| 109 | static const uint8_t pc_to_adb_keycode[256] = { | 114 | static const uint8_t pc_to_adb_keycode[256] = { |
| 110 | 0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48, | 115 | 0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48, |
| 111 | 12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54, 0, 1, | 116 | 12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54, 0, 1, |
| 112 | 2, 3, 5, 4, 38, 40, 37, 41, 39, 50, 56, 42, 6, 7, 8, 9, | 117 | 2, 3, 5, 4, 38, 40, 37, 41, 39, 50, 56, 42, 6, 7, 8, 9, |
| 113 | 11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96, | 118 | 11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96, |
| 114 | 97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83, | 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 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 121 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 124 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 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 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 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 | static void adb_kbd_put_keycode(void *opaque, int keycode) | 133 | static void adb_kbd_put_keycode(void *opaque, int keycode) |
| 129 | { | 134 | { |
| 130 | - static int ext_keycode; | ||
| 131 | ADBDevice *d = opaque; | 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 | cmd = buf[0] & 0xc; | 189 | cmd = buf[0] & 0xc; |
| 159 | reg = buf[0] & 0x3; | 190 | reg = buf[0] & 0x3; |
| 191 | + olen = 0; | ||
| 160 | switch(cmd) { | 192 | switch(cmd) { |
| 161 | case ADB_WRITEREG: | 193 | case ADB_WRITEREG: |
| 162 | switch(reg) { | 194 | switch(reg) { |
| 163 | case 2: | 195 | case 2: |
| 164 | /* LED status */ | 196 | /* LED status */ |
| 165 | - adb_send_packet1(d->bus, ADB_RET_OK); | ||
| 166 | break; | 197 | break; |
| 167 | case 3: | 198 | case 3: |
| 168 | switch(buf[2]) { | 199 | switch(buf[2]) { |
| 169 | case ADB_CMD_SELF_TEST: | 200 | case ADB_CMD_SELF_TEST: |
| 170 | - adb_send_packet1(d->bus, ADB_RET_OK); | ||
| 171 | break; | 201 | break; |
| 172 | case ADB_CMD_CHANGE_ID: | 202 | case ADB_CMD_CHANGE_ID: |
| 173 | case ADB_CMD_CHANGE_ID_AND_ACT: | 203 | case ADB_CMD_CHANGE_ID_AND_ACT: |
| 174 | case ADB_CMD_CHANGE_ID_AND_ENABLE: | 204 | case ADB_CMD_CHANGE_ID_AND_ENABLE: |
| 175 | d->devaddr = buf[1] & 0xf; | 205 | d->devaddr = buf[1] & 0xf; |
| 176 | - adb_send_packet1(d->bus, ADB_RET_OK); | ||
| 177 | break; | 206 | break; |
| 178 | default: | 207 | default: |
| 179 | /* XXX: check this */ | 208 | /* XXX: check this */ |
| 180 | d->devaddr = buf[1] & 0xf; | 209 | d->devaddr = buf[1] & 0xf; |
| 181 | d->handler = buf[2]; | 210 | d->handler = buf[2]; |
| 182 | - adb_send_packet1(d->bus, ADB_RET_OK); | ||
| 183 | break; | 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,98 +215,122 @@ static void adb_kbd_receive_packet(ADBDevice *d, const uint8_t *buf, int len) | ||
| 187 | case ADB_READREG: | 215 | case ADB_READREG: |
| 188 | switch(reg) { | 216 | switch(reg) { |
| 189 | case 1: | 217 | case 1: |
| 190 | - adb_send_packet1(d->bus, ADB_RET_OK); | ||
| 191 | break; | 218 | break; |
| 192 | case 2: | 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 | break; | 223 | break; |
| 198 | case 3: | 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 | break; | 228 | break; |
| 204 | } | 229 | } |
| 205 | break; | 230 | break; |
| 206 | } | 231 | } |
| 232 | + return olen; | ||
| 207 | } | 233 | } |
| 208 | 234 | ||
| 209 | void adb_kbd_init(ADBBusState *bus) | 235 | void adb_kbd_init(ADBBusState *bus) |
| 210 | { | 236 | { |
| 211 | ADBDevice *d; | 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 | qemu_add_kbd_event_handler(adb_kbd_put_keycode, d); | 242 | qemu_add_kbd_event_handler(adb_kbd_put_keycode, d); |
| 215 | } | 243 | } |
| 216 | 244 | ||
| 217 | /***************************************************************/ | 245 | /***************************************************************/ |
| 218 | /* Mouse ADB device */ | 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 | static void adb_mouse_event(void *opaque, | 253 | static void adb_mouse_event(void *opaque, |
| 221 | int dx1, int dy1, int dz1, int buttons_state) | 254 | int dx1, int dy1, int dz1, int buttons_state) |
| 222 | { | 255 | { |
| 223 | ADBDevice *d = opaque; | 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 | int dx, dy; | 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 | if (dx < -63) | 276 | if (dx < -63) |
| 229 | dx = -63; | 277 | dx = -63; |
| 230 | else if (dx > 63) | 278 | else if (dx > 63) |
| 231 | dx = 63; | 279 | dx = 63; |
| 232 | - | ||
| 233 | - dy = dy1; | 280 | + |
| 281 | + dy = s->dy; | ||
| 234 | if (dy < -63) | 282 | if (dy < -63) |
| 235 | dy = -63; | 283 | dy = -63; |
| 236 | else if (dy > 63) | 284 | else if (dy > 63) |
| 237 | dy = 63; | 285 | dy = 63; |
| 238 | - | 286 | + |
| 287 | + s->dx -= dx; | ||
| 288 | + s->dy -= dy; | ||
| 289 | + s->last_buttons_state = s->buttons_state; | ||
| 290 | + | ||
| 239 | dx &= 0x7f; | 291 | dx &= 0x7f; |
| 240 | dy &= 0x7f; | 292 | dy &= 0x7f; |
| 241 | - | ||
| 242 | - if (buttons_state & MOUSE_EVENT_LBUTTON) | 293 | + |
| 294 | + if (s->buttons_state & MOUSE_EVENT_LBUTTON) | ||
| 243 | dy |= 0x80; | 295 | dy |= 0x80; |
| 244 | - if (buttons_state & MOUSE_EVENT_RBUTTON) | 296 | + if (s->buttons_state & MOUSE_EVENT_RBUTTON) |
| 245 | dx |= 0x80; | 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 | cmd = buf[0] & 0xc; | 314 | cmd = buf[0] & 0xc; |
| 260 | reg = buf[0] & 0x3; | 315 | reg = buf[0] & 0x3; |
| 316 | + olen = 0; | ||
| 261 | switch(cmd) { | 317 | switch(cmd) { |
| 262 | case ADB_WRITEREG: | 318 | case ADB_WRITEREG: |
| 263 | switch(reg) { | 319 | switch(reg) { |
| 264 | case 2: | 320 | case 2: |
| 265 | - adb_send_packet1(d->bus, ADB_RET_OK); | ||
| 266 | break; | 321 | break; |
| 267 | case 3: | 322 | case 3: |
| 268 | switch(buf[2]) { | 323 | switch(buf[2]) { |
| 269 | case ADB_CMD_SELF_TEST: | 324 | case ADB_CMD_SELF_TEST: |
| 270 | - adb_send_packet1(d->bus, ADB_RET_OK); | ||
| 271 | break; | 325 | break; |
| 272 | case ADB_CMD_CHANGE_ID: | 326 | case ADB_CMD_CHANGE_ID: |
| 273 | case ADB_CMD_CHANGE_ID_AND_ACT: | 327 | case ADB_CMD_CHANGE_ID_AND_ACT: |
| 274 | case ADB_CMD_CHANGE_ID_AND_ENABLE: | 328 | case ADB_CMD_CHANGE_ID_AND_ENABLE: |
| 275 | d->devaddr = buf[1] & 0xf; | 329 | d->devaddr = buf[1] & 0xf; |
| 276 | - adb_send_packet1(d->bus, ADB_RET_OK); | ||
| 277 | break; | 330 | break; |
| 278 | default: | 331 | default: |
| 279 | /* XXX: check this */ | 332 | /* XXX: check this */ |
| 280 | d->devaddr = buf[1] & 0xf; | 333 | d->devaddr = buf[1] & 0xf; |
| 281 | - adb_send_packet1(d->bus, ADB_RET_OK); | ||
| 282 | break; | 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,23 +338,25 @@ static void adb_mouse_receive_packet(ADBDevice *d, const uint8_t *buf, int len) | ||
| 286 | case ADB_READREG: | 338 | case ADB_READREG: |
| 287 | switch(reg) { | 339 | switch(reg) { |
| 288 | case 1: | 340 | case 1: |
| 289 | - adb_send_packet1(d->bus, ADB_RET_OK); | ||
| 290 | break; | 341 | break; |
| 291 | case 3: | 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 | break; | 346 | break; |
| 297 | } | 347 | } |
| 298 | break; | 348 | break; |
| 299 | } | 349 | } |
| 350 | + return olen; | ||
| 300 | } | 351 | } |
| 301 | 352 | ||
| 302 | void adb_mouse_init(ADBBusState *bus) | 353 | void adb_mouse_init(ADBBusState *bus) |
| 303 | { | 354 | { |
| 304 | ADBDevice *d; | 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 | qemu_add_mouse_event_handler(adb_mouse_event, d); | 361 | qemu_add_mouse_event_handler(adb_mouse_event, d); |
| 308 | } | 362 | } |
hw/cuda.c
| @@ -85,6 +85,7 @@ | @@ -85,6 +85,7 @@ | ||
| 85 | #define CUDA_COMBINED_FORMAT_IIC 0x25 | 85 | #define CUDA_COMBINED_FORMAT_IIC 0x25 |
| 86 | 86 | ||
| 87 | #define CUDA_TIMER_FREQ (4700000 / 6) | 87 | #define CUDA_TIMER_FREQ (4700000 / 6) |
| 88 | +#define CUDA_ADB_POLL_FREQ 50 | ||
| 88 | 89 | ||
| 89 | typedef struct CUDATimer { | 90 | typedef struct CUDATimer { |
| 90 | unsigned int latch; | 91 | unsigned int latch; |
| @@ -121,6 +122,7 @@ typedef struct CUDAState { | @@ -121,6 +122,7 @@ typedef struct CUDAState { | ||
| 121 | uint8_t autopoll; | 122 | uint8_t autopoll; |
| 122 | uint8_t data_in[128]; | 123 | uint8_t data_in[128]; |
| 123 | uint8_t data_out[16]; | 124 | uint8_t data_out[16]; |
| 125 | + QEMUTimer *adb_poll_timer; | ||
| 124 | } CUDAState; | 126 | } CUDAState; |
| 125 | 127 | ||
| 126 | static CUDAState cuda_state; | 128 | static CUDAState cuda_state; |
| @@ -469,15 +471,42 @@ void adb_send_packet(ADBBusState *bus, const uint8_t *buf, int len) | @@ -469,15 +471,42 @@ void adb_send_packet(ADBBusState *bus, const uint8_t *buf, int len) | ||
| 469 | cuda_send_packet_to_host(s, data, len + 1); | 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 | static void cuda_receive_packet(CUDAState *s, | 491 | static void cuda_receive_packet(CUDAState *s, |
| 473 | const uint8_t *data, int len) | 492 | const uint8_t *data, int len) |
| 474 | { | 493 | { |
| 475 | uint8_t obuf[16]; | 494 | uint8_t obuf[16]; |
| 476 | - int ti; | 495 | + int ti, autopoll; |
| 477 | 496 | ||
| 478 | switch(data[0]) { | 497 | switch(data[0]) { |
| 479 | case CUDA_AUTOPOLL: | 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 | obuf[0] = CUDA_PACKET; | 510 | obuf[0] = CUDA_PACKET; |
| 482 | obuf[1] = data[1]; | 511 | obuf[1] = data[1]; |
| 483 | cuda_send_packet_to_host(s, obuf, 2); | 512 | cuda_send_packet_to_host(s, obuf, 2); |
| @@ -522,7 +551,20 @@ static void cuda_receive_packet_from_host(CUDAState *s, | @@ -522,7 +551,20 @@ static void cuda_receive_packet_from_host(CUDAState *s, | ||
| 522 | #endif | 551 | #endif |
| 523 | switch(data[0]) { | 552 | switch(data[0]) { |
| 524 | case ADB_PACKET: | 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 | break; | 568 | break; |
| 527 | case CUDA_PACKET: | 569 | case CUDA_PACKET: |
| 528 | cuda_receive_packet(s, data + 1, len - 1); | 570 | cuda_receive_packet(s, data + 1, len - 1); |
| @@ -574,6 +616,8 @@ int cuda_init(openpic_t *openpic, int irq) | @@ -574,6 +616,8 @@ int cuda_init(openpic_t *openpic, int irq) | ||
| 574 | s->timers[1].latch = 0x10000; | 616 | s->timers[1].latch = 0x10000; |
| 575 | s->ier = T1_INT | SR_INT; | 617 | s->ier = T1_INT | SR_INT; |
| 576 | set_counter(s, &s->timers[1], 0xffff); | 618 | set_counter(s, &s->timers[1], 0xffff); |
| 619 | + | ||
| 620 | + s->adb_poll_timer = qemu_new_timer(vm_clock, cuda_adb_poll, s); | ||
| 577 | cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s); | 621 | cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s); |
| 578 | return cuda_mem_index; | 622 | return cuda_mem_index; |
| 579 | } | 623 | } |
vl.h
| @@ -528,8 +528,7 @@ PCIBus *pci_pmac_init(void); | @@ -528,8 +528,7 @@ PCIBus *pci_pmac_init(void); | ||
| 528 | /* openpic.c */ | 528 | /* openpic.c */ |
| 529 | typedef struct openpic_t openpic_t; | 529 | typedef struct openpic_t openpic_t; |
| 530 | void openpic_set_irq (openpic_t *opp, int n_IRQ, int level); | 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 | /* vga.c */ | 533 | /* vga.c */ |
| 535 | 534 | ||
| @@ -727,28 +726,33 @@ int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, | @@ -727,28 +726,33 @@ int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, | ||
| 727 | 726 | ||
| 728 | #define MAX_ADB_DEVICES 16 | 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 | struct ADBDevice { | 736 | struct ADBDevice { |
| 735 | struct ADBBusState *bus; | 737 | struct ADBBusState *bus; |
| 736 | int devaddr; | 738 | int devaddr; |
| 737 | int handler; | 739 | int handler; |
| 738 | - ADBDeviceReceivePacket *receive_packet; | 740 | + ADBDeviceRequest *devreq; |
| 739 | void *opaque; | 741 | void *opaque; |
| 740 | }; | 742 | }; |
| 741 | 743 | ||
| 742 | typedef struct ADBBusState { | 744 | typedef struct ADBBusState { |
| 743 | ADBDevice devices[MAX_ADB_DEVICES]; | 745 | ADBDevice devices[MAX_ADB_DEVICES]; |
| 744 | int nb_devices; | 746 | int nb_devices; |
| 747 | + int poll_index; | ||
| 745 | } ADBBusState; | 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 | ADBDevice *adb_register_device(ADBBusState *s, int devaddr, | 754 | ADBDevice *adb_register_device(ADBBusState *s, int devaddr, |
| 751 | - ADBDeviceReceivePacket *receive_packet, | 755 | + ADBDeviceRequest *devreq, |
| 752 | void *opaque); | 756 | void *opaque); |
| 753 | void adb_kbd_init(ADBBusState *bus); | 757 | void adb_kbd_init(ADBBusState *bus); |
| 754 | void adb_mouse_init(ADBBusState *bus); | 758 | void adb_mouse_init(ADBBusState *bus); |