[coreboot-gerrit] New patch to review for coreboot: 8191649 chromeec: lpc: Read / write IO ports through common functions

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Tue Apr 21 15:19:03 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/9909

-gerrit

commit 8191649cdf104bcb5d53e99cdb86fc383f303acb
Author: Shawn Nematbakhsh <shawnn at chromium.org>
Date:   Wed Apr 1 15:49:57 2015 -0700

    chromeec: lpc: Read / write IO ports through common functions
    
    Rather than calling inb + outb directly, access the ports through common
    functions. This is in preparation for alternative access modes required
    by certain new embedded controllers.
    
    BUG=chrome-os-partner:38224
    TEST=Manual on Samus. Verify system boots cleanly in normal mode.
    BRANCH=None
    
    Change-Id: I98783ff67a37d970019683bb589825bc5d68c033
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Commit-Id: 25afa3f95183d8cf2e9a35272c77e92fbc6ee030
    Original-Change-Id: Ic9d8f7f5c5d392212e39db28ebceea461d46f796
    Original-Signed-off-by: Shawn Nematbakhsh <shawnn at chromium.org>
    Original-Reviewed-on: https://chromium-review.googlesource.com/263571
    Original-Reviewed-by: Duncan Laurie <dlaurie at chromium.org>
---
 src/ec/google/chromeec/ec_lpc.c | 149 +++++++++++++++++++++++++---------------
 1 file changed, 94 insertions(+), 55 deletions(-)

diff --git a/src/ec/google/chromeec/ec_lpc.c b/src/ec/google/chromeec/ec_lpc.c
index f5f5434..0fa0cf8 100644
--- a/src/ec/google/chromeec/ec_lpc.c
+++ b/src/ec/google/chromeec/ec_lpc.c
@@ -29,9 +29,63 @@
 #include "ec.h"
 #include "ec_commands.h"
 
+/*
+ * Read bytes from a given LPC-mapped address.
+ *
+ * @port: Base read address
+ * @length: Number of bytes to read
+ * @dest: Destination buffer
+ * @csum: Optional parameter, sums data read
+ */
+static void read_bytes(u16 port, unsigned int length, u8 *dest, u8 *csum)
+{
+	int i;
+
+	for (i = 0; i < length; ++i) {
+		dest[i] = inb(port + i);
+		if (csum)
+			*csum += dest[i];
+	}
+}
+
+/* Read single byte and return byte read */
+static inline u8 read_byte(u16 port)
+{
+	u8 byte;
+	read_bytes(port, 1, &byte, NULL);
+	return byte;
+}
+
+/*
+ * Write bytes to a given LPC-mapped address.
+ *
+ * @port: Base write address
+ * @length: Number of bytes to write
+ * @msg: Write data buffer
+ * @csum: Optional parameter, sums data written
+ */
+static void write_bytes(u16 port, unsigned int length, u8 *msg, u8 *csum)
+{
+	int i;
+
+	for (i = 0; i < length; ++i) {
+		outb(msg[i], port + i);
+		if (csum)
+			*csum += msg[i];
+	}
+}
+
+/* Write single byte and return byte written */
+static inline u8 write_byte(u8 val, u16 port)
+{
+	u8 byte = val;
+	write_bytes(port, 1, &byte, NULL);
+	return byte;
+}
+
 static int google_chromeec_wait_ready(u16 port)
 {
-	u8 ec_status = inb(port);
+	u8 ec_status = read_byte(port);
 	u32 time_count = 0;
 
 	/*
@@ -46,7 +100,7 @@ static int google_chromeec_wait_ready(u16 port)
 		udelay(1);
 		if (time_count++ == MAX_EC_TIMEOUT_US)
 			return -1;
-		ec_status = inb(port);
+		ec_status = read_byte(port);
 	}
 	return 0;
 }
@@ -61,7 +115,7 @@ static int read_memmap(u8 *data, u8 offset)
 	}
 
 	/* Issue the ACPI read command */
-	outb(EC_CMD_ACPI_READ, EC_LPC_ADDR_ACPI_CMD);
+	write_byte(EC_CMD_ACPI_READ, EC_LPC_ADDR_ACPI_CMD);
 
 	if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD)) {
 		printk(BIOS_ERR, "Timeout waiting for EC READ_EVENT!\n");
@@ -69,14 +123,14 @@ static int read_memmap(u8 *data, u8 offset)
 	}
 
 	/* Write data address */
-	outb(offset + EC_ACPI_MEM_MAPPED_BEGIN, EC_LPC_ADDR_ACPI_DATA);
+	write_byte(offset + EC_ACPI_MEM_MAPPED_BEGIN, EC_LPC_ADDR_ACPI_DATA);
 
 	if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD)) {
 		printk(BIOS_ERR, "Timeout waiting for EC DATA!\n");
 		return -1;
 	}
 
