From: Jamin Lin <jamin_lin@aspeedtech.com>
To: "peterx@redhat.com" <peterx@redhat.com>,
"philmd@linaro.org" <philmd@linaro.org>,
"Cédric Le Goater" <clg@kaod.org>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Steven Lee" <steven_lee@aspeedtech.com>,
"Troy Lee" <leetroy@gmail.com>,
"Kane Chen" <kane_chen@aspeedtech.com>,
"Andrew Jeffery" <andrew@codeconstruct.com.au>,
"Joel Stanley" <joel@jms.id.au>,
"Marcel Apfelbaum" <marcel.apfelbaum@gmail.com>,
"Yanan Wang" <wangyanan55@huawei.com>,
"Zhao Liu" <zhao1.liu@intel.com>,
"Michael S. Tsirkin" <mst@redhat.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Richard Henderson" <richard.henderson@linaro.org>,
"Laurent Vivier" <laurent@vivier.eu>,
"Nicholas Piggin" <npiggin@gmail.com>,
"Harsh Prateek Bora" <harshpb@linux.ibm.com>,
"Ilya Leoshkevich" <iii@linux.ibm.com>,
"David Hildenbrand" <david@kernel.org>,
"Halil Pasic" <pasic@linux.ibm.com>,
"Christian Borntraeger" <borntraeger@linux.ibm.com>,
"Eric Farman" <farman@linux.ibm.com>,
"Matthew Rosato" <mjrosato@linux.ibm.com>,
"Cornelia Huck" <cohuck@redhat.com>,
"open list:ASPEED BMCs" <qemu-arm@nongnu.org>,
"open list:All patches CC here" <qemu-devel@nongnu.org>,
"open list:sPAPR pseries" <qemu-ppc@nongnu.org>,
"open list:S390 TCG CPUs" <qemu-s390x@nongnu.org>
Cc: Jamin Lin <jamin_lin@aspeedtech.com>,
Troy Lee <troy_lee@aspeedtech.com>,
"farosas@suse.de" <farosas@suse.de>,
"flwu@google.com" <flwu@google.com>,
"nabihestefan@google.com" <nabihestefan@google.com>
Subject: [PATCH v5 11/18] hw/usb/hcd-ehci: Implement 64-bit QH descriptor addressing
Date: Fri, 24 Apr 2026 08:05:24 +0000 [thread overview]
Message-ID: <20260424080508.53992-12-jamin_lin@aspeedtech.com> (raw)
In-Reply-To: <20260424080508.53992-1-jamin_lin@aspeedtech.com>
EHCI supports 64-bit control data structure addressing when the
64-bit Addressing Capability bit in HCCPARAMS is set. In that mode,
the CTRLDSSEGMENT register supplies the upper 32 bits which are
concatenated with 32-bit link pointer fields to form full 64-bit
descriptor addresses (EHCI 1.0, section 2.3.5 and Appendix B).
The current implementation assumes 32-bit QH descriptor addresses
and directly uses link pointer values without applying the
CTRLDSSEGMENT upper dword.
Introduce a helper, ehci_get_desc_addr(), to construct full 64-bit
descriptor addresses when 64-bit capability is enabled. Update QH
traversal paths (async list walk, horizontal QH link, and periodic
schedule entry handling) to use the translated 64-bit addresses.
EHCI 64-bit buffer pointer fields are defined in Appendix B as
split 32-bit low/high parts located at separate offsets, rather
than a single contiguous 64-bit field. Therefore, the buffer
pointers cannot be represented as uint64_t bufptr[5] without
violating the descriptor layout defined by the specification.
Introduce ehci_get_buf_addr() to construct full 64-bit buffer
addresses from bufptr[] and bufptr_hi[] fields. Use this helper
when calculating transfer buffer addresses so that data buffers
above 4GB are correctly handled.
Also add bufptr_hi[5] to EHCIqh to support 64-bit buffer pointer
fields as defined in Appendix B.
When 64-bit capability is disabled, descriptor addresses remain
32-bit and existing behaviour is unchanged.
Note: Similar split 64-bit buffer pointer handling is required for
qTD, iTD and siTD descriptors, which will be addressed in follow-up
changes.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/usb/hcd-ehci.h | 4 ++++
hw/usb/hcd-ehci.c | 47 ++++++++++++++++++++++++++++++++++-----------
hw/usb/trace-events | 2 +-
3 files changed, 41 insertions(+), 12 deletions(-)
diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h
index f1f2fde578..3428839ec6 100644
--- a/hw/usb/hcd-ehci.h
+++ b/hw/usb/hcd-ehci.h
@@ -141,6 +141,9 @@ typedef struct EHCIqtd {
#define QTD_BUFPTR_SH 12
} EHCIqtd;
+/* QH overlay: altnext_qtd, token, bufptr[5], bufptr_hi[5] */
+#define EHCI_QH_OVERLAY_COUNT 12
+
/*
* EHCI spec version 1.0 Section 3.6
*/
@@ -194,6 +197,7 @@ typedef struct EHCIqh {
#define BUFPTR_FRAMETAG_MASK 0x0000001f
#define BUFPTR_SBYTES_MASK 0x00000fe0
#define BUFPTR_SBYTES_SH 5
+ uint32_t bufptr_hi[5];
} EHCIqh;
enum async_state {
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index b23ff92e12..5ffd4c9885 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -147,6 +147,23 @@ static const char *addr2str(hwaddr addr)
return nr2str(ehci_mmio_names, ARRAY_SIZE(ehci_mmio_names), addr);
}
+static uint64_t ehci_get_buf_addr(const EHCIState *s, uint32_t hi,
+ uint32_t lo, uint32_t lo_mask)
+{
+ uint64_t addr = lo & lo_mask;
+
+ if (s->caps_64bit_addr) {
+ addr = deposit64(addr, 32, 32, hi);
+ }
+
+ return addr;
+}
+
+static uint64_t ehci_get_desc_addr(const EHCIState *s, uint32_t lo)
+{
+ return ehci_get_buf_addr(s, s->ctrldssegment, lo, UINT32_MAX);
+}
+
static void ehci_trace_usbsts(uint32_t mask, int state)
{
/* interrupts */
@@ -440,7 +457,7 @@ static bool ehci_verify_qh(EHCIQueue *q, EHCIqh *qh)
(qh->current_qtd != q->qh.current_qtd) ||
(q->async && qh->next_qtd != q->qh.next_qtd) ||
(memcmp(&qh->altnext_qtd, &q->qh.altnext_qtd,
- 7 * sizeof(uint32_t)) != 0) ||
+ EHCI_QH_OVERLAY_COUNT * sizeof(uint32_t)) != 0) ||
(q->dev != NULL && q->dev->addr != devaddr)) {
return false;
} else {
@@ -1538,7 +1555,9 @@ static int ehci_state_waitlisthead(EHCIState *ehci, int async)
EHCIqh qh;
int i = 0;
int again = 0;
- uint64_t entry = ehci->asynclistaddr;
+ uint64_t entry = 0;
+
+ entry = ehci_get_desc_addr(ehci, ehci->asynclistaddr);
/* set reclamation flag at start event (4.8.6) */
if (async) {
@@ -1566,8 +1585,8 @@ static int ehci_state_waitlisthead(EHCIState *ehci, int async)
goto out;
}
- entry = qh.next;
- if (entry == ehci->asynclistaddr) {
+ entry = ehci_get_desc_addr(ehci, qh.next);
+ if (entry == ehci_get_desc_addr(ehci, ehci->asynclistaddr)) {
break;
}
}
@@ -1693,7 +1712,7 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async)
}
if (trace_event_get_state_backends(TRACE_USB_EHCI_FETCHQH_DBG)) {
- if (q->qhaddr != q->qh.next) {
+ if (q->qhaddr != ehci_get_desc_addr(ehci, q->qh.next)) {
trace_usb_ehci_fetchqh_dbg(q->qhaddr,
q->qh.epchar & QH_EPCHAR_H,
q->qh.token & QTD_TOKEN_HALT,
@@ -1876,10 +1895,12 @@ static int ehci_state_fetchqtd(EHCIQueue *q)
static int ehci_state_horizqh(EHCIQueue *q)
{
+ uint64_t addr;
int again = 0;
- if (ehci_get_fetch_addr(q->ehci, q->async) != q->qh.next) {
- ehci_set_fetch_addr(q->ehci, q->async, q->qh.next);
+ addr = ehci_get_desc_addr(q->ehci, q->qh.next);
+ if (ehci_get_fetch_addr(q->ehci, q->async) != addr) {
+ ehci_set_fetch_addr(q->ehci, q->async, addr);
ehci_set_state(q->ehci, q->async, EST_FETCHENTRY);
again = 1;
} else {
@@ -2205,6 +2226,8 @@ static void ehci_advance_periodic_state(EHCIState *ehci)
uint32_t entry;
uint32_t list;
const int async = 0;
+ uint64_t entry64;
+ uint64_t list64;
/* 4.6 */
@@ -2229,12 +2252,14 @@ static void ehci_advance_periodic_state(EHCIState *ehci)
break;
}
list |= ((ehci->frindex & 0x1ff8) >> 1);
-
- if (get_dwords(ehci, list, &entry, 1) < 0) {
+ list64 = ehci_get_desc_addr(ehci, list);
+ if (get_dwords(ehci, list64, &entry, 1) < 0) {
break;
}
- trace_usb_ehci_periodic_state_advance(ehci->frindex / 8, list, entry);
- ehci_set_fetch_addr(ehci, async, entry);
+ entry64 = ehci_get_desc_addr(ehci, entry);
+ trace_usb_ehci_periodic_state_advance(ehci->frindex / 8,
+ list64, entry64);
+ ehci_set_fetch_addr(ehci, async, entry64);
ehci_set_state(ehci, async, EST_FETCHENTRY);
ehci_advance_state(ehci, async);
ehci_queues_rip_unused(ehci, async);
diff --git a/hw/usb/trace-events b/hw/usb/trace-events
index 8c90688bb3..67249d69c2 100644
--- a/hw/usb/trace-events
+++ b/hw/usb/trace-events
@@ -113,7 +113,7 @@ usb_ehci_dma_error(void) ""
usb_ehci_execute_complete(uint64_t qhaddr, uint32_t next, uint64_t qtdaddr, int status, int actual_length) "qhaddr=0x%" PRIx64 ", next=0x%x, qtdaddr=0x%" PRIx64 ", status=%d, actual_length=%d"
usb_ehci_fetchqh_reclaim_done(uint64_t qhaddr) "QH 0x%" PRIx64 " H-bit set, reclamation status reset - done processing"
usb_ehci_fetchqh_dbg(uint64_t qhaddr, uint32_t h, uint32_t halt, uint32_t active, uint32_t next) "QH 0x%" PRIx64 " (h 0x%x halt 0x%x active 0x%x) next 0x%08x"
-usb_ehci_periodic_state_advance(uint32_t frame, uint32_t list, uint32_t entry) "frame=%d, list=0x%x, entry=0x%x"
+usb_ehci_periodic_state_advance(uint32_t frame, uint64_t list, uint64_t entry) "frame=%d, list=0x%" PRIx64 ", entry=0x%" PRIx64
usb_ehci_skipped_uframes(uint64_t skipped_uframes) "skipped %" PRIu64 " uframes"
usb_ehci_log(const char *msg) "%s"
--
2.43.0
next prev parent reply other threads:[~2026-04-24 8:06 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-24 8:05 [PATCH v5 00/18] hw/usb/ehci: Add 64-bit descriptor addressing support Jamin Lin
2026-04-24 8:05 ` [PATCH v5 01/18] tests/functional/arm/test_aspeed_ast2600_sdk: Add USB EHCI test for AST2600 SDK Jamin Lin
2026-04-24 8:05 ` [PATCH v5 02/18] hw/usb/hcd-ehci: Remove unused EHCIfstn structure and dead code Jamin Lin
2026-04-24 8:05 ` [PATCH v5 03/18] hw/usb/hcd-ehci.h: Fix coding style issues reported by checkpatch Jamin Lin
2026-04-24 8:05 ` [PATCH v5 04/18] hw/usb/hcd-ehci.c: " Jamin Lin
2026-04-24 8:05 ` [PATCH v5 05/18] hw/usb/hcd-ehci.c: Replace fprintf(stderr, ...) with qemu_log_mask(LOG_GUEST_ERROR) Jamin Lin
2026-04-24 8:05 ` [PATCH v5 06/18] hw/usb/hcd-ehci: Replace DPRINTF debug logs with trace events Jamin Lin
2026-04-24 8:05 ` [PATCH v5 07/18] hw/usb/hcd-ehci: Introduce common properties macro for sysbus and pci Jamin Lin
2026-04-24 15:23 ` Philippe Mathieu-Daudé
2026-04-24 8:05 ` [PATCH v5 08/18] hw/core: Add 11.0 machine compatibility properties Jamin Lin
2026-04-24 8:05 ` [PATCH v5 09/18] hw/usb/hcd-ehci: Change descriptor addresses to 64-bit with migration compatibility Jamin Lin
2026-04-24 11:35 ` Peter Xu
2026-05-03 20:20 ` Cédric Le Goater
2026-05-04 2:25 ` Jamin Lin
2026-04-24 8:05 ` [PATCH v5 10/18] hw/usb/hcd-ehci: Add property to advertise 64-bit addressing capability Jamin Lin
2026-05-03 20:18 ` Cédric Le Goater
2026-05-04 2:10 ` Jamin Lin
2026-04-24 8:05 ` Jamin Lin [this message]
2026-04-24 8:05 ` [PATCH v5 12/18] hw/usb/hcd-ehci: Implement 64-bit qTD descriptor addressing Jamin Lin
2026-04-24 8:05 ` [PATCH v5 13/18] hw/usb/hcd-ehci: Implement 64-bit iTD " Jamin Lin
2026-04-24 8:05 ` [PATCH v5 14/18] hw/usb/hcd-ehci: Implement 64-bit siTD " Jamin Lin
2026-04-24 8:05 ` [PATCH v5 15/18] hw/usb/hcd-ehci: Add ctrldssegment-default property Jamin Lin
2026-04-24 8:05 ` [PATCH v5 16/18] hw/arm/aspeed_ast27x0: Set EHCI ctrldssegment-default Jamin Lin
2026-05-03 20:18 ` Cédric Le Goater
2026-05-04 2:19 ` Jamin Lin
2026-04-24 8:05 ` [PATCH v5 17/18] hw/arm/aspeed_ast27x0: Enable 64-bit EHCI DMA addressing Jamin Lin
2026-04-24 8:05 ` [PATCH v5 18/18] tests/functional/aarch64/test_aspeed_ast2700: Add USB EHCI test for AST2700 A1/A2 Jamin Lin
2026-05-03 20:23 ` [PATCH v5 00/18] hw/usb/ehci: Add 64-bit descriptor addressing support Cédric Le Goater
2026-05-04 2:48 ` Jamin Lin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260424080508.53992-12-jamin_lin@aspeedtech.com \
--to=jamin_lin@aspeedtech.com \
--cc=andrew@codeconstruct.com.au \
--cc=borntraeger@linux.ibm.com \
--cc=clg@kaod.org \
--cc=cohuck@redhat.com \
--cc=david@kernel.org \
--cc=farman@linux.ibm.com \
--cc=farosas@suse.de \
--cc=flwu@google.com \
--cc=harshpb@linux.ibm.com \
--cc=iii@linux.ibm.com \
--cc=joel@jms.id.au \
--cc=kane_chen@aspeedtech.com \
--cc=laurent@vivier.eu \
--cc=leetroy@gmail.com \
--cc=marcel.apfelbaum@gmail.com \
--cc=mjrosato@linux.ibm.com \
--cc=mst@redhat.com \
--cc=nabihestefan@google.com \
--cc=npiggin@gmail.com \
--cc=pasic@linux.ibm.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=peterx@redhat.com \
--cc=philmd@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
--cc=qemu-s390x@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=steven_lee@aspeedtech.com \
--cc=troy_lee@aspeedtech.com \
--cc=wangyanan55@huawei.com \
--cc=zhao1.liu@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.