summaryrefslogtreecommitdiff
path: root/src/ec
diff options
context:
space:
mode:
authorJeremy Soller <jeremy@system76.com>2020-07-22 06:40:28 -0600
committerMichael Niewöhner <c0d3z3r0@review.coreboot.org>2020-09-07 21:46:34 +0000
commit52785ab327b6be15e573f1ec68e3528847bcbd89 (patch)
tree498e61404036bc69ce4484a6c09e9520733da170 /src/ec
parent7e396f380eb480aac7546bc65c16e4585f7dfc78 (diff)
ec/system76: Add console support
This adds support for line-buffered console output to System76 EC firmware. Once the print command is received, the EC firmware multiplexes the output to any enabled console on the EC. This can be a memory ringbuffer, a parallel port (using the keyboard connector), or i2c (using the battery connector). Once the entire buffer is sent, it sets the command register to 0, indicating completion. For more information, please see: https://github.com/system76/ec/blob/master/doc/debugging.md Tested on system76/lemp9 with CONSOLE_SYSTEM76_EC enabled. Signed-off-by: Jeremy Soller <jeremy@system76.com> Change-Id: I861bf3e22f40dd6c3ec7ba1d73711b399358e332 Reviewed-on: https://review.coreboot.org/c/coreboot/+/43718 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Michael Niewöhner
Diffstat (limited to 'src/ec')
-rw-r--r--src/ec/system76/ec/Makefile.inc6
-rw-r--r--src/ec/system76/ec/system76_ec.c61
2 files changed, 67 insertions, 0 deletions
diff --git a/src/ec/system76/ec/Makefile.inc b/src/ec/system76/ec/Makefile.inc
new file mode 100644
index 0000000000..382daa6581
--- /dev/null
+++ b/src/ec/system76/ec/Makefile.inc
@@ -0,0 +1,6 @@
+ifeq ($(CONFIG_EC_SYSTEM76_EC),y)
+
+all-y += system76_ec.c
+smm-$(CONFIG_DEBUG_SMI) += system76_ec.c
+
+endif
diff --git a/src/ec/system76/ec/system76_ec.c b/src/ec/system76/ec/system76_ec.c
new file mode 100644
index 0000000000..ddcb602d4c
--- /dev/null
+++ b/src/ec/system76/ec/system76_ec.c
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <arch/io.h>
+#include <console/system76_ec.h>
+#include <timer.h>
+
+// This is the command region for System76 EC firmware. It must be
+// enabled for LPC in the mainboard.
+#define SYSTEM76_EC_BASE 0x0E00
+#define SYSTEM76_EC_SIZE 256
+
+#define REG_CMD 0
+#define REG_RESULT 1
+
+// When command register is 0, command is complete
+#define CMD_FINISHED 0
+
+// Print command. Registers are unique for each command
+#define CMD_PRINT 4
+#define CMD_PRINT_REG_FLAGS 2
+#define CMD_PRINT_REG_LEN 3
+#define CMD_PRINT_REG_DATA 4
+
+static inline uint8_t system76_ec_read(uint8_t addr)
+{
+ return inb(SYSTEM76_EC_BASE + (uint16_t)addr);
+}
+
+static inline void system76_ec_write(uint8_t addr, uint8_t data)
+{
+ outb(data, SYSTEM76_EC_BASE + (uint16_t)addr);
+}
+
+void system76_ec_init(void)
+{
+ // Clear entire command region
+ for (int i = 0; i < SYSTEM76_EC_SIZE; i++)
+ system76_ec_write((uint8_t)i, 0);
+}
+
+void system76_ec_flush(void)
+{
+ system76_ec_write(REG_CMD, CMD_PRINT);
+
+ // Wait for command completion, for up to 10 milliseconds, with a
+ // test period of 1 microsecond
+ wait_us(10000, system76_ec_read(REG_CMD) == CMD_FINISHED);
+
+ system76_ec_write(CMD_PRINT_REG_LEN, 0);
+}
+
+void system76_ec_print(uint8_t byte)
+{
+ uint8_t len = system76_ec_read(CMD_PRINT_REG_LEN);
+ system76_ec_write(CMD_PRINT_REG_DATA + len, byte);
+ system76_ec_write(CMD_PRINT_REG_LEN, len + 1);
+
+ // If we hit the end of the buffer, or were given a newline, flush
+ if (byte == '\n' || len >= (SYSTEM76_EC_SIZE - CMD_PRINT_REG_DATA))
+ system76_ec_flush();
+}