From b6b0fe6460b7063ac60b9a3531ef210aedb31451 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Thu, 31 Jan 2008 13:58:13 +0100 Subject: [PATCH] [new uImage] Cleanup do_botm_linux() boot allocations This patch moves common pre-boot allocation steps shared between PPC and M68K to a helper routines: common: - get_boot_sp_limit() - get_boot_cmline() - get_boot_kbd() platform: - set_clocks_in_mhz() Signed-off-by: Marian Balakowicz --- common/image.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++----- include/image.h | 10 ++++- lib_m68k/bootm.c | 72 +++++++++++++-------------------- lib_ppc/bootm.c | 106 +++++++++++++++++++++---------------------------- 4 files changed, 189 insertions(+), 117 deletions(-) diff --git a/common/image.c b/common/image.c index 56d6b52..39e5f23 100644 --- a/common/image.c +++ b/common/image.c @@ -42,9 +42,15 @@ #endif extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + +#ifdef CONFIG_CMD_BDI +extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +#endif + +DECLARE_GLOBAL_DATA_PTR; #else #include "mkimage.h" -#endif +#endif /* USE_HOSTCC*/ #include @@ -501,17 +507,19 @@ void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], * variable and if requested ramdisk data is moved to a specified location. * * returns: - * initrd_start and initrd_end are set to final (after relocation) ramdisk + * - initrd_start and initrd_end are set to final (after relocation) ramdisk * start/end addresses if ramdisk image start and len were provided - * otherwise set initrd_start and initrd_end to zeros - * + * otherwise set initrd_start and initrd_end set to zeros + * - returns new allc_current, next free address below BOOTMAPSZ */ -void ramdisk_high (ulong rd_data, ulong rd_len, bd_t *kbd, ulong sp_limit, - ulong sp, ulong *initrd_start, ulong *initrd_end) +ulong ramdisk_high (ulong alloc_current, ulong rd_data, ulong rd_len, + bd_t *kbd, ulong sp_limit, ulong sp, + ulong *initrd_start, ulong *initrd_end) { char *s; ulong initrd_high; int initrd_copy_to_ram = 1; + ulong new_alloc_current = alloc_current; if ((s = getenv ("initrd_high")) != NULL) { /* a value of "no" or a similar string will act like 0, @@ -540,7 +548,8 @@ void ramdisk_high (ulong rd_data, ulong rd_len, bd_t *kbd, ulong sp_limit, *initrd_start = rd_data; *initrd_end = rd_data + rd_len; } else { - *initrd_start = (ulong)kbd - rd_len; + new_alloc_current = alloc_current - rd_len; + *initrd_start = new_alloc_current; *initrd_start &= ~(4096 - 1); /* align on page */ if (initrd_high) { @@ -566,8 +575,10 @@ void ramdisk_high (ulong rd_data, ulong rd_len, bd_t *kbd, ulong sp_limit, nsp -= rd_len; nsp &= ~(4096 - 1); /* align on page */ - if (nsp >= sp_limit) + if (nsp >= sp_limit) { *initrd_start = nsp; + new_alloc_current = alloc_current; + } } show_boot_progress (12); @@ -587,7 +598,96 @@ void ramdisk_high (ulong rd_data, ulong rd_len, bd_t *kbd, ulong sp_limit, } debug (" ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n", *initrd_start, *initrd_end); + + return new_alloc_current; +} + +/** + * get_boot_sp_limit - calculate stack pointer limit + * @sp: current stack pointer + * + * get_boot_sp_limit() takes current stack pointer adrress and calculates + * stack pointer limit, below which kernel boot data (cmdline, board info, + * etc.) will be allocated. + * + * returns: + * stack pointer limit + */ +ulong get_boot_sp_limit(ulong sp) +{ + ulong sp_limit = sp; + + sp_limit -= 2048; /* just to be sure */ + + /* make sure sp_limit is within kernel mapped space */ + if (sp_limit > CFG_BOOTMAPSZ) + sp_limit = CFG_BOOTMAPSZ; + sp_limit &= ~0xF; + + return sp_limit; +} + +/** + * get_boot_cmdline - allocate and initialize kernel cmdline + * @alloc_current: current boot allocation address (counting down + * from sp_limit) + * @cmd_start: pointer to a ulong variable, will hold cmdline start + * @cmd_end: pointer to a ulong variable, will hold cmdline end + * + * get_boot_cmdline() allocates space for kernel command line below + * provided alloc_current address. If "bootargs" U-boot environemnt + * variable is present its contents is copied to allocated kernel + * command line. + * + * returns: + * alloc_current after cmdline allocation + */ +ulong get_boot_cmdline (ulong alloc_current, ulong *cmd_start, ulong *cmd_end) +{ + char *cmdline; + char *s; + + cmdline = (char *)((alloc_current - CFG_BARGSIZE) & ~0xF); + + if ((s = getenv("bootargs")) == NULL) + s = ""; + + strcpy(cmdline, s); + + *cmd_start = (ulong) & cmdline[0]; + *cmd_end = *cmd_start + strlen(cmdline); + + debug ("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end); + + return (ulong)cmdline; +} + +/** + * get_boot_kbd - allocate and initialize kernel copy of board info + * @alloc_current: current boot allocation address (counting down + * from sp_limit) + * @kbd: double pointer to board info data + * + * get_boot_kbd() - allocates space for kernel copy of board info data. + * Space is allocated below provided alloc_current address and kernel + * board info is initialized with the current u-boot board info data. + * + * returns: + * alloc_current after kbd allocation + */ +ulong get_boot_kbd (ulong alloc_current, bd_t **kbd) +{ + *kbd = (bd_t *) (((ulong)alloc_current - sizeof(bd_t)) & ~0xF); + **kbd = *(gd->bd); + + debug ("## kernel board info at 0x%08lx\n", (ulong)*kbd); + +#if defined(DEBUG) && defined(CONFIG_CMD_BDI) + do_bdinfo(NULL, 0, 0, NULL); +#endif + + return (ulong)*kbd; } #endif /* CONFIG_PPC || CONFIG_M68K */ -#endif /* USE_HOSTCC */ +#endif /* USE_HOSTCC */ diff --git a/include/image.h b/include/image.h index a8cb1da..dbbbee9 100644 --- a/include/image.h +++ b/include/image.h @@ -343,9 +343,15 @@ void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], ulong *rd_start, ulong *rd_end); #if defined(CONFIG_PPC) || defined(CONFIG_M68K) -void ramdisk_high (ulong rd_data_start, ulong rd_len, bd_t *kbd, ulong sp_limit, - ulong sp, ulong *initrd_start, ulong *initrd_end); +ulong ramdisk_high (ulong alloc_current, ulong rd_data, ulong rd_len, + bd_t *kbd, ulong sp_limit, ulong sp, + ulong *initrd_start, ulong *initrd_end); + +ulong get_boot_sp_limit (ulong sp); +ulong get_boot_cmdline (ulong alloc_current, ulong *cmd_start, ulong *cmd_end); +ulong get_boot_kbd (ulong alloc_current, bd_t **kbd); #endif /* CONFIG_PPC || CONFIG_M68K */ + #endif /* USE_HOSTCC */ #endif /* __IMAGE_H__ */ diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c index 3fd38e9..ac04da0 100644 --- a/lib_m68k/bootm.c +++ b/lib_m68k/bootm.c @@ -29,6 +29,9 @@ #include #include #include +#ifdef CONFIG_SHOW_BOOT_PROGRESS +# include +#endif DECLARE_GLOBAL_DATA_PTR; @@ -37,27 +40,19 @@ DECLARE_GLOBAL_DATA_PTR; #define LINUX_MAX_ENVS 256 #define LINUX_MAX_ARGS 256 -#ifdef CONFIG_SHOW_BOOT_PROGRESS -# include -# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) -#else -# define SHOW_BOOT_PROGRESS(arg) -#endif - static ulong get_sp (void); +static void set_clocks_in_mhz (bd_t *kbd); void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], image_header_t *hdr, int verify) { - ulong sp_limit; + ulong sp, sp_limit, alloc_current; ulong rd_data_start, rd_data_end, rd_len; ulong initrd_start, initrd_end; ulong cmd_start, cmd_end; - char *cmdline; - char *s; bd_t *kbd; void (*kernel) (bd_t *, ulong, ulong, ulong, ulong); @@ -70,41 +65,18 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, * memory, which means far enough below the current stack * pointer. */ - sp_limit = get_sp(); - - debug("## Current stack ends at 0x%08lX ", sp_limit); - - sp_limit -= 2048; /* just to be sure */ - if (sp_limit > CFG_BOOTMAPSZ) - sp_limit = CFG_BOOTMAPSZ; - sp_limit &= ~0xF; - - debug("=> set upper limit to 0x%08lX\n", sp_limit); - - cmdline = (char *)((sp_limit - CFG_BARGSIZE) & ~0xF); - kbd = (bd_t *) (((ulong) cmdline - sizeof(bd_t)) & ~0xF); - - if ((s = getenv("bootargs")) == NULL) - s = ""; - - strcpy(cmdline, s); - - cmd_start = (ulong) & cmdline[0]; - cmd_end = cmd_start + strlen(cmdline); - - *kbd = *(gd->bd); + sp = get_sp(); + debug ("## Current stack ends at 0x%08lx ", sp); -#ifdef DEBUG - printf("## cmdline at 0x%08lX ... 0x%08lX\n", cmd_start, cmd_end); + alloc_current = sp_limit = get_boot_sp_limit(sp); + debug ("=> set upper limit to 0x%08lx\n", sp_limit); - do_bdinfo(NULL, 0, 0, NULL); -#endif + /* allocate space and init command line */ + alloc_current = get_boot_cmdline (alloc_current, &cmd_start, &cmd_end); - if ((s = getenv("clocks_in_mhz")) != NULL) { - /* convert all clock information to MHz */ - kbd->bi_intfreq /= 1000000L; - kbd->bi_busfreq /= 1000000L; - } + /* allocate space for kernel copy of board info */ + alloc_current = get_boot_kbd (alloc_current, &kbd); + set_clocks_in_mhz(kbd); /* find kernel */ kernel = @@ -115,13 +87,14 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, IH_ARCH_M68K, &rd_data_start, &rd_data_end); rd_len = rd_data_end - rd_data_start; - ramdisk_high (rd_data_start, rd_len, kdb, sp_limit, get_sp (), + alloc_current = ramdisk_high (alloc_current, rd_data_start, rd_len, + kbd, sp_limit, get_sp (), &initrd_start, &initrd_end); debug("## Transferring control to Linux (at address %08lx) ...\n", (ulong) kernel); - SHOW_BOOT_PROGRESS(15); + show_boot_progress (15); /* * Linux Kernel Parameters (passing board info data): @@ -144,3 +117,14 @@ static ulong get_sp (void) return sp; } + +static void set_clocks_in_mhz (bd_t *kbd) +{ + char *s; + + if ((s = getenv("clocks_in_mhz")) != NULL) { + /* convert all clock information to MHz */ + kbd->bi_intfreq /= 1000000L; + kbd->bi_busfreq /= 1000000L; + } +} diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c index d73d2fd..7eb8712 100644 --- a/lib_ppc/bootm.c +++ b/lib_ppc/bootm.c @@ -51,10 +51,7 @@ DECLARE_GLOBAL_DATA_PTR; extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); static ulong get_sp (void); - -#if defined(CONFIG_CMD_BDI) -extern int do_bdinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); -#endif +static void set_clocks_in_mhz (bd_t *kbd); void __attribute__((noinline)) do_bootm_linux(cmd_tbl_t *cmdtp, int flag, @@ -62,14 +59,12 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, image_header_t *hdr, int verify) { + ulong sp, sp_limit, alloc_current; + ulong initrd_start, initrd_end; ulong rd_data_start, rd_data_end, rd_len; ulong cmd_start, cmd_end; - char *cmdline; - - ulong sp_limit; - char *s; bd_t *kbd; void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); @@ -88,60 +83,18 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, * memory, which means far enough below the current stack * pointer. */ + sp = get_sp(); + debug ("## Current stack ends at 0x%08lx ", sp); - sp_limit = get_sp(); - debug ("## Current stack ends at 0x%08lX ", sp_limit); - - sp_limit -= 2048; /* just to be sure */ - if (sp_limit > CFG_BOOTMAPSZ) - sp_limit = CFG_BOOTMAPSZ; - sp_limit &= ~0xF; - - debug ("=> set upper limit to 0x%08lX\n", sp_limit); + alloc_current = sp_limit = get_boot_sp_limit(sp); + debug ("=> set upper limit to 0x%08lx\n", sp_limit); - cmdline = (char *)((sp_limit - CFG_BARGSIZE) & ~0xF); - kbd = (bd_t *)(((ulong)cmdline - sizeof(bd_t)) & ~0xF); + /* allocate space and init command line */ + alloc_current = get_boot_cmdline (alloc_current, &cmd_start, &cmd_end); - if ((s = getenv("bootargs")) == NULL) - s = ""; - - strcpy (cmdline, s); - - cmd_start = (ulong)&cmdline[0]; - cmd_end = cmd_start + strlen(cmdline); - - *kbd = *(gd->bd); - -#ifdef DEBUG - printf ("## cmdline at 0x%08lX ... 0x%08lX\n", cmd_start, cmd_end); - -#if defined(CONFIG_CMD_BDI) - do_bdinfo (NULL, 0, 0, NULL); -#endif -#endif - - if ((s = getenv ("clocks_in_mhz")) != NULL) { - /* convert all clock information to MHz */ - kbd->bi_intfreq /= 1000000L; - kbd->bi_busfreq /= 1000000L; -#if defined(CONFIG_MPC8220) - kbd->bi_inpfreq /= 1000000L; - kbd->bi_pcifreq /= 1000000L; - kbd->bi_pevfreq /= 1000000L; - kbd->bi_flbfreq /= 1000000L; - kbd->bi_vcofreq /= 1000000L; -#endif -#if defined(CONFIG_CPM2) - kbd->bi_cpmfreq /= 1000000L; - kbd->bi_brgfreq /= 1000000L; - kbd->bi_sccfreq /= 1000000L; - kbd->bi_vco /= 1000000L; -#endif -#if defined(CONFIG_MPC5xxx) - kbd->bi_ipbfreq /= 1000000L; - kbd->bi_pcifreq /= 1000000L; -#endif /* CONFIG_MPC5xxx */ - } + /* allocate space for kernel copy of board info */ + alloc_current = get_boot_kbd (alloc_current, &kbd); + set_clocks_in_mhz(kbd); /* find kernel */ kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep (hdr); @@ -152,7 +105,8 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, rd_len = rd_data_end - rd_data_start; - ramdisk_high (rd_data_start, rd_len, kbd, sp_limit, get_sp (), + alloc_current = ramdisk_high (alloc_current, rd_data_start, rd_len, + kbd, sp_limit, get_sp (), &initrd_start, &initrd_end); #if defined(CONFIG_OF_LIBFDT) @@ -266,8 +220,8 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, of_len = be32_to_cpu(fdt_totalsize(of_data)); - /* position on a 4K boundary before the kbd */ - of_start = (ulong)kbd - of_len; + /* position on a 4K boundary before the alloc_current */ + of_start = alloc_current - of_len; of_start &= ~(4096 - 1); /* align on page */ debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", of_data, of_data + of_len - 1, of_len, of_len); @@ -353,6 +307,34 @@ static ulong get_sp (void) return sp; } +static void set_clocks_in_mhz (bd_t *kbd) +{ + char *s; + + if ((s = getenv ("clocks_in_mhz")) != NULL) { + /* convert all clock information to MHz */ + kbd->bi_intfreq /= 1000000L; + kbd->bi_busfreq /= 1000000L; +#if defined(CONFIG_MPC8220) + kbd->bi_inpfreq /= 1000000L; + kbd->bi_pcifreq /= 1000000L; + kbd->bi_pevfreq /= 1000000L; + kbd->bi_flbfreq /= 1000000L; + kbd->bi_vcofreq /= 1000000L; +#endif +#if defined(CONFIG_CPM2) + kbd->bi_cpmfreq /= 1000000L; + kbd->bi_brgfreq /= 1000000L; + kbd->bi_sccfreq /= 1000000L; + kbd->bi_vco /= 1000000L; +#endif +#if defined(CONFIG_MPC5xxx) + kbd->bi_ipbfreq /= 1000000L; + kbd->bi_pcifreq /= 1000000L; +#endif /* CONFIG_MPC5xxx */ + } +} + #if defined(CONFIG_OF_LIBFDT) static void fdt_error (const char *msg) {