machdep.c revision 1.5
1/* $NetBSD: machdep.c,v 1.5 2019/04/01 06:33:57 simonb Exp $ */ 2 3/* 4 * Copyright 2000, 2001 5 * Broadcom Corporation. All rights reserved. 6 * 7 * This software is furnished under license and may be used and copied only 8 * in accordance with the following terms and conditions. Subject to these 9 * conditions, you may download, copy, install, use, modify and distribute 10 * modified or unmodified copies of this software in source and/or binary 11 * form. No title or ownership is transferred hereby. 12 * 13 * 1) Any source code used, modified or distributed must reproduce and 14 * retain this copyright notice and list of conditions as they appear in 15 * the source file. 16 * 17 * 2) No right is granted to use any trade name, trademark, or logo of 18 * Broadcom Corporation. The "Broadcom Corporation" name may not be 19 * used to endorse or promote products derived from this software 20 * without the prior written permission of Broadcom Corporation. 21 * 22 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED 23 * WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF 24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR 25 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE 26 * FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE 27 * LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 32 * OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35/* 36 * Copyright (c) 2000 Soren S. Jorvang. All rights reserved. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 1. Redistributions of source code must retain the above copyright 42 * notice, this list of conditions, and the following disclaimer. 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 47 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 48 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 50 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 51 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 57 * SUCH DAMAGE. 58 */ 59 60#include <sys/cdefs.h> 61__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.5 2019/04/01 06:33:57 simonb Exp $"); 62 63#include "opt_ddb.h" 64#include "opt_execfmt.h" 65#include "opt_modular.h" 66 67#include <sys/param.h> 68#include <sys/buf.h> 69#include <sys/conf.h> 70#include <sys/cpu.h> 71#include <sys/device.h> 72#include <sys/exec.h> 73#include <sys/file.h> 74#include <sys/intr.h> 75#include <sys/kcore.h> 76#include <sys/kernel.h> 77#include <sys/ksyms.h> 78#include <sys/malloc.h> 79#include <sys/mbuf.h> 80#include <sys/mount.h> 81#include <sys/msgbuf.h> 82#include <sys/proc.h> 83#include <sys/reboot.h> 84#include <sys/syscallargs.h> 85#include <sys/systm.h> 86 87#include <uvm/uvm_extern.h> 88 89#include <mips/locore.h> 90#include <mips/psl.h> 91#include <mips/pte.h> 92#include <mips/reg.h> 93 94#include <mips/cfe/cfe_api.h> 95 96#include <evbmips/sbmips/autoconf.h> 97#include <evbmips/sbmips/swarm.h> 98#include <evbmips/sbmips/systemsw.h> 99 100#if 0 /* XXXCGD */ 101#include <evbmips/sbmips/nvram.h> 102#endif /* XXXCGD */ 103#include <evbmips/sbmips/leds.h> 104 105#include <mips/sibyte/dev/sbbuswatchvar.h> 106 107#include "ksyms.h" 108 109#if NKSYMS || defined(DDB) || defined(MODULAR) 110#include <mips/db_machdep.h> 111#include <ddb/db_access.h> 112#include <ddb/db_sym.h> 113#include <ddb/db_extern.h> 114#include <sys/exec_elf.h> 115#endif 116 117#include <dev/cons.h> 118 119#if NKSYMS || defined(DDB) || defined(MODULAR) 120/* start and end of kernel symbol table */ 121void *ksym_start, *ksym_end; 122#endif 123 124/* Maps for VM objects. */ 125struct vm_map *phys_map = NULL; 126 127char bootstring[512]; /* Boot command */ 128int netboot; /* Are we netbooting? */ 129int cfe_present; 130 131struct bootinfo_v1 bootinfo; 132 133phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 134int mem_cluster_cnt; 135 136void configure(void); 137void mach_init(long, long, long, long); 138 139extern void *esym; 140 141#ifdef _LP64 142/* 143 * We do this KSEG0 to PHYS to KSEG0 dance if running 64-bit because 144 * CFE passes in parameters as 32-bit addresses. When used as a 64-bit 145 * address these CFE parameters are in user (XKUSEG) space and can't be 146 * accessed! Convert these to a physical address and and then to the 147 * proper KSEG0 address so we can use them in the kernel. 148 */ 149#define CFE_TO_KERNEL_PTR(x) MIPS_PHYS_TO_KSEG0(MIPS_KSEG0_TO_PHYS(x)) 150#else 151#define CFE_TO_KERNEL_PTR(x) (x) 152#endif 153 154/* 155 * Do all the stuff that locore normally does before calling main(). 156 */ 157void 158mach_init(long fwhandle, long magic, long bootdata, long reserved) 159{ 160 void *kernend; 161 extern char edata[], end[]; 162 uint32_t config; 163 164 /* XXX this code must run on the target CPU */ 165 config = mips3_cp0_config_read(); 166 config &= ~MIPS3_CONFIG_K0_MASK; 167 config |= 0x05; /* XXX. cacheable coherent */ 168 mips3_cp0_config_write(config); 169 170 /* Zero BSS. XXXCGD: uh, is this really necessary still? */ 171 memset(edata, 0, end - edata); 172 173 /* 174 * Copy the bootinfo structure from the boot loader. 175 * this has to be done before mips_vector_init is 176 * called because we may need CFE's TLB handler 177 */ 178 179 if (magic == BOOTINFO_MAGIC) 180 memcpy(&bootinfo, (struct bootinfo_v1 *)bootdata, 181 sizeof bootinfo); 182 else if (reserved == CFE_EPTSEAL) { 183 magic = BOOTINFO_MAGIC; 184 memset(&bootinfo, 0, sizeof bootinfo); 185 bootinfo.version = BOOTINFO_VERSION; 186 bootinfo.fwhandle = fwhandle; 187 bootinfo.fwentry = bootdata; 188 bootinfo.ssym = (vaddr_t)end; 189 bootinfo.esym = (vaddr_t)end; 190 } 191 192 kernend = (void *)mips_round_page(end); 193#if NKSYMS || defined(DDB) || defined(MODULAR) 194 if (magic == BOOTINFO_MAGIC) { 195 ksym_start = (void *)CFE_TO_KERNEL_PTR(bootinfo.ssym); 196 ksym_end = (void *)CFE_TO_KERNEL_PTR(bootinfo.esym); 197 kernend = (void *)mips_round_page((vaddr_t)ksym_end); 198 } 199#endif 200 201 consinit(); 202 203 uvm_md_init(); 204 205 /* 206 * Copy exception-dispatch code down to exception vector. 207 * Initialize locore-function vector. 208 * Clear out the I and D caches. 209 */ 210#ifdef MULTIPROCESSOR 211 mips_vector_init(NULL, true); 212#else 213 mips_vector_init(NULL, false); 214#endif 215 216 mips_locoresw.lsw_bus_error = sibyte_bus_watch_check; 217 218 sb1250_ipl_map_init(); 219 220#ifdef DEBUG 221 printf("fwhandle=%08X magic=%08X bootdata=%08X reserved=%08X\n", 222 (u_int)fwhandle, (u_int)magic, (u_int)bootdata, (u_int)reserved); 223#endif 224 225 cpu_setmodel("sb1250"); 226 227 if (magic == BOOTINFO_MAGIC) { 228 int idx; 229 int added; 230 uint64_t start, len, type; 231 232 cfe_init(CFE_TO_KERNEL_PTR(bootinfo.fwhandle), 233 CFE_TO_KERNEL_PTR(bootinfo.fwentry)); 234 cfe_present = 1; 235 236 idx = 0; 237 physmem = 0; 238 mem_cluster_cnt = 0; 239 while (cfe_enummem(idx, 0, &start, &len, &type) == 0) { 240 added = 0; 241 printf("Memory Block #%d start %08"PRIx64" len %08"PRIx64": %s: ", 242 idx, start, len, (type == CFE_MI_AVAILABLE) ? 243 "Available" : "Reserved"); 244 if ((type == CFE_MI_AVAILABLE) && 245 (mem_cluster_cnt < VM_PHYSSEG_MAX)) { 246 /* 247 * XXX Ignore memory above 256MB for now, it 248 * XXX needs special handling. 249 */ 250 if (start < (256*1024*1024)) { 251 physmem += btoc(((int) len)); 252 mem_clusters[mem_cluster_cnt].start = 253 (long) start; 254 mem_clusters[mem_cluster_cnt].size = 255 (long) len; 256 mem_cluster_cnt++; 257 added = 1; 258 } 259 } 260 if (added) 261 printf("added to map\n"); 262 else 263 printf("not added to map\n"); 264 idx++; 265 } 266 267 } else { 268 /* 269 * Handle the case of not being called from the firmware. 270 */ 271 /* XXX hardwire to 32MB; should be kernel config option */ 272 physmem = 32 * 1024 * 1024 / 4096; 273 mem_clusters[0].start = 0; 274 mem_clusters[0].size = ctob(physmem); 275 mem_cluster_cnt = 1; 276 } 277 278 279 for (u_int i = 0; i < sizeof(bootinfo.boot_flags); i++) { 280 switch (bootinfo.boot_flags[i]) { 281 case '\0': 282 break; 283 case ' ': 284 continue; 285 case '-': 286 while (bootinfo.boot_flags[i] != ' ' && 287 bootinfo.boot_flags[i] != '\0') { 288 switch (bootinfo.boot_flags[i]) { 289 case 'a': 290 boothowto |= RB_ASKNAME; 291 break; 292 case 'd': 293 boothowto |= RB_KDB; 294 break; 295 case 's': 296 boothowto |= RB_SINGLE; 297 break; 298 } 299 i++; 300 } 301 } 302 } 303 304 /* 305 * Load the rest of the available pages into the VM system. 306 */ 307 mips_page_physload(MIPS_KSEG0_START, (vaddr_t) kernend, 308 mem_clusters, mem_cluster_cnt, NULL, 0); 309 310 /* 311 * Initialize error message buffer (at end of core). 312 */ 313 mips_init_msgbuf(); 314 315 pmap_bootstrap(); 316 317 /* 318 * Allocate uarea for lwp0 and set it. 319 */ 320 mips_init_lwp0_uarea(); 321 322 /* 323 * Initialize debuggers, and break into them, if appropriate. 324 */ 325#if NKSYMS || defined(DDB) || defined(MODULAR) 326 ksyms_addsyms_elf(((uintptr_t)ksym_end - (uintptr_t)ksym_start), 327 ksym_start, ksym_end); 328#endif 329 330 if (boothowto & RB_KDB) { 331#if defined(DDB) 332 Debugger(); 333#endif 334 } 335 336#ifdef MULTIPROCESSOR 337 mips_fixup_exceptions(mips_fixup_zero_relative); 338#endif 339} 340 341/* 342 * Allocate memory for variable-sized tables, 343 */ 344void 345cpu_startup(void) 346{ 347 /* 348 * Just do the common stuff. 349 */ 350 cpu_startup_common(); 351} 352 353int waittime = -1; 354 355void 356cpu_reboot(int howto, char *bootstr) 357{ 358 359 /* Take a snapshot before clobbering any registers. */ 360 savectx(curpcb); 361 362 if (cold) { 363 howto |= RB_HALT; 364 goto haltsys; 365 } 366 367 /* If "always halt" was specified as a boot flag, obey. */ 368 if (boothowto & RB_HALT) 369 howto |= RB_HALT; 370 371 boothowto = howto; 372 if ((howto & RB_NOSYNC) == 0 && (waittime < 0)) { 373 waittime = 0; 374 vfs_shutdown(); 375 376 /* 377 * If we've been adjusting the clock, the todr 378 * will be out of synch; adjust it now. 379 */ 380 resettodr(); 381 } 382 383 splhigh(); 384 385 if (howto & RB_DUMP) 386 dumpsys(); 387 388haltsys: 389 doshutdownhooks(); 390 391 pmf_system_shutdown(boothowto); 392 393 if (howto & RB_HALT) { 394 printf("\n"); 395 printf("The operating system has halted.\n"); 396 printf("Please press any key to reboot.\n\n"); 397 cnpollc(1); /* For proper keyboard command handling */ 398 cngetc(); 399 cnpollc(0); 400 } 401 402 printf("rebooting...\n\n"); 403 404 if (cfe_present) { 405 /* 406 * XXX 407 * For some reason we can't return to CFE with 408 * and do a warm start. Need to look into this... 409 */ 410 cfe_exit(0, (howto & RB_DUMP) ? 1 : 0); 411 printf("cfe_exit didn't!\n"); 412 } 413 414 printf("WARNING: reboot failed!\n"); 415 416 for (;;); 417} 418 419static void 420cswarm_setled(u_int index, char c) 421{ 422 volatile u_char *led_ptr = 423 (void *)MIPS_PHYS_TO_KSEG1(SWARM_LEDS_PHYS); 424 425 if (index < 4) 426 led_ptr[0x20 + ((3 - index) << 3)] = c; 427} 428 429void 430cswarm_setleds(const char *str) 431{ 432 int i; 433 434 for (i = 0; i < 4 && str[i]; i++) 435 cswarm_setled(i, str[i]); 436 for (; i < 4; i++) 437 cswarm_setled(' ', str[i]); 438} 439 440int 441sbmips_cca_for_pa(paddr_t pa) 442{ 443 int rv; 444 445 rv = 2; /* Uncached. */ 446 447 /* Check each DRAM region. */ 448 if ((pa >= 0x0000000000 && pa <= 0x000fffffff) || /* DRAM 0 */ 449 (pa >= 0x0080000000 && pa <= 0x008fffffff) || /* DRAM 1 */ 450 (pa >= 0x0090000000 && pa <= 0x009fffffff) || /* DRAM 2 */ 451 (pa >= 0x00c0000000 && pa <= 0x00cfffffff) || /* DRAM 3 */ 452#ifdef _MIPS_PADDR_T_64BIT 453 (pa >= 0x0100000000LL && pa <= 0x07ffffffffLL) || /* DRAM exp */ 454#endif 455 0) { 456 rv = 5; /* Cacheable coherent. */ 457 } 458 459 return (rv); 460} 461