xref: /netbsd-src/sys/arch/hpcarm/hpcarm/hpc_machdep.c (revision a536ee5124e62c9a0051a252f7833dc8f50f44c9)
1 /*	$NetBSD: hpc_machdep.c,v 1.101 2012/07/29 00:07:06 matt 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.101 2012/07/29 00:07:06 matt 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 
58 #include <uvm/uvm.h>
59 
60 #include <arm/cpufunc.h>
61 
62 #include <machine/bootconfig.h>
63 #include <machine/bootinfo.h>
64 #include <machine/platid.h>
65 #include <machine/pmap.h>
66 #ifdef KLOADER
67 #include <machine/kloader.h>
68 #endif
69 
70 #include <dev/cons.h>
71 #include <dev/hpc/apm/apmvar.h>
72 
73 BootConfig bootconfig;		/* Boot config storage */
74 #ifdef KLOADER
75 struct kloader_bootinfo kbootinfo;
76 static char kernel_path[] = KLOADER_KERNEL_PATH;
77 #endif
78 struct bootinfo *bootinfo, bootinfo_storage;
79 char booted_kernel_storage[80];
80 extern char *booted_kernel;
81 
82 paddr_t physical_start;
83 paddr_t physical_freestart;
84 paddr_t physical_freeend;
85 paddr_t physical_end;
86 
87 #ifndef PMAP_STATIC_L1S
88 int max_processes = 64;			/* Default number */
89 #endif /* !PMAP_STATIC_L1S */
90 
91 char *boot_args = NULL;
92 char boot_file[16];
93 
94 vaddr_t msgbufphys;
95 
96 /* Prototypes */
97 void dumpsys(void);
98 
99 /* Mode dependent sleep function holder */
100 void (*__sleep_func)(void *);
101 void *__sleep_ctx;
102 
103 void (*__cpu_reset)(void) = cpu_reset;
104 
105 u_int initarm(int, char **, struct bootinfo *);
106 #if defined(CPU_SA1100) || defined(CPU_SA1110)
107 u_int init_sa11x0(int, char **, struct bootinfo *);
108 #endif
109 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270)
110 u_int init_pxa2x0(int, char **, struct bootinfo *);
111 #endif
112 
113 #ifdef BOOT_DUMP
114 void	dumppages(char *, int);
115 #endif
116 
117 /*
118  * Reboots the system.
119  *
120  * Deal with any syncing, unmounting, dumping and shutdown hooks,
121  * then reset the CPU.
122  */
123 void
124 cpu_reboot(int howto, char *bootstr)
125 {
126 
127 	/*
128 	 * If we are still cold then hit the air brakes
129 	 * and crash to earth fast.
130 	 */
131 	if (cold) {
132 		doshutdownhooks();
133 		pmf_system_shutdown(boothowto);
134 		printf("Halted while still in the ICE age.\n");
135 		printf("The operating system has halted.\n");
136 		printf("Please press any key to reboot.\n\n");
137 		cngetc();
138 		printf("rebooting...\n");
139 		__cpu_reset();
140 		/* NOTREACHED */
141 	}
142 
143 	/* Reset the sleep function. */
144 	__sleep_func = NULL;
145 	__sleep_ctx = NULL;
146 
147 	/* Disable console buffering. */
148 	cnpollc(1);
149 
150 #ifdef KLOADER
151 	if ((howto & RB_HALT) == 0) {
152 		if (howto & RB_STRING) {
153 			kloader_reboot_setup(bootstr);
154 		} else {
155 			kloader_reboot_setup(kernel_path);
156 		}
157 	}
158 #endif
159 
160 	/*
161 	 * If RB_NOSYNC was not specified sync the discs.
162 	 * Note: Unless cold is set to 1 here, syslogd will die during
163 	 * the unmount.  It looks like syslogd is getting woken up only
164 	 * to find that it cannot page part of the binary in as the
165 	 * file system has been unmounted.
166 	 */
167 	if (!(howto & RB_NOSYNC))
168 		bootsync();
169 
170 	/* Say NO to interrupts. */
171 	(void)splhigh();
172 
173 	/* Do a dump if requested. */
174 	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
175 		dumpsys();
176 
177 	/* Run any shutdown hooks. */
178 	doshutdownhooks();
179 
180 	pmf_system_shutdown(boothowto);
181 
182 	/* Make sure IRQs are disabled. */
183 	IRQdisable;
184 
185 	if (howto & RB_HALT) {
186 		printf("The operating system has halted.\n");
187 		printf("Please press any key to reboot.\n\n");
188 		cngetc();
189 #ifdef KLOADER
190 	} else {
191 		kloader_reboot();
192 		/* NOTREACHED */
193 #endif
194 	}
195 
196 	printf("rebooting...\n");
197 	__cpu_reset();
198 	/* NOTREACHED */
199 }
200 
201 void
202 machine_sleep(void)
203 {
204 
205 	if (__sleep_func != NULL)
206 		__sleep_func(__sleep_ctx);
207 }
208 
209 void
210 machine_standby(void)
211 {
212 }
213 
214 /*
215  * Initial entry point on startup. This gets called before main() is
216  * entered.
217  * It should be responsible for setting up everything that must be
218  * in place when main is called.
219  * This includes:
220  *   Taking a copy of the boot configuration structure.
221  */
222 u_int
223 initarm(int argc, char **argv, struct bootinfo *bi)
224 {
225 
226 	__sleep_func = NULL;
227 	__sleep_ctx = NULL;
228 
229 	/* parse kernel args */
230 	booted_kernel = booted_kernel_storage;
231 	boothowto = 0;
232 	boot_file[0] = '\0';
233 	if (argc > 0 && argv != NULL) {
234 		strncpy(booted_kernel_storage, argv[0],
235 		    sizeof(booted_kernel_storage));
236 		for (int i = 1; i < argc; i++) {
237 			char *cp = argv[i];
238 
239 			switch (*cp) {
240 			case 'b':
241 				/* boot device: -b=sd0 etc. */
242 				cp = cp + 2;
243 				if (strcmp(cp, MOUNT_NFS) == 0)
244 					rootfstype = MOUNT_NFS;
245 				else
246 					strncpy(boot_file, cp,
247 					    sizeof(boot_file));
248 				break;
249 
250 			default:
251 				BOOT_FLAG(*cp, boothowto);
252 				break;
253 			}
254 		}
255 	}
256 
257 	/* copy bootinfo into known kernel space */
258 	if (bi != NULL)
259 		bootinfo_storage = *bi;
260 	bootinfo = &bootinfo_storage;
261 
262 #ifdef BOOTINFO_FB_WIDTH
263 	bootinfo->fb_line_bytes = BOOTINFO_FB_LINE_BYTES;
264 	bootinfo->fb_width = BOOTINFO_FB_WIDTH;
265 	bootinfo->fb_height = BOOTINFO_FB_HEIGHT;
266 	bootinfo->fb_type = BOOTINFO_FB_TYPE;
267 #endif
268 
269 	if (bootinfo->magic == BOOTINFO_MAGIC) {
270 		platid.dw.dw0 = bootinfo->platid_cpu;
271 		platid.dw.dw1 = bootinfo->platid_machine;
272 
273 #ifndef RTC_OFFSET
274 		/*
275 		 * rtc_offset from bootinfo.timezone set by hpcboot.exe
276 		 */
277 		if (rtc_offset == 0 &&
278 		    (bootinfo->timezone > (-12 * 60) &&
279 		     bootinfo->timezone <= (12 * 60)))
280 			rtc_offset = bootinfo->timezone;
281 #endif
282 	}
283 
284 #ifdef KLOADER
285 	/* copy boot parameter for kloader */
286 	kloader_bootinfo_set(&kbootinfo, argc, argv, bi, false);
287 #endif
288 
289 	/*
290 	 * Heads up ... Setup the CPU / MMU / TLB functions.
291 	 */
292 	set_cpufuncs();
293 	IRQdisable;
294 
295 #if defined(CPU_SA1100) || defined(CPU_SA1110)
296 	return init_sa11x0(argc, argv, bi);
297 #elif defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270)
298 	return init_pxa2x0(argc, argv, bi);
299 #else
300 #error	No CPU support
301 #endif
302 }
303 
304 #ifdef BOOT_DUMP
305 static void
306 dumppages(char *start, int nbytes)
307 {
308 	char *p = start;
309 	char *p1;
310 	int i;
311 
312 	for (i = nbytes; i > 0; i -= 16, p += 16) {
313 		for (p1 = p + 15; p != p1; p1--) {
314 			if (*p1)
315 				break;
316 		}
317 		if (!*p1)
318 			continue;
319 		printf("%08x %02x %02x %02x %02x %02x %02x %02x %02x"
320 		    " %02x %02x %02x %02x %02x %02x %02x %02x\n",
321 		    (unsigned int)p,
322 		    p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
323 		    p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
324 	}
325 }
326 #endif
327