hcd-uhci.c (e2f89926f19d2940eda070542501f39f51a8c81f) hcd-uhci.c (f90c2bcdbc69e41e575f868b984c3e2de8f51bac)
1/*
2 * USB UHCI controller emulation
3 *
4 * Copyright (c) 2005 Fabrice Bellard
5 *
6 * Copyright (c) 2008 Max Krasnyansky
7 * Magor rewrite of the UHCI data structures parser and frame processor
8 * Support for fully async operation and multiple outstanding transactions

--- 117 unchanged lines hidden (view full) ---

126 uint16_t status;
127 uint16_t intr; /* interrupt enable register */
128 uint16_t frnum; /* frame number */
129 uint32_t fl_base_addr; /* frame list base address */
130 uint8_t sof_timing;
131 uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */
132 int64_t expire_time;
133 QEMUTimer *frame_timer;
1/*
2 * USB UHCI controller emulation
3 *
4 * Copyright (c) 2005 Fabrice Bellard
5 *
6 * Copyright (c) 2008 Max Krasnyansky
7 * Magor rewrite of the UHCI data structures parser and frame processor
8 * Support for fully async operation and multiple outstanding transactions

--- 117 unchanged lines hidden (view full) ---

126 uint16_t status;
127 uint16_t intr; /* interrupt enable register */
128 uint16_t frnum; /* frame number */
129 uint32_t fl_base_addr; /* frame list base address */
130 uint8_t sof_timing;
131 uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */
132 int64_t expire_time;
133 QEMUTimer *frame_timer;
134 QEMUBH *bh;
135 uint32_t frame_bytes;
136 uint32_t frame_bandwidth;
137 UHCIPort ports[NB_PORTS];
138
139 /* Interrupts that should be raised at the end of the current frame. */
140 uint32_t pending_int_mask;
134 UHCIPort ports[NB_PORTS];
135
136 /* Interrupts that should be raised at the end of the current frame. */
137 uint32_t pending_int_mask;
141 int irq_pin;
142
143 /* Active packets */
144 QTAILQ_HEAD(, UHCIQueue) queues;
145 uint8_t num_ports_vmstate;
146
147 /* Properties */
148 char *masterbus;
149 uint32_t firstport;

--- 137 unchanged lines hidden (view full) ---

287 uhci_async_unlink(curr);
288 uhci_async_cancel(curr);
289 }
290 }
291}
292
293static void uhci_async_cancel_all(UHCIState *s)
294{
138
139 /* Active packets */
140 QTAILQ_HEAD(, UHCIQueue) queues;
141 uint8_t num_ports_vmstate;
142
143 /* Properties */
144 char *masterbus;
145 uint32_t firstport;

--- 137 unchanged lines hidden (view full) ---

283 uhci_async_unlink(curr);
284 uhci_async_cancel(curr);
285 }
286 }
287}
288
289static void uhci_async_cancel_all(UHCIState *s)
290{
295 UHCIQueue *queue, *nq;
291 UHCIQueue *queue;
296 UHCIAsync *curr, *n;
297
292 UHCIAsync *curr, *n;
293
298 QTAILQ_FOREACH_SAFE(queue, &s->queues, next, nq) {
294 QTAILQ_FOREACH(queue, &s->queues, next) {
299 QTAILQ_FOREACH_SAFE(curr, &queue->asyncs, next, n) {
300 uhci_async_unlink(curr);
301 uhci_async_cancel(curr);
302 }
303 uhci_queue_free(queue);
304 }
305}
306

--- 29 unchanged lines hidden (view full) ---

336 ((s->status & UHCI_STS_USBERR) && (s->intr & (1 << 0))) ||
337 ((s->status & UHCI_STS_RD) && (s->intr & (1 << 1))) ||
338 (s->status & UHCI_STS_HSERR) ||
339 (s->status & UHCI_STS_HCPERR)) {
340 level = 1;
341 } else {
342 level = 0;
343 }
295 QTAILQ_FOREACH_SAFE(curr, &queue->asyncs, next, n) {
296 uhci_async_unlink(curr);
297 uhci_async_cancel(curr);
298 }
299 uhci_queue_free(queue);
300 }
301}
302

