From: Jamin Lin <jamin_lin@aspeedtech.com>
To: "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>,
"open list:ASPEED BMCs" <qemu-arm@nongnu.org>,
"open list:All patches CC here" <qemu-devel@nongnu.org>
Cc: Jamin Lin <jamin_lin@aspeedtech.com>,
Troy Lee <troy_lee@aspeedtech.com>,
"flwu@google.com" <flwu@google.com>,
"nabihestefan@google.com" <nabihestefan@google.com>
Subject: [PATCH v3 09/17] hw/usb/hcd-ehci: Implement 64-bit QH descriptor addressing
Date: Thu, 16 Apr 2026 01:49:47 +0000 [thread overview]
Message-ID: <20260416014928.1279360-10-jamin_lin@aspeedtech.com> (raw)
In-Reply-To: <20260416014928.1279360-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>
---
hw/usb/hcd-ehci.h | 4 ++++
hw/usb/hcd-ehci.c | 48 ++++++++++++++++++++++++++++++++++-----------
hw/usb/trace-events | 2 +-
3 files changed, 42 insertions(+), 12 deletions(-)
diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h
index fe4c508c32..773f376834 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 b9e4251d62..37ae637e08 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -147,6 +147,24 @@ static const char *addr2str(hwaddr addr)
return nr2str(ehci_mmio_names, ARRAY_SIZE(ehci_mmio_names), addr);
}
+static uint64_t ehci_get_buf_addr(EHCIState *s, uint32_t hi, uint32_t low,
+ uint32_t mask)
+{
+ uint64_t addr;
+
+ addr = (uint64_t)(low & mask);
+ if (s->caps_64bit_addr) {
+ addr |= (uint64_t)hi << 32;
+ }
+
+ return addr;
+}
+
+static uint64_t ehci_get_desc_addr(EHCIState *s, uint32_t low)
+{
+ return ehci_get_buf_addr(s, s->ctrldssegment, low, UINT32_MAX);
+}
+
static void ehci_trace_usbsts(uint32_t mask, int state)
{
/* interrupts */
@@ -440,7 +458,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 {
@@ -1536,7 +1554,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) {
@@ -1564,8 +1584,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;
}
}
@@ -1691,7 +1711,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,
@@ -1868,10 +1888,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 {
@@ -2200,6 +2222,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 */
@@ -2224,12 +2248,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-16 1:51 UTC|newest]
Thread overview: 69+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-16 1:49 [PATCH v3 00/17] hw/usb/ehci: Add 64-bit descriptor addressing support Jamin Lin
2026-04-16 1:49 ` [PATCH v3 01/17] hw/usb/hcd-ehci: Remove unused EHCIfstn structure and dead code Jamin Lin
2026-04-16 12:09 ` BALATON Zoltan
2026-04-17 1:16 ` Jamin Lin
2026-04-17 2:25 ` Jamin Lin
2026-04-17 9:47 ` BALATON Zoltan
2026-04-20 3:46 ` Jamin Lin
2026-04-17 6:30 ` Cédric Le Goater
2026-04-16 1:49 ` [PATCH v3 02/17] hw/usb/hcd-ehci.h: Fix coding style issues reported by checkpatch Jamin Lin
2026-04-17 6:32 ` Philippe Mathieu-Daudé
2026-04-16 1:49 ` [PATCH v3 03/17] hw/usb/hcd-ehci.c: " Jamin Lin
2026-04-17 6:31 ` Cédric Le Goater
2026-04-17 6:32 ` Philippe Mathieu-Daudé
2026-04-16 1:49 ` [PATCH v3 04/17] hw/usb/hcd-ehci.c: Replace fprintf(stderr, ...) with qemu_log_mask(LOG_GUEST_ERROR) Jamin Lin
2026-04-17 6:31 ` Philippe Mathieu-Daudé
2026-04-17 8:41 ` Jamin Lin
2026-04-16 1:49 ` [PATCH v3 05/17] hw/usb/hcd-ehci: Replace DPRINTF debug logs with trace events Jamin Lin
2026-04-17 5:04 ` Philippe Mathieu-Daudé
2026-04-16 1:49 ` [PATCH v3 06/17] hw/usb/hcd-ehci: Change descriptor addresses to 64-bit Jamin Lin
2026-04-17 4:54 ` Philippe Mathieu-Daudé
2026-04-17 7:01 ` Cédric Le Goater
2026-04-17 15:10 ` Peter Xu
2026-04-20 5:56 ` Jamin Lin
2026-04-20 13:34 ` Peter Xu
2026-04-22 9:21 ` Jamin Lin
2026-04-22 14:37 ` Peter Xu
2026-04-23 1:48 ` Jamin Lin
2026-04-23 16:03 ` Peter Xu
2026-04-20 16:04 ` Cédric Le Goater
2026-04-22 9:10 ` Jamin Lin
2026-04-16 1:49 ` [PATCH v3 07/17] hw/usb/hcd-ehci: Add property to advertise 64-bit addressing capability Jamin Lin
2026-04-17 4:55 ` Philippe Mathieu-Daudé
2026-04-16 1:49 ` [PATCH v3 08/17] hw/usb/hcd-ehci: Reject CTRLDSSEGMENT writes without 64-bit capability Jamin Lin
2026-04-17 6:33 ` Philippe Mathieu-Daudé
2026-04-17 8:07 ` Jamin Lin
2026-04-16 1:49 ` Jamin Lin [this message]
2026-04-17 5:03 ` [PATCH v3 09/17] hw/usb/hcd-ehci: Implement 64-bit QH descriptor addressing Philippe Mathieu-Daudé
2026-04-17 5:40 ` Jamin Lin
2026-04-17 6:14 ` Philippe Mathieu-Daudé
2026-04-17 7:02 ` Jamin Lin
2026-04-16 1:49 ` [PATCH v3 10/17] hw/usb/hcd-ehci: Implement 64-bit qTD " Jamin Lin
2026-04-17 6:14 ` Philippe Mathieu-Daudé
2026-04-16 1:49 ` [PATCH v3 11/17] hw/usb/hcd-ehci: Implement 64-bit iTD " Jamin Lin
2026-04-17 6:15 ` Philippe Mathieu-Daudé
2026-04-16 1:49 ` [PATCH v3 12/17] hw/usb/hcd-ehci: Implement 64-bit siTD " Jamin Lin
2026-04-17 6:27 ` Philippe Mathieu-Daudé
2026-04-17 7:44 ` Jamin Lin
2026-04-17 8:42 ` Philippe Mathieu-Daudé
2026-04-16 1:49 ` [PATCH v3 13/17] hw/usb/hcd-ehci: Add descriptor address offset property Jamin Lin
2026-04-17 6:23 ` Philippe Mathieu-Daudé
2026-04-22 5:00 ` Jamin Lin
2026-04-17 6:45 ` Cédric Le Goater
2026-04-17 7:08 ` Philippe Mathieu-Daudé
2026-04-20 5:47 ` Jamin Lin
2026-04-20 7:08 ` Cédric Le Goater
2026-04-22 6:58 ` Jamin Lin
2026-04-16 1:50 ` [PATCH v3 14/17] hw/arm/aspeed_ast27x0: Enable 64-bit EHCI DMA addressing Jamin Lin
2026-04-17 6:23 ` Philippe Mathieu-Daudé
2026-04-16 1:50 ` [PATCH v3 15/17] hw/arm/aspeed_ast27x0: Set EHCI descriptor address offset Jamin Lin
2026-04-17 6:25 ` Philippe Mathieu-Daudé
2026-04-22 5:03 ` Jamin Lin
2026-04-16 1:50 ` [PATCH v3 16/17] tests/functional/arm/test_aspeed_ast2600_sdk: Add USB EHCI test for AST2600 SDK Jamin Lin
2026-04-17 6:27 ` Philippe Mathieu-Daudé
2026-04-17 7:40 ` Jamin Lin
2026-04-17 8:44 ` Philippe Mathieu-Daudé
2026-04-17 8:50 ` Jamin Lin
2026-04-16 1:50 ` [PATCH v3 17/17] tests/functional/aarch64/test_aspeed_ast2700: Add USB EHCI test for AST2700 A1/A2 Jamin Lin
2026-04-17 6:27 ` Philippe Mathieu-Daudé
2026-04-17 6:35 ` [PATCH v3 00/17] hw/usb/ehci: Add 64-bit descriptor addressing support Philippe Mathieu-Daudé
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=20260416014928.1279360-10-jamin_lin@aspeedtech.com \
--to=jamin_lin@aspeedtech.com \
--cc=andrew@codeconstruct.com.au \
--cc=clg@kaod.org \
--cc=flwu@google.com \
--cc=joel@jms.id.au \
--cc=kane_chen@aspeedtech.com \
--cc=leetroy@gmail.com \
--cc=nabihestefan@google.com \
--cc=peter.maydell@linaro.org \
--cc=philmd@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=steven_lee@aspeedtech.com \
--cc=troy_lee@aspeedtech.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.