[coreboot-gerrit] Change in ...coreboot[master]: [WIP]opencelluar: Add EC interface

Patrick Rudolph (Code Review) gerrit at coreboot.org
Fri Nov 30 09:09:54 CET 2018


Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/29946


Change subject: [WIP]opencelluar: Add EC interface
......................................................................

[WIP]opencelluar: Add EC interface

Add the EC driver that uses the OpenCellular Management Protocol.
Implement the board_reset() method using introduced methods.

Change-Id: I67eb4ee8e0ad297a8d1984d55102146688c291fc
Signed-off-by: Patrick Rudolph <patrick.rudolph at 9elements.com>
---
A src/ec/opencellular/tiva/Kconfig
A src/ec/opencellular/tiva/Makefile.inc
A src/ec/opencellular/tiva/ec.c
A src/ec/opencellular/tiva/ec.h
M src/mainboard/opencellular/elgon/Kconfig
M src/mainboard/opencellular/elgon/Makefile.inc
A src/mainboard/opencellular/elgon/reset.c
7 files changed, 327 insertions(+), 1 deletion(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/46/29946/1

diff --git a/src/ec/opencellular/tiva/Kconfig b/src/ec/opencellular/tiva/Kconfig
new file mode 100644
index 0000000..a56b06a
--- /dev/null
+++ b/src/ec/opencellular/tiva/Kconfig
@@ -0,0 +1,5 @@
+config EC_OPENCELLULAR_TIVA
+	bool
+	depends on CONSOLE_SERIAL
+	help
+	  OpenCellular Tiva EC protocol driver over serial.
diff --git a/src/ec/opencellular/tiva/Makefile.inc b/src/ec/opencellular/tiva/Makefile.inc
new file mode 100644
index 0000000..fadaf44
--- /dev/null
+++ b/src/ec/opencellular/tiva/Makefile.inc
@@ -0,0 +1,9 @@
+ifeq ($(CONFIG_EC_OPENCELLULAR_TIVA),y)
+
+bootblock-y += ec.c
+romstage-y += ec.c
+verstage-y += ec.c
+postcar-y += ec.c
+ramstage-y += ec.c
+
+endif
diff --git a/src/ec/opencellular/tiva/ec.c b/src/ec/opencellular/tiva/ec.c
new file mode 100644
index 0000000..d46f284
--- /dev/null
+++ b/src/ec/opencellular/tiva/ec.c
@@ -0,0 +1,203 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2018 Facebook, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <console/console.h>
+#include <string.h>
+#include <console/uart.h>
+#include "ec.h"
+
+/* Packet definition as per OpenCellular Management Protocol */
+enum ec_iface {
+	EC_UART = 1,
+	EC_ETHERNET = 2,
+	EC_SBD = 3,
+	EC_USB = 4,
+};
+
+struct ec_header {
+	uint8_t sof;
+	uint8_t len;
+	uint8_t iface;
+	uint32_t seq;
+	uint32_t ts;
+} __packed;
+
+struct ec_payload {
+	uint8_t subsystem;
+	uint8_t component_id;
+	uint8_t message_type;
+	uint8_t action_type;
+	uint16_t parameter_info;
+	uint8_t message[48];
+} __packed;
+
+struct ec_packet {
+	struct ec_header hdr;
+	struct ec_payload pld;
+} __packed;
+
+struct ec_msg {
+	union {
+		struct ec_packet p;
+		uint8_t raw[sizeof(struct ec_packet)];
+	};
+};
+
+/* Create a packet to BMS:TIVA from given arguments */
+static size_t ec_create_tx_msg(struct ec_packet *p,
+			       const enum ec_message_type mt,
+			       const enum ec_action_type at,
+			       const uint8_t parameter_info,
+			       const enum ec_iface iface,
+			       const uint8_t *data_in,
+			       const uint8_t data_in_len)
+{
+	size_t len = sizeof(*p) - sizeof(p->pld.message) + data_in_len;
+
+	p->pld.subsystem = EC_BMS;
+	p->pld.component_id = EC_TIVA;
+	p->pld.message_type = mt;
+	p->pld.action_type = at;
+	p->pld.parameter_info = parameter_info;
+	if (data_in)
+		memcpy(&p->pld.message, data_in, data_in_len);
+
+	p->hdr.iface = iface;
+	p->hdr.len = data_in_len;
+	p->hdr.sof = 0x55;
+	p->hdr.ts = 0; /* Reserved for future use */
+	p->hdr.seq = 0; /* Reserved for future use */
+
+	return len;
+}
+
+/* Returns true on valid header */
+static bool ec_verify_rx_hdr(struct ec_packet *p, const enum ec_iface iface)
+{
+	if (p->hdr.sof != 0x55)
+		return false;
+	if (p->hdr.len > 48)
+		return false;
+	if (p->hdr.iface != iface)
+		return false;
+	return true;
+}
+
+
+/* Returns true on valid packet */
+static bool ec_verify_rx_msg(struct ec_packet *p, const enum ec_iface iface)
+{
+	if (!ec_verify_rx_hdr(p, iface))
+		return false;
+	if (p->pld.subsystem != EC_BMS)
+		return false;
+	if (p->pld.component_id != EC_TIVA)
+		return false;
+
+	return true;
+}
+
+/**
+ * Transmits a packet to EC using one of the UARTs.
+ * The function is blocking until a data has been transmitted.
+ *
+ * All pointers can be NULL if not required.
+ *
+ * @param uart_idx	The UART connected to EC
+ * @param mt	      Message type to transmit
+ * @param at	      Action type to transmit
+ * @param parameter_info  Parameter info to transmit
+ * @param data_in	 Buffer to data to transmit
+ * @param data_in_len     Length of data to transmit
+ *
+ * @return Zero on success, negative on failure
+ */
+int ec_transmit_msg_uart(const uint8_t uart_idx,
+			 const enum ec_message_type mt,
+			 const enum ec_action_type at,
+			 const uint8_t parameter_info,
+			 const uint8_t *data_in,
+			 const uint8_t data_in_len)
+{
+	struct ec_msg msg;
+
+	size_t len = ec_create_tx_msg(&msg.p, mt, at, parameter_info, EC_UART,
+			data_in, data_in_len);
+
+	for (size_t i = 0; i < len; i++)
+		uart_tx_byte(uart_idx, msg.raw[i]);
+
+	return 0;
+}
+
+/**
+ * Receives a packet from EC using one of the UARTs.
+ * The function is blocking and waits for a SOF byte.
+ *
+ * The caller must provide a data buffer of size 48.
+ * If no data buffer is provided the received data (if any) is dropped.
+ *
+ * All pointers can be NULL if not required.
+ *
+ * @param uart_idx	The UART connected to EC
+ * @param mt	      Receveived message type
+ * @param at	      Receveived action type
+ * @param parameter_info  Receveived parameter info
+ * @param data_out	Buffer to place receveived data
+ * @param data_out_len    Length of received data
+ *
+ * @return Zero on success, negative on failure
+ */
+int ec_receive_msg_uart(const uint8_t uart_idx,
+			enum ec_message_type *mt,
+			enum ec_action_type *at,
+			uint8_t *parameter_info,
+			uint8_t *data_out,
+			uint8_t *data_out_len)
+{
+	struct ec_msg msg;
+
+	do {
+		msg.raw[0] = uart_rx_byte(uart_idx);
+	} while (msg.raw[0] != 0x55);
+
+	for (size_t i = 0; i < sizeof(struct ec_header); i++)
+		msg.raw[i] = uart_rx_byte(uart_idx);
+
+	if (!ec_verify_rx_hdr(&msg.p, EC_UART))
+		return -1;
+
+	const size_t len = sizeof(msg.p.pld) - sizeof(msg.p.pld.message) +
+			   msg.p.hdr.len;
+
+	for (size_t i = 0; i < len; i++)
+		msg.raw[sizeof(struct ec_header) + i] = uart_rx_byte(uart_idx);
+
+	if (!ec_verify_rx_msg(&msg.p, EC_UART))
+		return -1;
+
+	if (mt)
+		*mt = msg.p.pld.message_type;
+	if (at)
+		*at = msg.p.pld.action_type;
+	if (parameter_info)
+		*parameter_info = msg.p.pld.parameter_info;
+	if (data_out)
+		memcpy(data_out, msg.p.pld.message, msg.p.hdr.len);
+	if (*data_out_len)
+		*data_out_len = msg.p.hdr.len;
+	return 0;
+}
+
diff --git a/src/ec/opencellular/tiva/ec.h b/src/ec/opencellular/tiva/ec.h
new file mode 100644
index 0000000..7728f7e
--- /dev/null
+++ b/src/ec/opencellular/tiva/ec.h
@@ -0,0 +1,77 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2018 Facebook, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <types.h>
+
+/**
+ * Command interface as per OpenCellular Management Protocol:
+ *
+ * This protocol allows to handle all the configuration,  status and alert
+ * processing through a ‘Request-Response’ mechanism between host and MCU.
+ */
+
+enum ec_subsystem {
+	EC_SYSTEM = 0,
+	EC_POWER = 1,
+	EC_BMS = 2,
+	EC_HCI = 3,
+	EC_ETHERNET_SWITCH = 4,
+	EC_OBC = 5,
+	EC_GPP = 6,
+	EC_SDR = 7,
+	EC_RF = 8,
+	EC_SYNC = 9,
+	EC_TEST_MODULE = 10,
+	EC_WATCHDOG = 11,
+	EC_ALERT_MANAGER = 12
+};
+
+/* We only support subsystem BMS here */
+enum ec_subsystem_bms {
+	EC_ALL = 0,
+	EC_TIVA = 1,
+};
+
+enum ec_message_type {
+	EC_CONFIG = 1,
+	EC_STATUS = 2,
+	EC_ALERT = 3,
+	EC_COMMAND = 4,
+};
+
+enum ec_action_type {
+	EC_GET = 1,
+	EC_SET = 2,
+	EC_REPLY = 3,
+	EC_ACTIVE = 4,
+	EC_CLEAR = 5,
+	EC_RESET = 6,
+	EC_ENABLE = 7,
+	EC_DISABLE = 8,
+};
+
+int ec_transmit_msg_uart(const uint8_t uart_idx,
+			 const enum ec_message_type mt,
+			 const enum ec_action_type at,
+			 const uint8_t parameter_info,
+			 const uint8_t *data_in,
+			 const uint8_t data_in_len);
+
+int ec_receive_msg_uart(const uint8_t uart_idx,
+			enum ec_message_type *mt,
+			enum ec_action_type *at,
+			uint8_t *parameter_info,
+			uint8_t *data_out,
+			uint8_t *data_out_len);
diff --git a/src/mainboard/opencellular/elgon/Kconfig b/src/mainboard/opencellular/elgon/Kconfig
index 3ba2a60..b9f93ab 100644
--- a/src/mainboard/opencellular/elgon/Kconfig
+++ b/src/mainboard/opencellular/elgon/Kconfig
@@ -25,7 +25,7 @@
 	select SPI_FLASH_WINBOND
 	select MAINBOARD_HAS_I2C_TPM_GENERIC
 	select MAINBOARD_HAS_TPM1
-	select MISSING_BOARD_RESET
+	select EC_OPENCELLULAR_TIVA
 
 config VBOOT
 	select VBOOT_NO_BOARD_SUPPORT
diff --git a/src/mainboard/opencellular/elgon/Makefile.inc b/src/mainboard/opencellular/elgon/Makefile.inc
index 343a52e..3440833 100644
--- a/src/mainboard/opencellular/elgon/Makefile.inc
+++ b/src/mainboard/opencellular/elgon/Makefile.inc
@@ -16,16 +16,20 @@
 bootblock-y += bootblock.c
 bootblock-y += memlayout.ld
 bootblock-y += death.c
+bootblock-y += reset.c
 
 romstage-y += memlayout.ld
 romstage-y += romstage.c
 romstage-y += bdk_devicetree.c
 romstage-y += death.c
+romstage-y += reset.c
 
 ramstage-y += mainboard.c
 ramstage-y += memlayout.ld
 ramstage-y += bdk_devicetree.c
 ramstage-y += death.c
+ramstage-y += reset.c
 
 verstage-y += memlayout.ld
 verstage-y += death.c
+verstage-y += reset.c
diff --git a/src/mainboard/opencellular/elgon/reset.c b/src/mainboard/opencellular/elgon/reset.c
new file mode 100644
index 0000000..d73d9af
--- /dev/null
+++ b/src/mainboard/opencellular/elgon/reset.c
@@ -0,0 +1,28 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2018 Facebook, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <ec/opencellular/tiva/ec.h>
+#include <reset.h>
+#include <soc/gpio.h>
+#include "mainboard.h"
+
+void do_board_reset(void)
+{
+	/* Route UART0 to EC */
+	gpio_output(ELGON_GPIO_UART_SEL, 1);
+
+	ec_transmit_msg_uart(0, EC_COMMAND, EC_RESET, 0, NULL, 0);
+	/* FIXME: Is there a response ? */
+}

-- 
To view, visit https://review.coreboot.org/c/coreboot/+/29946
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I67eb4ee8e0ad297a8d1984d55102146688c291fc
Gerrit-Change-Number: 29946
Gerrit-PatchSet: 1
Gerrit-Owner: Patrick Rudolph <patrick.rudolph at 9elements.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20181130/dcc5098f/attachment-0001.html>


More information about the coreboot-gerrit mailing list