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 <jamin_lin@aspeedtech.com>
---
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