xref: /netbsd-src/sys/arch/prep/stand/boot/boot.c (revision 55b16d1717fdd719656c15fd53d2f3f861d0eadc)
1*55b16d17Smartin /*	$NetBSD: boot.c,v 1.21 2019/09/03 14:18:32 martin Exp $	*/
237eb9eebSnonaka 
337eb9eebSnonaka /*
437eb9eebSnonaka  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
537eb9eebSnonaka  * Copyright (C) 1995, 1996 TooLs GmbH.
637eb9eebSnonaka  * All rights reserved.
737eb9eebSnonaka  *
837eb9eebSnonaka  * Redistribution and use in source and binary forms, with or without
937eb9eebSnonaka  * modification, are permitted provided that the following conditions
1037eb9eebSnonaka  * are met:
1137eb9eebSnonaka  * 1. Redistributions of source code must retain the above copyright
1237eb9eebSnonaka  *    notice, this list of conditions and the following disclaimer.
1337eb9eebSnonaka  * 2. Redistributions in binary form must reproduce the above copyright
1437eb9eebSnonaka  *    notice, this list of conditions and the following disclaimer in the
1537eb9eebSnonaka  *    documentation and/or other materials provided with the distribution.
1637eb9eebSnonaka  * 3. All advertising materials mentioning features or use of this software
1737eb9eebSnonaka  *    must display the following acknowledgement:
1837eb9eebSnonaka  *	This product includes software developed by TooLs GmbH.
1937eb9eebSnonaka  * 4. The name of TooLs GmbH may not be used to endorse or promote products
2037eb9eebSnonaka  *    derived from this software without specific prior written permission.
2137eb9eebSnonaka  *
2237eb9eebSnonaka  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
2337eb9eebSnonaka  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2437eb9eebSnonaka  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2537eb9eebSnonaka  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2637eb9eebSnonaka  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2737eb9eebSnonaka  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
2837eb9eebSnonaka  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2937eb9eebSnonaka  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
3037eb9eebSnonaka  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
3137eb9eebSnonaka  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3237eb9eebSnonaka  */
3337eb9eebSnonaka 
3437eb9eebSnonaka #include <lib/libsa/stand.h>
3537eb9eebSnonaka #include <lib/libsa/loadfile.h>
3655759344She #include <lib/libkern/libkern.h>
3737eb9eebSnonaka #include <sys/reboot.h>
3849c105ffSjdolecek #include <sys/boot_flag.h>
3937eb9eebSnonaka #include <machine/bootinfo.h>
4037eb9eebSnonaka #include <machine/cpu.h>
4137eb9eebSnonaka #include <machine/residual.h>
423cd264f0Skleink #include <powerpc/spr.h>
43eeda5809Smatt #include <powerpc/oea/spr.h>
4437eb9eebSnonaka 
4537eb9eebSnonaka #include "boot.h"
46158f609aSkiyohara #include "sdvar.h"
4737eb9eebSnonaka 
4837eb9eebSnonaka char *names[] = {
49*55b16d17Smartin #ifdef SCSI_SUPPORT
50158f609aSkiyohara 	"sd(0,0,0)netbsd", "sd(0,0,0)onetbsd",
51*55b16d17Smartin #endif
5237eb9eebSnonaka 	"in()",
5337eb9eebSnonaka };
5437eb9eebSnonaka #define	NUMNAMES (sizeof (names) / sizeof (names[0]))
5537eb9eebSnonaka 
5637eb9eebSnonaka #define	NAMELEN	128
5737eb9eebSnonaka char namebuf[NAMELEN];
5837eb9eebSnonaka char nametmp[NAMELEN];
5937eb9eebSnonaka 
6037eb9eebSnonaka char bootinfo[BOOTINFO_MAXSIZE];
6137eb9eebSnonaka struct btinfo_residual btinfo_residual;
6237eb9eebSnonaka struct btinfo_console btinfo_console;
6337eb9eebSnonaka struct btinfo_clock btinfo_clock;
6437eb9eebSnonaka 
6537eb9eebSnonaka RESIDUAL residual;
6637eb9eebSnonaka 
6737eb9eebSnonaka extern u_long ns_per_tick;
683c550524Sjoerg extern char bootprog_name[], bootprog_rev[];
6937eb9eebSnonaka 
7078fba760Sgarbled void boot(void *, u_long);
7178fba760Sgarbled static void exec_kernel(char *);
7237eb9eebSnonaka 
7337eb9eebSnonaka void
boot(void * resp,u_long loadaddr)7478fba760Sgarbled boot(void *resp, u_long loadaddr)
7537eb9eebSnonaka {
76d382cc6cSnonaka 	extern char _end[], _edata[];
7737eb9eebSnonaka 	int n = 0;
7837eb9eebSnonaka 	int addr, speed;
793cd264f0Skleink 	unsigned int cpuvers;
8037eb9eebSnonaka 	char *name, *cnname, *p;
81d382cc6cSnonaka 
82d382cc6cSnonaka 	/* Clear all of BSS */
83d382cc6cSnonaka 	memset(_edata, 0, _end - _edata);
8437eb9eebSnonaka 
8537eb9eebSnonaka 	/*
8637eb9eebSnonaka 	 * console init
8737eb9eebSnonaka 	 */
8837eb9eebSnonaka 	cnname = cninit(&addr, &speed);
89ccad3840Sgarbled #ifdef VGA_RESET
90ccad3840Sgarbled 	vga_reset((u_char *)0xc0000000);
91ccad3840Sgarbled #endif
9237eb9eebSnonaka 
9337eb9eebSnonaka 	/* make bootinfo */
9437eb9eebSnonaka 	/*
9537eb9eebSnonaka 	 * residual data
9637eb9eebSnonaka 	 */
9737eb9eebSnonaka 	btinfo_residual.common.next = sizeof(btinfo_residual);
9837eb9eebSnonaka 	btinfo_residual.common.type = BTINFO_RESIDUAL;
9937eb9eebSnonaka 	if (resp) {
10037eb9eebSnonaka 		memcpy(&residual, resp, sizeof(residual));
10137eb9eebSnonaka 		btinfo_residual.addr = (void *)&residual;
10237eb9eebSnonaka 	} else {
10337eb9eebSnonaka 		printf("Warning: no residual data.\n");
10437eb9eebSnonaka 		btinfo_residual.addr = 0;
10537eb9eebSnonaka 	}
10637eb9eebSnonaka 
10737eb9eebSnonaka 	/*
10837eb9eebSnonaka 	 * console
10937eb9eebSnonaka 	 */
11037eb9eebSnonaka 	btinfo_console.common.next = sizeof(btinfo_console);
11137eb9eebSnonaka 	btinfo_console.common.type = BTINFO_CONSOLE;
11237eb9eebSnonaka 	strcpy(btinfo_console.devname, cnname);
11337eb9eebSnonaka 	btinfo_console.addr = addr;
11437eb9eebSnonaka 	btinfo_console.speed = speed;
11537eb9eebSnonaka 
11637eb9eebSnonaka 	/*
11737eb9eebSnonaka 	 * clock
11837eb9eebSnonaka 	 */
1195f1c88d7Sperry 	__asm volatile ("mfpvr %0" : "=r"(cpuvers));
1203cd264f0Skleink 	cpuvers >>= 16;
121595d6a40Snonaka 	btinfo_clock.common.next = 0;
12237eb9eebSnonaka 	btinfo_clock.common.type = BTINFO_CLOCK;
1233cd264f0Skleink 	if (cpuvers == MPC601) {
1243cd264f0Skleink 		btinfo_clock.ticks_per_sec = 1000000000;
1253cd264f0Skleink 	} else {
12637eb9eebSnonaka 		btinfo_clock.ticks_per_sec = resp ?
12737eb9eebSnonaka 		    residual.VitalProductData.ProcessorBusHz/4 : TICKS_PER_SEC;
1283cd264f0Skleink 	}
1294c2b0e6fSnonaka 	ns_per_tick = 1000000000 / btinfo_clock.ticks_per_sec;
13037eb9eebSnonaka 
13137eb9eebSnonaka 	p = bootinfo;
13237eb9eebSnonaka         memcpy(p, (void *)&btinfo_residual, sizeof(btinfo_residual));
13337eb9eebSnonaka         p += sizeof(btinfo_residual);
13437eb9eebSnonaka         memcpy(p, (void *)&btinfo_console, sizeof(btinfo_console));
13537eb9eebSnonaka         p += sizeof(btinfo_console);
13637eb9eebSnonaka         memcpy(p, (void *)&btinfo_clock, sizeof(btinfo_clock));
13737eb9eebSnonaka 
13837eb9eebSnonaka 	/*
1394c2b0e6fSnonaka 	 * load kernel if attached
14037eb9eebSnonaka 	 */
1414c2b0e6fSnonaka 	init_in(loadaddr);
14237eb9eebSnonaka 
14337eb9eebSnonaka 	printf("\n");
14437eb9eebSnonaka 	printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev);
145158f609aSkiyohara 	printf("\n");
146158f609aSkiyohara 
147*55b16d17Smartin #ifdef SCSI_SUPPORT
148158f609aSkiyohara 	/*
149158f609aSkiyohara 	 * Initialize siop@pci0 dev 16 func 0
150158f609aSkiyohara 	 */
151158f609aSkiyohara 	siop_init(0, 16, 0);
152*55b16d17Smartin #endif
15337eb9eebSnonaka 
15437eb9eebSnonaka 	for (;;) {
15537eb9eebSnonaka 		name = names[n++];
15637eb9eebSnonaka 		if (n >= NUMNAMES)
15737eb9eebSnonaka 			n = 0;
15837eb9eebSnonaka 
15937eb9eebSnonaka 		exec_kernel(name);
16037eb9eebSnonaka 	}
16137eb9eebSnonaka }
16237eb9eebSnonaka 
16337eb9eebSnonaka /*
16437eb9eebSnonaka  * Exec kernel
16537eb9eebSnonaka  */
16637eb9eebSnonaka static void
exec_kernel(char * name)16778fba760Sgarbled exec_kernel(char *name)
16837eb9eebSnonaka {
16937eb9eebSnonaka 	int howto = 0;
17037eb9eebSnonaka 	char c, *ptr;
17137eb9eebSnonaka 	u_long marks[MARK_MAX];
17237eb9eebSnonaka #ifdef DBMONITOR
17337eb9eebSnonaka 	int go_monitor;
17402cdf4d2Sdsl 	extern int db_monitor(void);
17537eb9eebSnonaka 
17637eb9eebSnonaka ret:
1777c009730Sgarbled #endif /* DBMONITOR */
17837eb9eebSnonaka 	printf("\nBoot: ");
17937eb9eebSnonaka 	memset(namebuf, 0, sizeof (namebuf));
180261274d5Stsutsui 	if (tgets(namebuf) == -1)
181261274d5Stsutsui 		printf("\n");
18237eb9eebSnonaka 
18337eb9eebSnonaka 	ptr = namebuf;
18437eb9eebSnonaka #ifdef DBMONITOR
18537eb9eebSnonaka 	go_monitor = 0;
18637eb9eebSnonaka 	if (*ptr == '!') {
18737eb9eebSnonaka 		if (*(++ptr) == NULL) {
18837eb9eebSnonaka 			db_monitor();
18937eb9eebSnonaka 			printf("\n");
19037eb9eebSnonaka 			goto ret;
19137eb9eebSnonaka 		} else {
19237eb9eebSnonaka 			go_monitor++;
19337eb9eebSnonaka 		}
19437eb9eebSnonaka 	}
19537eb9eebSnonaka #endif /* DBMONITOR */
19637eb9eebSnonaka 	while ((c = *ptr)) {
19737eb9eebSnonaka 		while (c == ' ')
19837eb9eebSnonaka 			c = *++ptr;
19937eb9eebSnonaka 		if (!c)
20037eb9eebSnonaka 			goto next;
20137eb9eebSnonaka 		if (c == '-') {
20249c105ffSjdolecek 			while ((c = *++ptr) && c != ' ')
20349c105ffSjdolecek 				BOOT_FLAG(c, howto);
20437eb9eebSnonaka 		} else {
20537eb9eebSnonaka 			name = ptr;
20637eb9eebSnonaka 			while ((c = *++ptr) && c != ' ');
20737eb9eebSnonaka 			if (c)
20837eb9eebSnonaka 				*ptr++ = 0;
20937eb9eebSnonaka 		}
21037eb9eebSnonaka 	}
21137eb9eebSnonaka 
21237eb9eebSnonaka next:
21337eb9eebSnonaka 	printf("Loading %s", name);
21437eb9eebSnonaka 	if (howto)
21537eb9eebSnonaka 		printf(" (howto 0x%x)", howto);
21637eb9eebSnonaka 	printf("\n");
21737eb9eebSnonaka 
21837eb9eebSnonaka 	marks[MARK_START] = 0;
21937eb9eebSnonaka 	if (loadfile(name, marks, LOAD_ALL) == 0) {
22037eb9eebSnonaka #ifdef DBMONITOR
22137eb9eebSnonaka 		if (go_monitor) {
22237eb9eebSnonaka 			db_monitor();
22337eb9eebSnonaka 			printf("\n");
22437eb9eebSnonaka 		}
22537eb9eebSnonaka #endif /* DBMONITOR */
22637eb9eebSnonaka 
22737eb9eebSnonaka 		printf("start=0x%lx\n\n", marks[MARK_ENTRY]);
22837eb9eebSnonaka 		delay(1000);
22937eb9eebSnonaka 		__syncicache((void *)marks[MARK_ENTRY],
23037eb9eebSnonaka 			(u_int)marks[MARK_SYM] - (u_int)marks[MARK_ENTRY]);
23137eb9eebSnonaka 
23237eb9eebSnonaka 		run((void *)marks[MARK_SYM],
23337eb9eebSnonaka 		    (void *)marks[MARK_END],
23437eb9eebSnonaka 		    (void *)howto,
23537eb9eebSnonaka 		    (void *)bootinfo,
23637eb9eebSnonaka 		    (void *)marks[MARK_ENTRY]);
23737eb9eebSnonaka 	}
23837eb9eebSnonaka }
239158f609aSkiyohara 
240158f609aSkiyohara void
_rtt(void)241158f609aSkiyohara _rtt(void)
242158f609aSkiyohara {
243158f609aSkiyohara 
244158f609aSkiyohara 	/* XXXX */
24545137140Sjoerg 	__unreachable();
246158f609aSkiyohara }
247