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