From 2edffffa2da266e4f1f8e3e6e999ce57f4f80837 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 15 Mar 2020 12:23:51 -0600 Subject: [PATCH] System76 EC console support Change-Id: I04c2aeb19d780a7c6638b502192fa9f569e32e94 --- src/console/Kconfig | 7 ++++ src/console/console.c | 2 ++ src/drivers/system76_ec/Kconfig | 2 ++ src/drivers/system76_ec/Makefile.inc | 10 ++++++ src/drivers/system76_ec/system76_ec.c | 49 +++++++++++++++++++++++++++ src/include/console/system76_ec.h | 21 ++++++++++++ 6 files changed, 91 insertions(+) create mode 100644 src/drivers/system76_ec/Kconfig create mode 100644 src/drivers/system76_ec/Makefile.inc create mode 100644 src/drivers/system76_ec/system76_ec.c create mode 100644 src/include/console/system76_ec.h diff --git a/src/console/Kconfig b/src/console/Kconfig index cc18ec3756..8b994fe870 100644 --- a/src/console/Kconfig +++ b/src/console/Kconfig @@ -302,6 +302,13 @@ config SPI_CONSOLE This is currently working only in ramstage due to how the spi drivers are written. +config CONSOLE_SYSTEM76_EC + bool "System76 EC console output" + default y + depends on DRIVERS_SYSTEM76_EC + help + Send coreboot debug output to a System76 embedded controller. + config CONSOLE_OVERRIDE_LOGLEVEL bool help diff --git a/src/console/console.c b/src/console/console.c index a36cb96ed1..b52b2619e7 100644 --- a/src/console/console.c +++ b/src/console/console.c @@ -20,6 +20,7 @@ #include #include #include +#include void console_hw_init(void) { @@ -53,6 +54,7 @@ void console_tx_byte(unsigned char byte) __usb_tx_byte(byte); __spiconsole_tx_byte(byte); __flashconsole_tx_byte(byte); + __system76_ec_tx_byte(byte); } void console_tx_flush(void) diff --git a/src/drivers/system76_ec/Kconfig b/src/drivers/system76_ec/Kconfig new file mode 100644 index 0000000000..622f736127 --- /dev/null +++ b/src/drivers/system76_ec/Kconfig @@ -0,0 +1,2 @@ +config DRIVERS_SYSTEM76_EC + bool diff --git a/src/drivers/system76_ec/Makefile.inc b/src/drivers/system76_ec/Makefile.inc new file mode 100644 index 0000000000..58af38a363 --- /dev/null +++ b/src/drivers/system76_ec/Makefile.inc @@ -0,0 +1,10 @@ +ifeq ($(CONFIG_DRIVERS_SYSTEM76_EC),y) + +bootblock-y += system76_ec.c +verstage-y += system76_ec.c +romstage-y += system76_ec.c +postcar-y += system76_ec.c +ramstage-y += system76_ec.c +smm-$(CONFIG_DEBUG_SMI) += system76_ec.c + +endif diff --git a/src/drivers/system76_ec/system76_ec.c b/src/drivers/system76_ec/system76_ec.c new file mode 100644 index 0000000000..068c3baeeb --- /dev/null +++ b/src/drivers/system76_ec/system76_ec.c @@ -0,0 +1,49 @@ +#include +#include +#include + +#define SYSTEM76_EC_BASE 0x0E00 + +static uint8_t system76_ec_read(uint8_t addr) { + return inb(SYSTEM76_EC_BASE + (uint16_t)addr); +} + +static void system76_ec_write(uint8_t addr, uint8_t data) { + outb(data, SYSTEM76_EC_BASE + (uint16_t)addr); +} + +int system76_ec_print(uint8_t *buf, size_t len) { + size_t i; + for (i=0; i < len;) { + if (system76_ec_read(0) == 0) { + size_t j; + for (j=0; (i < len) && ((j + 4) < 256); i++, j++) { + system76_ec_write((uint8_t)(j + 4), buf[i]); + } + // Flags + system76_ec_write(2, 0); + // Length + system76_ec_write(3, (uint8_t)j); + // Command + system76_ec_write(0, 4); + // Wait for command completion, for up to 1 second + int timeout; + for (timeout = 1000000; timeout > 0; timeout--) { + if (system76_ec_read(0) == 0) break; + udelay(1); + } + if (timeout == 0) { + // Error: timeout occured + return -1; + } + if (system76_ec_read(1) != 0) { + // Error: command failed + return -1; + } + } else { + // Error: command is already running + return -1; + } + } + return (int)i; +} diff --git a/src/include/console/system76_ec.h b/src/include/console/system76_ec.h new file mode 100644 index 0000000000..e823baa914 --- /dev/null +++ b/src/include/console/system76_ec.h @@ -0,0 +1,21 @@ +#ifndef CONSOLE_SYSTEM76_EC_H +#define CONSOLE_SYSTEM76_EC_H 1 + +#include +#include + +int system76_ec_print(uint8_t *buf, size_t len); + +#define __CONSOLE_SYSTEM76_EC_ENABLE__ (CONFIG(CONSOLE_SYSTEM76_EC) && \ + (ENV_BOOTBLOCK || ENV_ROMSTAGE || ENV_RAMSTAGE || ENV_VERSTAGE || \ + ENV_POSTCAR || (ENV_SMM && CONFIG(DEBUG_SMI)))) + +#if __CONSOLE_SYSTEM76_EC_ENABLE__ +static inline void __system76_ec_tx_byte(unsigned char byte) { + system76_ec_print(&byte, 1); +} +#else +static inline void __system76_ec_tx_byte(unsigned char byte) {} +#endif + +#endif