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

Reply via email to