--- 29 unchanged lines hidden (view full) ---

332 ((s->status & UHCI_STS_USBERR) && (s->intr & (1 << 0))) ||
333 ((s->status & UHCI_STS_RD) && (s->intr & (1 << 1))) ||
334 (s->status & UHCI_STS_HSERR) ||
335 (s->status & UHCI_STS_HCPERR)) {
336 level = 1;
337 } else {
338 level = 0;
339 }
344 qemu_set_irq(s->dev.irq[s->irq_pin], level);
340 qemu_set_irq(s->dev.irq[3], level);
345}
346
347static void uhci_reset(void *opaque)
348{
349 UHCIState *s = opaque;
350 uint8_t *pci_conf;
351 int i;
352 UHCIPort *port;

--- 15 unchanged lines hidden (view full) ---

368 port = &s->ports[i];
369 port->ctrl = 0x0080;
370 if (port->port.dev && port->port.dev->attached) {
371 usb_port_reset(&port->port);
372 }
373 }
374
375 uhci_async_cancel_all(s);
341}
342
343static void uhci_reset(void *opaque)
344{
345 UHCIState *s = opaque;
346 uint8_t *pci_conf;
347 int i;
348 UHCIPort *port;

--- 15 unchanged lines hidden (view full) ---

364 port = &s->ports[i];
365 port->ctrl = 0x0080;
366 if (port->port.dev && port->port.dev->attached) {
367 usb_port_reset(&port->port);
368 }
369 }
370
371 uhci_async_cancel_all(s);
376 qemu_bh_cancel(s->bh);
377 uhci_update_irq(s);
378}
379
372 uhci_update_irq(s);
373}
374
375static void uhci_pre_save(void *opaque)
376{
377 UHCIState *s = opaque;
378
379 uhci_async_cancel_all(s);
380}
381
380static const VMStateDescription vmstate_uhci_port = {
381 .name = "uhci port",
382 .version_id = 1,
383 .minimum_version_id = 1,
384 .minimum_version_id_old = 1,
385 .fields = (VMStateField []) {
386 VMSTATE_UINT16(ctrl, UHCIPort),
387 VMSTATE_END_OF_LIST()
388 }
389};
390
391static const VMStateDescription vmstate_uhci = {
392 .name = "uhci",
393 .version_id = 2,
394 .minimum_version_id = 1,
395 .minimum_version_id_old = 1,
382static const VMStateDescription vmstate_uhci_port = {
383 .name = "uhci port",
384 .version_id = 1,
385 .minimum_version_id = 1,
386 .minimum_version_id_old = 1,
387 .fields = (VMStateField []) {
388 VMSTATE_UINT16(ctrl, UHCIPort),
389 VMSTATE_END_OF_LIST()
390 }
391};
392
393static const VMStateDescription vmstate_uhci = {
394 .name = "uhci",
395 .version_id = 2,
396 .minimum_version_id = 1,
397 .minimum_version_id_old = 1,
398 .pre_save = uhci_pre_save,
396 .fields = (VMStateField []) {
397 VMSTATE_PCI_DEVICE(dev, UHCIState),
398 VMSTATE_UINT8_EQUAL(num_ports_vmstate, UHCIState),
399 VMSTATE_STRUCT_ARRAY(ports, UHCIState, NB_PORTS, 1,
400 vmstate_uhci_port, UHCIPort),
401 VMSTATE_UINT16(cmd, UHCIState),
402 VMSTATE_UINT16(status, UHCIState),
403 VMSTATE_UINT16(intr, UHCIState),

--- 462 unchanged lines hidden (view full) ---

866 uhci_async_link(async);
867 return TD_RESULT_ASYNC_START;
868 }
869
870 async->packet.result = len;
871
872done:
873 len = uhci_complete_td(s, td, async, int_mask);
399 .fields = (VMStateField []) {
400 VMSTATE_PCI_DEVICE(dev, UHCIState),
401 VMSTATE_UINT8_EQUAL(num_ports_vmstate, UHCIState),
402 VMSTATE_STRUCT_ARRAY(ports, UHCIState, NB_PORTS, 1,
403 vmstate_uhci_port, UHCIPort),
404 VMSTATE_UINT16(cmd, UHCIState),
405 VMSTATE_UINT16(status, UHCIState),
406 VMSTATE_UINT16(intr, UHCIState),

--- 462 unchanged lines hidden (view full) ---

869 uhci_async_link(async);
870 return TD_RESULT_ASYNC_START;
871 }
872
873 async->packet.result = len;
874
875done:
876 len = uhci_complete_td(s, td, async, int_mask);
874 usb_packet_unmap(&async->packet, &async->sgl);
877 usb_packet_unmap(&async->packet);
875 uhci_async_free(async);
876 return len;
877}
878
879static void uhci_async_complete(USBPort *port, USBPacket *packet)
880{
881 UHCIAsync *async = container_of(packet, UHCIAsync, packet);
882 UHCIState *s = async->queue->uhci;

--- 14 unchanged lines hidden (view full) ---

897 s->pending_int_mask |= int_mask;
898
899 /* update the status bits of the TD */
900 val = cpu_to_le32(td.ctrl);
901 pci_dma_write(&s->dev, (link & ~0xf) + 4, &val, sizeof(val));
902 uhci_async_free(async);
903 } else {
904 async->done = 1;
878 uhci_async_free(async);
879 return len;
880}
881
882static void uhci_async_complete(USBPort *port, USBPacket *packet)
883{
884 UHCIAsync *async = container_of(packet, UHCIAsync, packet);
885 UHCIState *s = async->queue->uhci;

--- 14 unchanged lines hidden (view full) ---

900 s->pending_int_mask |= int_mask;
901
902 /* update the status bits of the TD */
903 val = cpu_to_le32(td.ctrl);
904 pci_dma_write(&s->dev, (link & ~0xf) + 4, &val, sizeof(val));
905 uhci_async_free(async);
906 } else {
907 async->done = 1;
905 if (s->frame_bytes < s->frame_bandwidth) {
906 qemu_bh_schedule(s->bh);
907 }
908 uhci_process_frame(s);
908 }
909}
910
911static int is_valid(uint32_t link)
912{
913 return (link & 1) == 0;
914}
915

