summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Staaf <robotboy@chromium.org>2015-02-11 15:34:52 -0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-02-17 18:19:14 +0000
commit6c83a4d3a560c84e4f7030d3dcad583e92781f8b (patch)
treeb575a9c5b03d838f11be5731b746e84a61edead9
parent2e6bee5642be6d863c8a87b8bf60643b99c64f62 (diff)
downloadchrome-ec-6c83a4d3a560c84e4f7030d3dcad583e92781f8b.tar.gz
USB: fix memcpy_to_usbram
A change to the toolchain or environment surfaced an issue where the writes to packet RAM were being split into two 16-bit writes. This was interacting poorly with the AHB2APB bridge. Marking the packet RAM destination pointer volatile forces the compiler to use full 32-bit writes. Signed-off-by: Anton Staaf <robotboy@chromium.org> BRANCH=None BUG=None TEST=make buildall -j Check that Ryu's console is accessible over USB Change-Id: I0c3db08c704389a627570b90ef97bce81ab553fa Reviewed-on: https://chromium-review.googlesource.com/248840 Trybot-Ready: Anton Staaf <robotboy@chromium.org> Tested-by: Anton Staaf <robotboy@chromium.org> Reviewed-by: Vic Yang <victoryang@chromium.org> Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Commit-Queue: Anton Staaf <robotboy@chromium.org>
-rw-r--r--chip/stm32/usb.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/chip/stm32/usb.c b/chip/stm32/usb.c
index 631dc8a19d..ff71b4e582 100644
--- a/chip/stm32/usb.c
+++ b/chip/stm32/usb.c
@@ -346,9 +346,15 @@ int usb_is_enabled(void)
void *memcpy_to_usbram(void *dest, const void *src, size_t n)
{
- int i;
- uint8_t *s = (uint8_t *) src;
- usb_uint *d = (usb_uint *)((uintptr_t) dest & ~1);
+ /*
+ * The d pointer needs to be volatile to prevent GCC from possibly
+ * breaking writes to the USB packet RAM into multiple 16-bit writes,
+ * which, due to the way the AHB2APB bridge works would clobber what
+ * we write with 32-bit extensions of the 16-bit writes.
+ */
+ int i;
+ uint8_t *s = (uint8_t *) src;
+ usb_uint volatile *d = (usb_uint volatile *)((uintptr_t) dest & ~1);
if ((((uintptr_t) dest) & 1) && n) {
/*