xref: /openbmc/u-boot/arch/m68k/lib/bootm.c (revision 2cb0e55a)
1ea0364f1SPeter Tyser /*
2ea0364f1SPeter Tyser  * (C) Copyright 2003
3ea0364f1SPeter Tyser  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4ea0364f1SPeter Tyser  *
5ea0364f1SPeter Tyser  * See file CREDITS for list of people who contributed to this
6ea0364f1SPeter Tyser  * project.
7ea0364f1SPeter Tyser  *
8ea0364f1SPeter Tyser  * This program is free software; you can redistribute it and/or modify
9ea0364f1SPeter Tyser  * it under the terms of the GNU General Public License as published by
10ea0364f1SPeter Tyser  * the Free Software Foundation; either version 2 of the License, or
11ea0364f1SPeter Tyser  * (at your option) any later version.
12ea0364f1SPeter Tyser  *
13ea0364f1SPeter Tyser  * This program is distributed in the hope that it will be useful,
14ea0364f1SPeter Tyser  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15ea0364f1SPeter Tyser  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
16ea0364f1SPeter Tyser  * GNU General Public License for more details.
17ea0364f1SPeter Tyser  *
18ea0364f1SPeter Tyser  * You should have received a copy of the GNU General Public License
19ea0364f1SPeter Tyser  * along with this program; if not, write to the Free Software
20ea0364f1SPeter Tyser  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307	 USA
21ea0364f1SPeter Tyser  *
22ea0364f1SPeter Tyser  */
23ea0364f1SPeter Tyser 
24ea0364f1SPeter Tyser #include <common.h>
25ea0364f1SPeter Tyser #include <command.h>
26ea0364f1SPeter Tyser #include <image.h>
27ea0364f1SPeter Tyser #include <u-boot/zlib.h>
28ea0364f1SPeter Tyser #include <bzlib.h>
29ea0364f1SPeter Tyser #include <watchdog.h>
30ea0364f1SPeter Tyser #include <environment.h>
31ea0364f1SPeter Tyser #include <asm/byteorder.h>
32ea0364f1SPeter Tyser #ifdef CONFIG_SHOW_BOOT_PROGRESS
33ea0364f1SPeter Tyser # include <status_led.h>
34ea0364f1SPeter Tyser #endif
35ea0364f1SPeter Tyser 
36ea0364f1SPeter Tyser DECLARE_GLOBAL_DATA_PTR;
37ea0364f1SPeter Tyser 
38ea0364f1SPeter Tyser #define PHYSADDR(x) x
39ea0364f1SPeter Tyser 
40ea0364f1SPeter Tyser #define LINUX_MAX_ENVS		256
41ea0364f1SPeter Tyser #define LINUX_MAX_ARGS		256
42ea0364f1SPeter Tyser 
43ea0364f1SPeter Tyser static ulong get_sp (void);
44ea0364f1SPeter Tyser static void set_clocks_in_mhz (bd_t *kbd);
45ea0364f1SPeter Tyser 
46ea0364f1SPeter Tyser void arch_lmb_reserve(struct lmb *lmb)
47ea0364f1SPeter Tyser {
48ea0364f1SPeter Tyser 	ulong sp;
49ea0364f1SPeter Tyser 
50ea0364f1SPeter Tyser 	/*
51ea0364f1SPeter Tyser 	 * Booting a (Linux) kernel image
52ea0364f1SPeter Tyser 	 *
53ea0364f1SPeter Tyser 	 * Allocate space for command line and board info - the
54ea0364f1SPeter Tyser 	 * address should be as high as possible within the reach of
55ea0364f1SPeter Tyser 	 * the kernel (see CONFIG_SYS_BOOTMAPSZ settings), but in unused
56ea0364f1SPeter Tyser 	 * memory, which means far enough below the current stack
57ea0364f1SPeter Tyser 	 * pointer.
58ea0364f1SPeter Tyser 	 */
59ea0364f1SPeter Tyser 	sp = get_sp();
60ea0364f1SPeter Tyser 	debug ("## Current stack ends at 0x%08lx ", sp);
61ea0364f1SPeter Tyser 
62ea0364f1SPeter Tyser 	/* adjust sp by 1K to be safe */
63ea0364f1SPeter Tyser 	sp -= 1024;
64ea0364f1SPeter Tyser 	lmb_reserve(lmb, sp, (CONFIG_SYS_SDRAM_BASE + gd->ram_size - sp));
65ea0364f1SPeter Tyser }
66ea0364f1SPeter Tyser 
6754841ab5SWolfgang Denk int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images)
68ea0364f1SPeter Tyser {
69ea0364f1SPeter Tyser 	ulong rd_len;
70ea0364f1SPeter Tyser 	ulong initrd_start, initrd_end;
71ea0364f1SPeter Tyser 	int ret;
72ea0364f1SPeter Tyser 
73ea0364f1SPeter Tyser 	ulong cmd_start, cmd_end;
74ea0364f1SPeter Tyser 	bd_t  *kbd;
75ea0364f1SPeter Tyser 	void  (*kernel) (bd_t *, ulong, ulong, ulong, ulong);
76ea0364f1SPeter Tyser 	struct lmb *lmb = &images->lmb;
77ea0364f1SPeter Tyser 
78*2cb0e55aSAndreas Bießmann 	/*
79*2cb0e55aSAndreas Bießmann 	 * allow the PREP bootm subcommand, it is required for bootm to work
80*2cb0e55aSAndreas Bießmann 	 */
81*2cb0e55aSAndreas Bießmann 	if (flag & BOOTM_STATE_OS_PREP)
82*2cb0e55aSAndreas Bießmann 		return 0;
83*2cb0e55aSAndreas Bießmann 
84ea0364f1SPeter Tyser 	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
85ea0364f1SPeter Tyser 		return 1;
86ea0364f1SPeter Tyser 
87ea0364f1SPeter Tyser 	/* allocate space for kernel copy of board info */
88590d3cacSGrant Likely 	ret = boot_get_kbd (lmb, &kbd);
89ea0364f1SPeter Tyser 	if (ret) {
90ea0364f1SPeter Tyser 		puts("ERROR with allocation of kernel bd\n");
91ea0364f1SPeter Tyser 		goto error;
92ea0364f1SPeter Tyser 	}
93ea0364f1SPeter Tyser 	set_clocks_in_mhz(kbd);
94ea0364f1SPeter Tyser 
9524507cf5SSimon Glass 	ret = image_setup_linux(images);
96ea0364f1SPeter Tyser 	if (ret)
97ea0364f1SPeter Tyser 		goto error;
98ea0364f1SPeter Tyser 
9924507cf5SSimon Glass 	kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))images->ep;
10024507cf5SSimon Glass 
101ea0364f1SPeter Tyser 	debug("## Transferring control to Linux (at address %08lx) ...\n",
102ea0364f1SPeter Tyser 	      (ulong) kernel);
103ea0364f1SPeter Tyser 
104770605e4SSimon Glass 	bootstage_mark(BOOTSTAGE_ID_RUN_OS);
105ea0364f1SPeter Tyser 
106ea0364f1SPeter Tyser 	/*
107ea0364f1SPeter Tyser 	 * Linux Kernel Parameters (passing board info data):
108ea0364f1SPeter Tyser 	 *   sp+00: Ignore, side effect of using jsr to jump to kernel
109ea0364f1SPeter Tyser 	 *   sp+04: ptr to board info data
110ea0364f1SPeter Tyser 	 *   sp+08: initrd_start or 0 if no initrd
111ea0364f1SPeter Tyser 	 *   sp+12: initrd_end - unused if initrd_start is 0
112ea0364f1SPeter Tyser 	 *   sp+16: Start of command line string
113ea0364f1SPeter Tyser 	 *   sp+20: End   of command line string
114ea0364f1SPeter Tyser 	 */
115ea0364f1SPeter Tyser 	(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
116ea0364f1SPeter Tyser 	/* does not return */
117ea0364f1SPeter Tyser error:
118ea0364f1SPeter Tyser 	return 1;
119ea0364f1SPeter Tyser }
120ea0364f1SPeter Tyser 
121ea0364f1SPeter Tyser static ulong get_sp (void)
122ea0364f1SPeter Tyser {
123ea0364f1SPeter Tyser 	ulong sp;
124ea0364f1SPeter Tyser 
125ea0364f1SPeter Tyser 	asm("movel %%a7, %%d0\n"
126ea0364f1SPeter Tyser 	    "movel %%d0, %0\n": "=d"(sp): :"%d0");
127ea0364f1SPeter Tyser 
128ea0364f1SPeter Tyser 	return sp;
129ea0364f1SPeter Tyser }
130ea0364f1SPeter Tyser 
131ea0364f1SPeter Tyser static void set_clocks_in_mhz (bd_t *kbd)
132ea0364f1SPeter Tyser {
133ea0364f1SPeter Tyser 	char *s;
134ea0364f1SPeter Tyser 
135ea0364f1SPeter Tyser 	if ((s = getenv("clocks_in_mhz")) != NULL) {
136ea0364f1SPeter Tyser 		/* convert all clock information to MHz */
137ea0364f1SPeter Tyser 		kbd->bi_intfreq /= 1000000L;
138ea0364f1SPeter Tyser 		kbd->bi_busfreq /= 1000000L;
139ea0364f1SPeter Tyser 	}
140ea0364f1SPeter Tyser }
141