[SLOF] [PATCH] usb: don't use 64bit accessors
Laurent Vivier
lvivier at redhat.com
Wed Jul 22 21:52:33 AEST 2020
On 22/07/2020 12:35, David Gibson wrote:
> On Tue, Jul 21, 2020 at 03:13:51PM +0200, Laurent Vivier wrote:
>> 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>
>
> Now that we've fixed this on the qemu side, this isn't so necessary.
> Alexey seems to think there might be some value to it for robustness,
> but we don't need to rush to get this into the SLOF that ships with
> qemu 5.1
I agree. I've posted the patch because I started by fixing SLOF so it
was already written.
Thanks,
Laurent
>> ---
>> 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)
>
More information about the SLOF
mailing list