[coreboot] New patch to review for coreboot: a699272 DRAFT: implement a rom stream

Ronald G. Minnich (rminnich@gmail.com) gerrit at coreboot.org
Tue Jan 22 23:25:25 CET 2013


Ronald G. Minnich (rminnich at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2184

-gerrit

commit a69927224ccfa1bbbe9e978edafc319c5cab6752
Author: Ronald G. Minnich <rminnich at gmail.com>
Date:   Tue Jan 22 11:44:00 2013 -0800

    DRAFT: implement a rom stream
    
    Until this year, we had not needed a streaming construct since LinuxBIOS V1 in 2002.
    New ARM SOCs do require something that looks like a stream.
    
    This is a proposed interface and sample implementation.
    
    The interface:
    void *stream_start(void *);
    Called with a void *, which might be a pointer or pointer to stuct, depending on
    circumstances; returns a pointer to an opaque type.
    
    int stream_read(void *stream, void *where, u32 len, u32 off);
    Read 'len' bytes from stream 'stream' at offset 'off' to 'where'.
    We assume any rom we'll ever see is 4G or less; hence the offset is a u32.
    
    int stream_fini(void *stream);
    
    do what needs to be done to finish this stream; it might include turning
    off a SPI controller.
    
    This compiles, but is not tested. I'll test when we get comments and get it right. Next
    in line is the SPI controller code. The sample stream source for spi is in
    bootblock.c
    
    Change-Id: I1e5e1b7c075ab36fe8729c60fa52d8406b6d26f0
    Signed-off-by: Ronald G. Minnich <rminnich at gmail.com>
---
 src/Kconfig                           |  5 +++
 src/drivers/realtek/Kconfig           |  1 +
 src/include/lib.h                     |  9 ++++
 src/lib/Makefile.inc                  |  1 +
 src/lib/romstream.c                   | 70 +++++++++++++++++++++++++++++
 src/mainboard/google/snow/bootblock.c | 84 +++++++++++++++++++++++++++++++++++
 6 files changed, 170 insertions(+)

diff --git a/src/Kconfig b/src/Kconfig
index 2c97327..7f12f3f 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -277,6 +277,11 @@ config HAVE_UART_MEMORY_MAPPED
 	bool
 	default n
 
+config ROMSTREAM
+	bool
+	default y if ARCH_X86
+	default n if ARCH_ARMV7
+
 config HAVE_ACPI_RESUME
 	bool
 	default n
diff --git a/src/drivers/realtek/Kconfig b/src/drivers/realtek/Kconfig
index 0799445..82b9e25 100644
--- a/src/drivers/realtek/Kconfig
+++ b/src/drivers/realtek/Kconfig
@@ -1,5 +1,6 @@
 config RTL8168_ROM_DISABLE
 	bool "Disable RTL8168 ROM"
+	depends on PCI
 	default n
 	help
 	  Just enough of a driver to make coreboot not look for an Option ROM.
diff --git a/src/include/lib.h b/src/include/lib.h
index 9d81085..86f595e 100644
--- a/src/include/lib.h
+++ b/src/include/lib.h
@@ -53,5 +53,14 @@ void cache_as_ram_main(void);
 void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx);
 #endif
 
+/* definition is architecture-dependent but at minimum, for most architectures,
+ * defined in src/lib/romstream.c. There are so few systems that don't have
+ * memory mapped ROM that we yanked this years ago. Now, thanks to
+ * some ARM systems, it's back.
+ */
+void *stream_start(void *v);
+int stream_read(void *stream, void *where, u32 size, u32 off);
+void stream_fini(void *stream);
+
 #endif /* __ROMCC__ */
 #endif /* __LIB_H__ */
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index 6796448..37d85d0 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -36,6 +36,7 @@ romstage-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c
 romstage-$(CONFIG_CONSOLE_NE2K) += ne2k.c
 romstage-$(CONFIG_USBDEBUG) += usbdebug.c
 romstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
+romstage-$(CONFIG_ROMSTREAM) += romstream.c
 romstage-y += compute_ip_checksum.c
 romstage-y += memmove.c
 
