96
*data = val; \
97
} while (0)
98
99
+/*
100
+ * EHCIqh / EHCIqtd / EHCIitd are sized to always include the extended
101
+ * high buffer pointer fields from EHCI 1.0 Appendix B. When 64-bit
102
+ * addressing capability is not advertised to the guest, the descriptors
103
+ * in guest memory only have the classic 32-bit layout, so DMA transfers
104
+ * must not read or write past that boundary.
105
+ */
106
+#define EHCI_QH_DWORDS_32 (offsetof(EHCIqh, bufptr_hi) / sizeof(uint32_t))
107
+
108
static const char *ehci_state_names[] = {
109
[EST_INACTIVE] = "INACTIVE",
110
[EST_ACTIVE] = "ACTIVE",
156
return nr2str(ehci_mmio_names, ARRAY_SIZE(ehci_mmio_names), addr);
157
}
158
159
+static uint64_t ehci_get_buf_addr(const EHCIState *s, uint32_t hi,
160
+ uint32_t lo, uint32_t lo_mask)
161
+{
162
+ uint64_t addr = lo & lo_mask;
163
+
164
+ if (s->caps_64bit_addr) {
165
+ addr = deposit64(addr, 32, 32, hi);
166
+ }
167
+
168
+ return addr;
169
+}
170
+
171
+static uint64_t ehci_get_desc_addr(const EHCIState *s, uint32_t lo)
172
+{
173
+ return ehci_get_buf_addr(s, s->ctrldssegment, lo, UINT32_MAX);
174
+}
175
+
176
+static uint32_t ehci_qh_dwords(const EHCIState *s)
177
+{
178
+ return s->caps_64bit_addr ? (sizeof(EHCIqh) >> 2) : EHCI_QH_DWORDS_32;
179
+}
180
+
181
static void ehci_trace_usbsts(uint32_t mask, int state)
182
{
183
/* interrupts */
471
(qh->current_qtd != q->qh.current_qtd) ||
472
(q->async && qh->next_qtd != q->qh.next_qtd) ||
473
(memcmp(&qh->altnext_qtd, &q->qh.altnext_qtd,
443
- 7 * sizeof(uint32_t)) != 0) ||
474
+ EHCI_QH_OVERLAY_COUNT * sizeof(uint32_t)) != 0) ||
475
(q->dev != NULL && q->dev->addr != devaddr)) {
476
return false;
477
} else {
518
int state;
519
520
/* Verify the qh + qtd, like we do when going through fetchqh & fetchqtd */
521
+ memset(&qh, 0, sizeof(qh));
522
get_dwords(q->ehci, NLPTR_GET(q->qhaddr),
491
- (uint32_t *) &qh, sizeof(EHCIqh) >> 2);
523
+ (uint32_t *) &qh, ehci_qh_dwords(q->ehci));
524
get_dwords(q->ehci, NLPTR_GET(q->qtdaddr),
525
(uint32_t *) &qtd, sizeof(EHCIqtd) >> 2);
526
if (!ehci_verify_qh(q, &qh) || !ehci_verify_qtd(p, &qtd)) {
1175
static void ehci_flush_qh(EHCIQueue *q)
1176
{
1177
uint32_t *qh = (uint32_t *) &q->qh;
1146
- uint32_t dwords = sizeof(EHCIqh) >> 2;
1178
+ uint32_t dwords = ehci_qh_dwords(q->ehci);
1179
uint64_t addr = NLPTR_GET(q->qhaddr);
1180
1181
put_dwords(q->ehci, addr + 3 * sizeof(uint32_t), qh + 3, dwords - 3);
1570
EHCIqh qh;
1571
int i = 0;
1572
int again = 0;
1541
- uint64_t entry = ehci->asynclistaddr;
1573
+ uint64_t entry = 0;
1574
+
1575
+ entry = ehci_get_desc_addr(ehci, ehci->asynclistaddr);
1576
1577
/* set reclamation flag at start event (4.8.6) */
1578
if (async) {
1582
ehci_queues_rip_unused(ehci, async);
1583
1584
/* Find the head of the list (4.9.1.1) */
1585
+ memset(&qh, 0, sizeof(qh));
1586
for (i = 0; i < MAX_QH; i++) {
1587
if (get_dwords(ehci, NLPTR_GET(entry), (uint32_t *) &qh,
1553
- sizeof(EHCIqh) >> 2) < 0) {
1588
+ ehci_qh_dwords(ehci)) < 0) {
1589
return 0;
1590
}
1591
ehci_trace_qh(NULL, NLPTR_GET(entry), &qh);
1601
goto out;
1602
}
1603
1569
- entry = qh.next;
1570
- if (entry == ehci->asynclistaddr) {
1604
+ entry = ehci_get_desc_addr(ehci, qh.next);
1605
+ if (entry == ehci_get_desc_addr(ehci, ehci->asynclistaddr)) {
1606
break;
1607
}
1608
}
1686
goto out;
1687
}
1688
1689
+ memset(&qh, 0, sizeof(qh));
1690
if (get_dwords(ehci, NLPTR_GET(q->qhaddr),
1655
- (uint32_t *) &qh, sizeof(EHCIqh) >> 2) < 0) {
1691
+ (uint32_t *) &qh, ehci_qh_dwords(ehci)) < 0) {
1692
q = NULL;
1693
goto out;
1694
}
1729
}
1730
1731
if (trace_event_get_state_backends(TRACE_USB_EHCI_FETCHQH_DBG)) {
1696
- if (q->qhaddr != q->qh.next) {
1732
+ if (q->qhaddr != ehci_get_desc_addr(ehci, q->qh.next)) {
1733
trace_usb_ehci_fetchqh_dbg(q->qhaddr,
1734
q->qh.epchar & QH_EPCHAR_H,
1735
q->qh.token & QTD_TOKEN_HALT,
1912
1913
static int ehci_state_horizqh(EHCIQueue *q)
1914
{
1915
+ uint64_t addr;
1916
int again = 0;
1917
1881
- if (ehci_get_fetch_addr(q->ehci, q->async) != q->qh.next) {
1882
- ehci_set_fetch_addr(q->ehci, q->async, q->qh.next);
1918
+ addr = ehci_get_desc_addr(q->ehci, q->qh.next);
1919
+ if (ehci_get_fetch_addr(q->ehci, q->async) != addr) {
1920
+ ehci_set_fetch_addr(q->ehci, q->async, addr);
1921
ehci_set_state(q->ehci, q->async, EST_FETCHENTRY);
1922
again = 1;
1923
} else {
2243
uint32_t entry;
2244
uint32_t list;
2245
const int async = 0;
2246
+ uint64_t entry64;
2247
+ uint64_t list64;
2248
2249
/* 4.6 */
2250
2269
break;
2270
}
2271
list |= ((ehci->frindex & 0x1ff8) >> 1);
2232
-
2233
- if (get_dwords(ehci, list, &entry, 1) < 0) {
2272
+ list64 = ehci_get_desc_addr(ehci, list);
2273
+ if (get_dwords(ehci, list64, &entry, 1) < 0) {
2274
break;
2275
}
2236
- trace_usb_ehci_periodic_state_advance(ehci->frindex / 8, list, entry);
2237
- ehci_set_fetch_addr(ehci, async, entry);
2276
+ entry64 = ehci_get_desc_addr(ehci, entry);
2277
+ trace_usb_ehci_periodic_state_advance(ehci->frindex / 8,
2278
+ list64, entry64);
2279
+ ehci_set_fetch_addr(ehci, async, entry64);
2280
ehci_set_state(ehci, async, EST_FETCHENTRY);
2281
ehci_advance_state(ehci, async);
2282
ehci_queues_rip_unused(ehci, async);