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