Blame view

arch/powerpc/lib/bootm.c 7.54 KB
5d3cc55ec   Marian Balakowicz   [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   Wolfgang Denk   Add GPL-2.0+ SPDX...
7
   * SPDX-License-Identifier:	GPL-2.0+
5d3cc55ec   Marian Balakowicz   [new uImage] Move...
8
   */
7582438c2   Marian Balakowicz   [new uImage] Retu...
9

5d3cc55ec   Marian Balakowicz   [new uImage] Move...
10
11
12
13
14
  #include <common.h>
  #include <watchdog.h>
  #include <command.h>
  #include <image.h>
  #include <malloc.h>
a31e091ad   Jean-Christophe PLAGNIOL-VILLARD   rename include/zl...
15
  #include <u-boot/zlib.h>
5d3cc55ec   Marian Balakowicz   [new uImage] Move...
16
17
18
  #include <bzlib.h>
  #include <environment.h>
  #include <asm/byteorder.h>
561e710a9   Kumar Gala   powerpc: Move cpu...
19
  #include <asm/mp.h>
5d3cc55ec   Marian Balakowicz   [new uImage] Move...
20
21
  
  #if defined(CONFIG_OF_LIBFDT)
5d3cc55ec   Marian Balakowicz   [new uImage] Move...
22
23
  #include <libfdt.h>
  #include <fdt_support.h>
9c67352f7   Wolfgang Denk   Revert "ppc: Unlo...
24
25
26
27
  #endif
  
  #ifdef CONFIG_SYS_INIT_RAM_LOCK
  #include <asm/cache.h>
5d3cc55ec   Marian Balakowicz   [new uImage] Move...
28
  #endif
5d3cc55ec   Marian Balakowicz   [new uImage] Move...
29
  DECLARE_GLOBAL_DATA_PTR;
5d3cc55ec   Marian Balakowicz   [new uImage] Move...
30

ceaed2b1e   Marian Balakowicz   [new uImage] Move...
31
  static ulong get_sp (void);
871a57bb8   Miao Yan   common/cmd_bootm:...
32
  extern void ft_fixup_num_cores(void *blob);
b6b0fe646   Marian Balakowicz   [new uImage] Clea...
33
  static void set_clocks_in_mhz (bd_t *kbd);
5d3cc55ec   Marian Balakowicz   [new uImage] Move...
34

6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
35
36
  #ifndef CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE
  #define CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE	(768*1024*1024)
d3f2fa0d2   Kumar Gala   [new uImage] Prov...
37
  #endif
5a98127d8   Kumar Gala   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   Simon Glass   bootstage: Replac...
51
  	bootstage_mark(BOOTSTAGE_ID_RUN_OS);
5a98127d8   Kumar Gala   bootm: support su...
52

b892465da   Mela Custodio   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   Wolfgang Denk   Revert "ppc: Unlo...
59
60
61
  #if defined(CONFIG_SYS_INIT_RAM_LOCK) && !defined(CONFIG_E500)
  	unlock_ram_in_cache();
  #endif
5a98127d8   Kumar Gala   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   Kumar Gala   bootm: support su...
74
75
  		debug ("   Booting using OF flat tree...
  ");
7ff66bb0b   Heiko Schocher   ppc: trigger WDT ...
76
  		WATCHDOG_RESET ();
5a98127d8   Kumar Gala   bootm: support su...
77
  		(*kernel) ((bd_t *)of_flat_tree, 0, 0, EPAPR_MAGIC,
c3624e6ed   Grant Likely   Default to bootm_...
78
  			   getenv_bootm_mapsize(), 0, 0);
5a98127d8   Kumar Gala   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   Heiko Schocher   ppc: trigger WDT ...
101
  		WATCHDOG_RESET ();
5a98127d8   Kumar Gala   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   Kumar Gala   Added arch_lmb_re...
108
  void arch_lmb_reserve(struct lmb *lmb)
5d3cc55ec   Marian Balakowicz   [new uImage] Move...
109
  {
391fd93ab   Becky Bruce   Change lmb to use...
110
  	phys_size_t bootm_size;
76da19df5   Kumar Gala   Added arch_lmb_re...
111
  	ulong size, sp, bootmap_base;
c160a9544   Kumar Gala   bootm: refactor e...
112

d3f2fa0d2   Kumar Gala   [new uImage] Prov...
113
  	bootmap_base = getenv_bootm_low();
391fd93ab   Becky Bruce   Change lmb to use...
114
  	bootm_size = getenv_bootm_size();
d3f2fa0d2   Kumar Gala   [new uImage] Prov...
115
116
  
  #ifdef DEBUG
391fd93ab   Becky Bruce   Change lmb to use...
117
  	if (((u64)bootmap_base + bootm_size) >
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
118
  	    (CONFIG_SYS_SDRAM_BASE + (u64)gd->ram_size))
d3f2fa0d2   Kumar Gala   [new uImage] Prov...
119
120
  		puts("WARNING: bootm_low + bootm_size exceed total memory
  ");
391fd93ab   Becky Bruce   Change lmb to use...
121
  	if ((bootmap_base + bootm_size) > get_effective_memsize())
d3f2fa0d2   Kumar Gala   [new uImage] Prov...
122
123
124
  		puts("WARNING: bootm_low + bootm_size exceed eff. memory
  ");
  #endif
391fd93ab   Becky Bruce   Change lmb to use...
125
  	size = min(bootm_size, get_effective_memsize());
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
126
  	size = min(size, CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE);
d3f2fa0d2   Kumar Gala   [new uImage] Prov...
127

391fd93ab   Becky Bruce   Change lmb to use...
128
  	if (size < bootm_size) {
d3f2fa0d2   Kumar Gala   [new uImage] Prov...
129
  		ulong base = bootmap_base + size;
dc4b0b38d   Andrew Klossner   Fix printf errors.
130
131
  		printf("WARNING: adjusting available memory to %lx
  ", size);
391fd93ab   Becky Bruce   Change lmb to use...
132
  		lmb_reserve(lmb, base, bootm_size - size);
d3f2fa0d2   Kumar Gala   [new uImage] Prov...
133
  	}
e822d7fc4   Kumar Gala   [new uImage] Use ...
134

5d3cc55ec   Marian Balakowicz   [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   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
140
  	 * the kernel (see CONFIG_SYS_BOOTMAPSZ settings), but in unused
5d3cc55ec   Marian Balakowicz   [new uImage] Move...
141
142
143
  	 * memory, which means far enough below the current stack
  	 * pointer.
  	 */
b6b0fe646   Marian Balakowicz   [new uImage] Clea...
144
  	sp = get_sp();
d3f2fa0d2   Kumar Gala   [new uImage] Prov...
145
146
  	debug ("## Current stack ends at 0x%08lx
  ", sp);
5d3cc55ec   Marian Balakowicz   [new uImage] Move...
147

3882d7a5a   Norbert van Bolhuis   ppc: unused memor...
148
149
  	/* adjust sp by 4K to be safe */
  	sp -= 4096;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
150
  	lmb_reserve(lmb, sp, (CONFIG_SYS_SDRAM_BASE + get_effective_memsize() - sp));
5d3cc55ec   Marian Balakowicz   [new uImage] Move...
151

561e710a9   Kumar Gala   powerpc: Move cpu...
152
153
154
  #ifdef CONFIG_MP
  	cpu_mp_lmb_reserve(lmb);
  #endif
76da19df5   Kumar Gala   Added arch_lmb_re...
155
156
  	return ;
  }
3b2001105   Kumar Gala   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   Kumar Gala   bootm: support su...
168
169
  static int boot_cmdline_linux(bootm_headers_t *images)
  {
5a98127d8   Kumar Gala   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   Kumar Gala   Added arch_lmb_re...
174

5a98127d8   Kumar Gala   bootm: support su...
175
  	int ret = 0;
76da19df5   Kumar Gala   Added arch_lmb_re...
176

27953493e   Kumar Gala   [new uImage] ppc:...
177
178
  	if (!of_size) {
  		/* allocate space and init command line */
590d3cacb   Grant Likely   Stop passing arou...
179
  		ret = boot_get_cmdline (lmb, cmd_start, cmd_end);
e822d7fc4   Kumar Gala   [new uImage] Use ...
180
181
182
  		if (ret) {
  			puts("ERROR with allocation of cmdline
  ");
5a98127d8   Kumar Gala   bootm: support su...
183
  			return ret;
e822d7fc4   Kumar Gala   [new uImage] Use ...
184
  		}
5a98127d8   Kumar Gala   bootm: support su...
185
186
187
188
189
190
191
  	}
  
  	return ret;
  }
  
  static int boot_bd_t_linux(bootm_headers_t *images)
  {
5a98127d8   Kumar Gala   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   Kumar Gala   [new uImage] ppc:...
197

5a98127d8   Kumar Gala   bootm: support su...
198
  	if (!of_size) {
27953493e   Kumar Gala   [new uImage] ppc:...
199
  		/* allocate space for kernel copy of board info */
590d3cacb   Grant Likely   Stop passing arou...
200
  		ret = boot_get_kbd (lmb, kbd);
e822d7fc4   Kumar Gala   [new uImage] Use ...
201
202
203
  		if (ret) {
  			puts("ERROR with allocation of kernel bd
  ");
5a98127d8   Kumar Gala   bootm: support su...
204
  			return ret;
e822d7fc4   Kumar Gala   [new uImage] Use ...
205
  		}
5a98127d8   Kumar Gala   bootm: support su...
206
  		set_clocks_in_mhz(*kbd);
27953493e   Kumar Gala   [new uImage] ppc:...
207
  	}
5d3cc55ec   Marian Balakowicz   [new uImage] Move...
208

5a98127d8   Kumar Gala   bootm: support su...
209
210
211
212
213
  	return ret;
  }
  
  static int boot_body_linux(bootm_headers_t *images)
  {
5a98127d8   Kumar Gala   bootm: support su...
214
  	int ret;
5a98127d8   Kumar Gala   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   Simon Glass   powerpc: Use imag...
219
  	ret = image_setup_linux(images);
06a09918f   Kumar Gala   bootm: refactor f...
220
  	if (ret)
5a98127d8   Kumar Gala   bootm: support su...
221
  		return ret;
5d3cc55ec   Marian Balakowicz   [new uImage] Move...
222

5a98127d8   Kumar Gala   bootm: support su...
223
224
  	return 0;
  }
d45d5a18b   Marian Balakowicz   [new uImage] Clea...
225

eef1cf2d5   Kim Phillips   include/linux/byt...
226
  noinline
54841ab50   Wolfgang Denk   Make sure that ar...
227
  int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images)
5a98127d8   Kumar Gala   bootm: support su...
228
229
  {
  	int	ret;
5d3cc55ec   Marian Balakowicz   [new uImage] Move...
230

5a98127d8   Kumar Gala   bootm: support su...
231
232
233
234
  	if (flag & BOOTM_STATE_OS_CMDLINE) {
  		boot_cmdline_linux(images);
  		return 0;
  	}
5d3cc55ec   Marian Balakowicz   [new uImage] Move...
235

5a98127d8   Kumar Gala   bootm: support su...
236
237
238
239
  	if (flag & BOOTM_STATE_OS_BD_T) {
  		boot_bd_t_linux(images);
  		return 0;
  	}
5d3cc55ec   Marian Balakowicz   [new uImage] Move...
240

3b2001105   Kumar Gala   powerpc/bootm: Fl...
241
242
  	if (flag & BOOTM_STATE_OS_PREP) {
  		boot_prep_linux(images);
5a98127d8   Kumar Gala   bootm: support su...
243
  		return 0;
3b2001105   Kumar Gala   powerpc/bootm: Fl...
244
  	}
a15b07104   Kumar Gala   Update linux boot...
245

3b2001105   Kumar Gala   powerpc/bootm: Fl...
246
  	boot_prep_linux(images);
5a98127d8   Kumar Gala   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   Marian Balakowicz   [new uImage] Move...
253
  }
d3c5eb6dd   Marian Balakowicz   [new uImage] Move...
254

ceaed2b1e   Marian Balakowicz   [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   Marian Balakowicz   [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   Marian Balakowicz   [new uImage] Clea...
270
271
272
273
  #if defined(CONFIG_CPM2)
  		kbd->bi_cpmfreq /= 1000000L;
  		kbd->bi_brgfreq /= 1000000L;
  		kbd->bi_sccfreq /= 1000000L;
438a4c112   Wolfgang Denk   Cleanup coding st...
274
  		kbd->bi_vco	/= 1000000L;
b6b0fe646   Marian Balakowicz   [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   Miao Yan   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