[SLOF] [PATCH] usb: don't use 64bit accessors

Laurent Vivier lvivier at redhat.com
Tue Jul 21 23:13:51 AEST 2020


A recent change in QEMU[1] breaks the 64bit access for XHCI and makes it
unusable.
QEMU always reports the AC64 bit so 64bit should be supported, but in fact
SLOF doesn't check for this bit and always does a 64bit access.

We need to fix QEMU to allow 64bit access when it reports AC64, but we need
also to fix SLOF to not use 64bit access when the AC64 bit is not set.

The easiest way to do that is, like linux kernel in xhci_read_64() and
xhci_write_64() (see drivers/usb/host/xhci.h), to access always a 64bit
register using two 32bit accesses, as the specs allow that.

[1] 5d971f9e6725 ("memory: Revert "memory: accept mismatching sizes in memory_region_access_valid"")

Signed-off-by: Laurent Vivier <lvivier at redhat.com>
---
 lib/libusb/tools.h | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/lib/libusb/tools.h b/lib/libusb/tools.h
index f531175c10a6..5758334b0247 100644
--- a/lib/libusb/tools.h
+++ b/lib/libusb/tools.h
@@ -54,13 +54,21 @@ static inline void write_reg16(uint16_t *reg, uint16_t value)
 
 static inline uint64_t read_reg64(uint64_t *reg)
 {
-	return bswap_64(ci_read_64(reg));
+	uint32_t *p = (uint32_t*)reg;
+	uint32_t low, high;
+
+	low = read_reg32(p);
+	high = read_reg32(p + 1);
+
+	return low + ((uint64_t)high << 32);
 }
 
 static inline void write_reg64(uint64_t *reg, uint64_t value)
 {
-	mb();
-	ci_write_64(reg, bswap_64(value));
+	uint32_t *p = (uint32_t*)reg;
+
+	write_reg32(p, value);
+	write_reg32(p + 1, value >> 32);
 }
 
 static inline uint32_t ci_read_reg(uint32_t *reg)
-- 
2.26.2



More information about the SLOF mailing list