1 /* $NetBSD: machdep.c,v 1.23 2020/08/17 07:50:42 simonb Exp $ */ 2 3 /* 4 * Copyright 2001, 2002 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Jason R. Thorpe and Simon Burge for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 /* 39 * Copyright (c) 1992, 1993 40 * The Regents of the University of California. All rights reserved. 41 * 42 * This code is derived from software contributed to Berkeley by 43 * the Systems Programming Group of the University of Utah Computer 44 * Science Department, The Mach Operating System project at 45 * Carnegie-Mellon University and Ralph Campbell. 46 * 47 * Redistribution and use in source and binary forms, with or without 48 * modification, are permitted provided that the following conditions 49 * are met: 50 * 1. Redistributions of source code must retain the above copyright 51 * notice, this list of conditions and the following disclaimer. 52 * 2. Redistributions in binary form must reproduce the above copyright 53 * notice, this list of conditions and the following disclaimer in the 54 * documentation and/or other materials provided with the distribution. 55 * 3. Neither the name of the University nor the names of its contributors 56 * may be used to endorse or promote products derived from this software 57 * without specific prior written permission. 58 * 59 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 62 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 69 * SUCH DAMAGE. 70 * 71 * @(#)machdep.c 8.3 (Berkeley) 1/12/94 72 * from: Utah Hdr: machdep.c 1.63 91/04/24 73 */ 74 /* 75 * Copyright (c) 1988 University of Utah. 76 * 77 * This code is derived from software contributed to Berkeley by 78 * the Systems Programming Group of the University of Utah Computer 79 * Science Department, The Mach Operating System project at 80 * Carnegie-Mellon University and Ralph Campbell. 81 * 82 * Redistribution and use in source and binary forms, with or without 83 * modification, are permitted provided that the following conditions 84 * are met: 85 * 1. Redistributions of source code must retain the above copyright 86 * notice, this list of conditions and the following disclaimer. 87 * 2. Redistributions in binary form must reproduce the above copyright 88 * notice, this list of conditions and the following disclaimer in the 89 * documentation and/or other materials provided with the distribution. 90 * 3. All advertising materials mentioning features or use of this software 91 * must display the following acknowledgement: 92 * This product includes software developed by the University of 93 * California, Berkeley and its contributors. 94 * 4. Neither the name of the University nor the names of its contributors 95 * may be used to endorse or promote products derived from this software 96 * without specific prior written permission. 97 * 98 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 99 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 100 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 101 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 102 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 103 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 104 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 105 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 106 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 107 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 108 * SUCH DAMAGE. 109 * 110 * @(#)machdep.c 8.3 (Berkeley) 1/12/94 111 * from: Utah Hdr: machdep.c 1.63 91/04/24 112 */ 113 114 #include "opt_multiprocessor.h" 115 116 #include <sys/cdefs.h> 117 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.23 2020/08/17 07:50:42 simonb Exp $"); 118 119 #include <sys/param.h> 120 #include <sys/systm.h> 121 #include <sys/kernel.h> 122 #include <sys/buf.h> 123 #include <sys/cpu.h> 124 #include <sys/reboot.h> 125 #include <sys/mount.h> 126 #include <sys/kcore.h> 127 #include <sys/boot_flag.h> 128 #include <sys/termios.h> 129 #include <sys/ksyms.h> 130 131 #include <uvm/uvm_extern.h> 132 133 #include <dev/cons.h> 134 135 #include "ksyms.h" 136 137 #if NKSYMS || defined(DDB) || defined(LKM) 138 #include <machine/db_machdep.h> 139 #include <ddb/db_extern.h> 140 #endif 141 142 #include <machine/psl.h> 143 #include <machine/locore.h> 144 145 #include <mips/cavium/autoconf.h> 146 #include <mips/cavium/octeonvar.h> 147 #include <mips/cavium/include/iobusvar.h> 148 #include <mips/cavium/include/bootbusvar.h> 149 150 #include <mips/cavium/dev/octeon_uartvar.h> 151 #include <mips/cavium/dev/octeon_ciureg.h> 152 #include <mips/cavium/dev/octeon_gpioreg.h> 153 154 #include <evbmips/cavium/octeon_uboot.h> 155 156 #include <dev/fdt/fdtvar.h> 157 #include <dev/fdt/fdt_private.h> 158 159 static void mach_init_vector(void); 160 static void mach_init_bus_space(void); 161 static void mach_init_console(void); 162 static void mach_init_memory(void); 163 static void parse_boot_args(void); 164 165 #include "com.h" 166 #if NCOM > 0 167 #include <dev/ic/comreg.h> 168 #include <dev/ic/comvar.h> 169 int comcnrate = 115200; /* XXX should be config option */ 170 #endif /* NCOM > 0 */ 171 172 /* Maps for VM objects. */ 173 struct vm_map *phys_map = NULL; 174 175 int netboot; 176 177 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 178 int mem_cluster_cnt; 179 extern char kernel_text[]; 180 extern char edata[]; 181 extern char end[]; 182 183 void mach_init(uint64_t, uint64_t, uint64_t, uint64_t); 184 185 struct octeon_config octeon_configuration; 186 struct octeon_btdesc octeon_btdesc; 187 struct octeon_btinfo octeon_btinfo; 188 189 char octeon_nmi_stack[PAGE_SIZE] __section(".data1") __aligned(PAGE_SIZE); 190 191 /* Currently the OCTEON kernels only support big endian boards */ 192 CTASSERT(_BYTE_ORDER == _BIG_ENDIAN); 193 194 /* 195 * Do all the stuff that locore normally does before calling main(). 196 */ 197 void 198 mach_init(uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3) 199 { 200 uint64_t btinfo_paddr; 201 void *fdt_data; 202 203 /* clear the BSS segment */ 204 memset(edata, 0, end - edata); 205 206 cpu_reset_address = octeon_soft_reset; 207 208 #if 1 || defined(OCTEON_EARLY_CONSOLE) /* XXX - remove "1 ||" when MP works */ 209 /* 210 * Set up very conservative timer params so we can use delay(9) 211 * early. It doesn't matter if we delay too long at this stage. 212 */ 213 octeon_cal_timer(2000 * 1000 * 1000); 214 octuart_early_cnattach(comcnrate); 215 #endif /* OCTEON_EARLY_CONSOLE */ 216 217 KASSERT(MIPS_XKPHYS_P(arg3)); 218 btinfo_paddr = mips3_ld(arg3 + OCTEON_BTINFO_PADDR_OFFSET); 219 220 /* XXX KASSERT these addresses? */ 221 memcpy(&octeon_btdesc, (void *)arg3, sizeof(octeon_btdesc)); 222 if ((octeon_btdesc.obt_desc_ver == OCTEON_SUPPORTED_DESCRIPTOR_VERSION) && 223 (octeon_btdesc.obt_desc_size == sizeof(octeon_btdesc))) { 224 btinfo_paddr = MIPS_PHYS_TO_XKPHYS(CCA_CACHEABLE, 225 octeon_btdesc.obt_boot_info_addr); 226 } else { 227 panic("unknown boot descriptor size %u", 228 octeon_btdesc.obt_desc_size); 229 } 230 memcpy(&octeon_btinfo, (void *)btinfo_paddr, sizeof(octeon_btinfo)); 231 parse_boot_args(); 232 233 octeon_cal_timer(octeon_btinfo.obt_eclock_hz); 234 235 cpu_setmodel("Cavium Octeon %s", 236 octeon_cpu_model(mips_options.mips_cpu_id)); 237 238 if (octeon_btinfo.obt_minor_version >= 3 && 239 octeon_btinfo.obt_fdt_addr != 0) { 240 fdt_data = (void *)MIPS_PHYS_TO_XKPHYS(CCA_CACHEABLE, 241 octeon_btinfo.obt_fdt_addr); 242 fdtbus_init(fdt_data); 243 } 244 245 mach_init_vector(); 246 247 uvm_md_init(); 248 249 mach_init_bus_space(); 250 251 mach_init_console(); 252 253 #ifdef DEBUG 254 /* Show a couple of boot desc/info params for positive feedback */ 255 printf(">> boot desc eclock = %d\n", octeon_btdesc.obt_eclock); 256 printf(">> boot desc core mask = %#x\n", octeon_btinfo.obt_core_mask); 257 printf(">> boot info board = %d\n", octeon_btinfo.obt_board_type); 258 #endif /* DEBUG */ 259 260 mach_init_memory(); 261 262 /* 263 * Allocate uarea page for lwp0 and set it. 264 */ 265 mips_init_lwp0_uarea(); 266 267 #if 0 268 curcpu()->ci_nmi_stack = octeon_nmi_stack + sizeof(octeon_nmi_stack) - sizeof(struct kernframe); 269 *(uint64_t *)MIPS_PHYS_TO_KSEG0(0x800) = (intptr_t)octeon_reset_vector; 270 const uint64_t wdog_reg = MIPS_PHYS_TO_XKPHYS_UNCACHED(CIU_WDOG0); 271 uint64_t wdog = mips3_ld(wdog_reg); 272 wdog &= ~(CIU_WDOGX_MODE|CIU_WDOGX_LEN); 273 wdog |= __SHIFTIN(3, CIU_WDOGX_MODE); 274 wdog |= CIU_WDOGX_LEN; // max period 275 mips64_sd_a64(wdog_reg, wdog); 276 printf("Watchdog enabled!\n"); 277 #endif 278 279 #if defined(DDB) 280 if (boothowto & RB_KDB) 281 Debugger(); 282 #endif 283 } 284 285 void 286 consinit(void) 287 { 288 289 /* 290 * Everything related to console initialization is done 291 * in mach_init(). 292 */ 293 } 294 295 void 296 mach_init_vector(void) 297 { 298 299 /* Make sure exception base at 0 (MIPS_COP_0_EBASE) */ 300 __asm __volatile("mtc0 %0, $15, 1" : : "r"(0x80000000) ); 301 302 /* 303 * Set up the exception vectors and CPU-specific function 304 * vectors early on. We need the wbflush() vector set up 305 * before comcnattach() is called (or at least before the 306 * first printf() after that is called). 307 * Also clears the I+D caches. 308 */ 309 mips_vector_init(NULL, true); 310 } 311 312 void 313 mach_init_bus_space(void) 314 { 315 struct octeon_config *mcp = &octeon_configuration; 316 317 octeon_dma_init(mcp); 318 319 iobus_bootstrap(mcp); 320 bootbus_bootstrap(mcp); 321 } 322 323 void 324 mach_init_console(void) 325 { 326 #if NCOM > 0 327 struct octeon_config *mcp = &octeon_configuration; 328 int status; 329 extern int octuart_com_cnattach(bus_space_tag_t, int, int); 330 331 /* 332 * Delay to allow firmware putchars to complete. 333 * FIFO depth * character time. 334 * character time = (1000000 / (defaultrate / 10)) 335 */ 336 delay(640000000 / comcnrate); 337 338 status = octuart_com_cnattach( 339 &mcp->mc_iobus_bust, 340 0, /* XXX port 0 */ 341 comcnrate); 342 if (status != 0) 343 panic("can't initialize console!"); /* XXX print to nowhere! */ 344 #else 345 panic("octeon: not configured to use serial console"); 346 #endif /* NCOM > 0 */ 347 } 348 349 static void 350 mach_init_memory(void) 351 { 352 struct octeon_bootmem_desc *memdesc; 353 struct octeon_bootmem_block_header *block; 354 paddr_t blockaddr; 355 int i; 356 357 mem_cluster_cnt = 0; 358 359 if (octeon_btinfo.obt_phy_mem_desc_addr == 0) 360 panic("bootmem desc is missing"); 361 362 memdesc = (void *)MIPS_PHYS_TO_XKPHYS(CCA_CACHEABLE, 363 octeon_btinfo.obt_phy_mem_desc_addr); 364 printf("u-boot bootmem desc @ 0x%x version %d.%d\n", 365 octeon_btinfo.obt_phy_mem_desc_addr, 366 memdesc->bmd_major_version, memdesc->bmd_minor_version); 367 if (memdesc->bmd_major_version > 3) 368 panic("unhandled bootmem desc version %d.%d", 369 memdesc->bmd_major_version, memdesc->bmd_minor_version); 370 371 blockaddr = memdesc->bmd_head_addr; 372 if (blockaddr == 0) 373 panic("bootmem list is empty"); 374 375 for (i = 0; i < VM_PHYSSEG_MAX && blockaddr != 0; 376 i++, blockaddr = block->bbh_next_block_addr) { 377 block = (void *)MIPS_PHYS_TO_XKPHYS(CCA_CACHEABLE, blockaddr); 378 379 mem_clusters[mem_cluster_cnt].start = blockaddr; 380 mem_clusters[mem_cluster_cnt].size = block->bbh_size; 381 mem_cluster_cnt++; 382 } 383 384 physmem = btoc(octeon_btinfo.obt_dram_size * 1024 * 1024); 385 386 #ifdef MULTIPROCESSOR 387 const uint64_t fuse = octeon_xkphys_read_8(CIU_FUSE); 388 const int cores = popcount64(fuse); 389 mem_clusters[0].start += cores * PAGE_SIZE; 390 mem_clusters[0].size -= cores * PAGE_SIZE; 391 #endif 392 393 /* 394 * Load the rest of the available pages into the VM system. 395 */ 396 mips_page_physload(mips_trunc_page(kernel_text), mips_round_page(end), 397 mem_clusters, mem_cluster_cnt, NULL, 0); 398 399 /* 400 * Initialize error message buffer (at end of core). 401 */ 402 mips_init_msgbuf(); 403 404 pmap_bootstrap(); 405 } 406 407 void 408 parse_boot_args(void) 409 { 410 int i; 411 char *arg, *p; 412 413 for (i = 0; i < octeon_btdesc.obt_argc; i++) { 414 arg = (char *)MIPS_PHYS_TO_KSEG0(octeon_btdesc.obt_argv[i]); 415 if (*arg == '-') { 416 for (p = arg + 1; *p; p++) { 417 switch (*p) { 418 case '1': 419 boothowto |= RB_MD1; 420 break; 421 case 's': 422 boothowto |= RB_SINGLE; 423 break; 424 case 'd': 425 boothowto |= RB_KDB; 426 break; 427 case 'a': 428 boothowto |= RB_ASKNAME; 429 break; 430 case 'q': 431 boothowto |= AB_QUIET; 432 break; 433 case 'v': 434 boothowto |= AB_VERBOSE; 435 break; 436 case 'x': 437 boothowto |= AB_DEBUG; 438 break; 439 case 'z': 440 boothowto |= AB_SILENT; 441 break; 442 } 443 } 444 } 445 if (strncmp(arg, "root=", 5) == 0) 446 rootspec = strchr(arg, '=') + 1; 447 } 448 } 449 450 /* 451 * cpu_startup 452 * cpu_reboot 453 */ 454 455 int waittime = -1; 456 457 /* 458 * Allocate memory for variable-sized tables, 459 */ 460 void 461 cpu_startup(void) 462 { 463 464 /* 465 * Do the common startup items. 466 */ 467 cpu_startup_common(); 468 469 /* 470 * Virtual memory is bootstrapped -- notify the bus spaces 471 * that memory allocation is now safe. 472 */ 473 octeon_configuration.mc_mallocsafe = 1; 474 475 fdtbus_intr_init(); 476 } 477 478 void 479 cpu_reboot(int howto, char *bootstr) 480 { 481 482 /* Take a snapshot before clobbering any registers. */ 483 savectx(curpcb); 484 485 if (cold) { 486 howto |= RB_HALT; 487 goto haltsys; 488 } 489 490 /* If "always halt" was specified as a boot flag, obey. */ 491 if (boothowto & RB_HALT) 492 howto |= RB_HALT; 493 494 boothowto = howto; 495 if ((howto & RB_NOSYNC) == 0 && (waittime < 0)) { 496 waittime = 0; 497 vfs_shutdown(); 498 499 /* 500 * If we've been adjusting the clock, the todr 501 * will be out of synch; adjust it now. 502 */ 503 resettodr(); 504 } 505 506 splhigh(); 507 508 if (howto & RB_DUMP) 509 dumpsys(); 510 511 haltsys: 512 doshutdownhooks(); 513 514 if (howto & RB_HALT) { 515 printf("\n"); 516 printf("The operating system has halted.\n"); 517 printf("Please press any key to reboot.\n\n"); 518 cnpollc(1); /* For proper keyboard command handling */ 519 cngetc(); 520 cnpollc(0); 521 } 522 523 printf("%s\n\n", ((howto & RB_HALT) != 0) ? "halted." : "rebooting..."); 524 525 /* 526 * Need a small delay here, otherwise we see the first few characters of 527 * the warning below. 528 */ 529 delay(80000); 530 531 octeon_soft_reset(); 532 533 delay(1000000); 534 535 printf("WARNING: reset failed!\nSpinning..."); 536 537 for (;;) 538 /* spin forever */ ; /* XXX */ 539 } 540