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 provides the upper 32 bits that are concatenated with 32-bit link pointer values to form full 64-bit descriptor addresses (EHCI 1.0, section 2.3.5 and Appendix B).
siTD link pointers are stored as 32-bit values and must be expanded to full 64-bit descriptor addresses when 64-bit mode is enabled. Update the siTD traversal path to use ehci_get_desc_addr() when following link pointers. Appendix B also defines high dword fields for siTD buffer pointers. Add bufptr_hi[] fields to EHCIsitd and use ehci_get_buf_addr() to construct full 64-bit buffer addresses from bufptr[] and bufptr_hi[] when processing split isochronous transfers. This allows buffers above 4GB to be handled correctly. When 64-bit capability is disabled, descriptor and buffer addresses remain 32-bit and existing behaviour is unchanged. Signed-off-by: Jamin Lin <[email protected]> --- hw/usb/hcd-ehci.h | 1 + hw/usb/hcd-ehci.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h index f0cb50ba45..a11d4179cd 100644 --- a/hw/usb/hcd-ehci.h +++ b/hw/usb/hcd-ehci.h @@ -119,6 +119,7 @@ typedef struct EHCIsitd { #define SITD_BUFPTR_TCNT_MASK 0x00000007 uint32_t backptr; /* Standard next link pointer */ + uint32_t bufptr_hi[2]; } EHCIsitd; /* diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index a4a45c7601..d9d1ac2d28 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -1798,7 +1798,7 @@ static int ehci_state_fetchsitd(EHCIState *ehci, int async) warn_report("Skipping active siTD"); } - ehci_set_fetch_addr(ehci, async, sitd.next); + ehci_set_fetch_addr(ehci, async, ehci_get_desc_addr(ehci, sitd.next)); ehci_set_state(ehci, async, EST_FETCHENTRY); return 1; } -- 2.43.0
