1*bee3dfabSskrll /* $NetBSD: hpc_machdep.c,v 1.106 2019/07/16 14:41:49 skrll Exp $ */
2c98cd6c0Sichiro
3c98cd6c0Sichiro /*
4c98cd6c0Sichiro * Copyright (c) 1994-1998 Mark Brinicombe.
5c98cd6c0Sichiro * Copyright (c) 1994 Brini.
6c98cd6c0Sichiro * All rights reserved.
7c98cd6c0Sichiro *
8c98cd6c0Sichiro * This code is derived from software written for Brini by Mark Brinicombe
9c98cd6c0Sichiro *
10c98cd6c0Sichiro * Redistribution and use in source and binary forms, with or without
11c98cd6c0Sichiro * modification, are permitted provided that the following conditions
12c98cd6c0Sichiro * are met:
13c98cd6c0Sichiro * 1. Redistributions of source code must retain the above copyright
14c98cd6c0Sichiro * notice, this list of conditions and the following disclaimer.
15c98cd6c0Sichiro * 2. Redistributions in binary form must reproduce the above copyright
16c98cd6c0Sichiro * notice, this list of conditions and the following disclaimer in the
17c98cd6c0Sichiro * documentation and/or other materials provided with the distribution.
18c98cd6c0Sichiro * 3. All advertising materials mentioning features or use of this software
19c98cd6c0Sichiro * must display the following acknowledgement:
20c98cd6c0Sichiro * This product includes software developed by Brini.
21c98cd6c0Sichiro * 4. The name of the company nor the name of the author may be used to
22c98cd6c0Sichiro * endorse or promote products derived from this software without specific
23c98cd6c0Sichiro * prior written permission.
24c98cd6c0Sichiro *
25c98cd6c0Sichiro * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
26c98cd6c0Sichiro * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
27c98cd6c0Sichiro * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28c98cd6c0Sichiro * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29c98cd6c0Sichiro * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30c98cd6c0Sichiro * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31c98cd6c0Sichiro * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32c98cd6c0Sichiro * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33c98cd6c0Sichiro * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34c98cd6c0Sichiro * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35c98cd6c0Sichiro * SUCH DAMAGE.
36c0a37e6eSpeter */
37c0a37e6eSpeter
38c0a37e6eSpeter /*
39c0a37e6eSpeter * Machine dependent functions for kernel setup.
40c98cd6c0Sichiro */
41c98cd6c0Sichiro
4208716eaeSlukem #include <sys/cdefs.h>
43*bee3dfabSskrll __KERNEL_RCSID(0, "$NetBSD: hpc_machdep.c,v 1.106 2019/07/16 14:41:49 skrll Exp $");
441e92636eSnonaka
451e92636eSnonaka #include "opt_cputypes.h"
461e92636eSnonaka #include "opt_kloader.h"
471e92636eSnonaka #ifndef KLOADER_KERNEL_PATH
481e92636eSnonaka #define KLOADER_KERNEL_PATH "/netbsd"
491e92636eSnonaka #endif
50c98cd6c0Sichiro
51c98cd6c0Sichiro #include <sys/param.h>
52c98cd6c0Sichiro #include <sys/kernel.h>
531e92636eSnonaka #include <sys/boot_flag.h>
541e92636eSnonaka #include <sys/mount.h>
557aed473aSuebayasi #include <sys/pmf.h>
561e92636eSnonaka #include <sys/reboot.h>
57aa45c3c1Smatt #include <sys/cpu.h>
58c98cd6c0Sichiro
59c98cd6c0Sichiro #include <uvm/uvm.h>
60c98cd6c0Sichiro
61aa45c3c1Smatt #include <arm/locore.h>
62c0a37e6eSpeter
63c0a37e6eSpeter #include <machine/bootconfig.h>
64c0a37e6eSpeter #include <machine/bootinfo.h>
651e92636eSnonaka #include <machine/platid.h>
66b62fc9e2Snonaka #include <machine/pmap.h>
671e92636eSnonaka #ifdef KLOADER
681e92636eSnonaka #include <machine/kloader.h>
691e92636eSnonaka #endif
70422658daSichiro
71c0a37e6eSpeter #include <dev/cons.h>
72a3d9242eSpeter #include <dev/hpc/apm/apmvar.h>
73c98cd6c0Sichiro
74c98cd6c0Sichiro BootConfig bootconfig; /* Boot config storage */
751e92636eSnonaka #ifdef KLOADER
761e92636eSnonaka struct kloader_bootinfo kbootinfo;
771e92636eSnonaka static char kernel_path[] = KLOADER_KERNEL_PATH;
781e92636eSnonaka #endif
79c98cd6c0Sichiro struct bootinfo *bootinfo, bootinfo_storage;
80b62fc9e2Snonaka char booted_kernel_storage[80];
81a039bd91Smatt extern char *booted_kernel;
82c98cd6c0Sichiro
833180bc6aStoshii paddr_t physical_start;
843180bc6aStoshii paddr_t physical_freestart;
853180bc6aStoshii paddr_t physical_freeend;
863180bc6aStoshii paddr_t physical_end;
87c98cd6c0Sichiro
88c98cd6c0Sichiro #ifndef PMAP_STATIC_L1S
89c98cd6c0Sichiro int max_processes = 64; /* Default number */
90c98cd6c0Sichiro #endif /* !PMAP_STATIC_L1S */
91c98cd6c0Sichiro
92c98cd6c0Sichiro char *boot_args = NULL;
93aa2f38ffStoshii char boot_file[16];
94c98cd6c0Sichiro
95079445e7Smatt paddr_t msgbufphys;
96c98cd6c0Sichiro
97b62fc9e2Snonaka /* Prototypes */
98b62fc9e2Snonaka void dumpsys(void);
99c45f5707Sthorpej
100f151a2cfSpeter /* Mode dependent sleep function holder */
101f151a2cfSpeter void (*__sleep_func)(void *);
102f151a2cfSpeter void *__sleep_ctx;
103f151a2cfSpeter
104e02d755cSjoerg void (*__cpu_reset)(void) __dead = cpu_reset;
1050c580269Snonaka
106*bee3dfabSskrll vaddr_t initarm(int, char **, struct bootinfo *);
1071e92636eSnonaka #if defined(CPU_SA1100) || defined(CPU_SA1110)
108*bee3dfabSskrll vaddr_t init_sa11x0(int, char **, struct bootinfo *);
1091e92636eSnonaka #endif
1101e92636eSnonaka #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270)
111*bee3dfabSskrll vaddr_t init_pxa2x0(int, char **, struct bootinfo *);
1121e92636eSnonaka #endif
1131e92636eSnonaka
114c98cd6c0Sichiro #ifdef BOOT_DUMP
115b62fc9e2Snonaka void dumppages(char *, int);
116c98cd6c0Sichiro #endif
117c98cd6c0Sichiro
118c98cd6c0Sichiro /*
119ab405b20Speter * Reboots the system.
120c98cd6c0Sichiro *
121c98cd6c0Sichiro * Deal with any syncing, unmounting, dumping and shutdown hooks,
122c98cd6c0Sichiro * then reset the CPU.
123c98cd6c0Sichiro */
124c98cd6c0Sichiro void
cpu_reboot(int howto,char * bootstr)125ab405b20Speter cpu_reboot(int howto, char *bootstr)
126c98cd6c0Sichiro {
1271e92636eSnonaka
128c98cd6c0Sichiro /*
129c98cd6c0Sichiro * If we are still cold then hit the air brakes
130ab405b20Speter * and crash to earth fast.
131c98cd6c0Sichiro */
132c98cd6c0Sichiro if (cold) {
133c98cd6c0Sichiro doshutdownhooks();
13494d98572Sdyoung pmf_system_shutdown(boothowto);
135c98cd6c0Sichiro printf("Halted while still in the ICE age.\n");
136c98cd6c0Sichiro printf("The operating system has halted.\n");
137c98cd6c0Sichiro printf("Please press any key to reboot.\n\n");
138c98cd6c0Sichiro cngetc();
139c98cd6c0Sichiro printf("rebooting...\n");
1400c580269Snonaka __cpu_reset();
141c98cd6c0Sichiro /* NOTREACHED */
142c98cd6c0Sichiro }
143c98cd6c0Sichiro
144f151a2cfSpeter /* Reset the sleep function. */
145f151a2cfSpeter __sleep_func = NULL;
146f151a2cfSpeter __sleep_ctx = NULL;
147f151a2cfSpeter
148c0a37e6eSpeter /* Disable console buffering. */
149c98cd6c0Sichiro cnpollc(1);
150c98cd6c0Sichiro
1511e92636eSnonaka #ifdef KLOADER
1521e92636eSnonaka if ((howto & RB_HALT) == 0) {
1531e92636eSnonaka if (howto & RB_STRING) {
1541e92636eSnonaka kloader_reboot_setup(bootstr);
1551e92636eSnonaka } else {
1561e92636eSnonaka kloader_reboot_setup(kernel_path);
1571e92636eSnonaka }
1581e92636eSnonaka }
1591e92636eSnonaka #endif
1601e92636eSnonaka
161c98cd6c0Sichiro /*
162c98cd6c0Sichiro * If RB_NOSYNC was not specified sync the discs.
163ab405b20Speter * Note: Unless cold is set to 1 here, syslogd will die during
164ab405b20Speter * the unmount. It looks like syslogd is getting woken up only
165ab405b20Speter * to find that it cannot page part of the binary in as the
166ab405b20Speter * file system has been unmounted.
167c98cd6c0Sichiro */
168c98cd6c0Sichiro if (!(howto & RB_NOSYNC))
169c98cd6c0Sichiro bootsync();
170c98cd6c0Sichiro
171c0a37e6eSpeter /* Say NO to interrupts. */
172c0a37e6eSpeter (void)splhigh();
173c98cd6c0Sichiro
174c98cd6c0Sichiro /* Do a dump if requested. */
175c98cd6c0Sichiro if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
176c98cd6c0Sichiro dumpsys();
177c98cd6c0Sichiro
178c0a37e6eSpeter /* Run any shutdown hooks. */
179c98cd6c0Sichiro doshutdownhooks();
180c98cd6c0Sichiro
18194d98572Sdyoung pmf_system_shutdown(boothowto);
18294d98572Sdyoung
183c0a37e6eSpeter /* Make sure IRQs are disabled. */
184c98cd6c0Sichiro IRQdisable;
185c98cd6c0Sichiro
186c98cd6c0Sichiro if (howto & RB_HALT) {
187c98cd6c0Sichiro printf("The operating system has halted.\n");
188c98cd6c0Sichiro printf("Please press any key to reboot.\n\n");
189c98cd6c0Sichiro cngetc();
1901e92636eSnonaka #ifdef KLOADER
1911e92636eSnonaka } else {
1921e92636eSnonaka kloader_reboot();
1931e92636eSnonaka /* NOTREACHED */
1941e92636eSnonaka #endif
195c98cd6c0Sichiro }
196c98cd6c0Sichiro
197c98cd6c0Sichiro printf("rebooting...\n");
1980c580269Snonaka __cpu_reset();
199c98cd6c0Sichiro /* NOTREACHED */
200c98cd6c0Sichiro }
201c98cd6c0Sichiro
2029221ef3bStoshii void
machine_sleep(void)203c0a37e6eSpeter machine_sleep(void)
204c0a37e6eSpeter {
205c0a37e6eSpeter
206c0a37e6eSpeter if (__sleep_func != NULL)
207c0a37e6eSpeter __sleep_func(__sleep_ctx);
208c0a37e6eSpeter }
209c0a37e6eSpeter
210c0a37e6eSpeter void
machine_standby(void)211c0a37e6eSpeter machine_standby(void)
212c0a37e6eSpeter {
213c0a37e6eSpeter }
214c0a37e6eSpeter
2151e92636eSnonaka /*
2161e92636eSnonaka * Initial entry point on startup. This gets called before main() is
2171e92636eSnonaka * entered.
2181e92636eSnonaka * It should be responsible for setting up everything that must be
2191e92636eSnonaka * in place when main is called.
2201e92636eSnonaka * This includes:
2211e92636eSnonaka * Taking a copy of the boot configuration structure.
2221e92636eSnonaka */
223*bee3dfabSskrll vaddr_t
initarm(int argc,char ** argv,struct bootinfo * bi)2241e92636eSnonaka initarm(int argc, char **argv, struct bootinfo *bi)
2251e92636eSnonaka {
2261e92636eSnonaka
2271e92636eSnonaka __sleep_func = NULL;
2281e92636eSnonaka __sleep_ctx = NULL;
2291e92636eSnonaka
2301e92636eSnonaka /* parse kernel args */
231a039bd91Smatt booted_kernel = booted_kernel_storage;
2321e92636eSnonaka boothowto = 0;
2331e92636eSnonaka boot_file[0] = '\0';
2341e92636eSnonaka if (argc > 0 && argv != NULL) {
2351e92636eSnonaka strncpy(booted_kernel_storage, argv[0],
2361e92636eSnonaka sizeof(booted_kernel_storage));
2371e92636eSnonaka for (int i = 1; i < argc; i++) {
2381e92636eSnonaka char *cp = argv[i];
2391e92636eSnonaka
2401e92636eSnonaka switch (*cp) {
2411e92636eSnonaka case 'b':
2421e92636eSnonaka /* boot device: -b=sd0 etc. */
2431e92636eSnonaka cp = cp + 2;
2441e92636eSnonaka if (strcmp(cp, MOUNT_NFS) == 0)
2451e92636eSnonaka rootfstype = MOUNT_NFS;
2461e92636eSnonaka else
2471e92636eSnonaka strncpy(boot_file, cp,
2481e92636eSnonaka sizeof(boot_file));
2491e92636eSnonaka break;
2501e92636eSnonaka
2511e92636eSnonaka default:
2521e92636eSnonaka BOOT_FLAG(*cp, boothowto);
2531e92636eSnonaka break;
2541e92636eSnonaka }
2551e92636eSnonaka }
2561e92636eSnonaka }
2571e92636eSnonaka
2581e92636eSnonaka /* copy bootinfo into known kernel space */
2591e92636eSnonaka if (bi != NULL)
2601e92636eSnonaka bootinfo_storage = *bi;
2611e92636eSnonaka bootinfo = &bootinfo_storage;
2621e92636eSnonaka
2631e92636eSnonaka #ifdef BOOTINFO_FB_WIDTH
2641e92636eSnonaka bootinfo->fb_line_bytes = BOOTINFO_FB_LINE_BYTES;
2651e92636eSnonaka bootinfo->fb_width = BOOTINFO_FB_WIDTH;
2661e92636eSnonaka bootinfo->fb_height = BOOTINFO_FB_HEIGHT;
2671e92636eSnonaka bootinfo->fb_type = BOOTINFO_FB_TYPE;
2681e92636eSnonaka #endif
2691e92636eSnonaka
2701e92636eSnonaka if (bootinfo->magic == BOOTINFO_MAGIC) {
2711e92636eSnonaka platid.dw.dw0 = bootinfo->platid_cpu;
2721e92636eSnonaka platid.dw.dw1 = bootinfo->platid_machine;
2731e92636eSnonaka
2741e92636eSnonaka #ifndef RTC_OFFSET
2751e92636eSnonaka /*
2761e92636eSnonaka * rtc_offset from bootinfo.timezone set by hpcboot.exe
2771e92636eSnonaka */
2781e92636eSnonaka if (rtc_offset == 0 &&
2791e92636eSnonaka (bootinfo->timezone > (-12 * 60) &&
2801e92636eSnonaka bootinfo->timezone <= (12 * 60)))
2811e92636eSnonaka rtc_offset = bootinfo->timezone;
2821e92636eSnonaka #endif
2831e92636eSnonaka }
2841e92636eSnonaka
2851e92636eSnonaka #ifdef KLOADER
2861e92636eSnonaka /* copy boot parameter for kloader */
2871e92636eSnonaka kloader_bootinfo_set(&kbootinfo, argc, argv, bi, false);
2881e92636eSnonaka #endif
2891e92636eSnonaka
2901e92636eSnonaka /*
2911e92636eSnonaka * Heads up ... Setup the CPU / MMU / TLB functions.
2921e92636eSnonaka */
2931e92636eSnonaka set_cpufuncs();
2941e92636eSnonaka IRQdisable;
2951e92636eSnonaka
2961e92636eSnonaka #if defined(CPU_SA1100) || defined(CPU_SA1110)
2971e92636eSnonaka return init_sa11x0(argc, argv, bi);
2981e92636eSnonaka #elif defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270)
2991e92636eSnonaka return init_pxa2x0(argc, argv, bi);
3001e92636eSnonaka #else
3011e92636eSnonaka #error No CPU support
3021e92636eSnonaka #endif
3031e92636eSnonaka }
3041e92636eSnonaka
305c98cd6c0Sichiro #ifdef BOOT_DUMP
306d5929c35Sryo void
dumppages(char * start,int nbytes)307c0a37e6eSpeter dumppages(char *start, int nbytes)
308c98cd6c0Sichiro {
309c98cd6c0Sichiro char *p = start;
310c98cd6c0Sichiro char *p1;
311c98cd6c0Sichiro int i;
312c98cd6c0Sichiro
313c98cd6c0Sichiro for (i = nbytes; i > 0; i -= 16, p += 16) {
314c98cd6c0Sichiro for (p1 = p + 15; p != p1; p1--) {
315c98cd6c0Sichiro if (*p1)
316c98cd6c0Sichiro break;
317c98cd6c0Sichiro }
318c98cd6c0Sichiro if (!*p1)
319c98cd6c0Sichiro continue;
320c98cd6c0Sichiro printf("%08x %02x %02x %02x %02x %02x %02x %02x %02x"
321c98cd6c0Sichiro " %02x %02x %02x %02x %02x %02x %02x %02x\n",
322c98cd6c0Sichiro (unsigned int)p,
323c98cd6c0Sichiro p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
324c98cd6c0Sichiro p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
325c98cd6c0Sichiro }
326c98cd6c0Sichiro }
327c98cd6c0Sichiro #endif
328