diff options
author | Martin Roth <martinroth@google.com> | 2015-09-28 15:27:24 -0600 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2015-10-05 17:43:11 +0000 |
commit | 3a54318856428cda41c5a45e41c4da727d352bf6 (patch) | |
tree | b318ca7a8576d130ec18e853543d21542114d41b /src/drivers | |
parent | f35f5ff3cd86b247a1e8ff1df8d071a3a4556079 (diff) |
Add EM100 'hyper term' spi console support in ramstage & smm
The EM100Pro allows the debug console to be sent over the SPI bus.
This is not yet working in romstage due to the use of static variables
in the SPI driver code. It is also not working on chipsets that have
SPI write buffers of less than 10 characters due to the 9 byte
command/header length specified by the EM100 protocol.
While this currently works only with the EM100, it seems like it would
be useful on any logic analyzer with SPI debug - just filter on command
bytes of 0x11.
Change-Id: Icd42ccd96cab0a10a4e70f4b02ecf9de8169564b
Signed-off-by: Martin Roth <martinroth@google.com>
Reviewed-on: http://review.coreboot.org/11743
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/drivers')
-rw-r--r-- | src/drivers/spi/Kconfig | 4 | ||||
-rw-r--r-- | src/drivers/spi/Makefile.inc | 5 | ||||
-rw-r--r-- | src/drivers/spi/spiconsole.c | 71 |
3 files changed, 80 insertions, 0 deletions
diff --git a/src/drivers/spi/Kconfig b/src/drivers/spi/Kconfig index 4052bb4713..dedb88f664 100644 --- a/src/drivers/spi/Kconfig +++ b/src/drivers/spi/Kconfig @@ -137,3 +137,7 @@ config SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B to the chip on MOSI and data is received on both MOSI and MISO. endif # SPI_FLASH + +config HAVE_SPI_CONSOLE_SUPPORT + def_bool n + diff --git a/src/drivers/spi/Makefile.inc b/src/drivers/spi/Makefile.inc index ade34a2988..6697c702fb 100644 --- a/src/drivers/spi/Makefile.inc +++ b/src/drivers/spi/Makefile.inc @@ -1,5 +1,10 @@ # SPI flash driver interface +ifeq ($(CONFIG_SPI_CONSOLE),y) +ramstage-y += spiconsole.c +smm-$(CONFIG_DEBUG_SMI) += spiconsole.c +endif + ifeq ($(CONFIG_COMMON_CBFS_SPI_WRAPPER),y) bootblock-y += spi_flash.c bootblock-$(CONFIG_SPI_FLASH_EON) += eon.c diff --git a/src/drivers/spi/spiconsole.c b/src/drivers/spi/spiconsole.c new file mode 100644 index 0000000000..39a574c3ca --- /dev/null +++ b/src/drivers/spi/spiconsole.c @@ -0,0 +1,71 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2015 Google 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc. + */ + +#include <spi-generic.h> +#include <spi_flash.h> +#include <console/spi.h> + +void spiconsole_init(void) { + spi_init(); + return; +} + +/* + * The EM100 'hyper terminal' specification defines a header of 9 characters. + * Because of this, devices with a spi_crop_chunk of less than 10 characters + * can't be supported by this standard. + * + * To add support in romstage, the static struct here and the ones used by + * spi_xfer will need to be modified - removed, or mapped into cbmem. + * + * Because the Dediprog software expects strings, not single characters, and + * because of the header overhead, this builds up a buffer to send. + */ +void spiconsole_tx_byte(unsigned char c) { + static struct em100_msg msg = { + .header.spi_command = EM100_DEDICATED_CMD, + .header.em100_command = EM100_UFIFO_CMD, + .header.msg_signature = EM100_MSG_SIGNATURE, + .header.msg_type = EM100_MSG_ASCII, + .header.msg_length = 0 + }; + + /* Verify the spi buffer is big enough to send even a single byte */ + if (spi_crop_chunk(0,MAX_MSG_LENGTH) < + sizeof(struct em100_msg_header) + 1) + return; + + msg.data[msg.header.msg_length] = c; + msg.header.msg_length++; + + /* Send the data on newline or when the max spi length is reached */ + if (c == '\n' || (sizeof(struct em100_msg_header) + + msg.header.msg_length == spi_crop_chunk(0, + MAX_MSG_LENGTH))) { + struct spi_slave spi = {.rw = SPI_READ_FLAG}; + + spi_xfer(&spi, &msg, sizeof(struct em100_msg_header) + + msg.header.msg_length, NULL, 0); + + msg.header.msg_length = 0; + } + + return; +} + |