xref: /netbsd-src/sys/arch/hpcarm/hpcarm/hpc_machdep.c (revision bee3dfab549b89f1a37e3d2ab37c6186cbd9e929)
1 /*	$NetBSD: hpc_machdep.c,v 1.106 2019/07/16 14:41:49 skrll Exp $	*/
2 
3 /*
4  * Copyright (c) 1994-1998 Mark Brinicombe.
5  * Copyright (c) 1994 Brini.
6  * All rights reserved.
7  *
8  * This code is derived from software written for Brini by Mark Brinicombe
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by Brini.
21  * 4. The name of the company nor the name of the author may be used to
22  *    endorse or promote products derived from this software without specific
23  *    prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
26  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
27  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28  * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  */
37 
38 /*
39  * Machine dependent functions for kernel setup.
40  */
41 
42 #include <sys/cdefs.h>
43 __KERNEL_RCSID(0, "$NetBSD: hpc_machdep.c,v 1.106 2019/07/16 14:41:49 skrll Exp $");
44 
45 #include "opt_cputypes.h"
46 #include "opt_kloader.h"
47 #ifndef KLOADER_KERNEL_PATH
48 #define KLOADER_KERNEL_PATH	"/netbsd"
49 #endif
50 
51 #include <sys/param.h>
52 #include <sys/kernel.h>
53 #include <sys/boot_flag.h>
54 #include <sys/mount.h>
55 #include <sys/pmf.h>
56 #include <sys/reboot.h>
57 #include <sys/cpu.h>
58 
59 #include <uvm/uvm.h>
60 
61 #include <arm/locore.h>
62 
63 #include <machine/bootconfig.h>
64 #include <machine/bootinfo.h>
65 #include <machine/platid.h>
66 #include <machine/pmap.h>
67 #ifdef KLOADER
68 #include <machine/kloader.h>
69 #endif
70 
71 #include <dev/cons.h>
72 #include <dev/hpc/apm/apmvar.h>
73 
74 BootConfig bootconfig;		/* Boot config storage */
75 #ifdef KLOADER
76 struct kloader_bootinfo kbootinfo;
77 static char kernel_path[] = KLOADER_KERNEL_PATH;
78 #endif
79 struct bootinfo *bootinfo, bootinfo_storage;
80 char booted_kernel_storage[80];
81 extern char *booted_kernel;
82 
83 paddr_t physical_start;
84 paddr_t physical_freestart;
85 paddr_t physical_freeend;
86 paddr_t physical_end;
87 
88 #ifndef PMAP_STATIC_L1S
89 int max_processes = 64;			/* Default number */
90 #endif /* !PMAP_STATIC_L1S */
91 
92 char *boot_args = NULL;
93 char boot_file[16];
94 
95 paddr_t msgbufphys;
96 
97 /* Prototypes */
98 void dumpsys(void);
99 
100 /* Mode dependent sleep function holder */
101 void (*__sleep_func)(void *);
102 void *__sleep_ctx;
103 
104 void (*__cpu_reset)(void) __dead = cpu_reset;
105 
106 vaddr_t initarm(int, char **, struct bootinfo *);
107 #if defined(CPU_SA1100) || defined(CPU_SA1110)
108 vaddr_t init_sa11x0(int, char **, struct bootinfo *);
109 #endif
110 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270)
111 vaddr_t init_pxa2x0(int, char **, struct bootinfo *);
112 #endif
113 
114 #ifdef BOOT_DUMP
115 void	dumppages(char *, int);
116 #endif
117 
118 /*
119  * Reboots the system.
120  *
121  * Deal with any syncing, unmounting, dumping and shutdown hooks,
122  * then reset the CPU.
123  */
124 void
cpu_reboot(int howto,char * bootstr)125 cpu_reboot(int howto, char *bootstr)
126 {
127 
128 	/*
129 	 * If we are still cold then hit the air brakes
130 	 * and crash to earth fast.
131 	 */
132 	if (cold) {
133 		doshutdownhooks();
134 		pmf_system_shutdown(boothowto);
135 		printf("Halted while still in the ICE age.\n");
136 		printf("The operating system has halted.\n");
137 		printf("Please press any key to reboot.\n\n");
138 		cngetc();
139 		printf("rebooting...\n");
140 		__cpu_reset();
141 		/* NOTREACHED */
142 	}
143 
144 	/* Reset the sleep function. */
145 	__sleep_func = NULL;
146 	__sleep_ctx = NULL;
147 
148 	/* Disable console buffering. */
149 	cnpollc(1);
150 
151 #ifdef KLOADER
152 	if ((howto & RB_HALT) == 0) {
153 		if (howto & RB_STRING) {
154 			kloader_reboot_setup(bootstr);
155 		} else {
156 			kloader_reboot_setup(kernel_path);
157 		}
158 	}
159 #endif
160 
161 	/*
162 	 * If RB_NOSYNC was not specified sync the discs.
163 	 * Note: Unless cold is set to 1 here, syslogd will die during
164 	 * the unmount.  It looks like syslogd is getting woken up only
165 	 * to find that it cannot page part of the binary in as the
166 	 * file system has been unmounted.
167 	 */
168 	if (!(howto & RB_NOSYNC))
169 		bootsync();
170 
171 	/* Say NO to interrupts. */
172 	(void)splhigh();
173 
174 	/* Do a dump if requested. */
175 	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
176 		dumpsys();
177 
178 	/* Run any shutdown hooks. */
179 	doshutdownhooks();
180 
181 	pmf_system_shutdown(boothowto);
182 
183 	/* Make sure IRQs are disabled. */
184 	IRQdisable;
185 
186 	if (howto & RB_HALT) {
187 		printf("The operating system has halted.\n");
188 		printf("Please press any key to reboot.\n\n");
189 		cngetc();
190 #ifdef KLOADER
191 	} else {
192 		kloader_reboot();
193 		/* NOTREACHED */
194 #endif
195 	}
196 
197 	printf("rebooting...\n");
198 	__cpu_reset();
199 	/* NOTREACHED */
200 }
201 
202 void
machine_sleep(void)203 machine_sleep(void)
204 {
205 
206 	if (__sleep_func != NULL)
207 		__sleep_func(__sleep_ctx);
208 }
209 
210 void
machine_standby(void)211 machine_standby(void)
212 {
213 }
214 
215 /*
216  * Initial entry point on startup. This gets called before main() is
217  * entered.
218  * It should be responsible for setting up everything that must be
219  * in place when main is called.
220  * This includes:
221  *   Taking a copy of the boot configuration structure.
222  */
223 vaddr_t
initarm(int argc,char ** argv,struct bootinfo * bi)224 initarm(int argc, char **argv, struct bootinfo *bi)
225 {
226 
227 	__sleep_func = NULL;
228 	__sleep_ctx = NULL;
229 
230 	/* parse kernel args */
231 	booted_kernel = booted_kernel_storage;
232 	boothowto = 0;
233 	boot_file[0] = '\0';
234 	if (argc > 0 && argv != NULL) {
235 		strncpy(booted_kernel_storage, argv[0],
236 		    sizeof(booted_kernel_storage));
237 		for (int i = 1; i < argc; i++) {
238 			char *cp = argv[i];
239 
240 			switch (*cp) {
241 			case 'b':
242 				/* boot device: -b=sd0 etc. */
243 				cp = cp + 2;
244 				if (strcmp(cp, MOUNT_NFS) == 0)
245 					rootfstype = MOUNT_NFS;
246 				else
247 					strncpy(boot_file, cp,
248 					    sizeof(boot_file));
249 				break;
250 
251 			default:
252 				BOOT_FLAG(*cp, boothowto);
253 				break;
254 			}
255 		}
256 	}
257 
258 	/* copy bootinfo into known kernel space */
259 	if (bi != NULL)
260 		bootinfo_storage = *bi;
261 	bootinfo = &bootinfo_storage;
262 
263 #ifdef BOOTINFO_FB_WIDTH
264 	bootinfo->fb_line_bytes = BOOTINFO_FB_LINE_BYTES;
265 	bootinfo->fb_width = BOOTINFO_FB_WIDTH;
266 	bootinfo->fb_height = BOOTINFO_FB_HEIGHT;
267 	bootinfo->fb_type = BOOTINFO_FB_TYPE;
268 #endif
269 
270 	if (bootinfo->magic == BOOTINFO_MAGIC) {
271 		platid.dw.dw0 = bootinfo->platid_cpu;
272 		platid.dw.dw1 = bootinfo->platid_machine;
273 
274 #ifndef RTC_OFFSET
275 		/*
276 		 * rtc_offset from bootinfo.timezone set by hpcboot.exe
277 		 */
278 		if (rtc_offset == 0 &&
279 		    (bootinfo->timezone > (-12 * 60) &&
280 		     bootinfo->timezone <= (12 * 60)))
281 			rtc_offset = bootinfo->timezone;
282 #endif
283 	}
284 
285 #ifdef KLOADER
286 	/* copy boot parameter for kloader */
287 	kloader_bootinfo_set(&kbootinfo, argc, argv, bi, false);
288 #endif
289 
290 	/*
291 	 * Heads up ... Setup the CPU / MMU / TLB functions.
292 	 */
293 	set_cpufuncs();
294 	IRQdisable;
295 
296 #if defined(CPU_SA1100) || defined(CPU_SA1110)
297 	return init_sa11x0(argc, argv, bi);
298 #elif defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270)
299 	return init_pxa2x0(argc, argv, bi);
300 #else
301 #error	No CPU support
302 #endif
303 }
304 
305 #ifdef BOOT_DUMP
306 void
dumppages(char * start,int nbytes)307 dumppages(char *start, int nbytes)
308 {
309 	char *p = start;
310 	char *p1;
311 	int i;
312 
313 	for (i = nbytes; i > 0; i -= 16, p += 16) {
314 		for (p1 = p + 15; p != p1; p1--) {
315 			if (*p1)
316 				break;
317 		}
318 		if (!*p1)
319 			continue;
320 		printf("%08x %02x %02x %02x %02x %02x %02x %02x %02x"
321 		    " %02x %02x %02x %02x %02x %02x %02x %02x\n",
322 		    (unsigned int)p,
323 		    p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
324 		    p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
325 	}
326 }
327 #endif
328