diff --git a/src/lib/romstream.c b/src/lib/romstream.c
new file mode 100644
index 0000000..fb6ceac
--- /dev/null
+++ b/src/lib/romstream.c
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 The ChromiumOS Authors.  All rights reserved.
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include <lib.h>
+#include <console/console.h>
+
+/*
+ * romstream. This is a very simple stream interface. 
+ * The stream interface has three functions. The first, start, accepts a void * and a size and returns a void *
+ * which points to an opaque, and possibly internal, interface value. 
+ * the second, read, accepts the opaque pointer, a data pointer, a length, and an offset and returns
+ * the number of bytes read or -1 if there is an error.
+ * The third, end, frees any internal stucts (if needed) and shuts do the stream (if needed)
+ * we assume that flash is 4G or less.
+ * The romstream is very simple: it's a u8 pointer. 
+ */
+
+void *
+stream_start(void *v)
+{
+	/* this seems not needed but we're allowing for future changes */
+	u8 *romstream = v;
+	return romstream;
+}
+
+int
+stream_read(void *stream, void *where, u32 len, u32 off)
+{
+	u8 *romstream = stream;
+	u32 amount;
+	u8 *from, *to;
+	int i;
+
+	if (off >= CONFIG_ROM_SIZE)
+		return 0;
+
+	amount = CONFIG_ROM_SIZE - off;
+	if (amount > len)
+		amount = len;
+	from =  romstream+off;
+	to = where;
+	/* we don't have memmove in all modes, so we'll just it by ourselves. */
+	for(i = 0; i < amount; i++)
+		*to++ = *from++;
+
+	return amount;
+}
+
+void
+stream_fini(void *stream)
+{
+}
diff --git a/src/mainboard/google/snow/bootblock.c b/src/mainboard/google/snow/bootblock.c
index d5ee0a3..b022a4f 100644
--- a/src/mainboard/google/snow/bootblock.c
+++ b/src/mainboard/google/snow/bootblock.c
@@ -22,6 +22,7 @@
 
 #include <stdlib.h>
 #include <types.h>
+#include <lib.h>
 #include <arch/io.h>
 #include "cpu/samsung/exynos5250/clk.h"
 #include "cpu/samsung/exynos5250/cpu.h"
@@ -2130,6 +2131,89 @@ int do_printk(int msg_level, const char *fmt, ...)
 	return i;
 }
 
+void *stream_start(void *v)
+{
+//	struct exynos_spi *regs = (struct exynos_spi *)samsung_get_base_spi1();
+	struct exynos_spi *regs = (struct exynos_spi *)0x12d30000;
+
+	clock_set_rate(PERIPH_ID_SPI1, 50000000); /* set spi clock to 50Mhz */
+	/* set the spi1 GPIO */
+//	exynos_pinmux_config(PERIPH_ID_SPI1, PINMUX_FLAG_NONE);
+	gpio_cfg_pin(GPIO_A24, 0x2);
+	gpio_cfg_pin(GPIO_A25, 0x2);
+	gpio_cfg_pin(GPIO_A26, 0x2);
+	gpio_cfg_pin(GPIO_A27, 0x2);
+
+	/* set pktcnt and enable it */
+	writel(4 | SPI_PACKET_CNT_EN, &regs->pkt_cnt);
+	/* set FB_CLK_SEL */
+	writel(SPI_FB_DELAY_180, &regs->fb_clk);
+	/* set CH_WIDTH and BUS_WIDTH as word */
+	setbits_le32(&regs->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
+					SPI_MODE_BUS_WIDTH_WORD);
+	clrbits_le32(&regs->ch_cfg, SPI_CH_CPOL_L); /* CPOL: active high */
+
+	/* clear rx and tx channel if set priveously */
+	clrbits_le32(&regs->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON);
+
+	setbits_le32(&regs->swap_cfg, SPI_RX_SWAP_EN |
+		SPI_RX_BYTE_SWAP |
+		SPI_RX_HWORD_SWAP);
+
+	/* do a soft reset */
+	setbits_le32(&regs->ch_cfg, SPI_CH_RST);
+	clrbits_le32(&regs->ch_cfg, SPI_CH_RST);
+
+	/* now set rx and tx channel ON */
+	setbits_le32(&regs->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON | SPI_CH_HS_EN);
+	clrbits_le32(&regs->cs_reg, SPI_SLAVE_SIG_INACT); /* CS low */
+	return (void *)regs;
+}
+
+int stream_read(void *stream, void *where, u32 len, u32 off)
+{
+	int upto, todo;
+	int i;
+	struct exynos_spi *regs = stream;
+	/* Send read instruction (0x3h) followed by a 24 bit addr */
+	writel((SF_READ_DATA_CMD << 24) | off, &regs->tx_data);
+
+	/* waiting for TX done */
+	while (!(readl(&regs->spi_sts) & SPI_ST_TX_DONE));
+
+	for (upto = 0, i = 0; upto < len; upto += todo, i++) {
+		todo = MIN(len - upto, (1 << 15));
+		spi_rx_tx(regs, todo, (void *)(where),
+					(void *)(off), i);
+	}
+
+	setbits_le32(&regs->cs_reg, SPI_SLAVE_SIG_INACT);/* make the CS high */
+
+	/*
+	 * Let put controller mode to BYTE as
+	 * SPI driver does not support WORD mode yet
+	 */
+	clrbits_le32(&regs->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
+					SPI_MODE_BUS_WIDTH_WORD);
+	writel(0, &regs->swap_cfg);
+
+	return len;
+}
+
+void stream_fini(void *stream)
+{
+	struct exynos_spi *regs = stream;
+
+	/*
+	 * Flush spi tx, rx fifos and reset the SPI controller
+	 * and clear rx/tx channel
+	 */
+	clrsetbits_le32(&regs->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST);
+	clrbits_le32(&regs->ch_cfg, SPI_CH_RST);
+	clrbits_le32(&regs->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
+}
+
+
 void bootblock_mainboard_init(void);
 void bootblock_mainboard_init(void)
 {



More information about the coreboot mailing list