Home | History | Annotate | Line # | Download | only in boot
      1 /*	$NetBSD: boot.c,v 1.21 2019/09/03 14:18:32 martin 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 #ifdef SCSI_SUPPORT
     50 	"sd(0,0,0)netbsd", "sd(0,0,0)onetbsd",
     51 #endif
     52 	"in()",
     53 };
     54 #define	NUMNAMES (sizeof (names) / sizeof (names[0]))
     55 
     56 #define	NAMELEN	128
     57 char namebuf[NAMELEN];
     58 char nametmp[NAMELEN];
     59 
     60 char bootinfo[BOOTINFO_MAXSIZE];
     61 struct btinfo_residual btinfo_residual;
     62 struct btinfo_console btinfo_console;
     63 struct btinfo_clock btinfo_clock;
     64 
     65 RESIDUAL residual;
     66 
     67 extern u_long ns_per_tick;
     68 extern char bootprog_name[], bootprog_rev[];
     69 
     70 void boot(void *, u_long);
     71 static void exec_kernel(char *);
     72 
     73 void
     74 boot(void *resp, u_long loadaddr)
     75 {
     76 	extern char _end[], _edata[];
     77 	int n = 0;
     78 	int addr, speed;
     79 	unsigned int cpuvers;
     80 	char *name, *cnname, *p;
     81 
     82 	/* Clear all of BSS */
     83 	memset(_edata, 0, _end - _edata);
     84 
     85 	/*
     86 	 * console init
     87 	 */
     88 	cnname = cninit(&addr, &speed);
     89 #ifdef VGA_RESET
     90 	vga_reset((u_char *)0xc0000000);
     91 #endif
     92 
     93 	/* make bootinfo */
     94 	/*
     95 	 * residual data
     96 	 */
     97 	btinfo_residual.common.next = sizeof(btinfo_residual);
     98 	btinfo_residual.common.type = BTINFO_RESIDUAL;
     99 	if (resp) {
    100 		memcpy(&residual, resp, sizeof(residual));
    101 		btinfo_residual.addr = (void *)&residual;
    102 	} else {
    103 		printf("Warning: no residual data.\n");
    104 		btinfo_residual.addr = 0;
    105 	}
    106 
    107 	/*
    108 	 * console
    109 	 */
    110 	btinfo_console.common.next = sizeof(btinfo_console);
    111 	btinfo_console.common.type = BTINFO_CONSOLE;
    112 	strcpy(btinfo_console.devname, cnname);
    113 	btinfo_console.addr = addr;
    114 	btinfo_console.speed = speed;
    115 
    116 	/*
    117 	 * clock
    118 	 */
    119 	__asm volatile ("mfpvr %0" : "=r"(cpuvers));
    120 	cpuvers >>= 16;
    121 	btinfo_clock.common.next = 0;
    122 	btinfo_clock.common.type = BTINFO_CLOCK;
    123 	if (cpuvers == MPC601) {
    124 		btinfo_clock.ticks_per_sec = 1000000000;
    125 	} else {
    126 		btinfo_clock.ticks_per_sec = resp ?
    127 		    residual.VitalProductData.ProcessorBusHz/4 : TICKS_PER_SEC;
    128 	}
    129 	ns_per_tick = 1000000000 / btinfo_clock.ticks_per_sec;
    130 
    131 	p = bootinfo;
    132         memcpy(p, (void *)&btinfo_residual, sizeof(btinfo_residual));
    133         p += sizeof(btinfo_residual);
    134         memcpy(p, (void *)&btinfo_console, sizeof(btinfo_console));
    135         p += sizeof(btinfo_console);
    136         memcpy(p, (void *)&btinfo_clock, sizeof(btinfo_clock));
    137 
    138 	/*
    139 	 * load kernel if attached
    140 	 */
    141 	init_in(loadaddr);
    142 
    143 	printf("\n");
    144 	printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev);
    145 	printf("\n");
    146 
    147 #ifdef SCSI_SUPPORT
    148 	/*
    149 	 * Initialize siop@pci0 dev 16 func 0
    150 	 */
    151 	siop_init(0, 16, 0);
    152 #endif
    153 
    154 	for (;;) {
    155 		name = names[n++];
    156 		if (n >= NUMNAMES)
    157 			n = 0;
    158 
    159 		exec_kernel(name);
    160 	}
    161 }
    162 
    163 /*
    164  * Exec kernel
    165  */
    166 static void
    167 exec_kernel(char *name)
    168 {
    169 	int howto = 0;
    170 	char c, *ptr;
    171 	u_long marks[MARK_MAX];
    172 #ifdef DBMONITOR
    173 	int go_monitor;
    174 	extern int db_monitor(void);
    175 
    176 ret:
    177 #endif /* DBMONITOR */
    178 	printf("\nBoot: ");
    179 	memset(namebuf, 0, sizeof (namebuf));
    180 	if (tgets(namebuf) == -1)
    181 		printf("\n");
    182 
    183 	ptr = namebuf;
    184 #ifdef DBMONITOR
    185 	go_monitor = 0;
    186 	if (*ptr == '!') {
    187 		if (*(++ptr) == NULL) {
    188 			db_monitor();
    189 			printf("\n");
    190 			goto ret;
    191 		} else {
    192 			go_monitor++;
    193 		}
    194 	}
    195 #endif /* DBMONITOR */
    196 	while ((c = *ptr)) {
    197 		while (c == ' ')
    198 			c = *++ptr;
    199 		if (!c)
    200 			goto next;
    201 		if (c == '-') {
    202 			while ((c = *++ptr) && c != ' ')
    203 				BOOT_FLAG(c, howto);
    204 		} else {
    205 			name = ptr;
    206 			while ((c = *++ptr) && c != ' ');
    207 			if (c)
    208 				*ptr++ = 0;
    209 		}
    210 	}
    211 
    212 next:
    213 	printf("Loading %s", name);
    214 	if (howto)
    215 		printf(" (howto 0x%x)", howto);
    216 	printf("\n");
    217 
    218 	marks[MARK_START] = 0;
    219 	if (loadfile(name, marks, LOAD_ALL) == 0) {
    220 #ifdef DBMONITOR
    221 		if (go_monitor) {
    222 			db_monitor();
    223 			printf("\n");
    224 		}
    225 #endif /* DBMONITOR */
    226 
    227 		printf("start=0x%lx\n\n", marks[MARK_ENTRY]);
    228 		delay(1000);
    229 		__syncicache((void *)marks[MARK_ENTRY],
    230 			(u_int)marks[MARK_SYM] - (u_int)marks[MARK_ENTRY]);
    231 
    232 		run((void *)marks[MARK_SYM],
    233 		    (void *)marks[MARK_END],
    234 		    (void *)howto,
    235 		    (void *)bootinfo,
    236 		    (void *)marks[MARK_ENTRY]);
    237 	}
    238 }
    239 
    240 void
    241 _rtt(void)
    242 {
    243 
    244 	/* XXXX */
    245 	__unreachable();
    246 }
    247