diff options
| -rw-r--r-- | arch/arm/lib/bootm.c | 23 | ||||
| -rw-r--r-- | arch/powerpc/lib/bootm.c | 56 | ||||
| -rw-r--r-- | common/cmd_bootm.c | 81 | ||||
| -rw-r--r-- | include/common.h | 4 | ||||
| -rw-r--r-- | include/vxworks.h | 3 | 
5 files changed, 155 insertions, 12 deletions
| diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index f476a8970..dff10ba3a 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -326,3 +326,26 @@ int bootz_setup(ulong image, ulong *start, ulong *end)  }  #endif	/* CONFIG_CMD_BOOTZ */ + +#if defined(CONFIG_BOOTM_VXWORKS) +void boot_prep_vxworks(bootm_headers_t *images) +{ +#if defined(CONFIG_OF_LIBFDT) +	int off; + +	if (images->ft_addr) { +		off = fdt_path_offset(images->ft_addr, "/memory"); +		if (off < 0) { +			if (arch_fixup_memory_node(images->ft_addr)) +				puts("## WARNING: fixup memory failed!\n"); +		} +	} +#endif +	cleanup_before_linux(); +} +void boot_jump_vxworks(bootm_headers_t *images) +{ +	/* ARM VxWorks requires device tree physical address to be passed */ +	((void (*)(void *))images->ep)(images->ft_addr); +} +#endif diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c index e7153b048..41fc8f7ff 100644 --- a/arch/powerpc/lib/bootm.c +++ b/arch/powerpc/lib/bootm.c @@ -32,6 +32,7 @@ DECLARE_GLOBAL_DATA_PTR;  extern ulong get_effective_memsize(void);  static ulong get_sp (void); +extern void ft_fixup_num_cores(void *blob);  static void set_clocks_in_mhz (bd_t *kbd);  #ifndef CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE @@ -277,3 +278,58 @@ static void set_clocks_in_mhz (bd_t *kbd)  #endif /* CONFIG_MPC5xxx */  	}  } + +#if defined(CONFIG_BOOTM_VXWORKS) +void boot_prep_vxworks(bootm_headers_t *images) +{ +#if defined(CONFIG_OF_LIBFDT) +	int off; +	u64 base, size; + +	if (!images->ft_addr) +		return; + +	base = (u64)gd->bd->bi_memstart; +	size = (u64)gd->bd->bi_memsize; + +	off = fdt_path_offset(images->ft_addr, "/memory"); +	if (off < 0) +		fdt_fixup_memory(images->ft_addr, base, size); + +#if defined(CONFIG_MP) +#if defined(CONFIG_MPC85xx) +	ft_fixup_cpu(images->ft_addr, base + size); +	ft_fixup_num_cores(images->ft_addr); +#elif defined(CONFIG_MPC86xx) +	off = fdt_add_mem_rsv(images->ft_addr, +			determine_mp_bootpg(NULL), (u64)4096); +	if (off < 0) +		printf("## WARNING %s: %s\n", __func__, fdt_strerror(off)); +	ft_fixup_num_cores(images->ft_addr); +#endif +	flush_cache((unsigned long)images->ft_addr, images->ft_len); +#endif +#endif +} + +void boot_jump_vxworks(bootm_headers_t *images) +{ +	/* PowerPC VxWorks boot interface conforms to the ePAPR standard +	 * general purpuse registers: +	 * +	 *	r3: Effective address of the device tree image +	 *	r4: 0 +	 *	r5: 0 +	 *	r6: ePAPR magic value +	 *	r7: shall be the size of the boot IMA in bytes +	 *	r8: 0 +	 *	r9: 0 +	 *	TCR: WRC = 0, no watchdog timer reset will occur +	 */ +	WATCHDOG_RESET(); + +	((void (*)(void *, ulong, ulong, ulong, +		ulong, ulong, ulong))images->ep)(images->ft_addr, +		0, 0, EPAPR_MAGIC, getenv_bootm_mapsize(), 0, 0); +} +#endif diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 56d53b15c..3f576594d 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -23,6 +23,11 @@  #include <asm/io.h>  #include <linux/compiler.h> +#if defined(CONFIG_BOOTM_VXWORKS) && \ +	(defined(CONFIG_PPC) || defined(CONFIG_ARM)) +#include <vxworks.h> +#endif +  #if defined(CONFIG_CMD_USB)  #include <usb.h>  #endif @@ -120,7 +125,8 @@ static boot_os_fn do_bootm_ose;  #if defined(CONFIG_BOOTM_PLAN9)  static boot_os_fn do_bootm_plan9;  #endif -#if defined(CONFIG_BOOTM_VXWORKS) +#if defined(CONFIG_BOOTM_VXWORKS) && \ +	(defined(CONFIG_PPC) || defined(CONFIG_ARM))  static boot_os_fn do_bootm_vxworks;  #endif  #if defined(CONFIG_CMD_ELF) @@ -151,7 +157,8 @@ static boot_os_fn *boot_os[] = {  #if defined(CONFIG_BOOTM_PLAN9)  	[IH_OS_PLAN9] = do_bootm_plan9,  #endif -#if defined(CONFIG_BOOTM_VXWORKS) +#if defined(CONFIG_BOOTM_VXWORKS) && \ +	(defined(CONFIG_PPC) || defined(CONFIG_ARM))  	[IH_OS_VXWORKS] = do_bootm_vxworks,  #endif  #if defined(CONFIG_CMD_ELF) @@ -337,7 +344,8 @@ static int bootm_find_other(cmd_tbl_t *cmdtp, int flag, int argc,  	if (((images.os.type == IH_TYPE_KERNEL) ||  	     (images.os.type == IH_TYPE_KERNEL_NOLOAD) ||  	     (images.os.type == IH_TYPE_MULTI)) && -	    (images.os.os == IH_OS_LINUX)) { +	    (images.os.os == IH_OS_LINUX || +		 images.os.os == IH_OS_VXWORKS)) {  		if (bootm_find_ramdisk(flag, argc, argv))  			return 1; @@ -1682,12 +1690,66 @@ static int do_bootm_plan9(int flag, int argc, char * const argv[],  }  #endif /* CONFIG_BOOTM_PLAN9 */ -#if defined(CONFIG_BOOTM_VXWORKS) +#if defined(CONFIG_BOOTM_VXWORKS) && \ +	(defined(CONFIG_PPC) || defined(CONFIG_ARM)) + +void do_bootvx_fdt(bootm_headers_t *images) +{ +#if defined(CONFIG_OF_LIBFDT) +	int ret; +	char *bootline; +	ulong of_size = images->ft_len; +	char **of_flat_tree = &images->ft_addr; +	struct lmb *lmb = &images->lmb; + +	if (*of_flat_tree) { +		boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); + +		ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); +		if (ret) +			return; + +		ret = fdt_add_subnode(*of_flat_tree, 0, "chosen"); +		if ((ret >= 0 || ret == -FDT_ERR_EXISTS)) { +			bootline = getenv("bootargs"); +			if (bootline) { +				ret = fdt_find_and_setprop(*of_flat_tree, +						"/chosen", "bootargs", +						bootline, +						strlen(bootline) + 1, 1); +				if (ret < 0) { +					printf("## ERROR: %s : %s\n", __func__, +					       fdt_strerror(ret)); +					return; +				} +			} +		} else { +			printf("## ERROR: %s : %s\n", __func__, +			       fdt_strerror(ret)); +			return; +		} +	} +#endif + +	boot_prep_vxworks(images); + +	bootstage_mark(BOOTSTAGE_ID_RUN_OS); + +#if defined(CONFIG_OF_LIBFDT) +	printf("## Starting vxWorks at 0x%08lx, device tree at 0x%08lx ...\n", +	       (ulong)images->ep, (ulong)*of_flat_tree); +#else +	printf("## Starting vxWorks at 0x%08lx\n", (ulong)images->ep); +#endif + +	boot_jump_vxworks(images); + +	puts("## vxWorks terminated\n"); +} +  static int do_bootm_vxworks(int flag, int argc, char * const argv[],  			     bootm_headers_t *images)  { -	char str[80]; -  	if (flag != BOOTM_STATE_OS_GO)  		return 0; @@ -1698,12 +1760,7 @@ static int do_bootm_vxworks(int flag, int argc, char * const argv[],  	}  #endif -	sprintf(str, "%lx", images->ep); /* write entry-point into string */ -	setenv("loadaddr", str); - -#if defined(CONFIG_CMD_ELF) -	do_bootvx(NULL, 0, 0, NULL); -#endif +	do_bootvx_fdt(images);  	return 1;  } diff --git a/include/common.h b/include/common.h index 8ca67f64f..d49c51464 100644 --- a/include/common.h +++ b/include/common.h @@ -698,6 +698,10 @@ ulong get_ddr_freq(ulong);  #if defined(CONFIG_MPC85xx)  typedef MPC85xx_SYS_INFO sys_info_t;  void	get_sys_info  ( sys_info_t * ); +#  if defined(CONFIG_OF_LIBFDT) +	void ft_fixup_cpu(void *, u64); +	void ft_fixup_num_cores(void *); +#  endif  #endif  #if defined(CONFIG_MPC86xx)  typedef MPC86xx_SYS_INFO sys_info_t; diff --git a/include/vxworks.h b/include/vxworks.h index c5d1577f9..122043c94 100644 --- a/include/vxworks.h +++ b/include/vxworks.h @@ -9,6 +9,9 @@  #define _VXWORKS_H_  int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); +void boot_prep_vxworks(bootm_headers_t *images); +void boot_jump_vxworks(bootm_headers_t *images); +void do_bootvx_fdt(bootm_headers_t *images);  /*   * Use bootaddr to find the location in memory that VxWorks |