xref: /netbsd-src/sys/arch/prep/stand/boot/boot.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*	$NetBSD: boot.c,v 1.20 2014/08/08 19:45:48 joerg Exp $	*/
2 
3 /*
4  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5  * Copyright (C) 1995, 1996 TooLs GmbH.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by TooLs GmbH.
19  * 4. The name of TooLs GmbH may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include <lib/libsa/stand.h>
35 #include <lib/libsa/loadfile.h>
36 #include <lib/libkern/libkern.h>
37 #include <sys/reboot.h>
38 #include <sys/boot_flag.h>
39 #include <machine/bootinfo.h>
40 #include <machine/cpu.h>
41 #include <machine/residual.h>
42 #include <powerpc/spr.h>
43 #include <powerpc/oea/spr.h>
44 
45 #include "boot.h"
46 #include "sdvar.h"
47 
48 char *names[] = {
49 	"sd(0,0,0)netbsd", "sd(0,0,0)onetbsd",
50 	"in()",
51 };
52 #define	NUMNAMES (sizeof (names) / sizeof (names[0]))
53 
54 #define	NAMELEN	128
55 char namebuf[NAMELEN];
56 char nametmp[NAMELEN];
57 
58 char bootinfo[BOOTINFO_MAXSIZE];
59 struct btinfo_residual btinfo_residual;
60 struct btinfo_console btinfo_console;
61 struct btinfo_clock btinfo_clock;
62 
63 RESIDUAL residual;
64 
65 extern u_long ns_per_tick;
66 extern char bootprog_name[], bootprog_rev[];
67 
68 void boot(void *, u_long);
69 static void exec_kernel(char *);
70 
71 void
72 boot(void *resp, u_long loadaddr)
73 {
74 	extern char _end[], _edata[];
75 	int n = 0;
76 	int addr, speed;
77 	unsigned int cpuvers;
78 	char *name, *cnname, *p;
79 
80 	/* Clear all of BSS */
81 	memset(_edata, 0, _end - _edata);
82 
83 	/*
84 	 * console init
85 	 */
86 	cnname = cninit(&addr, &speed);
87 #ifdef VGA_RESET
88 	vga_reset((u_char *)0xc0000000);
89 #endif
90 
91 	/* make bootinfo */
92 	/*
93 	 * residual data
94 	 */
95 	btinfo_residual.common.next = sizeof(btinfo_residual);
96 	btinfo_residual.common.type = BTINFO_RESIDUAL;
97 	if (resp) {
98 		memcpy(&residual, resp, sizeof(residual));
99 		btinfo_residual.addr = (void *)&residual;
100 	} else {
101 		printf("Warning: no residual data.\n");
102 		btinfo_residual.addr = 0;
103 	}
104 
105 	/*
106 	 * console
107 	 */
108 	btinfo_console.common.next = sizeof(btinfo_console);
109 	btinfo_console.common.type = BTINFO_CONSOLE;
110 	strcpy(btinfo_console.devname, cnname);
111 	btinfo_console.addr = addr;
112 	btinfo_console.speed = speed;
113 
114 	/*
115 	 * clock
116 	 */
117 	__asm volatile ("mfpvr %0" : "=r"(cpuvers));
118 	cpuvers >>= 16;
119 	btinfo_clock.common.next = 0;
120 	btinfo_clock.common.type = BTINFO_CLOCK;
121 	if (cpuvers == MPC601) {
122 		btinfo_clock.ticks_per_sec = 1000000000;
123 	} else {
124 		btinfo_clock.ticks_per_sec = resp ?
125 		    residual.VitalProductData.ProcessorBusHz/4 : TICKS_PER_SEC;
126 	}
127 	ns_per_tick = 1000000000 / btinfo_clock.ticks_per_sec;
128 
129 	p = bootinfo;
130         memcpy(p, (void *)&btinfo_residual, sizeof(btinfo_residual));
131         p += sizeof(btinfo_residual);
132         memcpy(p, (void *)&btinfo_console, sizeof(btinfo_console));
133         p += sizeof(btinfo_console);
134         memcpy(p, (void *)&btinfo_clock, sizeof(btinfo_clock));
135 
136 	/*
137 	 * load kernel if attached
138 	 */
139 	init_in(loadaddr);
140 
141 	printf("\n");
142 	printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev);
143 	printf("\n");
144 
145 	/*
146 	 * Initialize siop@pci0 dev 16 func 0
147 	 */
148 	siop_init(0, 16, 0);
149 
150 	for (;;) {
151 		name = names[n++];
152 		if (n >= NUMNAMES)
153 			n = 0;
154 
155 		exec_kernel(name);
156 	}
157 }
158 
159 /*
160  * Exec kernel
161  */
162 static void
163 exec_kernel(char *name)
164 {
165 	int howto = 0;
166 	char c, *ptr;
167 	u_long marks[MARK_MAX];
168 #ifdef DBMONITOR
169 	int go_monitor;
170 	extern int db_monitor(void);
171 
172 ret:
173 #endif /* DBMONITOR */
174 	printf("\nBoot: ");
175 	memset(namebuf, 0, sizeof (namebuf));
176 	if (tgets(namebuf) == -1)
177 		printf("\n");
178 
179 	ptr = namebuf;
180 #ifdef DBMONITOR
181 	go_monitor = 0;
182 	if (*ptr == '!') {
183 		if (*(++ptr) == NULL) {
184 			db_monitor();
185 			printf("\n");
186 			goto ret;
187 		} else {
188 			go_monitor++;
189 		}
190 	}
191 #endif /* DBMONITOR */
192 	while ((c = *ptr)) {
193 		while (c == ' ')
194 			c = *++ptr;
195 		if (!c)
196 			goto next;
197 		if (c == '-') {
198 			while ((c = *++ptr) && c != ' ')
199 				BOOT_FLAG(c, howto);
200 		} else {
201 			name = ptr;
202 			while ((c = *++ptr) && c != ' ');
203 			if (c)
204 				*ptr++ = 0;
205 		}
206 	}
207 
208 next:
209 	printf("Loading %s", name);
210 	if (howto)
211 		printf(" (howto 0x%x)", howto);
212 	printf("\n");
213 
214 	marks[MARK_START] = 0;
215 	if (loadfile(name, marks, LOAD_ALL) == 0) {
216 #ifdef DBMONITOR
217 		if (go_monitor) {
218 			db_monitor();
219 			printf("\n");
220 		}
221 #endif /* DBMONITOR */
222 
223 		printf("start=0x%lx\n\n", marks[MARK_ENTRY]);
224 		delay(1000);
225 		__syncicache((void *)marks[MARK_ENTRY],
226 			(u_int)marks[MARK_SYM] - (u_int)marks[MARK_ENTRY]);
227 
228 		run((void *)marks[MARK_SYM],
229 		    (void *)marks[MARK_END],
230 		    (void *)howto,
231 		    (void *)bootinfo,
232 		    (void *)marks[MARK_ENTRY]);
233 	}
234 }
235 
236 void
237 _rtt(void)
238 {
239 
240 	/* XXXX */
241 	__unreachable();
242 }
243