[coreboot-gerrit] New patch to review for coreboot: google/chromeec: Ensure data is ready before reading it

Furquan Shaikh (furquan@google.com) gerrit at coreboot.org
Fri Aug 19 06:40:44 CEST 2016


Furquan Shaikh (furquan at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16258

-gerrit

commit 2ff94b3bda2f158ab18bbabc0309afee14998713
Author: Furquan Shaikh <furquan at google.com>
Date:   Thu Aug 18 21:39:14 2016 -0700

    google/chromeec: Ensure data is ready before reading it
    
    Before reading the data provided by EC to the host, ensure that data
    ready flag is set. Otherwise, it could result in reading stale/incorrect
    data from the data buffer.
    
    BUG=chrome-os-partner:56395
    BRANCH=None
    TEST=Verified that lidclose event is read correctly by host.
    
    Change-Id: I88e345d64256af8325b3dbf670467d09f09420f0
    Signed-off-by: Furquan Shaikh <furquan at google.com>
---
 src/ec/google/chromeec/ec_lpc.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/src/ec/google/chromeec/ec_lpc.c b/src/ec/google/chromeec/ec_lpc.c
index 06b506b..47f1cd6 100644
--- a/src/ec/google/chromeec/ec_lpc.c
+++ b/src/ec/google/chromeec/ec_lpc.c
@@ -481,6 +481,26 @@ struct chip_operations ec_google_chromeec_ops = {
 
 #endif /* __SMM__ */
 
+static int google_chromeec_data_ready(u16 port)
+{
+	u8 ec_status = read_byte(port);
+	u32 time_count = 0;
+
+	/*
+	 * One second is more than plenty for data to be copied into the data
+	 * buffer.
+	 */
+#define MAX_EC_TIMEOUT_US 1000000
+
+	while (!(ec_status & (EC_LPC_CMDR_DATA))) {
+		udelay(1);
+		if (time_count++ == MAX_EC_TIMEOUT_US)
+			return -1;
+		ec_status = read_byte(port);
+	}
+	return 0;
+}
+
 u8 google_chromeec_get_event(void)
 {
 	if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD)) {
@@ -496,6 +516,11 @@ u8 google_chromeec_get_event(void)
 		return 0;
 	}
 
+	if (google_chromeec_data_ready(EC_LPC_ADDR_ACPI_CMD)) {
+		printk(BIOS_ERR, "Timeout waiting for data ready!\n");
+		return 0;
+	}
+
 	/* Event (or 0 if none) is returned directly in the data byte */
 	return read_byte(EC_LPC_ADDR_ACPI_DATA);
 }



More information about the coreboot-gerrit mailing list