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