-	*data = inb(EC_LPC_ADDR_ACPI_DATA);
+	*data = read_byte(EC_LPC_ADDR_ACPI_DATA);
 	return 0;
 }
 #endif
@@ -93,9 +147,9 @@ static int google_chromeec_command_version(void)
 		return -1;
 	}
 #else
-	id1 = inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID);
-	id2 = inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID + 1);
-	flags = inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_HOST_CMD_FLAGS);
+	id1 = read_byte(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID);
+	id2 = read_byte(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID + 1);
+	flags = read_byte(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_HOST_CMD_FLAGS);
 #endif
 
 	if (id1 != 'E' || id2 != 'C') {
@@ -119,8 +173,7 @@ static int google_chromeec_command_v3(struct chromeec_command *cec_command)
 	struct ec_host_request rq;
 	struct ec_host_response rs;
 	const u8 *d;
-	u8 *dout;
-	int csum = 0;
+	u8 csum = 0;
 	int i;
 
 	if (cec_command->cmd_size_in + sizeof(rq) > EC_LPC_HOST_PACKET_SIZE) {
@@ -151,25 +204,23 @@ static int google_chromeec_command_v3(struct chromeec_command *cec_command)
 	rq.data_len = cec_command->cmd_size_in;
 
 	/* Copy data and start checksum */
-	for (i = 0, d = (const u8 *)cec_command->cmd_data_in;
-	     i < cec_command->cmd_size_in; i++, d++) {
-		outb(*d, EC_LPC_ADDR_HOST_PACKET + sizeof(rq) + i);
-		csum += *d;
-	}
+	write_bytes(EC_LPC_ADDR_HOST_PACKET + sizeof(rq),
+		    cec_command->cmd_size_in,
+		    (u8*)cec_command->cmd_data_in,
+		    &csum);
 
 	/* Finish checksum */
 	for (i = 0, d = (const u8 *)&rq; i < sizeof(rq); i++, d++)
 		csum += *d;
 
 	/* Write checksum field so the entire packet sums to 0 */
-	rq.checksum = (u8)(-csum);
+	rq.checksum = -csum;
 
 	/* Copy header */
-	for (i = 0, d = (const uint8_t *)&rq; i < sizeof(rq); i++, d++)
-		outb(*d, EC_LPC_ADDR_HOST_PACKET + i);
+	write_bytes(EC_LPC_ADDR_HOST_PACKET, sizeof(rq), (u8*)&rq, NULL);
 
 	/* Start the command */
-	outb(EC_COMMAND_PROTOCOL_3, EC_LPC_ADDR_HOST_CMD);
+	write_byte(EC_COMMAND_PROTOCOL_3, EC_LPC_ADDR_HOST_CMD);
 
 	if (google_chromeec_wait_ready(EC_LPC_ADDR_HOST_CMD)) {
 		printk(BIOS_ERR, "Timeout waiting for EC process command %d!\n",
@@ -178,7 +229,7 @@ static int google_chromeec_command_v3(struct chromeec_command *cec_command)
 	}
 
 	/* Check result */
-	cec_command->cmd_code = inb(EC_LPC_ADDR_HOST_DATA);
+	cec_command->cmd_code = read_byte(EC_LPC_ADDR_HOST_DATA);
 	if (cec_command->cmd_code) {
 		printk(BIOS_ERR, "EC returned error result code %d\n",
 			cec_command->cmd_code);
@@ -187,10 +238,7 @@ static int google_chromeec_command_v3(struct chromeec_command *cec_command)
 
 	/* Read back response header and start checksum */
 	csum = 0;
-	for (i = 0, dout = (u8 *)&rs; i < sizeof(rs); i++, dout++) {
-		*dout = inb(EC_LPC_ADDR_HOST_PACKET + i);
-		csum += *dout;
-	}
+	read_bytes(EC_LPC_ADDR_HOST_PACKET, sizeof(rs), (u8*)&rs, &csum);
 
 	if (rs.struct_version != EC_HOST_RESPONSE_VERSION) {
 		printk(BIOS_ERR, "EC response version mismatch (%d != %d)\n",
@@ -211,14 +259,13 @@ static int google_chromeec_command_v3(struct chromeec_command *cec_command)
 	}
 
 	/* Read back data and update checksum */
-	for (i = 0, dout = (uint8_t *)cec_command->cmd_data_out;
-	     i < rs.data_len; i++, dout++) {
-		*dout = inb(EC_LPC_ADDR_HOST_PACKET + sizeof(rs) + i);
-		csum += *dout;
-	}
+	read_bytes(EC_LPC_ADDR_HOST_PACKET + sizeof(rs),
+		   rs.data_len,
+		   cec_command->cmd_data_out,
+		   &csum);
 
 	/* Verify checksum */
-	if ((u8)csum) {
+	if (csum) {
 		printk(BIOS_ERR, "EC response has invalid checksum\n");
 		return -1;
 	}
@@ -229,11 +276,8 @@ static int google_chromeec_command_v3(struct chromeec_command *cec_command)
 static int google_chromeec_command_v1(struct chromeec_command *cec_command)
 {
 	struct ec_lpc_host_args args;
-	const u8 *d;
-	u8 *dout;
 	u8 cmd_code = cec_command->cmd_code;
-	int csum;
-	int i;
+	u8 csum;
 
 	/* Fill in args */
 	args.flags = EC_HOST_ARGS_FLAG_FROM_HOST;
@@ -243,21 +287,18 @@ static int google_chromeec_command_v1(struct chromeec_command *cec_command)
 	/* Initialize checksum */
 	csum = cmd_code + args.flags + args.command_version + args.data_size;
 
-	/* Write data and update checksum */
-	for (i = 0, d = (const u8 *)cec_command->cmd_data_in;
-	     i < cec_command->cmd_size_in; i++, d++) {
-		outb(*d, EC_LPC_ADDR_HOST_PARAM + i);
-		csum += *d;
-	}
+	write_bytes(EC_LPC_ADDR_HOST_PARAM,
+		    cec_command->cmd_size_in,
+		    (u8*)cec_command->cmd_data_in,
+		    &csum);
 
 	/* Finalize checksum and write args */
-	args.checksum = (u8)csum;
-	for (i = 0, d = (const u8 *)&args; i < sizeof(args); i++, d++)
-		outb(*d, EC_LPC_ADDR_HOST_ARGS + i);
+	args.checksum = csum;
+	write_bytes(EC_LPC_ADDR_HOST_ARGS, sizeof(args), (u8*)&args, NULL);
 
 
 	/* Issue the command */
-	outb(cmd_code, EC_LPC_ADDR_HOST_CMD);
+	write_byte(cmd_code, EC_LPC_ADDR_HOST_CMD);
 
 	if (google_chromeec_wait_ready(EC_LPC_ADDR_HOST_CMD)) {
 		printk(BIOS_ERR, "Timeout waiting for EC process command %d!\n",
@@ -266,13 +307,12 @@ static int google_chromeec_command_v1(struct chromeec_command *cec_command)
 	}
 
 	/* Check result */
-	cec_command->cmd_code = inb(EC_LPC_ADDR_HOST_DATA);
+	cec_command->cmd_code = read_byte(EC_LPC_ADDR_HOST_DATA);
 	if (cec_command->cmd_code)
 		return 1;
 
 	/* Read back args */
-	for (i = 0, dout = (u8 *)&args; i < sizeof(args); i++, dout++)
-		*dout = inb(EC_LPC_ADDR_HOST_ARGS + i);
+	read_bytes(EC_LPC_ADDR_HOST_ARGS, sizeof(args), (u8*)&args, NULL);
 
 	/*
 	 * If EC didn't modify args flags, then somehow we sent a new-style
@@ -294,14 +334,13 @@ static int google_chromeec_command_v1(struct chromeec_command *cec_command)
 	csum = cmd_code + args.flags + args.command_version + args.data_size;
 
 	/* Read data, if any */
-	for (i = 0, dout = (u8 *)cec_command->cmd_data_out;
-	     i < args.data_size; i++, dout++) {
-		*dout = inb(EC_LPC_ADDR_HOST_PARAM + i);
-		csum += *dout;
-	}
+	read_bytes(EC_LPC_ADDR_HOST_PARAM,
+		   args.data_size,
+		   cec_command->cmd_data_out,
+		   &csum);
 
 	/* Verify checksum */
-	if (args.checksum != (u8)csum) {
+	if (args.checksum != csum) {
 		printk(BIOS_ERR, "EC response has invalid checksum\n");
 		return 1;
 	}
@@ -391,7 +430,7 @@ u8 google_chromeec_get_event(void)
 	}
 
 	/* Issue the ACPI query-event command */
-	outb(EC_CMD_ACPI_QUERY_EVENT, EC_LPC_ADDR_ACPI_CMD);
+	write_byte(EC_CMD_ACPI_QUERY_EVENT, EC_LPC_ADDR_ACPI_CMD);
 
 	if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD)) {
 		printk(BIOS_ERR, "Timeout waiting for EC QUERY_EVENT!\n");
@@ -399,6 +438,6 @@ u8 google_chromeec_get_event(void)
 	}
 
 	/* Event (or 0 if none) is returned directly in the data byte */
-	return inb(EC_LPC_ADDR_ACPI_DATA);
+	return read_byte(EC_LPC_ADDR_ACPI_DATA);
 }
 #endif



More information about the coreboot-gerrit mailing list