summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Werner <jwerner@chromium.org>2015-08-07 13:14:20 -0700
committerAaron Durbin <adurbin@chromium.org>2015-08-14 15:17:30 +0200
commit57ddd9abc79048efc658878f021927846fef6a0a (patch)
tree968317136c761b56085799463d3fd46eb98a76c4
parent8b4988933c129028f97a7300800ff58afbb366d6 (diff)
downloadcoreboot-57ddd9abc79048efc658878f021927846fef6a0a.tar.xz
libpayload: usb: xhci: Count new Max Scratchpad Bufs bits from XHCI 1.1
The 1.1 revision of the XHCI specification added an extra 5 bits to the Max Scratchpad Bufs field of HCSPARAMS2 that newer controllers make use of. Not honoring these bits means we're not allocating as many scratchpad buffers as the controller expects, which means it will interpret some uninitialized values from the end of the pointer array as scratchpad buffer pointers, which obviously doesn't end well. Let's fix that. BRANCH=none BUG=chrome-os-partner:42279 TEST=Makes a USB-related memory corruption issue disappear. Original-Change-Id: I7c907492339262bda31cdd2b5c0b588de7df8544 Original-Signed-off-by: Julius Werner <jwerner@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/291681 Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org> Change-Id: Iba1007bfebffe1f564f78bb875fff9ba0fe11a38 Signed-off-by: Julius Werner <jwerner@chromium.org> Reviewed-on: http://review.coreboot.org/11189 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
-rw-r--r--payloads/libpayload/drivers/usb/xhci.c6
-rw-r--r--payloads/libpayload/drivers/usb/xhci_private.h5
2 files changed, 7 insertions, 4 deletions
diff --git a/payloads/libpayload/drivers/usb/xhci.c b/payloads/libpayload/drivers/usb/xhci.c
index 315efb7530..71272c7133 100644
--- a/payloads/libpayload/drivers/usb/xhci.c
+++ b/payloads/libpayload/drivers/usb/xhci.c
@@ -227,7 +227,8 @@ xhci_init (unsigned long physical_bar)
* Let dcbaa[0] point to another array of pointers, sp_ptrs.
* The pointers therein point to scratchpad buffers (pages).
*/
- const size_t max_sp_bufs = xhci->capreg->Max_Scratchpad_Bufs;
+ const size_t max_sp_bufs = xhci->capreg->Max_Scratchpad_Bufs_Hi << 5 |
+ xhci->capreg->Max_Scratchpad_Bufs_Lo;
xhci_debug("max scratchpad bufs: 0x%zx\n", max_sp_bufs);
if (max_sp_bufs) {
const size_t sp_ptrs_size = max_sp_bufs * sizeof(u64);
@@ -417,7 +418,8 @@ xhci_shutdown(hci_t *const controller)
#endif
if (xhci->sp_ptrs) {
- const size_t max_sp_bufs = xhci->capreg->Max_Scratchpad_Bufs;
+ size_t max_sp_bufs = xhci->capreg->Max_Scratchpad_Bufs_Hi << 5 |
+ xhci->capreg->Max_Scratchpad_Bufs_Lo;
for (i = 0; i < max_sp_bufs; ++i) {
if (xhci->sp_ptrs[i])
free(phys_to_virt(xhci->sp_ptrs[i]));
diff --git a/payloads/libpayload/drivers/usb/xhci_private.h b/payloads/libpayload/drivers/usb/xhci_private.h
index 05cf195235..f64442579d 100644
--- a/payloads/libpayload/drivers/usb/xhci_private.h
+++ b/payloads/libpayload/drivers/usb/xhci_private.h
@@ -348,9 +348,10 @@ typedef struct xhci {
struct {
unsigned long IST:4;
unsigned long ERST_Max:4;
- unsigned long:18;
+ unsigned long:13;
+ unsigned long Max_Scratchpad_Bufs_Hi:5;
unsigned long SPR:1;
- unsigned long Max_Scratchpad_Bufs:5;
+ unsigned long Max_Scratchpad_Bufs_Lo:5;
} __attribute__ ((packed));
} __attribute__ ((packed));
union {