libpayload EHCI: Add memory barrier to EHCI driver

EHCI driver accesses mmio space using regular struct pointers. In order to avoid
any CPU re-ordering, memory barrier is required in async_set_schedule,
especially for arm64. Without the memory barrier, there seems to be re-ordering
taking place which leads to USB errors with some flash drives as well as
transfer errors in netboot.

BUG=chrome-os-partner:31533
BRANCH=None
TEST=With the memory barrier introduced, netboot for ryu completes transfer
without any error and finishes within 6-7 seconds.

Change-Id: Ic05d47422312a1cddbebe3180f4f159853604440
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://chromium-review.googlesource.com/213917
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Tested-by: Furquan Shaikh <furquan@chromium.org>
Commit-Queue: Furquan Shaikh <furquan@chromium.org>
This commit is contained in:
Furquan Shaikh 2014-08-24 23:07:43 -07:00 committed by chrome-internal-fetch
commit 561bdd746c

View file

@ -30,6 +30,7 @@
//#define USB_DEBUG
#include <libpayload.h>
#include <arch/barrier.h>
#include <arch/cache.h>
#include "ehci.h"
#include "ehci_private.h"
@ -317,6 +318,14 @@ static int wait_for_tds(qtd_t *head)
static int ehci_set_async_schedule(ehci_t *ehcic, int enable)
{
/* Memory barrier to ensure that all memory accesses before we set the
* async schedule are complete. It was observed especially in the case of
* arm64, that netboot and usb stuff resulted in lot of errors possibly
* due to CPU reordering. Hence, enforcing strict CPU ordering.
*/
mb();
/* Set async schedule status. */
if (enable)
ehcic->operation->usbcmd |= HC_OP_ASYNC_SCHED_EN;