From 3c7888bf293ad6c5d879dd0ef1ddc1a6bad7470c Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Sat, 18 Jul 2020 20:49:38 +0200 Subject: libpayload/xhci: Try harder to read 32-bit caps at once With commit 287cf6c7d1 (lp/drivers/usb: Work around QEMU XHCI register issue) we restructured our capability register accesses because the compiler used the wrong access size. While we do use only 32-bit types now, a compiler may still try to be clever and optimize things in unexpected ways. So we add an explicit read32() now. For instance for the 8-bit MaxPorts field, in the most significant bits of `capreg + 4`, our read + mask + shift ((cap)->hciparams1 & 0xff000000) >> 24 was turned into a single 8-bit read instruction by GCC on x86: 31: 0f b6 52 07 movzbl 0x7(%edx),%edx Change-Id: I76accd0ef718e70ca46807eb06a9177c3afd99f1 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/43575 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie Reviewed-by: Angel Pons Reviewed-by: Julius Werner --- payloads/libpayload/drivers/usb/xhci_private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/payloads/libpayload/drivers/usb/xhci_private.h b/payloads/libpayload/drivers/usb/xhci_private.h index 8e11937ac5..b4c8825dc6 100644 --- a/payloads/libpayload/drivers/usb/xhci_private.h +++ b/payloads/libpayload/drivers/usb/xhci_private.h @@ -363,7 +363,7 @@ typedef struct erst_entry { #define CAP_CSZ_LEN 1 #define CAP_MASK(tok) MASK(CAP_##tok##_START, CAP_##tok##_LEN) -#define CAP_GET(tok, cap) (((cap)->CAP_##tok##_FIELD & CAP_MASK(tok)) \ +#define CAP_GET(tok, cap) ((read32(&(cap)->CAP_##tok##_FIELD) & CAP_MASK(tok)) \ >> CAP_##tok##_START) #define CTXSIZE(xhci) (CAP_GET(CSZ, (xhci)->capreg) ? 64 : 32) -- cgit v1.2.3