From 211a5d56db2ecf580b722fab132d908a6ba84dde Mon Sep 17 00:00:00 2001 From: David Hendricks Date: Thu, 17 Jan 2013 20:52:21 -0800 Subject: armv7/snow: get to romstage This patch does a few things to get us into romstage: - 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! - Eliminate magic offsets from code/ldscripts and centralize Kconfig variables in src/cpu/samsung/exynos5250/Kconfig. - Tidy up code and serial output Change-Id: Iae4d2f9e7f429cb1df15d49daf9a08b88d75d79d Signed-off-by: David Hendricks Signed-off-by: Ronald G. Minnich Reviewed-on: http://review.coreboot.org/2174 Tested-by: build bot (Jenkins) --- src/arch/armv7/Makefile.inc | 5 +-- src/arch/armv7/bootblock.inc | 2 +- src/arch/armv7/bootblock_simple.c | 7 ++-- src/arch/armv7/include/arch/cbfs.h | 69 ++++++++++++++++++++++++++---- src/arch/armv7/include/arch/hlt.h | 1 - src/arch/armv7/lib/id.lds | 3 +- src/arch/armv7/romstage.ld | 12 ++---- src/cpu/samsung/exynos5250/Kconfig | 77 +++++++++++++++++++++++----------- src/cpu/samsung/exynos5250/bootblock.c | 3 +- src/mainboard/google/snow/Kconfig | 23 ---------- src/mainboard/google/snow/bootblock.c | 36 ++++++++++++---- src/mainboard/google/snow/romstage.c | 25 +++++++++++ 12 files changed, 178 insertions(+), 85 deletions(-) (limited to 'src') diff --git a/src/arch/armv7/Makefile.inc b/src/arch/armv7/Makefile.inc index 1d12eca3b7..2cf6ed942f 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.inc b/src/arch/armv7/bootblock.inc index 4fe7502681..1eb8e112d6 100644 --- a/src/arch/armv7/bootblock.inc +++ b/src/arch/armv7/bootblock.inc @@ -92,4 +92,4 @@ wait_for_interrupt: */ .align 2 .Stack: - .word CONFIG_SYS_INIT_SP_ADDR + .word CONFIG_IRAM_STACK diff --git a/src/arch/armv7/bootblock_simple.c b/src/arch/armv7/bootblock_simple.c index 6897e15fc6..f6bcf980b1 100644 --- a/src/arch/armv7/bootblock_simple.c +++ b/src/arch/armv7/bootblock_simple.c @@ -39,12 +39,13 @@ void main(unsigned long bist) unsigned long entry; if (boot_cpu()) { - bootblock_mainboard_init(); bootblock_cpu_init(); + bootblock_mainboard_init(); } - entry = findstage(target1); + printk(BIOS_INFO, "bootblock main(): loading romstage\n"); + entry = loadstage(target1); + printk(BIOS_INFO, "bootblock main(): jumping to romstage\n"); if (entry) call(entry); - hlt(); } diff --git a/src/arch/armv7/include/arch/cbfs.h b/src/arch/armv7/include/arch/cbfs.h index 0affa5e5d3..99b7b43e66 100644 --- a/src/arch/armv7/include/arch/cbfs.h +++ b/src/arch/armv7/include/arch/cbfs.h @@ -26,42 +26,93 @@ #include #include + 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; + struct cbfs_header *header = (struct cbfs_header *)(CONFIG_BOOTBLOCK_BASE + 0x40); /* FIXME: magic offsets */ - struct cbfs_header *header = (struct cbfs_header *)(0x02023400 + 0x40); // 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 (0x%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; + /* FIXME: SPI image hack */ + file = (struct cbfs_file *)(offset + CONFIG_SPI_IMAGE_HACK); + 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 > CONFIG_ROMSTAGE_SIZE) 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 535508a714..285b6f8786 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/lib/id.lds b/src/arch/armv7/lib/id.lds index b521f3956b..9d5047967c 100644 --- a/src/arch/armv7/lib/id.lds +++ b/src/arch/armv7/lib/id.lds @@ -1,6 +1,5 @@ SECTIONS { - /* FIXME: determine a sensible location... */ - . = (0x2026400); + . = CONFIG_ID_SECTION_BASE; .id (.): { *(.id) } diff --git a/src/arch/armv7/romstage.ld b/src/arch/armv7/romstage.ld index faf7d6d38a..b4bc29d196 100644 --- a/src/arch/armv7/romstage.ld +++ b/src/arch/armv7/romstage.ld @@ -24,22 +24,16 @@ INCLUDE ldoptions */ -/* - * FIXME: what exactly should these be? maybe defined on a per-CPU basis? - * FIXME 2: Somehow linker didn't like CONFIG_SPL_MAX_SIZE and CONFIG_SPL_TEXT_BASE... - */ -/* MEMORY { .sram : ORIGIN = 0x02023400, LENGTH = 0x3800 } */ -/*MEMORY { .sram : ORIGIN = 0x02023400, LENGTH = 0x10000 }*/ - /* We use ELF as output format. So that we can debug the code in some form. */ 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). */ + . = CONFIG_ROMSTAGE_BASE; .romtext . : { _rom = .; diff --git a/src/cpu/samsung/exynos5250/Kconfig b/src/cpu/samsung/exynos5250/Kconfig index 206df9260b..f5beddcdb4 100644 --- a/src/cpu/samsung/exynos5250/Kconfig +++ b/src/cpu/samsung/exynos5250/Kconfig @@ -14,43 +14,72 @@ config SATA_AHCI bool default n -config SPL_BUILD - bool - default n +# Example SRAM/iRAM map for Exynos5250 platform: +# +# 0x0202_0000: vendor-provided BL1 +# 0x0202_3400: bootblock, assume up to 32KB in size +# 0x0202_2600: ID section, assume 2KB in size. This will be +# within the bootblock section. +# 0x0203_0000: romstage, assume up to 128KB in size. +# 0x0207_7f00: stack pointer -config SYS_TEXT_BASE - hex "Executable code section" - default 0x43e00000 +# this may be used to calculate offsets +config IRAM_BOTTOM + hex + default 0x02020000 -config SYS_SDRAM_BASE - hex "SDRAM base address" - default 0x40000000 +config IRAM_TOP + hex + default 0x02077fff -#FIXME(dhendrix, reinauer): re-visit this RAMBASE/RAMTOP stuff... -config RAMBASE +config BOOTBLOCK_BASE hex - default SYS_SDRAM_BASE -# according to stefan, this is RAMBASE + 1M. -config RAMTOP + default 0x02023400 + +config ID_SECTION_BASE hex - default 0x40100000 + default 0x02026000 -config IRAM_BOTTOM +config ROMSTAGE_BASE hex - default 0x02020000 + default 0x02030000 -config IRAM_TOP +config ROMSTAGE_SIZE hex - default 0x02077fff + default 0x10000 -config SYS_INIT_SP_ADDR +# FIXME: This is for copying SPI content into SRAM temporarily and +# will be removed when we have the SPI streaming driver implemented. +config SPI_IMAGE_HACK hex - default 0x02058000 + default 0x02060000 config IRAM_STACK hex - default SYS_INIT_SP_ADDR + default 0x02077f00 +# FIXME: other magic numbers that should probably go away config XIP_ROM_SIZE - hex "ROM stage (BL2) size" - default 0x20000 + hex + default ROMSTAGE_SIZE + +config SYS_SDRAM_BASE + hex "SDRAM base address" + default 0x40000000 + +config SPL_BUILD + bool + default n + +config SYS_TEXT_BASE + hex "Executable code section" + default 0x43e00000 + +config RAMBASE + hex + default SYS_SDRAM_BASE +# according to stefan, this is RAMBASE + 1M. +config RAMTOP + hex + default 0x40100000 + diff --git a/src/cpu/samsung/exynos5250/bootblock.c b/src/cpu/samsung/exynos5250/bootblock.c index 0d65676bb5..2852764577 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/Kconfig b/src/mainboard/google/snow/Kconfig index 8f41c64a40..a0c76d6b8c 100644 --- a/src/mainboard/google/snow/Kconfig +++ b/src/mainboard/google/snow/Kconfig @@ -60,29 +60,6 @@ config BOOTBLOCK_MAINBOARD_INIT string default "mainboard/google/snow/bootblock.c" -# SPL (second-phase loader) stuff -config SPL_TEXT_BASE - hex - default 0x02023400 - help - Location of SPL. Default location is within iRAM region. - -config ROMSTAGE_BASE - hex - default SPL_TEXT_BASE - -# FIXME: increased "SPL" size to get around build issues -#config SPL_MAX_SIZE -# hex "SPL executable max size" -# default 0x3800 -# help -# Max size of SPL. Default is 14KB -config SPL_MAX_SIZE - hex - default 0x8000 - help - Max size of SPL. Let's say 32KB for now... - config DRAM_SIZE_MB int default 2048 diff --git a/src/mainboard/google/snow/bootblock.c b/src/mainboard/google/snow/bootblock.c index a025b28740..d5ee0a378a 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) @@ -2137,10 +2139,26 @@ void bootblock_mainboard_init(void) power_init(); clock_init(); do_serial(); - printk(BIOS_INFO, "%s: hello world\n", __func__); + printk(BIOS_INFO, "%s: UART initialized\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); + 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); +#if 0 + /* FIXME: dump SRAM content for sanity checking */ + uint32_t u; + for (u = CONFIG_SPI_IMAGE_HACK; u < CONFIG_SPI_IMAGE_HACK + 128; u++) { + if (u % 16 == 0) + printk(BIOS_INFO, "\n0x%08x: ", u); + else + printk(BIOS_INFO, " "); + printk(BIOS_INFO, "%02x", *(uint8_t *)(u)); + } + printk(BIOS_INFO, "\n"); +#endif + printk(BIOS_INFO, "%s: finished\n", __func__); } diff --git a/src/mainboard/google/snow/romstage.c b/src/mainboard/google/snow/romstage.c index e2af2c0c4e..45016a5434 100644 --- a/src/mainboard/google/snow/romstage.c +++ b/src/mainboard/google/snow/romstage.c @@ -21,6 +21,22 @@ #include #include +#if 0 +#include + +/* FIXME: make i2c.h use standard types */ +#define uchar unsigned char +#define uint unsigned int +#include + +#include +#include "cpu/samsung/exynos5250/dmc.h" +#include +#include +#include +#endif +#include + static void mmu_setup(void) { dram_bank_mmu_setup(CONFIG_SYS_SDRAM_BASE, CONFIG_DRAM_SIZE_MB * 1024); @@ -29,5 +45,14 @@ static void mmu_setup(void) void main(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(); } -- cgit v1.2.3