the following patch was just integrated into master:
commit be0e92568f115488e0555ec67a27a6b93d212a4e
Author: Aladyshev Konstantin <aladyshev(a)nicevt.ru>
Date: Tue Dec 18 22:29:20 2012 +0400
clear_ioapic: Fix reading of number of interrupts for IO-APICs
Apply the same fix for `setup_ioapic` as done in the following commit.
commit 23c046b6f16805ff0131460189967bf261d704de Author: Nico Huber <nico.huber(a)secunet.com> Date: Mon Sep 24 10:48:43 2012 +0200
Fix reading of number of interrupts for IO-APICs
The number read from the io-apic register represents the index of the
highest interrupt redirection entry, i.e. the number of interrupts
minus one.
Change-Id: I54c992e4ff400de24bb9fef5d82251078f92c588
Signed-off-by: Nico Huber <nico.huber(a)secunet.com>
Reviewed-on: http://review.coreboot.org/1624
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer(a)coreboot.org>
Change-Id: I7b730d016a514c95c3b32aee6f31bd3d7b2c08cb
Signed-off-by: Aladyshev Konstantin <aladyshev(a)nicevt.ru>
Reviewed-on: http://review.coreboot.org/2043
Tested-by: build bot (Jenkins)
Reviewed-by: Paul Menzel <paulepanter(a)users.sourceforge.net>
Reviewed-by: Patrick Georgi <patrick(a)georgi-clan.de>
Reviewed-By: Patrick Georgi <patrick(a)georgi-clan.de> at Wed Jan 23 13:16:57 2013, giving +2
See http://review.coreboot.org/2043 for details.
-gerrit
Ronald G. Minnich (rminnich(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2184
-gerrit
commit 9ad53dfe42e78159890508308aecdb907c78f01b
Author: Ronald G. Minnich <rminnich(a)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);
On memory-addressed ROMs, set *where to point to a buffer of
0 or more bytes, up to len bytes. This avoids unnecessary copies.
On non-memory-addressed ROMs, 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. We've also put example usage in there. And, finally, modified
the cbfs for arm to use the stream code.
Change-Id: I1e5e1b7c075ab36fe8729c60fa52d8406b6d26f0
Signed-off-by: Ronald G. Minnich <rminnich(a)gmail.com>
---
src/Kconfig | 5 ++
src/arch/armv7/include/arch/cbfs.h | 63 ++++++++++++++---------
src/drivers/realtek/Kconfig | 1 +
src/include/lib.h | 16 ++++++
src/lib/Makefile.inc | 1 +
src/lib/romstream.c | 65 +++++++++++++++++++++++
src/mainboard/google/snow/bootblock.c | 97 +++++++++++++++++++++++++++++++++--
7 files changed, 222 insertions(+), 26 deletions(-)
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/arch/armv7/include/arch/cbfs.h b/src/arch/armv7/include/arch/cbfs.h
index f060643..d3e54ed 100644
--- a/src/arch/armv7/include/arch/cbfs.h
+++ b/src/arch/armv7/include/arch/cbfs.h
@@ -32,13 +32,13 @@ static int cbfs_check_magic(struct cbfs_file *file)
return strcmp(file->magic, CBFS_FILE_MAGIC) ? 0 : 1;
}
+/* start and stop the stream each time. It's the simplest thing to do */
static unsigned long loadstage(const char* target)
{
unsigned long offset, align;
+ void *stream;
struct cbfs_header *header = (struct cbfs_header *)(CONFIG_BOOTBLOCK_BASE + 0x40);
- /* FIXME: magic offsets */
- // if (ntohl(header->magic) != CBFS_HEADER_MAGIC)
- // printk(BIOS_ERR, "ERROR: No valid CBFS header found!\n");
+ stream = stream_start((void *)0x12d30000);
offset = ntohl(header->offset);
align = ntohl(header->align);
@@ -50,13 +50,20 @@ static unsigned long loadstage(const char* target)
printk(BIOS_INFO, "\talign: 0x%08x\n", ntohl(header->align));
printk(BIOS_INFO, "\toffset: 0x%08x\n", ntohl(header->offset));
while(1) {
- struct cbfs_file *file;
- struct cbfs_stage *stage;
+ struct cbfs_file f, *file = &f;
+ struct cbfs_stage s, *stage = &s;
+ int amount;
/* FIXME: SPI image hack */
- file = (struct cbfs_file *)(offset + CONFIG_SPI_IMAGE_HACK);
+ amount = stream_read(stream, (void *)&file, sizeof(file), offset);
+ if (amount < sizeof(*file)){
+ printk(BIOS_INFO, "Stream read of file header only returned %d bytes, wanted %d\n",
+ amount, sizeof(*file));
+ goto fail;
+ }
+
if (!cbfs_check_magic(file)) {
printk(BIOS_INFO, "magic is wrong, file: %p\n", file);
- return 0;
+ goto fail;
}
if (!strcmp(CBFS_NAME(file), target)) {
uint32_t load, entry;
@@ -68,23 +75,29 @@ static unsigned long loadstage(const char* target)
printk(BIOS_INFO, "\ttype: 0x%08x\n", ntohl(file->type));
printk(BIOS_INFO, "\tchecksum: 0x%08x\n", ntohl(file->checksum));
printk(BIOS_INFO, "\toffset: 0x%08x\n", ntohl(file->offset));
- /* exploit the fact that this is all word-aligned. */
- stage = CBFS_SUBHEADER(file);
+ offset += file->offset;
+ amount = stream_read(stream, (void *)&stage,
+ sizeof(stage), offset);
+ if (amount < sizeof(*stage)){
+ printk(BIOS_ERR, "Read stage: got %d, wanted %d\n",
+ amount, sizeof(stage));
+ goto fail;
+ }
load = stage->load;
entry = stage->entry;
int i;
- u32 *to = (void *)load;
- u32 *from = (void *)((u8 *)stage+sizeof(*stage));
- /* we could do memmove/memset here. But the math gets messy.
- * far easier just to do what we want.
- */
- printk(BIOS_INFO, "entry: 0x%08x, load: 0x%08x, "
- "len: 0x%08x, memlen: 0x%08x\n", entry,
- load, stage->len, stage->memlen);
- for(i = 0; i < stage->len; i += 4)
- *to++ = *from++;
- for(; i < stage->memlen; i += 4)
- *to++ = 0;
+ offset += sizeof(stage);
+ amount = stream_read(stream, (void *)load, stage->len, offset);
+ if (amount < stage->len){
+ printk(BIOS_ERR, "Stage read: got %d, wanted %d\n",
+ amount, stage->len);
+
+ goto fail;
+ }
+ u32 *zero = (u32 *)(load + stage->len);
+ for(i = stage->len; i < stage->memlen; i += 4)
+ *zero++ = 0;
+ stream_fini(stream);
return entry;
}
int flen = ntohl(file->len);
@@ -93,9 +106,13 @@ static unsigned long loadstage(const char* target)
offset = ALIGN(offset + foffset + flen, align);
printk(BIOS_INFO, "offset: 0x%08lx\n", offset);
if (offset <= oldoffset)
- return 0;
+ goto fail;
if (offset > CONFIG_ROMSTAGE_SIZE)
- return 0;
+ goto fail;
}
+
+ fail:
+ stream_fini(stream);
+ return 0;
}
#endif
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..ff63349 100644
--- a/src/include/lib.h
+++ b/src/include/lib.h
@@ -53,5 +53,21 @@ 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.
+ * There is a subtle design trick here. For rom streams which are memory-addressable,
+ * we don't want to copy the data. So we can return a pointer to the data in **where, along
+ * with the length of the available date.
+ * For spi streams, as on ARM, the caller must set *where to a data buffer.
+ * In any event, the implementation guarantee that on return, *where points to a data
+ * area and return the length of the area it points to, which is at most 'len' bytes
+ * and may be zero bytes. In this way, we can be efficient on machines with memory-addressed ROM.
+ */
+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..000479c
--- /dev/null
+++ b/src/lib/romstream.c
@@ -0,0 +1,65 @@
+/*
+ * 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;
+}
+
+/* This is a memory-addressable stream. So we will be setting *where to the address */
+int
+stream_read(void *stream, void **where, u32 len, u32 off)
+{
+ u8 *romstream = stream;
+ u32 amount;
+
+ if (off >= CONFIG_ROM_SIZE)
+ return 0;
+
+ amount = CONFIG_ROM_SIZE - off;
+ if (amount > len)
+ amount = len;
+ *where = romstream+off;
+
+ 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..d21e1f4 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"
@@ -358,6 +359,7 @@ void gpio_cfg_pin(int gpio, int cfg)
writel(value, &bank->con);
}
+#if 0
//static void exynos_spi_copy(unsigned int uboot_size)
static void copy_romstage(uint32_t spi_addr, uint32_t sram_addr, unsigned int len)
{
@@ -428,7 +430,7 @@ static void copy_romstage(uint32_t spi_addr, uint32_t sram_addr, unsigned int le
clrbits_le32(®s->ch_cfg, SPI_CH_RST);
clrbits_le32(®s->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
}
-
+#endif
/* Pull mode */
#define EXYNOS_GPIO_PULL_NONE 0x0
#define EXYNOS_GPIO_PULL_DOWN 0x1
@@ -2130,6 +2132,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 = v;
+
+ 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, ®s->pkt_cnt);
+ /* set FB_CLK_SEL */
+ writel(SPI_FB_DELAY_180, ®s->fb_clk);
+ /* set CH_WIDTH and BUS_WIDTH as word */
+ setbits_le32(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
+ SPI_MODE_BUS_WIDTH_WORD);
+ clrbits_le32(®s->ch_cfg, SPI_CH_CPOL_L); /* CPOL: active high */
+
+ /* clear rx and tx channel if set priveously */
+ clrbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON);
+
+ setbits_le32(®s->swap_cfg, SPI_RX_SWAP_EN |
+ SPI_RX_BYTE_SWAP |
+ SPI_RX_HWORD_SWAP);
+
+ /* do a soft reset */
+ setbits_le32(®s->ch_cfg, SPI_CH_RST);
+ clrbits_le32(®s->ch_cfg, SPI_CH_RST);
+
+ /* now set rx and tx channel ON */
+ setbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON | SPI_CH_HS_EN);
+ clrbits_le32(®s->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, ®s->tx_data);
+
+ /* waiting for TX done */
+ while (!(readl(®s->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(®s->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(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
+ SPI_MODE_BUS_WIDTH_WORD);
+ writel(0, ®s->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(®s->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST);
+ clrbits_le32(®s->ch_cfg, SPI_CH_RST);
+ clrbits_le32(®s->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
+}
+
+
void bootblock_mainboard_init(void);
void bootblock_mainboard_init(void)
{
@@ -2140,14 +2225,20 @@ void bootblock_mainboard_init(void)
clock_init();
do_serial();
printk(BIOS_INFO, "%s: UART initialized\n", __func__);
-
+#if 0
/* Copy romstage data from SPI ROM to SRAM */
printk(BIOS_INFO, "Copying romstage:\n"
"\tSPI offset: 0x%06x\n"
"\tiRAM offset: 0x%08x\n"
"\tSize: 0x%x\n",
0, CONFIG_SPI_IMAGE_HACK, CONFIG_ROMSTAGE_SIZE);
- copy_romstage(0x0, CONFIG_SPI_IMAGE_HACK, CONFIG_ROMSTAGE_SIZE);
+
+ stream = stream_start((void *)0x12d30000);
+ len = stream_read(stream, &where, CONFIG_ROMSTAGE_SIZE, 0);
+ if (len < CONFIG_ROMSTAGE_SIZE)
+ printk(BIOS_ERR, "Did not read all of the SPI! Wanted %d, got %d\n", CONFIG_ROMSTAGE_SIZE, len);
+ stream_fini(stream);
+#endif
#if 0
/* FIXME: dump SRAM content for sanity checking */
uint32_t u;
Siyuan,
Can you tell us what CPU family and southbridge this is failing on?
thanks,
Dave
----- Original Message -----
> From: "WANG Siyuan" <wangsiyuanbuaa(a)gmail.com>
> To: "Patrick Georgi" <patrick(a)georgi-clan.de>
> Cc: coreboot(a)coreboot.org
> Sent: Tuesday, January 22, 2013 3:12:00 AM
> Subject: Re: [coreboot] coreboot can boot Linux but cannot boot Windows7
>
> Hi, Patrick
> My windows 7 stopped at windows logo, It cannot enter win7 desktop.
> Can this situation debug by windbg?
>
>
> On Tue, Jan 22, 2013 at 3:42 PM, Patrick Georgi
> <patrick(a)georgi-clan.de> wrote:
> > Am 2013-01-22 03:14, schrieb WANG Siyuan:
> >
> >> I am debugging a board. coreboot could boot Linux and load graphic
> >> driver, but it could not boot Windows 7.
> >> Has anyone encountered similar problem?
> >
> > Linux is much more tolerant about many things, in particular about
> > ACPI and
> > a couple more tables.
> >
> > I collected a bunch of issues at
> > http://www.coreboot.org/ACPI#Windows_Errors
> > - if you find issues that aren't listed there, you can look for an
> > explanation (of STOP codes and similar behaviour) on msdn.com. If
> > that still
> > doesn't help you, you will have to debug your windows install (with
> > windbg)
> > and figure out what the problem is.
> > If you can get hold of checked Windows builds, I recommend these -
> > they're
> > much more helpful (especially when it comes to ACPI). Unfortunately
> > their
> > install CD is unchecked, so if you fail to find informations on the
> > installer, you'll have to install on another machine and swap disks
> > (or use
> > legacy BIOS), and probe the installed windows.
> >
> > In any case, please document your results on the wiki page I
> > mentioned.
> >
> >
> > Patrick
> >
> > --
> > coreboot mailing list: coreboot(a)coreboot.org
> > http://www.coreboot.org/mailman/listinfo/coreboot
>
>
>
> --
> Yours sincerely,
> WANG Siyuan
>
> --
> coreboot mailing list: coreboot(a)coreboot.org
> http://www.coreboot.org/mailman/listinfo/coreboot
>
Ronald G. Minnich (rminnich(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2184
-gerrit
commit 01903b02bfd540371526e4b73983f865ff5bf5bc
Author: Ronald G. Minnich <rminnich(a)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);
On memory-addressed ROMs, set *where to point to a buffer of
0 or more bytes, up to len bytes. This avoids unnecessary copies.
On non-memory-addressed ROMs, 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. We've also put example usage in there.
Change-Id: I1e5e1b7c075ab36fe8729c60fa52d8406b6d26f0
Signed-off-by: Ronald G. Minnich <rminnich(a)gmail.com>
---
src/Kconfig | 5 ++
src/drivers/realtek/Kconfig | 1 +
src/include/lib.h | 16 ++++++
src/lib/Makefile.inc | 1 +
src/lib/romstream.c | 65 ++++++++++++++++++++++++
src/mainboard/google/snow/bootblock.c | 96 ++++++++++++++++++++++++++++++++++-
6 files changed, 182 insertions(+), 2 deletions(-)
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..ff63349 100644
--- a/src/include/lib.h
+++ b/src/include/lib.h
@@ -53,5 +53,21 @@ 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.
+ * There is a subtle design trick here. For rom streams which are memory-addressable,
+ * we don't want to copy the data. So we can return a pointer to the data in **where, along
+ * with the length of the available date.
+ * For spi streams, as on ARM, the caller must set *where to a data buffer.
+ * In any event, the implementation guarantee that on return, *where points to a data
+ * area and return the length of the area it points to, which is at most 'len' bytes
+ * and may be zero bytes. In this way, we can be efficient on machines with memory-addressed ROM.
+ */
+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..000479c
--- /dev/null
+++ b/src/lib/romstream.c
@@ -0,0 +1,65 @@
+/*
+ * 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;
+}
+
+/* This is a memory-addressable stream. So we will be setting *where to the address */
+int
+stream_read(void *stream, void **where, u32 len, u32 off)
+{
+ u8 *romstream = stream;
+ u32 amount;
+
+ if (off >= CONFIG_ROM_SIZE)
+ return 0;
+
+ amount = CONFIG_ROM_SIZE - off;
+ if (amount > len)
+ amount = len;
+ *where = romstream+off;
+
+ 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..65265d7 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"
@@ -358,6 +359,7 @@ void gpio_cfg_pin(int gpio, int cfg)
writel(value, &bank->con);
}
+#if 0
//static void exynos_spi_copy(unsigned int uboot_size)
static void copy_romstage(uint32_t spi_addr, uint32_t sram_addr, unsigned int len)
{
@@ -428,7 +430,7 @@ static void copy_romstage(uint32_t spi_addr, uint32_t sram_addr, unsigned int le
clrbits_le32(®s->ch_cfg, SPI_CH_RST);
clrbits_le32(®s->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
}
-
+#endif
/* Pull mode */
#define EXYNOS_GPIO_PULL_NONE 0x0
#define EXYNOS_GPIO_PULL_DOWN 0x1
@@ -2130,11 +2132,97 @@ 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 = v;
+
+ 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, ®s->pkt_cnt);
+ /* set FB_CLK_SEL */
+ writel(SPI_FB_DELAY_180, ®s->fb_clk);
+ /* set CH_WIDTH and BUS_WIDTH as word */
+ setbits_le32(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
+ SPI_MODE_BUS_WIDTH_WORD);
+ clrbits_le32(®s->ch_cfg, SPI_CH_CPOL_L); /* CPOL: active high */
+
+ /* clear rx and tx channel if set priveously */
+ clrbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON);
+
+ setbits_le32(®s->swap_cfg, SPI_RX_SWAP_EN |
+ SPI_RX_BYTE_SWAP |
+ SPI_RX_HWORD_SWAP);
+
+ /* do a soft reset */
+ setbits_le32(®s->ch_cfg, SPI_CH_RST);
+ clrbits_le32(®s->ch_cfg, SPI_CH_RST);
+
+ /* now set rx and tx channel ON */
+ setbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON | SPI_CH_HS_EN);
+ clrbits_le32(®s->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, ®s->tx_data);
+
+ /* waiting for TX done */
+ while (!(readl(®s->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(®s->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(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
+ SPI_MODE_BUS_WIDTH_WORD);
+ writel(0, ®s->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(®s->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST);
+ clrbits_le32(®s->ch_cfg, SPI_CH_RST);
+ clrbits_le32(®s->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
+}
+
+
void bootblock_mainboard_init(void);
void bootblock_mainboard_init(void)
{
/* FIXME: we should not need UART in bootblock, this is only
done for testing purposes */
+ void *stream;
+ void *where = (void *)CONFIG_SPI_IMAGE_HACK;
+ int len;
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
power_init();
clock_init();
@@ -2147,7 +2235,11 @@ void bootblock_mainboard_init(void)
"\tiRAM offset: 0x%08x\n"
"\tSize: 0x%x\n",
0, CONFIG_SPI_IMAGE_HACK, CONFIG_ROMSTAGE_SIZE);
- copy_romstage(0x0, CONFIG_SPI_IMAGE_HACK, CONFIG_ROMSTAGE_SIZE);
+ stream = stream_start((void *)0x12d30000);
+ len = stream_read(stream, &where, CONFIG_ROMSTAGE_SIZE, 0);
+ if (len < CONFIG_ROMSTAGE_SIZE)
+ printk(BIOS_ERR, "Did not read all of the SPI! Wanted %d, got %d\n", CONFIG_ROMSTAGE_SIZE, len);
+ stream_fini(stream);
#if 0
/* FIXME: dump SRAM content for sanity checking */
uint32_t u;
Ronald G. Minnich (rminnich(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2184
-gerrit
commit d5a2f60b28d5abb76b6d901c9ffce465b060cfce
Author: Ronald G. Minnich <rminnich(a)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. We've also put example usage in there.
Change-Id: I1e5e1b7c075ab36fe8729c60fa52d8406b6d26f0
Signed-off-by: Ronald G. Minnich <rminnich(a)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 | 95 ++++++++++++++++++++++++++++++++++-
6 files changed, 179 insertions(+), 2 deletions(-)
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..f4ac5e0 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"
@@ -358,6 +359,7 @@ void gpio_cfg_pin(int gpio, int cfg)
writel(value, &bank->con);
}
+#if 0
//static void exynos_spi_copy(unsigned int uboot_size)
static void copy_romstage(uint32_t spi_addr, uint32_t sram_addr, unsigned int len)
{
@@ -428,7 +430,7 @@ static void copy_romstage(uint32_t spi_addr, uint32_t sram_addr, unsigned int le
clrbits_le32(®s->ch_cfg, SPI_CH_RST);
clrbits_le32(®s->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
}
-
+#endif
/* Pull mode */
#define EXYNOS_GPIO_PULL_NONE 0x0
#define EXYNOS_GPIO_PULL_DOWN 0x1
@@ -2130,11 +2132,96 @@ 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 = v;
+
+ 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, ®s->pkt_cnt);
+ /* set FB_CLK_SEL */
+ writel(SPI_FB_DELAY_180, ®s->fb_clk);
+ /* set CH_WIDTH and BUS_WIDTH as word */
+ setbits_le32(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
+ SPI_MODE_BUS_WIDTH_WORD);
+ clrbits_le32(®s->ch_cfg, SPI_CH_CPOL_L); /* CPOL: active high */
+
+ /* clear rx and tx channel if set priveously */
+ clrbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON);
+
+ setbits_le32(®s->swap_cfg, SPI_RX_SWAP_EN |
+ SPI_RX_BYTE_SWAP |
+ SPI_RX_HWORD_SWAP);
+
+ /* do a soft reset */
+ setbits_le32(®s->ch_cfg, SPI_CH_RST);
+ clrbits_le32(®s->ch_cfg, SPI_CH_RST);
+
+ /* now set rx and tx channel ON */
+ setbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON | SPI_CH_HS_EN);
+ clrbits_le32(®s->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, ®s->tx_data);
+
+ /* waiting for TX done */
+ while (!(readl(®s->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(®s->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(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
+ SPI_MODE_BUS_WIDTH_WORD);
+ writel(0, ®s->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(®s->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST);
+ clrbits_le32(®s->ch_cfg, SPI_CH_RST);
+ clrbits_le32(®s->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
+}
+
+
void bootblock_mainboard_init(void);
void bootblock_mainboard_init(void)
{
/* FIXME: we should not need UART in bootblock, this is only
done for testing purposes */
+ void *stream;
+ int len;
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
power_init();
clock_init();
@@ -2147,7 +2234,11 @@ void bootblock_mainboard_init(void)
"\tiRAM offset: 0x%08x\n"
"\tSize: 0x%x\n",
0, CONFIG_SPI_IMAGE_HACK, CONFIG_ROMSTAGE_SIZE);
- copy_romstage(0x0, CONFIG_SPI_IMAGE_HACK, CONFIG_ROMSTAGE_SIZE);
+ stream = stream_start((void *)0x12d30000);
+ len = stream_read(stream, (void *)CONFIG_SPI_IMAGE_HACK, CONFIG_ROMSTAGE_SIZE, 0);
+ if (len < CONFIG_ROMSTAGE_SIZE)
+ printk(BIOS_ERR, "Did not read all of the SPI! Wanted %d, got %d\n", CONFIG_ROMSTAGE_SIZE, len);
+ stream_fini(stream);
#if 0
/* FIXME: dump SRAM content for sanity checking */
uint32_t u;
Ronald G. Minnich (rminnich(a)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(a)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(a)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, ®s->pkt_cnt);
+ /* set FB_CLK_SEL */
+ writel(SPI_FB_DELAY_180, ®s->fb_clk);
+ /* set CH_WIDTH and BUS_WIDTH as word */
+ setbits_le32(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
+ SPI_MODE_BUS_WIDTH_WORD);
+ clrbits_le32(®s->ch_cfg, SPI_CH_CPOL_L); /* CPOL: active high */
+
+ /* clear rx and tx channel if set priveously */
+ clrbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON);
+
+ setbits_le32(®s->swap_cfg, SPI_RX_SWAP_EN |
+ SPI_RX_BYTE_SWAP |
+ SPI_RX_HWORD_SWAP);
+
+ /* do a soft reset */
+ setbits_le32(®s->ch_cfg, SPI_CH_RST);
+ clrbits_le32(®s->ch_cfg, SPI_CH_RST);
+
+ /* now set rx and tx channel ON */
+ setbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON | SPI_CH_HS_EN);
+ clrbits_le32(®s->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, ®s->tx_data);
+
+ /* waiting for TX done */
+ while (!(readl(®s->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(®s->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(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
+ SPI_MODE_BUS_WIDTH_WORD);
+ writel(0, ®s->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(®s->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST);
+ clrbits_le32(®s->ch_cfg, SPI_CH_RST);
+ clrbits_le32(®s->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
+}
+
+
void bootblock_mainboard_init(void);
void bootblock_mainboard_init(void)
{
the following patch was just integrated into master:
commit d5c998be99709c92f200b3b08aed2ca3fee2d519
Author: Marc Jones <marc.jones(a)se-eng.com>
Date: Wed Jan 16 17:14:24 2013 -0700
Add MMCONF resource to AMD fam14 PCI_DOMAIN.
The coreboot resource allocator doesn't respect resources
claimed in the APIC_CLUSTER. Move the MMCONF resource to the
PCI_DOMAIN to prevent overlap with PCI devices.
Change-Id: I8541795f69bbdd9041b390103fb901d37e07eeb9
Signed-off-by: Marc Jones <marc.jones(a)se-eng.com>
Reviewed-on: http://review.coreboot.org/2167
Reviewed-by: Dave Frodin <dave.frodin(a)se-eng.com>
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martin.roth(a)se-eng.com>
Reviewed-by: Steve Goodrich <steve.goodrich(a)se-eng.com>
Build-Tested: build bot (Jenkins) at Thu Jan 17 19:25:33 2013, giving +1
See http://review.coreboot.org/2167 for details.
-gerrit
the following patch was just integrated into master:
commit 5e732b8bf0fde8a304758e8845f3100a09037f2b
Author: Paul Menzel <paulepanter(a)users.sourceforge.net>
Date: Tue Jan 22 11:58:13 2013 +0100
util/runfw/googlesnow.c: Remove trailing whitespace
$ git stripspace < util/runfw/googlesnow.c > /tmp/bla
$ mv /tmp/bla util/runfw/googlesnow.c
Introduced with original commit.
commit b867281a07addd1eb00f964ff4f8727664e13e19
Author: Ronald G. Minnich <rminnich(a)gmail.com>
Date: Wed Jan 16 11:59:34 2013 -0600
Utility to run the snow bios in user mode
Change-Id: I146c07a918ef99e8ae3c0dd72cf28fae22312e43
Signed-off-by: Paul Menzel <paulepanter(a)users.sourceforge.net>
Reviewed-on: http://review.coreboot.org/2183
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich(a)gmail.com>
Build-Tested: build bot (Jenkins) at Tue Jan 22 12:38:36 2013, giving +1
Reviewed-By: Ronald G. Minnich <rminnich(a)gmail.com> at Tue Jan 22 19:04:29 2013, giving +2
See http://review.coreboot.org/2183 for details.
-gerrit