[coreboot-gerrit] Patch set updated for coreboot: 79b64fa chromeec: ec_mec: Fix misaligned data access

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Fri Apr 24 14:02:36 CEST 2015


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9987

-gerrit

commit 79b64fabf8e85dfbda7adbc42e7c2d4ebea75d87
Author: Shawn Nematbakhsh <shawnn at chromium.org>
Date:   Tue Apr 21 09:30:10 2015 -0700

    chromeec: ec_mec: Fix misaligned data access
    
    Long auto-increment access cannot be used when our initial address is
    misaligned or when our terminal address is misaligned on write
    operations.
    
    BUG=chrome-os-partner:38224
    TEST=Verify host command functionality on cyan.
    BRANCH=None
    
    Change-Id: Ieba0e8e05dabd44a28c63d5d56a2a634c2d349bf
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Commit-Id: a7237c8df027ae70a38478846ff3d5ce97543ff1
    Original-Signed-off-by: Shawn Nematbakhsh <shawnn at chromium.org>
    Original-Change-Id: Id709ca92cc386f9ea5b2a1139733961e1bc59354
    Original-Reviewed-on: https://chromium-review.googlesource.com/266653
    Original-Reviewed-by: Duncan Laurie <dlaurie at chromium.org>
---
 src/ec/google/chromeec/ec_mec.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/src/ec/google/chromeec/ec_mec.c b/src/ec/google/chromeec/ec_mec.c
index 9836eda..a062371 100644
--- a/src/ec/google/chromeec/ec_mec.c
+++ b/src/ec/google/chromeec/ec_mec.c
@@ -76,12 +76,22 @@ void mec_io_bytes(int write, u16 port, unsigned int length, u8 *buf, u8 *csum)
 {
 	int i = 0;
 	int io_addr;
+	u8 access_mode, new_access_mode;
 
 	if (length == 0)
 		return;
 
+	/*
+	 * Long access cannot be used on misaligned data since reading B0 loads
+	 * the data register and writing B3 flushes.
+	 */
+	if (port & 0x3)
+		access_mode = ACCESS_TYPE_BYTE;
+	else
+		access_mode = ACCESS_TYPE_LONG_AUTO_INCREMENT;
+
 	/* Initialize I/O at desired address */
-	mec_emi_write_address(port, ACCESS_TYPE_LONG_AUTO_INCREMENT);
+	mec_emi_write_address(port, access_mode);
 
 	/* Skip bytes in case of misaligned port */
 	io_addr = MEC_EMI_EC_DATA_B0 + (port & 0x3);
@@ -94,11 +104,26 @@ void mec_io_bytes(int write, u16 port, unsigned int length, u8 *buf, u8 *csum)
 			if (csum)
 				*csum += buf[i];
 
+			port++;
 			/* Extra bounds check in case of misaligned length */
 			if (++i == length)
 				return;
 		}
 
+		/*
+		 * Use long auto-increment access except for misaligned write,
+		 * since writing B3 triggers the flush.
+		 */
+		if (length - i < 4 && write)
+			new_access_mode = ACCESS_TYPE_BYTE;
+		else
+			new_access_mode = ACCESS_TYPE_LONG_AUTO_INCREMENT;
+		if (new_access_mode != access_mode ||
+		    access_mode != ACCESS_TYPE_LONG_AUTO_INCREMENT) {
+			access_mode = new_access_mode;
+			mec_emi_write_address(port, access_mode);
+		}
+
 		/* Access [B0, B3] on each loop pass */
 		io_addr = MEC_EMI_EC_DATA_B0;
 	}



More information about the coreboot-gerrit mailing list