1 /* $NetBSD: hpc_machdep.c,v 1.105 2018/03/16 12:10:16 ryo 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.105 2018/03/16 12:10:16 ryo 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 u_int initarm(int, char **, struct bootinfo *); 107 #if defined(CPU_SA1100) || defined(CPU_SA1110) 108 u_int init_sa11x0(int, char **, struct bootinfo *); 109 #endif 110 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) 111 u_int 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 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 203 machine_sleep(void) 204 { 205 206 if (__sleep_func != NULL) 207 __sleep_func(__sleep_ctx); 208 } 209 210 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 u_int 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 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