|
|
1.1 root 1: /*
2: * USB UHCI controller emulation
1.1.1.5 ! root 3: *
1.1 root 4: * Copyright (c) 2005 Fabrice Bellard
1.1.1.5 ! root 5: *
1.1 root 6: * Permission is hereby granted, free of charge, to any person obtaining a copy
7: * of this software and associated documentation files (the "Software"), to deal
8: * in the Software without restriction, including without limitation the rights
9: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10: * copies of the Software, and to permit persons to whom the Software is
11: * furnished to do so, subject to the following conditions:
12: *
13: * The above copyright notice and this permission notice shall be included in
14: * all copies or substantial portions of the Software.
15: *
16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22: * THE SOFTWARE.
23: */
1.1.1.5 ! root 24: #include "hw.h"
! 25: #include "usb.h"
! 26: #include "pci.h"
! 27: #include "qemu-timer.h"
1.1 root 28:
29: //#define DEBUG
30: //#define DEBUG_PACKET
1.1.1.5 ! root 31: //#define DEBUG_ISOCH
1.1 root 32:
1.1.1.5 ! root 33: #define UHCI_CMD_FGR (1 << 4)
! 34: #define UHCI_CMD_EGSM (1 << 3)
1.1 root 35: #define UHCI_CMD_GRESET (1 << 2)
36: #define UHCI_CMD_HCRESET (1 << 1)
37: #define UHCI_CMD_RS (1 << 0)
38:
39: #define UHCI_STS_HCHALTED (1 << 5)
40: #define UHCI_STS_HCPERR (1 << 4)
41: #define UHCI_STS_HSERR (1 << 3)
42: #define UHCI_STS_RD (1 << 2)
43: #define UHCI_STS_USBERR (1 << 1)
44: #define UHCI_STS_USBINT (1 << 0)
45:
46: #define TD_CTRL_SPD (1 << 29)
47: #define TD_CTRL_ERROR_SHIFT 27
48: #define TD_CTRL_IOS (1 << 25)
49: #define TD_CTRL_IOC (1 << 24)
50: #define TD_CTRL_ACTIVE (1 << 23)
51: #define TD_CTRL_STALL (1 << 22)
52: #define TD_CTRL_BABBLE (1 << 20)
53: #define TD_CTRL_NAK (1 << 19)
54: #define TD_CTRL_TIMEOUT (1 << 18)
55:
56: #define UHCI_PORT_RESET (1 << 9)
57: #define UHCI_PORT_LSDA (1 << 8)
58: #define UHCI_PORT_ENC (1 << 3)
59: #define UHCI_PORT_EN (1 << 2)
60: #define UHCI_PORT_CSC (1 << 1)
61: #define UHCI_PORT_CCS (1 << 0)
62:
63: #define FRAME_TIMER_FREQ 1000
64:
65: #define FRAME_MAX_LOOPS 100
66:
67: #define NB_PORTS 2
68:
69: typedef struct UHCIPort {
70: USBPort port;
71: uint16_t ctrl;
72: } UHCIPort;
73:
74: typedef struct UHCIState {
75: PCIDevice dev;
76: uint16_t cmd; /* cmd register */
77: uint16_t status;
78: uint16_t intr; /* interrupt enable register */
79: uint16_t frnum; /* frame number */
80: uint32_t fl_base_addr; /* frame list base address */
81: uint8_t sof_timing;
82: uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */
83: QEMUTimer *frame_timer;
84: UHCIPort ports[NB_PORTS];
1.1.1.4 root 85:
86: /* Interrupts that should be raised at the end of the current frame. */
87: uint32_t pending_int_mask;
88: /* For simplicity of implementation we only allow a single pending USB
89: request. This means all usb traffic on this controller is effectively
90: suspended until that transfer completes. When the transfer completes
1.1.1.5 ! root 91: the next transfer from that queue will be processed. However
1.1.1.4 root 92: other queues will not be processed until the next frame. The solution
93: is to allow multiple pending requests. */
94: uint32_t async_qh;
1.1.1.5 ! root 95: uint32_t async_frame_addr;
1.1.1.4 root 96: USBPacket usb_packet;
97: uint8_t usb_buf[2048];
1.1 root 98: } UHCIState;
99:
100: typedef struct UHCI_TD {
101: uint32_t link;
102: uint32_t ctrl; /* see TD_CTRL_xxx */
103: uint32_t token;
104: uint32_t buffer;
105: } UHCI_TD;
106:
107: typedef struct UHCI_QH {
108: uint32_t link;
109: uint32_t el_link;
110: } UHCI_QH;
111:
112: static void uhci_attach(USBPort *port1, USBDevice *dev);
113:
114: static void uhci_update_irq(UHCIState *s)
115: {
116: int level;
117: if (((s->status2 & 1) && (s->intr & (1 << 2))) ||
118: ((s->status2 & 2) && (s->intr & (1 << 3))) ||
119: ((s->status & UHCI_STS_USBERR) && (s->intr & (1 << 0))) ||
120: ((s->status & UHCI_STS_RD) && (s->intr & (1 << 1))) ||
121: (s->status & UHCI_STS_HSERR) ||
122: (s->status & UHCI_STS_HCPERR)) {
123: level = 1;
124: } else {
125: level = 0;
126: }
1.1.1.5 ! root 127: qemu_set_irq(s->dev.irq[3], level);
1.1 root 128: }
129:
130: static void uhci_reset(UHCIState *s)
131: {
132: uint8_t *pci_conf;
133: int i;
134: UHCIPort *port;
135:
136: pci_conf = s->dev.config;
137:
138: pci_conf[0x6a] = 0x01; /* usb clock */
139: pci_conf[0x6b] = 0x00;
140: s->cmd = 0;
141: s->status = 0;
142: s->status2 = 0;
143: s->intr = 0;
144: s->fl_base_addr = 0;
145: s->sof_timing = 64;
146: for(i = 0; i < NB_PORTS; i++) {
147: port = &s->ports[i];
148: port->ctrl = 0x0080;
149: if (port->port.dev)
150: uhci_attach(&port->port, port->port.dev);
151: }
152: }
153:
1.1.1.5 ! root 154: #if 0
! 155: static void uhci_save(QEMUFile *f, void *opaque)
! 156: {
! 157: UHCIState *s = opaque;
! 158: uint8_t num_ports = NB_PORTS;
! 159: int i;
! 160:
! 161: pci_device_save(&s->dev, f);
! 162:
! 163: qemu_put_8s(f, &num_ports);
! 164: for (i = 0; i < num_ports; ++i)
! 165: qemu_put_be16s(f, &s->ports[i].ctrl);
! 166: qemu_put_be16s(f, &s->cmd);
! 167: qemu_put_be16s(f, &s->status);
! 168: qemu_put_be16s(f, &s->intr);
! 169: qemu_put_be16s(f, &s->frnum);
! 170: qemu_put_be32s(f, &s->fl_base_addr);
! 171: qemu_put_8s(f, &s->sof_timing);
! 172: qemu_put_8s(f, &s->status2);
! 173: qemu_put_timer(f, s->frame_timer);
! 174: }
! 175:
! 176: static int uhci_load(QEMUFile *f, void *opaque, int version_id)
! 177: {
! 178: UHCIState *s = opaque;
! 179: uint8_t num_ports;
! 180: int i, ret;
! 181:
! 182: if (version_id > 1)
! 183: return -EINVAL;
! 184:
! 185: ret = pci_device_load(&s->dev, f);
! 186: if (ret < 0)
! 187: return ret;
! 188:
! 189: qemu_get_8s(f, &num_ports);
! 190: if (num_ports != NB_PORTS)
! 191: return -EINVAL;
! 192:
! 193: for (i = 0; i < num_ports; ++i)
! 194: qemu_get_be16s(f, &s->ports[i].ctrl);
! 195: qemu_get_be16s(f, &s->cmd);
! 196: qemu_get_be16s(f, &s->status);
! 197: qemu_get_be16s(f, &s->intr);
! 198: qemu_get_be16s(f, &s->frnum);
! 199: qemu_get_be32s(f, &s->fl_base_addr);
! 200: qemu_get_8s(f, &s->sof_timing);
! 201: qemu_get_8s(f, &s->status2);
! 202: qemu_get_timer(f, s->frame_timer);
! 203:
! 204: return 0;
! 205: }
! 206: #endif
! 207:
1.1 root 208: static void uhci_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
209: {
210: UHCIState *s = opaque;
1.1.1.5 ! root 211:
1.1 root 212: addr &= 0x1f;
213: switch(addr) {
214: case 0x0c:
215: s->sof_timing = val;
216: break;
217: }
218: }
219:
220: static uint32_t uhci_ioport_readb(void *opaque, uint32_t addr)
221: {
222: UHCIState *s = opaque;
223: uint32_t val;
224:
225: addr &= 0x1f;
226: switch(addr) {
227: case 0x0c:
228: val = s->sof_timing;
1.1.1.2 root 229: break;
1.1 root 230: default:
231: val = 0xff;
232: break;
233: }
234: return val;
235: }
236:
237: static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
238: {
239: UHCIState *s = opaque;
1.1.1.5 ! root 240:
1.1 root 241: addr &= 0x1f;
242: #ifdef DEBUG
243: printf("uhci writew port=0x%04x val=0x%04x\n", addr, val);
244: #endif
245: switch(addr) {
246: case 0x00:
247: if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
248: /* start frame processing */
249: qemu_mod_timer(s->frame_timer, qemu_get_clock(vm_clock));
1.1.1.2 root 250: s->status &= ~UHCI_STS_HCHALTED;
251: } else if (!(val & UHCI_CMD_RS)) {
252: s->status |= UHCI_STS_HCHALTED;
1.1 root 253: }
254: if (val & UHCI_CMD_GRESET) {
255: UHCIPort *port;
256: USBDevice *dev;
257: int i;
258:
259: /* send reset on the USB bus */
260: for(i = 0; i < NB_PORTS; i++) {
261: port = &s->ports[i];
262: dev = port->port.dev;
263: if (dev) {
1.1.1.4 root 264: usb_send_msg(dev, USB_MSG_RESET);
1.1 root 265: }
266: }
267: uhci_reset(s);
268: return;
269: }
270: if (val & UHCI_CMD_HCRESET) {
271: uhci_reset(s);
272: return;
273: }
274: s->cmd = val;
275: break;
276: case 0x02:
277: s->status &= ~val;
278: /* XXX: the chip spec is not coherent, so we add a hidden
279: register to distinguish between IOC and SPD */
280: if (val & UHCI_STS_USBINT)
281: s->status2 = 0;
282: uhci_update_irq(s);
283: break;
284: case 0x04:
285: s->intr = val;
286: uhci_update_irq(s);
287: break;
288: case 0x06:
289: if (s->status & UHCI_STS_HCHALTED)
290: s->frnum = val & 0x7ff;
291: break;
292: case 0x10 ... 0x1f:
293: {
294: UHCIPort *port;
295: USBDevice *dev;
296: int n;
297:
298: n = (addr >> 1) & 7;
299: if (n >= NB_PORTS)
300: return;
301: port = &s->ports[n];
302: dev = port->port.dev;
303: if (dev) {
304: /* port reset */
1.1.1.5 ! root 305: if ( (val & UHCI_PORT_RESET) &&
1.1 root 306: !(port->ctrl & UHCI_PORT_RESET) ) {
1.1.1.4 root 307: usb_send_msg(dev, USB_MSG_RESET);
1.1 root 308: }
309: }
310: port->ctrl = (port->ctrl & 0x01fb) | (val & ~0x01fb);
311: /* some bits are reset when a '1' is written to them */
312: port->ctrl &= ~(val & 0x000a);
313: }
314: break;
315: }
316: }
317:
318: static uint32_t uhci_ioport_readw(void *opaque, uint32_t addr)
319: {
320: UHCIState *s = opaque;
321: uint32_t val;
322:
323: addr &= 0x1f;
324: switch(addr) {
325: case 0x00:
326: val = s->cmd;
327: break;
328: case 0x02:
329: val = s->status;
330: break;
331: case 0x04:
332: val = s->intr;
333: break;
334: case 0x06:
335: val = s->frnum;
336: break;
337: case 0x10 ... 0x1f:
338: {
339: UHCIPort *port;
340: int n;
341: n = (addr >> 1) & 7;
1.1.1.5 ! root 342: if (n >= NB_PORTS)
1.1 root 343: goto read_default;
344: port = &s->ports[n];
345: val = port->ctrl;
346: }
347: break;
348: default:
349: read_default:
350: val = 0xff7f; /* disabled port */
351: break;
352: }
353: #ifdef DEBUG
354: printf("uhci readw port=0x%04x val=0x%04x\n", addr, val);
355: #endif
356: return val;
357: }
358:
359: static void uhci_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
360: {
361: UHCIState *s = opaque;
362:
363: addr &= 0x1f;
364: #ifdef DEBUG
365: printf("uhci writel port=0x%04x val=0x%08x\n", addr, val);
366: #endif
367: switch(addr) {
368: case 0x08:
369: s->fl_base_addr = val & ~0xfff;
370: break;
371: }
372: }
373:
374: static uint32_t uhci_ioport_readl(void *opaque, uint32_t addr)
375: {
376: UHCIState *s = opaque;
377: uint32_t val;
378:
379: addr &= 0x1f;
380: switch(addr) {
381: case 0x08:
382: val = s->fl_base_addr;
383: break;
384: default:
385: val = 0xffffffff;
386: break;
387: }
388: return val;
389: }
390:
1.1.1.5 ! root 391: /* signal resume if controller suspended */
! 392: static void uhci_resume (void *opaque)
! 393: {
! 394: UHCIState *s = (UHCIState *)opaque;
! 395:
! 396: if (!s)
! 397: return;
! 398:
! 399: if (s->cmd & UHCI_CMD_EGSM) {
! 400: s->cmd |= UHCI_CMD_FGR;
! 401: s->status |= UHCI_STS_RD;
! 402: uhci_update_irq(s);
! 403: }
! 404: }
! 405:
1.1 root 406: static void uhci_attach(USBPort *port1, USBDevice *dev)
407: {
408: UHCIState *s = port1->opaque;
409: UHCIPort *port = &s->ports[port1->index];
410:
411: if (dev) {
412: if (port->port.dev) {
413: usb_attach(port1, NULL);
414: }
415: /* set connect status */
1.1.1.3 root 416: port->ctrl |= UHCI_PORT_CCS | UHCI_PORT_CSC;
417:
1.1 root 418: /* update speed */
419: if (dev->speed == USB_SPEED_LOW)
420: port->ctrl |= UHCI_PORT_LSDA;
421: else
422: port->ctrl &= ~UHCI_PORT_LSDA;
1.1.1.5 ! root 423:
! 424: uhci_resume(s);
! 425:
1.1 root 426: port->port.dev = dev;
427: /* send the attach message */
1.1.1.4 root 428: usb_send_msg(dev, USB_MSG_ATTACH);
1.1 root 429: } else {
430: /* set connect status */
1.1.1.3 root 431: if (port->ctrl & UHCI_PORT_CCS) {
432: port->ctrl &= ~UHCI_PORT_CCS;
433: port->ctrl |= UHCI_PORT_CSC;
1.1 root 434: }
435: /* disable port */
436: if (port->ctrl & UHCI_PORT_EN) {
437: port->ctrl &= ~UHCI_PORT_EN;
438: port->ctrl |= UHCI_PORT_ENC;
439: }
1.1.1.5 ! root 440:
! 441: uhci_resume(s);
! 442:
1.1 root 443: dev = port->port.dev;
444: if (dev) {
445: /* send the detach message */
1.1.1.4 root 446: usb_send_msg(dev, USB_MSG_DETACH);
1.1 root 447: }
448: port->port.dev = NULL;
449: }
450: }
451:
1.1.1.4 root 452: static int uhci_broadcast_packet(UHCIState *s, USBPacket *p)
1.1 root 453: {
454: UHCIPort *port;
455: USBDevice *dev;
456: int i, ret;
457:
458: #ifdef DEBUG_PACKET
459: {
460: const char *pidstr;
1.1.1.4 root 461: switch(p->pid) {
1.1 root 462: case USB_TOKEN_SETUP: pidstr = "SETUP"; break;
463: case USB_TOKEN_IN: pidstr = "IN"; break;
464: case USB_TOKEN_OUT: pidstr = "OUT"; break;
465: default: pidstr = "?"; break;
466: }
467: printf("frame %d: pid=%s addr=0x%02x ep=%d len=%d\n",
1.1.1.4 root 468: s->frnum, pidstr, p->devaddr, p->devep, p->len);
469: if (p->pid != USB_TOKEN_IN) {
1.1 root 470: printf(" data_out=");
1.1.1.4 root 471: for(i = 0; i < p->len; i++) {
472: printf(" %02x", p->data[i]);
1.1 root 473: }
474: printf("\n");
475: }
476: }
477: #endif
478: for(i = 0; i < NB_PORTS; i++) {
479: port = &s->ports[i];
480: dev = port->port.dev;
481: if (dev && (port->ctrl & UHCI_PORT_EN)) {
1.1.1.4 root 482: ret = dev->handle_packet(dev, p);
1.1 root 483: if (ret != USB_RET_NODEV) {
484: #ifdef DEBUG_PACKET
1.1.1.4 root 485: if (ret == USB_RET_ASYNC) {
486: printf("usb-uhci: Async packet\n");
487: } else {
1.1 root 488: printf(" ret=%d ", ret);
1.1.1.4 root 489: if (p->pid == USB_TOKEN_IN && ret > 0) {
1.1 root 490: printf("data_in=");
491: for(i = 0; i < ret; i++) {
1.1.1.4 root 492: printf(" %02x", p->data[i]);
1.1 root 493: }
494: }
495: printf("\n");
496: }
497: #endif
498: return ret;
499: }
500: }
501: }
502: return USB_RET_NODEV;
503: }
504:
1.1.1.4 root 505: static void uhci_async_complete_packet(USBPacket * packet, void *opaque);
506:
1.1 root 507: /* return -1 if fatal error (frame must be stopped)
508: 0 if TD successful
509: 1 if TD unsuccessful or inactive
510: */
1.1.1.5 ! root 511: static int uhci_handle_td(UHCIState *s, UHCI_TD *td, uint32_t *int_mask,
! 512: int completion)
1.1 root 513: {
514: uint8_t pid;
1.1.1.5 ! root 515: int len = 0, max_len, err, ret = 0;
1.1 root 516:
1.1.1.4 root 517: /* ??? This is wrong for async completion. */
1.1 root 518: if (td->ctrl & TD_CTRL_IOC) {
519: *int_mask |= 0x01;
520: }
1.1.1.5 ! root 521:
1.1 root 522: if (!(td->ctrl & TD_CTRL_ACTIVE))
523: return 1;
524:
525: /* TD is active */
526: max_len = ((td->token >> 21) + 1) & 0x7ff;
527: pid = td->token & 0xff;
1.1.1.5 ! root 528:
! 529: if (completion && (s->async_qh || s->async_frame_addr)) {
1.1.1.4 root 530: ret = s->usb_packet.len;
1.1 root 531: if (ret >= 0) {
532: len = ret;
533: if (len > max_len) {
534: len = max_len;
535: ret = USB_RET_BABBLE;
536: }
537: if (len > 0) {
538: /* write the data back */
1.1.1.4 root 539: cpu_physical_memory_write(td->buffer, s->usb_buf, len);
1.1 root 540: }
541: } else {
542: len = 0;
543: }
1.1.1.4 root 544: s->async_qh = 0;
1.1.1.5 ! root 545: s->async_frame_addr = 0;
! 546: } else if (!completion) {
1.1.1.4 root 547: s->usb_packet.pid = pid;
548: s->usb_packet.devaddr = (td->token >> 8) & 0x7f;
549: s->usb_packet.devep = (td->token >> 15) & 0xf;
550: s->usb_packet.data = s->usb_buf;
551: s->usb_packet.len = max_len;
552: s->usb_packet.complete_cb = uhci_async_complete_packet;
553: s->usb_packet.complete_opaque = s;
554: switch(pid) {
555: case USB_TOKEN_OUT:
556: case USB_TOKEN_SETUP:
557: cpu_physical_memory_read(td->buffer, s->usb_buf, max_len);
558: ret = uhci_broadcast_packet(s, &s->usb_packet);
559: len = max_len;
560: break;
561: case USB_TOKEN_IN:
562: ret = uhci_broadcast_packet(s, &s->usb_packet);
563: if (ret >= 0) {
564: len = ret;
565: if (len > max_len) {
566: len = max_len;
567: ret = USB_RET_BABBLE;
568: }
569: if (len > 0) {
570: /* write the data back */
571: cpu_physical_memory_write(td->buffer, s->usb_buf, len);
572: }
573: } else {
574: len = 0;
575: }
576: break;
577: default:
578: /* invalid pid : frame interrupted */
579: s->status |= UHCI_STS_HCPERR;
580: uhci_update_irq(s);
581: return -1;
582: }
583: }
1.1.1.5 ! root 584:
1.1.1.4 root 585: if (ret == USB_RET_ASYNC) {
586: return 2;
1.1 root 587: }
588: if (td->ctrl & TD_CTRL_IOS)
589: td->ctrl &= ~TD_CTRL_ACTIVE;
590: if (ret >= 0) {
591: td->ctrl = (td->ctrl & ~0x7ff) | ((len - 1) & 0x7ff);
1.1.1.5 ! root 592: /* The NAK bit may have been set by a previous frame, so clear it
! 593: here. The docs are somewhat unclear, but win2k relies on this
! 594: behavior. */
! 595: td->ctrl &= ~(TD_CTRL_ACTIVE | TD_CTRL_NAK);
! 596: if (pid == USB_TOKEN_IN &&
1.1 root 597: (td->ctrl & TD_CTRL_SPD) &&
598: len < max_len) {
599: *int_mask |= 0x02;
600: /* short packet: do not update QH */
601: return 1;
602: } else {
603: /* success */
604: return 0;
605: }
606: } else {
607: switch(ret) {
608: default:
609: case USB_RET_NODEV:
610: do_timeout:
611: td->ctrl |= TD_CTRL_TIMEOUT;
612: err = (td->ctrl >> TD_CTRL_ERROR_SHIFT) & 3;
613: if (err != 0) {
614: err--;
615: if (err == 0) {
616: td->ctrl &= ~TD_CTRL_ACTIVE;
617: s->status |= UHCI_STS_USBERR;
618: uhci_update_irq(s);
619: }
620: }
1.1.1.5 ! root 621: td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |
1.1 root 622: (err << TD_CTRL_ERROR_SHIFT);
623: return 1;
624: case USB_RET_NAK:
625: td->ctrl |= TD_CTRL_NAK;
626: if (pid == USB_TOKEN_SETUP)
627: goto do_timeout;
628: return 1;
629: case USB_RET_STALL:
630: td->ctrl |= TD_CTRL_STALL;
631: td->ctrl &= ~TD_CTRL_ACTIVE;
632: return 1;
633: case USB_RET_BABBLE:
634: td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
635: td->ctrl &= ~TD_CTRL_ACTIVE;
636: /* frame interrupted */
637: return -1;
638: }
639: }
640: }
641:
1.1.1.4 root 642: static void uhci_async_complete_packet(USBPacket * packet, void *opaque)
643: {
644: UHCIState *s = opaque;
645: UHCI_QH qh;
646: UHCI_TD td;
647: uint32_t link;
648: uint32_t old_td_ctrl;
649: uint32_t val;
1.1.1.5 ! root 650: uint32_t frame_addr;
1.1.1.4 root 651: int ret;
652:
1.1.1.5 ! root 653: /* Handle async isochronous packet completion */
! 654: frame_addr = s->async_frame_addr;
! 655: if (frame_addr) {
! 656: cpu_physical_memory_read(frame_addr, (uint8_t *)&link, 4);
! 657: le32_to_cpus(&link);
! 658:
! 659: cpu_physical_memory_read(link & ~0xf, (uint8_t *)&td, sizeof(td));
! 660: le32_to_cpus(&td.link);
! 661: le32_to_cpus(&td.ctrl);
! 662: le32_to_cpus(&td.token);
! 663: le32_to_cpus(&td.buffer);
! 664: old_td_ctrl = td.ctrl;
! 665: ret = uhci_handle_td(s, &td, &s->pending_int_mask, 1);
! 666:
! 667: /* update the status bits of the TD */
! 668: if (old_td_ctrl != td.ctrl) {
! 669: val = cpu_to_le32(td.ctrl);
! 670: cpu_physical_memory_write((link & ~0xf) + 4,
! 671: (const uint8_t *)&val,
! 672: sizeof(val));
! 673: }
! 674: if (ret == 2) {
! 675: s->async_frame_addr = frame_addr;
! 676: } else if (ret == 0) {
! 677: /* update qh element link */
! 678: val = cpu_to_le32(td.link);
! 679: cpu_physical_memory_write(frame_addr,
! 680: (const uint8_t *)&val,
! 681: sizeof(val));
! 682: }
! 683: return;
! 684: }
! 685:
1.1.1.4 root 686: link = s->async_qh;
687: if (!link) {
688: /* This should never happen. It means a TD somehow got removed
689: without cancelling the associated async IO request. */
690: return;
691: }
692: cpu_physical_memory_read(link & ~0xf, (uint8_t *)&qh, sizeof(qh));
693: le32_to_cpus(&qh.link);
694: le32_to_cpus(&qh.el_link);
695: /* Re-process the queue containing the async packet. */
696: while (1) {
1.1.1.5 ! root 697: cpu_physical_memory_read(qh.el_link & ~0xf,
1.1.1.4 root 698: (uint8_t *)&td, sizeof(td));
699: le32_to_cpus(&td.link);
700: le32_to_cpus(&td.ctrl);
701: le32_to_cpus(&td.token);
702: le32_to_cpus(&td.buffer);
703: old_td_ctrl = td.ctrl;
1.1.1.5 ! root 704: ret = uhci_handle_td(s, &td, &s->pending_int_mask, 1);
! 705:
1.1.1.4 root 706: /* update the status bits of the TD */
707: if (old_td_ctrl != td.ctrl) {
708: val = cpu_to_le32(td.ctrl);
1.1.1.5 ! root 709: cpu_physical_memory_write((qh.el_link & ~0xf) + 4,
! 710: (const uint8_t *)&val,
1.1.1.4 root 711: sizeof(val));
712: }
713: if (ret < 0)
714: break; /* interrupted frame */
715: if (ret == 2) {
716: s->async_qh = link;
717: break;
718: } else if (ret == 0) {
719: /* update qh element link */
720: qh.el_link = td.link;
721: val = cpu_to_le32(qh.el_link);
1.1.1.5 ! root 722: cpu_physical_memory_write((link & ~0xf) + 4,
! 723: (const uint8_t *)&val,
1.1.1.4 root 724: sizeof(val));
725: if (!(qh.el_link & 4))
726: break;
727: }
728: break;
729: }
730: }
731:
1.1 root 732: static void uhci_frame_timer(void *opaque)
733: {
734: UHCIState *s = opaque;
735: int64_t expire_time;
1.1.1.5 ! root 736: uint32_t frame_addr, link, old_td_ctrl, val, int_mask;
! 737: int cnt, ret;
1.1 root 738: UHCI_TD td;
739: UHCI_QH qh;
1.1.1.4 root 740: uint32_t old_async_qh;
1.1 root 741:
742: if (!(s->cmd & UHCI_CMD_RS)) {
743: qemu_del_timer(s->frame_timer);
1.1.1.2 root 744: /* set hchalted bit in status - UHCI11D 2.1.2 */
745: s->status |= UHCI_STS_HCHALTED;
1.1 root 746: return;
747: }
1.1.1.4 root 748: /* Complete the previous frame. */
749: s->frnum = (s->frnum + 1) & 0x7ff;
750: if (s->pending_int_mask) {
751: s->status2 |= s->pending_int_mask;
752: s->status |= UHCI_STS_USBINT;
753: uhci_update_irq(s);
754: }
755: old_async_qh = s->async_qh;
1.1 root 756: frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2);
757: cpu_physical_memory_read(frame_addr, (uint8_t *)&link, 4);
758: le32_to_cpus(&link);
759: int_mask = 0;
760: cnt = FRAME_MAX_LOOPS;
761: while ((link & 1) == 0) {
762: if (--cnt == 0)
763: break;
764: /* valid frame */
765: if (link & 2) {
766: /* QH */
1.1.1.4 root 767: if (link == s->async_qh) {
768: /* We've found a previously issues packet.
769: Nothing else to do. */
770: old_async_qh = 0;
771: break;
772: }
1.1 root 773: cpu_physical_memory_read(link & ~0xf, (uint8_t *)&qh, sizeof(qh));
774: le32_to_cpus(&qh.link);
775: le32_to_cpus(&qh.el_link);
776: depth_first:
777: if (qh.el_link & 1) {
778: /* no element : go to next entry */
779: link = qh.link;
780: } else if (qh.el_link & 2) {
781: /* QH */
782: link = qh.el_link;
1.1.1.4 root 783: } else if (s->async_qh) {
784: /* We can only cope with one pending packet. Keep looking
785: for the previously issued packet. */
786: link = qh.link;
1.1 root 787: } else {
788: /* TD */
789: if (--cnt == 0)
790: break;
1.1.1.5 ! root 791: cpu_physical_memory_read(qh.el_link & ~0xf,
1.1 root 792: (uint8_t *)&td, sizeof(td));
793: le32_to_cpus(&td.link);
794: le32_to_cpus(&td.ctrl);
795: le32_to_cpus(&td.token);
796: le32_to_cpus(&td.buffer);
797: old_td_ctrl = td.ctrl;
1.1.1.5 ! root 798: ret = uhci_handle_td(s, &td, &int_mask, 0);
! 799:
1.1 root 800: /* update the status bits of the TD */
801: if (old_td_ctrl != td.ctrl) {
802: val = cpu_to_le32(td.ctrl);
1.1.1.5 ! root 803: cpu_physical_memory_write((qh.el_link & ~0xf) + 4,
! 804: (const uint8_t *)&val,
1.1 root 805: sizeof(val));
806: }
807: if (ret < 0)
808: break; /* interrupted frame */
1.1.1.4 root 809: if (ret == 2) {
810: s->async_qh = link;
811: } else if (ret == 0) {
1.1 root 812: /* update qh element link */
813: qh.el_link = td.link;
814: val = cpu_to_le32(qh.el_link);
1.1.1.5 ! root 815: cpu_physical_memory_write((link & ~0xf) + 4,
! 816: (const uint8_t *)&val,
1.1 root 817: sizeof(val));
818: if (qh.el_link & 4) {
819: /* depth first */
820: goto depth_first;
821: }
822: }
823: /* go to next entry */
824: link = qh.link;
825: }
826: } else {
827: /* TD */
828: cpu_physical_memory_read(link & ~0xf, (uint8_t *)&td, sizeof(td));
829: le32_to_cpus(&td.link);
830: le32_to_cpus(&td.ctrl);
831: le32_to_cpus(&td.token);
832: le32_to_cpus(&td.buffer);
1.1.1.5 ! root 833:
! 834: /* Handle isochonous transfer. */
! 835: /* FIXME: might be more than one isoc in frame */
! 836: old_td_ctrl = td.ctrl;
! 837: ret = uhci_handle_td(s, &td, &int_mask, 0);
! 838:
! 839: /* update the status bits of the TD */
! 840: if (old_td_ctrl != td.ctrl) {
! 841: val = cpu_to_le32(td.ctrl);
! 842: cpu_physical_memory_write((link & ~0xf) + 4,
! 843: (const uint8_t *)&val,
! 844: sizeof(val));
! 845: }
! 846: if (ret < 0)
! 847: break; /* interrupted frame */
! 848: if (ret == 2) {
! 849: s->async_frame_addr = frame_addr;
1.1 root 850: }
851: link = td.link;
852: }
853: }
1.1.1.4 root 854: s->pending_int_mask = int_mask;
855: if (old_async_qh) {
856: /* A previously started transfer has disappeared from the transfer
857: list. There's nothing useful we can do with it now, so just
858: discard the packet and hope it wasn't too important. */
859: #ifdef DEBUG
860: printf("Discarding USB packet\n");
861: #endif
862: usb_cancel_packet(&s->usb_packet);
863: s->async_qh = 0;
1.1 root 864: }
1.1.1.5 ! root 865:
1.1 root 866: /* prepare the timer for the next frame */
1.1.1.5 ! root 867: expire_time = qemu_get_clock(vm_clock) +
1.1 root 868: (ticks_per_sec / FRAME_TIMER_FREQ);
869: qemu_mod_timer(s->frame_timer, expire_time);
870: }
871:
1.1.1.5 ! root 872: static void uhci_map(PCIDevice *pci_dev, int region_num,
1.1 root 873: uint32_t addr, uint32_t size, int type)
874: {
875: UHCIState *s = (UHCIState *)pci_dev;
876:
877: register_ioport_write(addr, 32, 2, uhci_ioport_writew, s);
878: register_ioport_read(addr, 32, 2, uhci_ioport_readw, s);
879: register_ioport_write(addr, 32, 4, uhci_ioport_writel, s);
880: register_ioport_read(addr, 32, 4, uhci_ioport_readl, s);
881: register_ioport_write(addr, 32, 1, uhci_ioport_writeb, s);
882: register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
883: }
884:
1.1.1.5 ! root 885: void usb_uhci_piix3_init(PCIBus *bus, int devfn)
1.1 root 886: {
887: UHCIState *s;
888: uint8_t *pci_conf;
889: int i;
890:
891: s = (UHCIState *)pci_register_device(bus,
892: "USB-UHCI", sizeof(UHCIState),
1.1.1.3 root 893: devfn, NULL, NULL);
1.1 root 894: pci_conf = s->dev.config;
895: pci_conf[0x00] = 0x86;
896: pci_conf[0x01] = 0x80;
897: pci_conf[0x02] = 0x20;
898: pci_conf[0x03] = 0x70;
899: pci_conf[0x08] = 0x01; // revision number
900: pci_conf[0x09] = 0x00;
901: pci_conf[0x0a] = 0x03;
902: pci_conf[0x0b] = 0x0c;
903: pci_conf[0x0e] = 0x00; // header_type
904: pci_conf[0x3d] = 4; // interrupt pin 3
1.1.1.2 root 905: pci_conf[0x60] = 0x10; // release number
1.1.1.5 ! root 906:
! 907: for(i = 0; i < NB_PORTS; i++) {
! 908: qemu_register_usb_port(&s->ports[i].port, s, i, uhci_attach);
! 909: }
! 910: s->frame_timer = qemu_new_timer(vm_clock, uhci_frame_timer, s);
! 911:
! 912: uhci_reset(s);
! 913:
! 914: /* Use region 4 for consistency with real hardware. BSD guests seem
! 915: to rely on this. */
! 916: pci_register_io_region(&s->dev, 4, 0x20,
! 917: PCI_ADDRESS_SPACE_IO, uhci_map);
! 918: }
! 919:
! 920: void usb_uhci_piix4_init(PCIBus *bus, int devfn)
! 921: {
! 922: UHCIState *s;
! 923: uint8_t *pci_conf;
! 924: int i;
! 925:
! 926: s = (UHCIState *)pci_register_device(bus,
! 927: "USB-UHCI", sizeof(UHCIState),
! 928: devfn, NULL, NULL);
! 929: pci_conf = s->dev.config;
! 930: pci_conf[0x00] = 0x86;
! 931: pci_conf[0x01] = 0x80;
! 932: pci_conf[0x02] = 0x12;
! 933: pci_conf[0x03] = 0x71;
! 934: pci_conf[0x08] = 0x01; // revision number
! 935: pci_conf[0x09] = 0x00;
! 936: pci_conf[0x0a] = 0x03;
! 937: pci_conf[0x0b] = 0x0c;
! 938: pci_conf[0x0e] = 0x00; // header_type
! 939: pci_conf[0x3d] = 4; // interrupt pin 3
! 940: pci_conf[0x60] = 0x10; // release number
! 941:
1.1 root 942: for(i = 0; i < NB_PORTS; i++) {
1.1.1.3 root 943: qemu_register_usb_port(&s->ports[i].port, s, i, uhci_attach);
1.1 root 944: }
945: s->frame_timer = qemu_new_timer(vm_clock, uhci_frame_timer, s);
946:
947: uhci_reset(s);
948:
1.1.1.2 root 949: /* Use region 4 for consistency with real hardware. BSD guests seem
950: to rely on this. */
1.1.1.5 ! root 951: pci_register_io_region(&s->dev, 4, 0x20,
1.1 root 952: PCI_ADDRESS_SPACE_IO, uhci_map);
953: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.