David Hendricks (dhendrix@chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2174
-gerrit
commit faf6bb02b90339194f40e32efb4eb34f5dd9dc4f Author: David Hendricks dhendrix@chromium.org Date: Thu Jan 17 20:52:21 2013 -0800
WIP: armv7/snow patch dump
** do not submit **
This is just a patch dump so others can more easily get up to speed.
The user should see a bunch of prints to the UART, and PSHOLD will be held high so the machine should not turn itself off. We are actually able to CBFS and get the romstage address successfully, but calling romstage's main() function fails...
Add romstage as a stage (a later patch adds it as a binary, which is probably wrong). The Makefile magic is complex enough that we let it build the XIP file for now, but we no longer use it.
replace findstage with loadstage. Loadstage will find a stage, load the code to memory, and zero the remaining part of memory.
Now we can link the romstage to go anywhere!
TODO: - Eliminate magic offsets (in romstage.ld and cbfs.h) - Make it so that the call to romstage's address does not switch to a mode that's incompatible with romstage's entry point.
Depends-On: 2173 Change-Id: Iae4d2f9e7f429cb1df15d49daf9a08b88d75d79d Signed-off-by: David Hendricks dhendrix@chromium.org Signed-off-by: Ronald G. Minnich rminnich@gmail.com --- src/arch/armv7/Makefile.inc | 5 +-- src/arch/armv7/bootblock_simple.c | 6 +-- src/arch/armv7/include/arch/cbfs.h | 68 +++++++++++++++++++++++++++++----- src/arch/armv7/include/arch/hlt.h | 1 - src/arch/armv7/romstage.ld | 5 ++- src/cpu/samsung/exynos5250/bootblock.c | 3 +- src/mainboard/google/snow/bootblock.c | 18 +++++---- src/mainboard/google/snow/romstage.c | 25 +++++++++++++ 8 files changed, 104 insertions(+), 27 deletions(-)
diff --git a/src/arch/armv7/Makefile.inc b/src/arch/armv7/Makefile.inc index ecb5aee..a5833a7 100644 --- a/src/arch/armv7/Makefile.inc +++ b/src/arch/armv7/Makefile.inc @@ -215,9 +215,8 @@ $(obj)/coreboot.pre: $(objcbfs)/romstage_xip.elf $(obj)/coreboot.pre1 $(CBFSTOOL @printf " CBFS $(subst $(obj)/,,$(@))\n" cp $(obj)/coreboot.pre1 $@.tmp $(CBFSTOOL) $@.tmp add-stage \ - -f $(objcbfs)/romstage_xip.elf \ - -n $(CONFIG_CBFS_PREFIX)/romstage -c none \ - -b $(shell cat $(objcbfs)/base_xip.txt) + -f $(objcbfs)/romstage_null.debug \ + -n $(CONFIG_CBFS_PREFIX)/romstage -c none mv $@.tmp $@
################################################################################ diff --git a/src/arch/armv7/bootblock_simple.c b/src/arch/armv7/bootblock_simple.c index 6897e15..a48a490 100644 --- a/src/arch/armv7/bootblock_simple.c +++ b/src/arch/armv7/bootblock_simple.c @@ -39,12 +39,12 @@ void main(unsigned long bist) unsigned long entry;
if (boot_cpu()) { - bootblock_mainboard_init(); bootblock_cpu_init(); + bootblock_mainboard_init(); }
- entry = findstage(target1); + entry = loadstage(target1); + printk(BIOS_INFO, "entry: 0x%08lx\n", entry); if (entry) call(entry); - hlt(); } diff --git a/src/arch/armv7/include/arch/cbfs.h b/src/arch/armv7/include/arch/cbfs.h index 0affa5e..ed55d80 100644 --- a/src/arch/armv7/include/arch/cbfs.h +++ b/src/arch/armv7/include/arch/cbfs.h @@ -26,42 +26,92 @@ #include <arch/byteorder.h> #include <arch/cbfs.h>
+ static int cbfs_check_magic(struct cbfs_file *file) { - return !strcmp(file->magic, CBFS_FILE_MAGIC) ? 1 : 0; + return strcmp(file->magic, CBFS_FILE_MAGIC) ? 0 : 1; }
-static unsigned long findstage(const char* target) +static unsigned long loadstage(const char* target) { unsigned long offset, align; /* FIXME: magic offsets */ - struct cbfs_header *header = (struct cbfs_header *)(0x02023400 + 0x40); + struct cbfs_header *header = (struct cbfs_header *)(0x02062040); // if (ntohl(header->magic) != CBFS_HEADER_MAGIC) // printk(BIOS_ERR, "ERROR: No valid CBFS header found!\n");
offset = ntohl(header->offset); align = ntohl(header->align); + printk(BIOS_INFO, "cbfs header (%p)\n", header); + printk(BIOS_INFO, "\tmagic: 0x%08x\n", ntohl(header->magic)); + printk(BIOS_INFO, "\tversion: 0x%08x\n", ntohl(header->version)); + printk(BIOS_INFO, "\tromsize: 0x%08x\n", ntohl(header->romsize)); + printk(BIOS_INFO, "\tbootblocksize: 0x%08x\n", ntohl(header->bootblocksize)); + 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; - file = (struct cbfs_file *)(offset + CONFIG_ROMSTAGE_BASE); - if (!cbfs_check_magic(file)) + struct cbfs_stage *stage; + file = (struct cbfs_file *)(offset + 0x02060000); + if (!cbfs_check_magic(file)) { + printk(BIOS_INFO, "magic is wrong, file: %p\n", file); return 0; - if (!strcmp(CBFS_NAME(file), target)) - return (unsigned long)CBFS_SUBHEADER(file); + } + if (!strcmp(CBFS_NAME(file), target)) { + uint32_t load, entry; + printk(BIOS_INFO, "CBFS name matched, offset: %p\n", file); + printk(BIOS_INFO, "\tmagic: %02x%02x%02x%02x%02x%02x%02x%02x\n", + file->magic[0], file->magic[1], file->magic[2], file->magic[3], + file->magic[4], file->magic[5], file->magic[6], file->magic[7]); + printk(BIOS_INFO, "\tlen: 0x%08x\n", ntohl(file->len)); + 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); + 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; + return entry; + } int flen = ntohl(file->len); int foffset = ntohl(file->offset); unsigned long oldoffset = offset; offset = ALIGN(offset + foffset + flen, align); + printk(BIOS_INFO, "offset: 0x%08lx\n", offset); if (offset <= oldoffset) return 0; - if (offset < CONFIG_ROMSTAGE_BASE + ntohl(header->romsize)); + if (offset > (128 * 1024)) return 0; } }
static inline void call(unsigned long addr) { - void (*doit)(void) = (void *)addr; + __attribute__((noreturn)) void (*doit)(void) = (void *)addr; + printk(BIOS_INFO, "addr: %08lx, doit: %p\n", addr, doit); + /* FIXME: dumping SRAM content for sanity checking */ + int i; + for (i = 0; i < 128; i++) { + if (i % 16 == 0) + printk(BIOS_INFO, "\n0x%08lx: ", addr + i); + else + printk(BIOS_INFO, " "); + printk(BIOS_INFO, "%02x", *(uint8_t *)(addr + i)); + } + /* FIXME: do we need to change to/from arm/thumb? */ doit(); } #endif diff --git a/src/arch/armv7/include/arch/hlt.h b/src/arch/armv7/include/arch/hlt.h index 535508a..285b6f8 100644 --- a/src/arch/armv7/include/arch/hlt.h +++ b/src/arch/armv7/include/arch/hlt.h @@ -4,7 +4,6 @@ static inline __attribute__((always_inline)) void hlt(void) { for (;;) ; - //asm("hlt"); }
#endif /* ARCH_HLT_H */ diff --git a/src/arch/armv7/romstage.ld b/src/arch/armv7/romstage.ld index d40d2ef..8343a4a 100644 --- a/src/arch/armv7/romstage.ld +++ b/src/arch/armv7/romstage.ld @@ -35,11 +35,12 @@ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm)
-/* ENTRY(_start) */ +ENTRY(_start)
SECTIONS { - . = 0x02023400 + 0x4000; + /* TODO make this a configurable option (per chipset). */ + . = 0x02050000;
.romtext . : { _rom = .; diff --git a/src/cpu/samsung/exynos5250/bootblock.c b/src/cpu/samsung/exynos5250/bootblock.c index 0d65676..2852764 100644 --- a/src/cpu/samsung/exynos5250/bootblock.c +++ b/src/cpu/samsung/exynos5250/bootblock.c @@ -36,5 +36,6 @@ static int config_branch_prediction(int set_cr_z) void bootblock_cpu_init(void); void bootblock_cpu_init(void) { - /* FIXME: this is a stub for now */ + volatile unsigned long *pshold = (unsigned long *)0x1004330c; + *pshold |= 0x100; } diff --git a/src/mainboard/google/snow/bootblock.c b/src/mainboard/google/snow/bootblock.c index a025b28..48854a7 100644 --- a/src/mainboard/google/snow/bootblock.c +++ b/src/mainboard/google/snow/bootblock.c @@ -42,8 +42,6 @@
#define EXYNOS5_CLOCK_BASE 0x10010000
-volatile unsigned long *pshold = (unsigned long *)0x1004330c; - /* FIXME(dhendrix): Can we move this SPI stuff elsewhere? */ static void spi_rx_tx(struct exynos_spi *regs, int todo, void *dinp, void const *doutp, int i) @@ -723,6 +721,9 @@ static void exynos5_uart_tx_byte(unsigned char data) // struct s5p_uart *const uart = s5p_get_base_uart(dev_index); struct s5p_uart *uart = (struct s5p_uart *)uart3_base;
+ if (data == '\n') + exynos5_uart_tx_byte('\r'); + /* wait for room in the tx FIFO */ while ((readl(uart->ufstat) & TX_FIFO_FULL_MASK)) { if (exynos5_uart_err_check(1)) @@ -738,12 +739,13 @@ void puts(const char *s) int n = 0;
while (*s) { + if (*s == '\n') { + exynos5_uart_tx_byte(0xd); /* CR */ + } + exynos5_uart_tx_byte(*s++); n++; } - - exynos5_uart_tx_byte(0xd); /* CR */ - exynos5_uart_tx_byte(0xa); /* LF */ }
static void do_serial(void) @@ -2140,7 +2142,7 @@ void bootblock_mainboard_init(void) printk(BIOS_INFO, "%s: hello world\n", __func__);
/* Copy romstage data from SPI ROM to SRAM */ - /* FIXME: test with something benign, then fix the offsets once - we're more confident in this */ - copy_romstage(0x2000, 0x2060000, 0x800); + /* FIXME: magic offsets */ + copy_romstage(0x0, 0x2060000, 0x10000); + printk(BIOS_INFO, "%s: goodbye world\n", __func__); } diff --git a/src/mainboard/google/snow/romstage.c b/src/mainboard/google/snow/romstage.c index 9092b7c..859c69e 100644 --- a/src/mainboard/google/snow/romstage.c +++ b/src/mainboard/google/snow/romstage.c @@ -21,6 +21,22 @@ #include <system.h> #include <cache.h>
+#if 0 +#include <arch/io.h> + +/* FIXME: make i2c.h use standard types */ +#define uchar unsigned char +#define uint unsigned int +#include <device/i2c.h> + +#include <cpu/samsung/s5p-common/s3c24x0_i2c.h> +#include "cpu/samsung/exynos5250/dmc.h" +#include <cpu/samsung/exynos5250/power.h> +#include <cpu/samsung/exynos5250/clock_init.h> +#include <cpu/samsung/exynos5-common/uart.h> +#endif +#include <console/console.h> + static void mmu_setup(void) { dram_bank_mmu_setup(CONFIG_SYS_SDRAM_BASE, CONFIG_DRAM_SIZE_MB * 1024); @@ -28,5 +44,14 @@ static void mmu_setup(void)
void main(void) { +// volatile unsigned long *pshold = (unsigned long *)0x1004330c; +// i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); +// power_init(); +// clock_init(); +// exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE); + console_init(); + printk(BIOS_INFO, "hello from romstage\n"); + +// *pshold &= ~0x100; /* shut down */ mmu_setup(); }