Blame view
arch/powerpc/lib/bootm.c
7.54 KB
5d3cc55ec [new uImage] Move... |
1 2 3 4 5 6 |
/* * (C) Copyright 2008 Semihalf * * (C) Copyright 2000-2006 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * |
1a4596601 Add GPL-2.0+ SPDX... |
7 |
* SPDX-License-Identifier: GPL-2.0+ |
5d3cc55ec [new uImage] Move... |
8 |
*/ |
7582438c2 [new uImage] Retu... |
9 |
|
5d3cc55ec [new uImage] Move... |
10 11 12 13 14 |
#include <common.h> #include <watchdog.h> #include <command.h> #include <image.h> #include <malloc.h> |
a31e091ad rename include/zl... |
15 |
#include <u-boot/zlib.h> |
5d3cc55ec [new uImage] Move... |
16 17 18 |
#include <bzlib.h> #include <environment.h> #include <asm/byteorder.h> |
561e710a9 powerpc: Move cpu... |
19 |
#include <asm/mp.h> |
5d3cc55ec [new uImage] Move... |
20 21 |
#if defined(CONFIG_OF_LIBFDT) |
5d3cc55ec [new uImage] Move... |
22 23 |
#include <libfdt.h> #include <fdt_support.h> |
9c67352f7 Revert "ppc: Unlo... |
24 25 26 27 |
#endif #ifdef CONFIG_SYS_INIT_RAM_LOCK #include <asm/cache.h> |
5d3cc55ec [new uImage] Move... |
28 |
#endif |
5d3cc55ec [new uImage] Move... |
29 |
DECLARE_GLOBAL_DATA_PTR; |
5d3cc55ec [new uImage] Move... |
30 |
|
ceaed2b1e [new uImage] Move... |
31 |
static ulong get_sp (void); |
871a57bb8 common/cmd_bootm:... |
32 |
extern void ft_fixup_num_cores(void *blob); |
b6b0fe646 [new uImage] Clea... |
33 |
static void set_clocks_in_mhz (bd_t *kbd); |
5d3cc55ec [new uImage] Move... |
34 |
|
6d0f6bcf3 rename CFG_ macro... |
35 36 |
#ifndef CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE #define CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE (768*1024*1024) |
d3f2fa0d2 [new uImage] Prov... |
37 |
#endif |
5a98127d8 bootm: support su... |
38 39 40 41 42 43 44 45 46 47 48 49 50 |
static void boot_jump_linux(bootm_headers_t *images) { void (*kernel)(bd_t *, ulong r4, ulong r5, ulong r6, ulong r7, ulong r8, ulong r9); #ifdef CONFIG_OF_LIBFDT char *of_flat_tree = images->ft_addr; #endif kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong, ulong, ulong))images->ep; debug ("## Transferring control to Linux (at address %08lx) ... ", (ulong)kernel); |
770605e4f bootstage: Replac... |
51 |
bootstage_mark(BOOTSTAGE_ID_RUN_OS); |
5a98127d8 bootm: support su... |
52 |
|
b892465da bootstage: powerp... |
53 54 55 56 57 58 |
#ifdef CONFIG_BOOTSTAGE_FDT bootstage_fdt_add_report(); #endif #ifdef CONFIG_BOOTSTAGE_REPORT bootstage_report(); #endif |
9c67352f7 Revert "ppc: Unlo... |
59 60 61 |
#if defined(CONFIG_SYS_INIT_RAM_LOCK) && !defined(CONFIG_E500) unlock_ram_in_cache(); #endif |
5a98127d8 bootm: support su... |
62 63 64 65 66 67 68 69 70 71 72 73 |
#if defined(CONFIG_OF_LIBFDT) if (of_flat_tree) { /* device tree; boot new style */ /* * Linux Kernel Parameters (passing device tree): * r3: pointer to the fdt * r4: 0 * r5: 0 * r6: epapr magic * r7: size of IMA in bytes * r8: 0 * r9: 0 */ |
5a98127d8 bootm: support su... |
74 75 |
debug (" Booting using OF flat tree... "); |
7ff66bb0b ppc: trigger WDT ... |
76 |
WATCHDOG_RESET (); |
5a98127d8 bootm: support su... |
77 |
(*kernel) ((bd_t *)of_flat_tree, 0, 0, EPAPR_MAGIC, |
c3624e6ed Default to bootm_... |
78 |
getenv_bootm_mapsize(), 0, 0); |
5a98127d8 bootm: support su... |
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
/* does not return */ } else #endif { /* * Linux Kernel Parameters (passing board info data): * r3: ptr to board info data * r4: initrd_start or 0 if no initrd * r5: initrd_end - unused if r4 is 0 * r6: Start of command line string * r7: End of command line string * r8: 0 * r9: 0 */ ulong cmd_start = images->cmdline_start; ulong cmd_end = images->cmdline_end; ulong initrd_start = images->initrd_start; ulong initrd_end = images->initrd_end; bd_t *kbd = images->kbd; debug (" Booting using board info... "); |
7ff66bb0b ppc: trigger WDT ... |
101 |
WATCHDOG_RESET (); |
5a98127d8 bootm: support su... |
102 103 104 105 106 107 |
(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end, 0, 0); /* does not return */ } return ; } |
76da19df5 Added arch_lmb_re... |
108 |
void arch_lmb_reserve(struct lmb *lmb) |
5d3cc55ec [new uImage] Move... |
109 |
{ |
391fd93ab Change lmb to use... |
110 |
phys_size_t bootm_size; |
76da19df5 Added arch_lmb_re... |
111 |
ulong size, sp, bootmap_base; |
c160a9544 bootm: refactor e... |
112 |
|
d3f2fa0d2 [new uImage] Prov... |
113 |
bootmap_base = getenv_bootm_low(); |
391fd93ab Change lmb to use... |
114 |
bootm_size = getenv_bootm_size(); |
d3f2fa0d2 [new uImage] Prov... |
115 116 |
#ifdef DEBUG |
391fd93ab Change lmb to use... |
117 |
if (((u64)bootmap_base + bootm_size) > |
6d0f6bcf3 rename CFG_ macro... |
118 |
(CONFIG_SYS_SDRAM_BASE + (u64)gd->ram_size)) |
d3f2fa0d2 [new uImage] Prov... |
119 120 |
puts("WARNING: bootm_low + bootm_size exceed total memory "); |
391fd93ab Change lmb to use... |
121 |
if ((bootmap_base + bootm_size) > get_effective_memsize()) |
d3f2fa0d2 [new uImage] Prov... |
122 123 124 |
puts("WARNING: bootm_low + bootm_size exceed eff. memory "); #endif |
391fd93ab Change lmb to use... |
125 |
size = min(bootm_size, get_effective_memsize()); |
6d0f6bcf3 rename CFG_ macro... |
126 |
size = min(size, CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE); |
d3f2fa0d2 [new uImage] Prov... |
127 |
|
391fd93ab Change lmb to use... |
128 |
if (size < bootm_size) { |
d3f2fa0d2 [new uImage] Prov... |
129 |
ulong base = bootmap_base + size; |
dc4b0b38d Fix printf errors. |
130 131 |
printf("WARNING: adjusting available memory to %lx ", size); |
391fd93ab Change lmb to use... |
132 |
lmb_reserve(lmb, base, bootm_size - size); |
d3f2fa0d2 [new uImage] Prov... |
133 |
} |
e822d7fc4 [new uImage] Use ... |
134 |
|
5d3cc55ec [new uImage] Move... |
135 136 137 138 139 |
/* * Booting a (Linux) kernel image * * Allocate space for command line and board info - the * address should be as high as possible within the reach of |
6d0f6bcf3 rename CFG_ macro... |
140 |
* the kernel (see CONFIG_SYS_BOOTMAPSZ settings), but in unused |
5d3cc55ec [new uImage] Move... |
141 142 143 |
* memory, which means far enough below the current stack * pointer. */ |
b6b0fe646 [new uImage] Clea... |
144 |
sp = get_sp(); |
d3f2fa0d2 [new uImage] Prov... |
145 146 |
debug ("## Current stack ends at 0x%08lx ", sp); |
5d3cc55ec [new uImage] Move... |
147 |
|
3882d7a5a ppc: unused memor... |
148 149 |
/* adjust sp by 4K to be safe */ sp -= 4096; |
6d0f6bcf3 rename CFG_ macro... |
150 |
lmb_reserve(lmb, sp, (CONFIG_SYS_SDRAM_BASE + get_effective_memsize() - sp)); |
5d3cc55ec [new uImage] Move... |
151 |
|
561e710a9 powerpc: Move cpu... |
152 153 154 |
#ifdef CONFIG_MP cpu_mp_lmb_reserve(lmb); #endif |
76da19df5 Added arch_lmb_re... |
155 156 |
return ; } |
3b2001105 powerpc/bootm: Fl... |
157 158 159 160 161 162 163 164 165 166 167 |
static void boot_prep_linux(bootm_headers_t *images) { #ifdef CONFIG_MP /* * if we are MP make sure to flush the device tree so any changes are * made visibile to all other cores. In AMP boot scenarios the cores * might not be HW cache coherent with each other. */ flush_cache((unsigned long)images->ft_addr, images->ft_len); #endif } |
5a98127d8 bootm: support su... |
168 169 |
static int boot_cmdline_linux(bootm_headers_t *images) { |
5a98127d8 bootm: support su... |
170 171 172 173 |
ulong of_size = images->ft_len; struct lmb *lmb = &images->lmb; ulong *cmd_start = &images->cmdline_start; ulong *cmd_end = &images->cmdline_end; |
76da19df5 Added arch_lmb_re... |
174 |
|
5a98127d8 bootm: support su... |
175 |
int ret = 0; |
76da19df5 Added arch_lmb_re... |
176 |
|
27953493e [new uImage] ppc:... |
177 178 |
if (!of_size) { /* allocate space and init command line */ |
590d3cacb Stop passing arou... |
179 |
ret = boot_get_cmdline (lmb, cmd_start, cmd_end); |
e822d7fc4 [new uImage] Use ... |
180 181 182 |
if (ret) { puts("ERROR with allocation of cmdline "); |
5a98127d8 bootm: support su... |
183 |
return ret; |
e822d7fc4 [new uImage] Use ... |
184 |
} |
5a98127d8 bootm: support su... |
185 186 187 188 189 190 191 |
} return ret; } static int boot_bd_t_linux(bootm_headers_t *images) { |
5a98127d8 bootm: support su... |
192 193 194 195 196 |
ulong of_size = images->ft_len; struct lmb *lmb = &images->lmb; bd_t **kbd = &images->kbd; int ret = 0; |
27953493e [new uImage] ppc:... |
197 |
|
5a98127d8 bootm: support su... |
198 |
if (!of_size) { |
27953493e [new uImage] ppc:... |
199 |
/* allocate space for kernel copy of board info */ |
590d3cacb Stop passing arou... |
200 |
ret = boot_get_kbd (lmb, kbd); |
e822d7fc4 [new uImage] Use ... |
201 202 203 |
if (ret) { puts("ERROR with allocation of kernel bd "); |
5a98127d8 bootm: support su... |
204 |
return ret; |
e822d7fc4 [new uImage] Use ... |
205 |
} |
5a98127d8 bootm: support su... |
206 |
set_clocks_in_mhz(*kbd); |
27953493e [new uImage] ppc:... |
207 |
} |
5d3cc55ec [new uImage] Move... |
208 |
|
5a98127d8 bootm: support su... |
209 210 211 212 213 |
return ret; } static int boot_body_linux(bootm_headers_t *images) { |
5a98127d8 bootm: support su... |
214 |
int ret; |
5a98127d8 bootm: support su... |
215 216 217 218 |
/* allocate space for kernel copy of board info */ ret = boot_bd_t_linux(images); if (ret) return ret; |
3e51266a4 powerpc: Use imag... |
219 |
ret = image_setup_linux(images); |
06a09918f bootm: refactor f... |
220 |
if (ret) |
5a98127d8 bootm: support su... |
221 |
return ret; |
5d3cc55ec [new uImage] Move... |
222 |
|
5a98127d8 bootm: support su... |
223 224 |
return 0; } |
d45d5a18b [new uImage] Clea... |
225 |
|
eef1cf2d5 include/linux/byt... |
226 |
noinline |
54841ab50 Make sure that ar... |
227 |
int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images) |
5a98127d8 bootm: support su... |
228 229 |
{ int ret; |
5d3cc55ec [new uImage] Move... |
230 |
|
5a98127d8 bootm: support su... |
231 232 233 234 |
if (flag & BOOTM_STATE_OS_CMDLINE) { boot_cmdline_linux(images); return 0; } |
5d3cc55ec [new uImage] Move... |
235 |
|
5a98127d8 bootm: support su... |
236 237 238 239 |
if (flag & BOOTM_STATE_OS_BD_T) { boot_bd_t_linux(images); return 0; } |
5d3cc55ec [new uImage] Move... |
240 |
|
3b2001105 powerpc/bootm: Fl... |
241 242 |
if (flag & BOOTM_STATE_OS_PREP) { boot_prep_linux(images); |
5a98127d8 bootm: support su... |
243 |
return 0; |
3b2001105 powerpc/bootm: Fl... |
244 |
} |
a15b07104 Update linux boot... |
245 |
|
3b2001105 powerpc/bootm: Fl... |
246 |
boot_prep_linux(images); |
5a98127d8 bootm: support su... |
247 248 249 250 251 252 |
ret = boot_body_linux(images); if (ret) return ret; boot_jump_linux(images); return 0; |
5d3cc55ec [new uImage] Move... |
253 |
} |
d3c5eb6dd [new uImage] Move... |
254 |
|
ceaed2b1e [new uImage] Move... |
255 256 257 258 259 260 261 |
static ulong get_sp (void) { ulong sp; asm( "mr %0,1": "=r"(sp) : ); return sp; } |
b6b0fe646 [new uImage] Clea... |
262 263 264 265 266 267 268 269 |
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; |
b6b0fe646 [new uImage] Clea... |
270 271 272 273 |
#if defined(CONFIG_CPM2) kbd->bi_cpmfreq /= 1000000L; kbd->bi_brgfreq /= 1000000L; kbd->bi_sccfreq /= 1000000L; |
438a4c112 Cleanup coding st... |
274 |
kbd->bi_vco /= 1000000L; |
b6b0fe646 [new uImage] Clea... |
275 276 277 278 279 280 281 |
#endif #if defined(CONFIG_MPC5xxx) kbd->bi_ipbfreq /= 1000000L; kbd->bi_pcifreq /= 1000000L; #endif /* CONFIG_MPC5xxx */ } } |
871a57bb8 common/cmd_bootm:... |
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 |
#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 ", __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 |