X-Git-Url: https://git.kernelconcepts.de/?a=blobdiff_plain;f=arch%2Fmips%2Flib%2Fbootm.c;h=e289799c1ee3c42247f308465494a356eb087691;hb=3b2ae345d176b3cdd8b21732ce9fc2e6dd212ee2;hp=ba9fd687eccad302861b8168ca3777269e22442d;hpb=59e8cbdb15953d3b3bfeb9feb20afc7205a0ad93;p=karo-tx-uboot.git diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index ba9fd687ec..e289799c1e 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -6,10 +6,8 @@ */ #include -#include #include -#include -#include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -17,6 +15,24 @@ DECLARE_GLOBAL_DATA_PTR; #define LINUX_MAX_ENVS 256 #define LINUX_MAX_ARGS 256 +#if defined(CONFIG_MALTA) +#define mips_boot_malta 1 +#else +#define mips_boot_malta 0 +#endif + +#if defined(CONFIG_MIPS_BOOT_CMDLINE_LEGACY) +#define mips_boot_cmdline_legacy 1 +#else +#define mips_boot_cmdline_legacy 0 +#endif + +#if defined(CONFIG_MIPS_BOOT_ENV_LEGACY) +#define mips_boot_env_legacy 1 +#else +#define mips_boot_env_legacy 0 +#endif + static int linux_argc; static char **linux_argv; static char *linux_argp; @@ -25,9 +41,6 @@ static char **linux_env; static char *linux_env_p; static int linux_env_idx; -static void linux_params_init(void); -static void linux_env_set(char *env_name, char *env_val); - static ulong arch_get_sp(void) { ulong ret; @@ -49,6 +62,50 @@ void arch_lmb_reserve(struct lmb *lmb) lmb_reserve(lmb, sp, CONFIG_SYS_SDRAM_BASE + gd->ram_size - sp); } +static int boot_setup_linux(bootm_headers_t *images) +{ + int ret; + ulong rd_len; + + rd_len = images->rd_end - images->rd_start; + ret = boot_ramdisk_high(&images->lmb, images->rd_start, + rd_len, &images->initrd_start, &images->initrd_end); + if (ret) + return ret; + +#if defined(CONFIG_MIPS_BOOT_FDT) && defined(CONFIG_OF_LIBFDT) + if (images->ft_len) { + boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr); + + ret = boot_relocate_fdt(&images->lmb, &images->ft_addr, + &images->ft_len); + if (ret) + return ret; + } +#endif + + return 0; +} + +static void boot_setup_fdt(bootm_headers_t *images) +{ +#if defined(CONFIG_MIPS_BOOT_FDT) && defined(CONFIG_OF_LIBFDT) + u64 mem_start = 0; + u64 mem_size = gd->ram_size; + + debug("## setup FDT\n"); + + fdt_chosen(images->ft_addr, 1); + fdt_fixup_memory_banks(images->ft_addr, &mem_start, &mem_size, 1); + fdt_fixup_ethernet(images->ft_addr); + fdt_initrd(images->ft_addr, images->initrd_start, images->initrd_end, 1); + +#if defined(CONFIG_OF_BOARD_SETUP) + ft_board_setup(images->ft_addr, gd->bd); +#endif +#endif +} + static void linux_cmdline_init(void) { linux_argc = 1; @@ -78,7 +135,7 @@ static void linux_cmdline_dump(void) debug(" arg %03d: %s\n", i, linux_argv[i]); } -static void boot_cmdline_linux(bootm_headers_t *images) +static void linux_cmdline_legacy(bootm_headers_t *images) { const char *bootargs, *next, *quote; @@ -116,16 +173,78 @@ static void boot_cmdline_linux(bootm_headers_t *images) bootargs = next; } +} - linux_cmdline_dump(); +static void linux_cmdline_append(bootm_headers_t *images) +{ + char buf[24]; + ulong mem, rd_start, rd_size; + + /* append mem */ + mem = gd->ram_size >> 20; + sprintf(buf, "mem=%luM", mem); + linux_cmdline_set(buf, strlen(buf)); + + /* append rd_start and rd_size */ + rd_start = images->initrd_start; + rd_size = images->initrd_end - images->initrd_start; + + if (rd_size) { + sprintf(buf, "rd_start=0x%08lX", rd_start); + linux_cmdline_set(buf, strlen(buf)); + sprintf(buf, "rd_size=0x%lX", rd_size); + linux_cmdline_set(buf, strlen(buf)); + } } -static void boot_prep_linux(bootm_headers_t *images) +static void boot_cmdline_linux(bootm_headers_t *images) { - char env_buf[12]; - char *cp; + if (mips_boot_cmdline_legacy && !images->ft_len) { + linux_cmdline_legacy(images); + + if (!mips_boot_env_legacy) + linux_cmdline_append(images); + + 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_malta) { + linux_env_p++; + linux_env[++linux_env_idx] = linux_env_p; + } else { + *linux_env_p++ = '='; + } - linux_params_init(); + strcpy(linux_env_p, env_val); + linux_env_p += strlen(env_val); + + linux_env_p++; + linux_env[++linux_env_idx] = 0; + } +} + +static void linux_env_legacy(bootm_headers_t *images) +{ + char env_buf[12]; + const char *cp; + ulong rd_start, rd_size; #ifdef CONFIG_MEMSIZE_IN_BYTES sprintf(env_buf, "%lu", (ulong)gd->ram_size); @@ -136,12 +255,17 @@ static void boot_prep_linux(bootm_headers_t *images) (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)); @@ -157,26 +281,54 @@ static void boot_prep_linux(bootm_headers_t *images) cp = getenv("eth1addr"); if (cp) linux_env_set("eth1addr", cp); + + if (mips_boot_malta) { + sprintf(env_buf, "%un8r", gd->baudrate); + linux_env_set("modetty0", env_buf); + } +} + +static void boot_prep_linux(bootm_headers_t *images) +{ + if (mips_boot_env_legacy && !images->ft_len) + linux_env_legacy(images); + + if (images->ft_len) + boot_setup_fdt(images); } static void boot_jump_linux(bootm_headers_t *images) { 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 %p) ...\n", kernel); bootstage_mark(BOOTSTAGE_ID_RUN_OS); - /* we assume that the kernel is in place */ - printf("\nStarting kernel ...\n\n"); - - kernel(linux_argc, (ulong)linux_argv, (ulong)linux_env, 0); + if (mips_boot_malta) + linux_extra = gd->ram_size; + +#ifdef CONFIG_BOOTSTAGE_FDT + bootstage_fdt_add_report(); +#endif +#ifdef CONFIG_BOOTSTAGE_REPORT + bootstage_report(); +#endif + + if (images->ft_len) + kernel(-2, (ulong)images->ft_addr, 0, 0); + else + 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) { + int ret; + /* No need for those on MIPS */ if (flag & BOOTM_STATE_OS_BD_T) return -1; @@ -196,6 +348,10 @@ int do_bootm_linux(int flag, int argc, char * const argv[], return 0; } + ret = boot_setup_linux(images); + if (ret) + return ret; + boot_cmdline_linux(images); boot_prep_linux(images); boot_jump_linux(images); @@ -203,30 +359,3 @@ int do_bootm_linux(int flag, int argc, char * const argv[], /* does not return */ return 1; } - -static void linux_params_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(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; - } -}