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