diff options
Diffstat (limited to 'arch/mips')
| -rw-r--r-- | arch/mips/include/asm/config.h | 3 | ||||
| -rw-r--r-- | arch/mips/lib/Makefile | 4 | ||||
| -rw-r--r-- | arch/mips/lib/bootm.c | 241 | ||||
| -rw-r--r-- | arch/mips/lib/bootm_qemu_mips.c | 62 | 
4 files changed, 160 insertions, 150 deletions
| diff --git a/arch/mips/include/asm/config.h b/arch/mips/include/asm/config.h index cd2973478..3a891ba62 100644 --- a/arch/mips/include/asm/config.h +++ b/arch/mips/include/asm/config.h @@ -7,4 +7,7 @@  #ifndef _ASM_CONFIG_H_  #define _ASM_CONFIG_H_ +#define CONFIG_LMB +#define CONFIG_SYS_BOOT_RAMDISK_HIGH +  #endif diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index e9f82f711..f91406c06 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -19,11 +19,7 @@ LGOBJS	:= $(addprefix $(obj),$(GLSOBJS))  SOBJS-y	+=  COBJS-y	+= board.o -ifeq ($(CONFIG_QEMU_MIPS),y) -COBJS-$(CONFIG_CMD_BOOTM) += bootm_qemu_mips.o -else  COBJS-$(CONFIG_CMD_BOOTM) += bootm.o -endif  SRCS	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)  OBJS	:= $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index ade9af47e..66340ea47 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -17,23 +17,148 @@ DECLARE_GLOBAL_DATA_PTR;  #define	LINUX_MAX_ENVS		256  #define	LINUX_MAX_ARGS		256 +#if defined(CONFIG_QEMU_MALTA) +#define mips_boot_qemu_malta	1 +#else +#define mips_boot_qemu_malta	0 +#endif +  static int linux_argc;  static char **linux_argv; +static char *linux_argp;  static char **linux_env;  static char *linux_env_p;  static int linux_env_idx; -static void linux_params_init(ulong start, char *commandline); -static void linux_env_set(char *env_name, char *env_val); +static ulong arch_get_sp(void) +{ +	ulong ret; + +	__asm__ __volatile__("move %0, $sp" : "=r"(ret) : ); + +	return ret; +} + +void arch_lmb_reserve(struct lmb *lmb) +{ +	ulong sp; + +	sp = arch_get_sp(); +	debug("## Current stack ends at 0x%08lx\n", sp); + +	/* adjust sp by 4K to be safe */ +	sp -= 4096; +	lmb_reserve(lmb, sp, CONFIG_SYS_SDRAM_BASE + gd->ram_size - sp); +} + +static void linux_cmdline_init(void) +{ +	linux_argc = 1; +	linux_argv = (char **)UNCACHED_SDRAM(gd->bd->bi_boot_params); +	linux_argv[0] = 0; +	linux_argp = (char *)(linux_argv + LINUX_MAX_ARGS); +} + +static void linux_cmdline_set(const char *value, size_t len) +{ +	linux_argv[linux_argc] = linux_argp; +	memcpy(linux_argp, value, len); +	linux_argp[len] = 0; + +	linux_argp += len + 1; +	linux_argc++; +} + +static void linux_cmdline_dump(void) +{ +	int i; + +	debug("## cmdline argv at 0x%p, argp at 0x%p\n", +	      linux_argv, linux_argp); + +	for (i = 1; i < linux_argc; i++) +		debug("   arg %03d: %s\n", i, linux_argv[i]); +} + +static void boot_cmdline_linux(bootm_headers_t *images) +{ +	const char *bootargs, *next, *quote; + +	linux_cmdline_init(); + +	bootargs = getenv("bootargs"); +	if (!bootargs) +		return; + +	next = bootargs; + +	while (bootargs && *bootargs && linux_argc < LINUX_MAX_ARGS) { +		quote = strchr(bootargs, '"'); +		next = strchr(bootargs, ' '); + +		while (next && quote && quote < next) { +			/* +			 * we found a left quote before the next blank +			 * now we have to find the matching right quote +			 */ +			next = strchr(quote + 1, '"'); +			if (next) { +				quote = strchr(next + 1, '"'); +				next = strchr(next + 1, ' '); +			} +		} + +		if (!next) +			next = bootargs + strlen(bootargs); + +		linux_cmdline_set(bootargs, next - bootargs); + +		if (*next) +			next++; + +		bootargs = next; +	} + +	linux_cmdline_dump(); +} + +static void linux_env_init(void) +{ +	linux_env = (char **)(((ulong) linux_argp + 15) & ~15); +	linux_env[0] = 0; +	linux_env_p = (char *)(linux_env + LINUX_MAX_ENVS); +	linux_env_idx = 0; +} + +static void linux_env_set(const char *env_name, const char *env_val) +{ +	if (linux_env_idx < LINUX_MAX_ENVS - 1) { +		linux_env[linux_env_idx] = linux_env_p; + +		strcpy(linux_env_p, env_name); +		linux_env_p += strlen(env_name); + +		if (mips_boot_qemu_malta) { +			linux_env_p++; +			linux_env[++linux_env_idx] = linux_env_p; +		} else { +			*linux_env_p++ = '='; +		} + +		strcpy(linux_env_p, env_val); +		linux_env_p += strlen(env_val); + +		linux_env_p++; +		linux_env[++linux_env_idx] = 0; +	} +}  static void boot_prep_linux(bootm_headers_t *images)  { -	char *commandline = getenv("bootargs");  	char env_buf[12]; -	char *cp; - -	linux_params_init(UNCACHED_SDRAM(gd->bd->bi_boot_params), commandline); +	const char *cp; +	ulong rd_start, rd_size;  #ifdef CONFIG_MEMSIZE_IN_BYTES  	sprintf(env_buf, "%lu", (ulong)gd->ram_size); @@ -41,15 +166,20 @@ static void boot_prep_linux(bootm_headers_t *images)  #else  	sprintf(env_buf, "%lu", (ulong)(gd->ram_size >> 20));  	debug("## Giving linux memsize in MB, %lu\n", -		(ulong)(gd->ram_size >> 20)); +	      (ulong)(gd->ram_size >> 20));  #endif /* CONFIG_MEMSIZE_IN_BYTES */ +	rd_start = UNCACHED_SDRAM(images->initrd_start); +	rd_size = images->initrd_end - images->initrd_start; + +	linux_env_init(); +  	linux_env_set("memsize", env_buf); -	sprintf(env_buf, "0x%08X", (uint) UNCACHED_SDRAM(images->rd_start)); +	sprintf(env_buf, "0x%08lX", rd_start);  	linux_env_set("initrd_start", env_buf); -	sprintf(env_buf, "0x%X", (uint) (images->rd_end - images->rd_start)); +	sprintf(env_buf, "0x%lX", rd_size);  	linux_env_set("initrd_size", env_buf);  	sprintf(env_buf, "0x%08X", (uint) (gd->bd->bi_flashstart)); @@ -65,33 +195,42 @@ static void boot_prep_linux(bootm_headers_t *images)  	cp = getenv("eth1addr");  	if (cp)  		linux_env_set("eth1addr", cp); + +	if (mips_boot_qemu_malta) +		linux_env_set("modetty0", "38400n8r");  }  static void boot_jump_linux(bootm_headers_t *images)  { -	void (*theKernel) (int, char **, char **, int *); - -	/* find kernel entry point */ -	theKernel = (void (*)(int, char **, char **, int *))images->ep; +	typedef void __noreturn (*kernel_entry_t)(int, ulong, ulong, ulong); +	kernel_entry_t kernel = (kernel_entry_t) images->ep; +	ulong linux_extra = 0; -	debug("## Transferring control to Linux (at address %08lx) ...\n", -		(ulong) theKernel); +	debug("## Transferring control to Linux (at address %p) ...\n", kernel);  	bootstage_mark(BOOTSTAGE_ID_RUN_OS); +	if (mips_boot_qemu_malta) +		linux_extra = gd->ram_size; +  	/* we assume that the kernel is in place */  	printf("\nStarting kernel ...\n\n"); -	theKernel(linux_argc, linux_argv, linux_env, 0); +	kernel(linux_argc, (ulong)linux_argv, (ulong)linux_env, linux_extra);  }  int do_bootm_linux(int flag, int argc, char * const argv[],  			bootm_headers_t *images)  {  	/* No need for those on MIPS */ -	if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE) +	if (flag & BOOTM_STATE_OS_BD_T)  		return -1; +	if (flag & BOOTM_STATE_OS_CMDLINE) { +		boot_cmdline_linux(images); +		return 0; +	} +  	if (flag & BOOTM_STATE_OS_PREP) {  		boot_prep_linux(images);  		return 0; @@ -102,76 +241,10 @@ int do_bootm_linux(int flag, int argc, char * const argv[],  		return 0;  	} +	boot_cmdline_linux(images);  	boot_prep_linux(images);  	boot_jump_linux(images);  	/* does not return */  	return 1;  } - -static void linux_params_init(ulong start, char *line) -{ -	char *next, *quote, *argp; - -	linux_argc = 1; -	linux_argv = (char **) start; -	linux_argv[0] = 0; -	argp = (char *) (linux_argv + LINUX_MAX_ARGS); - -	next = line; - -	while (line && *line && linux_argc < LINUX_MAX_ARGS) { -		quote = strchr(line, '"'); -		next = strchr(line, ' '); - -		while (next && quote && quote < next) { -			/* we found a left quote before the next blank -			 * now we have to find the matching right quote -			 */ -			next = strchr(quote + 1, '"'); -			if (next) { -				quote = strchr(next + 1, '"'); -				next = strchr(next + 1, ' '); -			} -		} - -		if (!next) -			next = line + strlen(line); - -		linux_argv[linux_argc] = argp; -		memcpy(argp, line, next - line); -		argp[next - line] = 0; - -		argp += next - line + 1; -		linux_argc++; - -		if (*next) -			next++; - -		line = next; -	} - -	linux_env = (char **) (((ulong) argp + 15) & ~15); -	linux_env[0] = 0; -	linux_env_p = (char *) (linux_env + LINUX_MAX_ENVS); -	linux_env_idx = 0; -} - -static void linux_env_set(char *env_name, char *env_val) -{ -	if (linux_env_idx < LINUX_MAX_ENVS - 1) { -		linux_env[linux_env_idx] = linux_env_p; - -		strcpy(linux_env_p, env_name); -		linux_env_p += strlen(env_name); - -		strcpy(linux_env_p, "="); -		linux_env_p += 1; - -		strcpy(linux_env_p, env_val); -		linux_env_p += strlen(env_val); - -		linux_env_p++; -		linux_env[++linux_env_idx] = 0; -	} -} diff --git a/arch/mips/lib/bootm_qemu_mips.c b/arch/mips/lib/bootm_qemu_mips.c deleted file mode 100644 index 910ab7363..000000000 --- a/arch/mips/lib/bootm_qemu_mips.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * (C) Copyright 2008 - * Jean-Christophe PLAGNIOL-VILLARD <jcplagniol@jcrosoft.com> - * - * SPDX-License-Identifier:	GPL-2.0+ - */ - -#include <common.h> -#include <command.h> -#include <image.h> -#include <asm/byteorder.h> -#include <asm/addrspace.h> - -DECLARE_GLOBAL_DATA_PTR; - -int do_bootm_linux(int flag, int argc, char * const argv[], -			bootm_headers_t *images) -{ -	void (*theKernel) (int, char **, char **, int *); -	char *bootargs = getenv("bootargs"); -	char *start; -	uint len; - -	/* find kernel entry point */ -	theKernel = (void (*)(int, char **, char **, int *))images->ep; - -	bootstage_mark(BOOTSTAGE_ID_RUN_OS); - -	debug("## Transferring control to Linux (at address %08lx) ...\n", -		(ulong) theKernel); - -	gd->bd->bi_boot_params = gd->bd->bi_memstart + (16 << 20) - 256; -	debug("%-12s= 0x%08lX\n", "boot_params", (ulong)gd->bd->bi_boot_params); - -	/* set Magic */ -	*(int32_t *)(gd->bd->bi_boot_params - 4) = 0x12345678; -	/* set ram_size */ -	*(int32_t *)(gd->bd->bi_boot_params - 8) = gd->ram_size; - -	start = (char *)gd->bd->bi_boot_params; - -	len = strlen(bootargs); - -	strncpy(start, bootargs, len + 1); - -	start += len; - -	len = images->rd_end - images->rd_start; -	if (len > 0) { -		start += sprintf(start, " rd_start=0x%08X rd_size=0x%0X", -		(uint) UNCACHED_SDRAM(images->rd_start), -		(uint) len); -	} - -	/* we assume that the kernel is in place */ -	printf("\nStarting kernel ...\n\n"); - -	theKernel(0, NULL, NULL, 0); - -	/* does not return */ -	return 1; -} |