--- 63 unchanged lines hidden (view full) ---

979 assert(int_mask == 0);
980 plink = ptd.link;
981 }
982}
983
984static void uhci_process_frame(UHCIState *s)
985{
986 uint32_t frame_addr, link, old_td_ctrl, val, int_mask;
909 }
910}
911
912static int is_valid(uint32_t link)
913{
914 return (link & 1) == 0;
915}
916

--- 63 unchanged lines hidden (view full) ---

980 assert(int_mask == 0);
981 plink = ptd.link;
982 }
983}
984
985static void uhci_process_frame(UHCIState *s)
986{
987 uint32_t frame_addr, link, old_td_ctrl, val, int_mask;
987 uint32_t curr_qh, td_count = 0;
988 uint32_t curr_qh, td_count = 0, bytes_count = 0;
988 int cnt, ret;
989 UHCI_TD td;
990 UHCI_QH qh;
991 QhDb qhdb;
992
993 frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2);
994
995 pci_dma_read(&s->dev, frame_addr, &link, 4);
996 le32_to_cpus(&link);
997
998 int_mask = 0;
999 curr_qh = 0;
1000
1001 qhdb_reset(&qhdb);
1002
1003 for (cnt = FRAME_MAX_LOOPS; is_valid(link) && cnt; cnt--) {
989 int cnt, ret;
990 UHCI_TD td;
991 UHCI_QH qh;
992 QhDb qhdb;
993
994 frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2);
995
996 pci_dma_read(&s->dev, frame_addr, &link, 4);
997 le32_to_cpus(&link);
998
999 int_mask = 0;
1000 curr_qh = 0;
1001
1002 qhdb_reset(&qhdb);
1003
1004 for (cnt = FRAME_MAX_LOOPS; is_valid(link) && cnt; cnt--) {
1004 if (s->frame_bytes >= s->frame_bandwidth) {
1005 /* We've reached the usb 1.1 bandwidth, which is
1006 1280 bytes/frame, stop processing */
1007 trace_usb_uhci_frame_stop_bandwidth();
1008 break;
1009 }
1010 if (is_qh(link)) {
1011 /* QH */
1012 trace_usb_uhci_qh_load(link & ~0xf);
1013
1014 if (qhdb_insert(&qhdb, link)) {
1015 /*
1016 * We're going in circles. Which is not a bug because
1017 * HCD is allowed to do that as part of the BW management.
1018 *
1005 if (is_qh(link)) {
1006 /* QH */
1007 trace_usb_uhci_qh_load(link & ~0xf);
1008
1009 if (qhdb_insert(&qhdb, link)) {
1010 /*
1011 * We're going in circles. Which is not a bug because
1012 * HCD is allowed to do that as part of the BW management.
1013 *
1019 * Stop processing here if no transaction has been done
1020 * since we've been here last time.
1014 * Stop processing here if
1015 * (a) no transaction has been done since we've been
1016 * here last time, or
1017 * (b) we've reached the usb 1.1 bandwidth, which is
1018 * 1280 bytes/frame.
1021 */
1022 if (td_count == 0) {
1023 trace_usb_uhci_frame_loop_stop_idle();
1024 break;
1019 */
1020 if (td_count == 0) {
1021 trace_usb_uhci_frame_loop_stop_idle();
1022 break;
1023 } else if (bytes_count >= 1280) {
1024 trace_usb_uhci_frame_loop_stop_bandwidth();
1025 break;
1025 } else {
1026 trace_usb_uhci_frame_loop_continue();
1027 td_count = 0;
1028 qhdb_reset(&qhdb);
1029 qhdb_insert(&qhdb, link);
1030 }
1031 }
1032

--- 46 unchanged lines hidden (view full) ---

1079 }
1080 link = curr_qh ? qh.link : td.link;
1081 continue;
1082
1083 case TD_RESULT_COMPLETE:
1084 trace_usb_uhci_td_complete(curr_qh & ~0xf, link & ~0xf);
1085 link = td.link;
1086 td_count++;
1026 } else {
1027 trace_usb_uhci_frame_loop_continue();
1028 td_count = 0;
1029 qhdb_reset(&qhdb);
1030 qhdb_insert(&qhdb, link);
1031 }
1032 }
1033

--- 46 unchanged lines hidden (view full) ---

1080 }
1081 link = curr_qh ? qh.link : td.link;
1082 continue;
1083
1084 case TD_RESULT_COMPLETE:
1085 trace_usb_uhci_td_complete(curr_qh & ~0xf, link & ~0xf);
1086 link = td.link;
1087 td_count++;
1087 s->frame_bytes += (td.ctrl & 0x7ff) + 1;
1088 bytes_count += (td.ctrl & 0x7ff) + 1;
1088
1089 if (curr_qh) {
1090 /* update QH element link */
1091 qh.el_link = link;
1092 val = cpu_to_le32(qh.el_link);
1093 pci_dma_write(&s->dev, (curr_qh & ~0xf) + 4, &val, sizeof(val));
1094
1095 if (!depth_first(link)) {

--- 10 unchanged lines hidden (view full) ---

1106
1107 /* go to the next entry */
1108 }
1109
1110out:
1111 s->pending_int_mask |= int_mask;
1112}
1113
1089
1090 if (curr_qh) {
1091 /* update QH element link */
1092 qh.el_link = link;
1093 val = cpu_to_le32(qh.el_link);
1094 pci_dma_write(&s->dev, (curr_qh & ~0xf) + 4, &val, sizeof(val));
1095
1096 if (!depth_first(link)) {

--- 10 unchanged lines hidden (view full) ---

1107
1108 /* go to the next entry */
1109 }
1110
1111out:
1112 s->pending_int_mask |= int_mask;
1113}
1114
1114static void uhci_bh(void *opaque)
1115{
1116 UHCIState *s = opaque;
1117 uhci_process_frame(s);
1118}
1119
1120static void uhci_frame_timer(void *opaque)
1121{
1122 UHCIState *s = opaque;
1123
1124 /* prepare the timer for the next frame */
1125 s->expire_time += (get_ticks_per_sec() / FRAME_TIMER_FREQ);
1115static void uhci_frame_timer(void *opaque)
1116{
1117 UHCIState *s = opaque;
1118
1119 /* prepare the timer for the next frame */
1120 s->expire_time += (get_ticks_per_sec() / FRAME_TIMER_FREQ);
1126 s->frame_bytes = 0;
1127 qemu_bh_cancel(s->bh);
1128
1129 if (!(s->cmd & UHCI_CMD_RS)) {
1130 /* Full stop */
1131 trace_usb_uhci_schedule_stop();
1132 qemu_del_timer(s->frame_timer);
1133 uhci_async_cancel_all(s);
1134 /* set hchalted bit in status - UHCI11D 2.1.2 */
1135 s->status |= UHCI_STS_HCHALTED;

--- 44 unchanged lines hidden (view full) ---

1180 .complete = uhci_async_complete,
1181};
1182
1183static USBBusOps uhci_bus_ops = {
1184};
1185
1186static int usb_uhci_common_initfn(PCIDevice *dev)
1187{
1121
1122 if (!(s->cmd & UHCI_CMD_RS)) {
1123 /* Full stop */
1124 trace_usb_uhci_schedule_stop();
1125 qemu_del_timer(s->frame_timer);
1126 uhci_async_cancel_all(s);
1127 /* set hchalted bit in status - UHCI11D 2.1.2 */
1128 s->status |= UHCI_STS_HCHALTED;

--- 44 unchanged lines hidden (view full) ---

1173 .complete = uhci_async_complete,
1174};
1175
1176static USBBusOps uhci_bus_ops = {
1177};
1178
1179static int usb_uhci_common_initfn(PCIDevice *dev)
1180{
1188 PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
1189 UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
1190 uint8_t *pci_conf = s->dev.config;
1191 int i;
1192
1193 pci_conf[PCI_CLASS_PROG] = 0x00;
1194 /* TODO: reset value should be 0. */
1181 UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
1182 uint8_t *pci_conf = s->dev.config;
1183 int i;
1184
1185 pci_conf[PCI_CLASS_PROG] = 0x00;
1186 /* TODO: reset value should be 0. */
1187 pci_conf[PCI_INTERRUPT_PIN] = 4; /* interrupt pin D */
1195 pci_conf[USB_SBRN] = USB_RELEASE_1; // release number
1196
1188 pci_conf[USB_SBRN] = USB_RELEASE_1; // release number
1189
1197 switch (pc->device_id) {
1198 case PCI_DEVICE_ID_INTEL_82801I_UHCI1:
1199 s->irq_pin = 0; /* A */
1200 break;
1201 case PCI_DEVICE_ID_INTEL_82801I_UHCI2:
1202 s->irq_pin = 1; /* B */
1203 break;
1204 case PCI_DEVICE_ID_INTEL_82801I_UHCI3:
1205 s->irq_pin = 2; /* C */
1206 break;
1207 default:
1208 s->irq_pin = 3; /* D */
1209 break;
1210 }
1211 pci_config_set_interrupt_pin(pci_conf, s->irq_pin + 1);
1212
1213 if (s->masterbus) {
1214 USBPort *ports[NB_PORTS];
1215 for(i = 0; i < NB_PORTS; i++) {
1216 ports[i] = &s->ports[i].port;
1217 }
1218 if (usb_register_companion(s->masterbus, ports, NB_PORTS,
1219 s->firstport, s, &uhci_port_ops,
1220 USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL) != 0) {
1221 return -1;
1222 }
1223 } else {
1224 usb_bus_new(&s->bus, &uhci_bus_ops, &s->dev.qdev);
1225 for (i = 0; i < NB_PORTS; i++) {
1226 usb_register_port(&s->bus, &s->ports[i].port, s, i, &uhci_port_ops,
1227 USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
1228 }
1229 }
1190 if (s->masterbus) {
1191 USBPort *ports[NB_PORTS];
1192 for(i = 0; i < NB_PORTS; i++) {
1193 ports[i] = &s->ports[i].port;
1194 }
1195 if (usb_register_companion(s->masterbus, ports, NB_PORTS,
1196 s->firstport, s, &uhci_port_ops,
1197 USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL) != 0) {
1198 return -1;
1199 }
1200 } else {
1201 usb_bus_new(&s->bus, &uhci_bus_ops, &s->dev.qdev);
1202 for (i = 0; i < NB_PORTS; i++) {
1203 usb_register_port(&s->bus, &s->ports[i].port, s, i, &uhci_port_ops,
1204 USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
1205 }
1206 }
1230 s->bh = qemu_bh_new(uhci_bh, s);
1231 s->frame_timer = qemu_new_timer_ns(vm_clock, uhci_frame_timer, s);
1232 s->num_ports_vmstate = NB_PORTS;
1233 QTAILQ_INIT(&s->queues);
1234
1235 qemu_register_reset(uhci_reset, s);
1236
1237 memory_region_init_io(&s->io_bar, &uhci_ioport_ops, s, "uhci", 0x20);
1238 /* Use region 4 for consistency with real hardware. BSD guests seem

--- 13 unchanged lines hidden (view full) ---

1252 /* PM capability */
1253 pci_set_long(pci_conf + 0x80,0x00020001);
1254 /* USB legacy support */
1255 pci_set_long(pci_conf + 0xc0,0x00002000);
1256
1257 return usb_uhci_common_initfn(dev);
1258}
1259
1207 s->frame_timer = qemu_new_timer_ns(vm_clock, uhci_frame_timer, s);
1208 s->num_ports_vmstate = NB_PORTS;
1209 QTAILQ_INIT(&s->queues);
1210
1211 qemu_register_reset(uhci_reset, s);
1212
1213 memory_region_init_io(&s->io_bar, &uhci_ioport_ops, s, "uhci", 0x20);
1214 /* Use region 4 for consistency with real hardware. BSD guests seem

--- 13 unchanged lines hidden (view full) ---

1228 /* PM capability */
1229 pci_set_long(pci_conf + 0x80,0x00020001);
1230 /* USB legacy support */
1231 pci_set_long(pci_conf + 0xc0,0x00002000);
1232
1233 return usb_uhci_common_initfn(dev);
1234}
1235
1260static int usb_uhci_exit(PCIDevice *dev)
1236static void usb_uhci_exit(PCIDevice *dev)
1261{
1262 UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
1263
1264 memory_region_destroy(&s->io_bar);
1237{
1238 UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
1239
1240 memory_region_destroy(&s->io_bar);
1265 return 0;
1266}
1267
1268static Property uhci_properties[] = {
1269 DEFINE_PROP_STRING("masterbus", UHCIState, masterbus),
1270 DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0),
1241}
1242
1243static Property uhci_properties[] = {
1244 DEFINE_PROP_STRING("masterbus", UHCIState, masterbus),
1245 DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0),
1271 DEFINE_PROP_UINT32("bandwidth", UHCIState, frame_bandwidth, 1280),
1272 DEFINE_PROP_END_OF_LIST(),
1273};
1274
1275static void piix3_uhci_class_init(ObjectClass *klass, void *data)
1276{
1277 DeviceClass *dc = DEVICE_CLASS(klass);
1278 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1279

--- 135 unchanged lines hidden ---
1246 DEFINE_PROP_END_OF_LIST(),
1247};
1248
1249static void piix3_uhci_class_init(ObjectClass *klass, void *data)
1250{
1251 DeviceClass *dc = DEVICE_CLASS(klass);
1252 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1253

--- 135 unchanged lines hidden ---