From 9d24274509cdd463992dc1fb1a2820d6a4b6d21d Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 21 Jan 2014 07:30:37 +0100 Subject: microblaze: Add SPL support Add support for U-BOOT SPL. NOR and RAM mode are supported. There are 3 images in NOR flash. u-boot.img, dtb and kernel. Signed-off-by: Michal Simek --- arch/microblaze/cpu/Makefile | 1 + arch/microblaze/cpu/spl.c | 55 +++++++++++++++++++++++++++++++++ arch/microblaze/cpu/start.S | 12 ++++++++ arch/microblaze/cpu/timer.c | 8 ++++- arch/microblaze/cpu/u-boot-spl.lds | 57 ++++++++++++++++++++++++++++++++++ arch/microblaze/include/asm/spl.h | 16 ++++++++++ arch/microblaze/include/asm/u-boot.h | 1 + arch/microblaze/lib/board.c | 11 ++++++- include/configs/microblaze-generic.h | 60 ++++++++++++++++++++++++++++++++++++ 9 files changed, 219 insertions(+), 2 deletions(-) create mode 100644 arch/microblaze/cpu/spl.c create mode 100644 arch/microblaze/cpu/u-boot-spl.lds create mode 100644 arch/microblaze/include/asm/spl.h diff --git a/arch/microblaze/cpu/Makefile b/arch/microblaze/cpu/Makefile index 6e201f2..4955e81 100644 --- a/arch/microblaze/cpu/Makefile +++ b/arch/microblaze/cpu/Makefile @@ -8,3 +8,4 @@ extra-y = start.o obj-y = irq.o obj-y += cpu.o interrupts.o cache.o exception.o timer.o +obj-$(CONFIG_SPL_BUILD) += spl.o diff --git a/arch/microblaze/cpu/spl.c b/arch/microblaze/cpu/spl.c new file mode 100644 index 0000000..0912261 --- /dev/null +++ b/arch/microblaze/cpu/spl.c @@ -0,0 +1,55 @@ +/* + * (C) Copyright 2013 - 2014 Xilinx, Inc + * + * Michal Simek + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +bool boot_linux; + +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_NOR; +} + +/* Board initialization after bss clearance */ +void spl_board_init(void) +{ + gd = (gd_t *)CONFIG_SPL_STACK_ADDR; + + /* enable console uart printing */ + preloader_console_init(); +} + +#ifdef CONFIG_SPL_OS_BOOT +void __noreturn jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%p\n", arg); + typedef void (*image_entry_arg_t)(char *, ulong, ulong) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t)spl_image.entry_point; + + image_entry(NULL, 0, (ulong)arg); +} +#endif /* CONFIG_SPL_OS_BOOT */ + +int spl_start_uboot(void) +{ +#ifdef CONFIG_SPL_OS_BOOT + if (boot_linux) + return 0; +#endif + + return 1; +} diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index 8928024..1757bbf 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -22,6 +22,11 @@ _start: */ mts rmsr, r0 /* disable cache */ + +#if defined(CONFIG_SPL_BUILD) + addi r1, r0, CONFIG_SPL_STACK_ADDR + addi r1, r1, -4 /* Decrement SP to top of memory */ +#else addi r1, r0, CONFIG_SYS_INIT_SP_OFFSET addi r1, r1, -4 /* Decrement SP to top of memory */ @@ -115,6 +120,7 @@ _start: sh r7, r0, r8 rsubi r8, r10, 0x26 sh r6, r0, r8 +#endif /* BUILD_SPL */ /* Flush cache before enable cache */ addik r5, r0, 0 @@ -139,9 +145,14 @@ clear_bss: cmp r6, r5, r4 /* check if we have reach the end */ bnei r6, 2b 3: /* jumping to board_init */ +#ifndef CONFIG_SPL_BUILD brai board_init_f +#else + brai board_init_r +#endif 1: bri 1b +#ifndef CONFIG_SPL_BUILD /* * Read 16bit little endian */ @@ -174,3 +185,4 @@ out16: bslli r3, r6, 8 rtsd r15, 8 or r0, r0, r0 .end out16 +#endif diff --git a/arch/microblaze/cpu/timer.c b/arch/microblaze/cpu/timer.c index 69ae6d4..3960bbb 100644 --- a/arch/microblaze/cpu/timer.c +++ b/arch/microblaze/cpu/timer.c @@ -34,6 +34,7 @@ void __udelay(unsigned long usec) } } +#ifndef CONFIG_SPL_BUILD static void timer_isr(void *arg) { timestamp++; @@ -62,10 +63,15 @@ int timer_init (void) if (ret) tmr = NULL; } - /* No problem if timer is not found/initialized */ return 0; } +#else +int timer_init(void) +{ + return 0; +} +#endif /* * This function is derived from PowerPC code (read timebase as long long). diff --git a/arch/microblaze/cpu/u-boot-spl.lds b/arch/microblaze/cpu/u-boot-spl.lds new file mode 100644 index 0000000..96353cd --- /dev/null +++ b/arch/microblaze/cpu/u-boot-spl.lds @@ -0,0 +1,57 @@ +/* + * (C) Copyright 2013 - 2014 Xilinx, Inc + * + * Michal Simek + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +OUTPUT_ARCH(microblaze) +ENTRY(_start) + +SECTIONS +{ + .text ALIGN(0x4): + { + __text_start = .; + arch/microblaze/cpu/start.o (.text) + *(.text) + *(.text.*) + __text_end = .; + } + + .rodata ALIGN(0x4): + { + __rodata_start = .; + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) + __rodata_end = .; + } + + .data ALIGN(0x4): + { + __data_start = .; + *(.data) + *(.data.*) + __data_end = .; + } + + .bss ALIGN(0x4): + { + __bss_start = .; + *(.sbss) + *(.scommon) + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(4); + __bss_end = .; + } + __end = . ; +} + +#if defined(CONFIG_SPL_MAX_FOOTPRINT) +ASSERT(__end - _start < (CONFIG_SPL_MAX_FOOTPRINT), \ + "SPL image plus BSS too big"); +#endif diff --git a/arch/microblaze/include/asm/spl.h b/arch/microblaze/include/asm/spl.h new file mode 100644 index 0000000..c1cae6c --- /dev/null +++ b/arch/microblaze/include/asm/spl.h @@ -0,0 +1,16 @@ +/* + * (C) Copyright 2013 - 2014 Xilinx, Inc + * + * Michal Simek + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_MICROBLAZE_SPL_H_ +#define _ASM_MICROBLAZE_SPL_H_ + +#define BOOT_DEVICE_RAM 1 +#define BOOT_DEVICE_NOR 2 +#define BOOT_DEVICE_SPI 3 + +#endif diff --git a/arch/microblaze/include/asm/u-boot.h b/arch/microblaze/include/asm/u-boot.h index 31b014c..ab3f232 100644 --- a/arch/microblaze/include/asm/u-boot.h +++ b/arch/microblaze/include/asm/u-boot.h @@ -25,6 +25,7 @@ typedef struct bd_info { unsigned long bi_sramstart; /* start of SRAM memory */ unsigned long bi_sramsize; /* size of SRAM memory */ unsigned int bi_baudrate; /* Console Baudrate */ + ulong bi_boot_params; /* where this board expects params */ } bd_t; /* For image.h:image_check_target_arch() */ diff --git a/arch/microblaze/lib/board.c b/arch/microblaze/lib/board.c index d22aa85..59956a8 100644 --- a/arch/microblaze/lib/board.c +++ b/arch/microblaze/lib/board.c @@ -50,10 +50,14 @@ init_fnc_t *init_sequence[] = { fdtdec_check_fdt, #endif serial_init, +#ifndef CONFIG_SPL_BUILD console_init_f, +#endif display_banner, +#ifndef CONFIG_SPL_BUILD interrupts_init, timer_init, +#endif NULL, }; @@ -66,7 +70,7 @@ void board_init_f(ulong not_used) gd = (gd_t *)(CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET); bd = (bd_t *)(CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET - GENERATED_BD_INFO_SIZE); -#if defined(CONFIG_CMD_FLASH) +#if defined(CONFIG_CMD_FLASH) && !defined(CONFIG_SPL_BUILD) ulong flash_size = 0; #endif asm ("nop"); /* FIXME gd is not initialize - wait */ @@ -88,9 +92,12 @@ void board_init_f(ulong not_used) /* FDT is at end of image */ gd->fdt_blob = (void *)__end; #endif + +#ifndef CONFIG_SPL_BUILD /* Allow the early environment to override the fdt address */ gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16, (uintptr_t)gd->fdt_blob); +#endif /* * The Malloc area is immediately below the monitor copy in DRAM @@ -110,6 +117,7 @@ void board_init_f(ulong not_used) hang(); } +#ifndef CONFIG_SPL_BUILD #ifdef CONFIG_OF_CONTROL /* For now, put this check after the console is ready */ if (fdtdec_prepare_fdt()) @@ -190,4 +198,5 @@ void board_init_f(ulong not_used) WATCHDOG_RESET(); main_loop(); } +#endif /* CONFIG_SPL_BUILD */ } diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index 35e5a4a..486787e 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -447,4 +447,64 @@ # undef CONFIG_PHYLIB #endif +/* SPL part */ +#define CONFIG_SPL +#define CONFIG_CMD_SPL +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT +#define CONFIG_SPL_BOARD_INIT + +#define CONFIG_SPL_LDSCRIPT "arch/microblaze/cpu/u-boot-spl.lds" + +#define CONFIG_SPL_RAM_DEVICE +#define CONFIG_SPL_NOR_SUPPORT + +/* for booting directly linux */ +#define CONFIG_SPL_OS_BOOT + +#define CONFIG_SYS_OS_BASE (CONFIG_SYS_FLASH_BASE + \ + 0x60000) +#define CONFIG_SYS_FDT_BASE (CONFIG_SYS_FLASH_BASE + \ + 0x40000) +#define CONFIG_SYS_SPL_ARGS_ADDR (CONFIG_SYS_TEXT_BASE + \ + 0x1000000) + +/* SP location before relocation, must use scratch RAM */ +/* BRAM start */ +#define CONFIG_SYS_INIT_RAM_ADDR 0x0 +/* BRAM size - will be generated */ +#define CONFIG_SYS_INIT_RAM_SIZE 0x10000 +/* Stack pointer prior relocation, must situated at on-chip RAM */ +#define CONFIG_SYS_SPL_MALLOC_END (CONFIG_SYS_INIT_RAM_ADDR + \ + CONFIG_SYS_INIT_RAM_SIZE - \ + GENERATED_GBL_DATA_SIZE) + +#define CONFIG_SYS_SPL_MALLOC_SIZE 0x100 + +/* + * The main reason to do it in this way is that MALLOC_START + * can't be defined - common/spl/spl.c + */ +#if (CONFIG_SYS_SPL_MALLOC_SIZE != 0) +# define CONFIG_SYS_SPL_MALLOC_START (CONFIG_SYS_SPL_MALLOC_END - \ + CONFIG_SYS_SPL_MALLOC_SIZE) +# define CONFIG_SPL_STACK_ADDR CONFIG_SYS_SPL_MALLOC_START +#else +# define CONFIG_SPL_STACK_ADDR CONFIG_SYS_SPL_MALLOC_END +#endif + +/* Just for sure that there is a space for stack */ +#define CONFIG_SPL_STACK_SIZE 0x100 + +#define CONFIG_SYS_UBOOT_BASE CONFIG_SYS_FLASH_BASE +#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE + +#define CONFIG_SPL_MAX_FOOTPRINT (CONFIG_SYS_INIT_RAM_SIZE - \ + CONFIG_SYS_INIT_RAM_ADDR - \ + GENERATED_GBL_DATA_SIZE - \ + CONFIG_SYS_SPL_MALLOC_SIZE - \ + CONFIG_SPL_STACK_SIZE) + #endif /* __CONFIG_H */ -- cgit v1.1