machdep.c revision 1.4
11.4Ssimonb/* $NetBSD: machdep.c,v 1.4 2019/03/29 00:24:56 simonb Exp $ */ 21.1Smrg 31.1Smrg/* 41.1Smrg * Copyright 2000, 2001 51.1Smrg * Broadcom Corporation. All rights reserved. 61.1Smrg * 71.1Smrg * This software is furnished under license and may be used and copied only 81.1Smrg * in accordance with the following terms and conditions. Subject to these 91.1Smrg * conditions, you may download, copy, install, use, modify and distribute 101.1Smrg * modified or unmodified copies of this software in source and/or binary 111.1Smrg * form. No title or ownership is transferred hereby. 121.1Smrg * 131.1Smrg * 1) Any source code used, modified or distributed must reproduce and 141.1Smrg * retain this copyright notice and list of conditions as they appear in 151.1Smrg * the source file. 161.1Smrg * 171.1Smrg * 2) No right is granted to use any trade name, trademark, or logo of 181.1Smrg * Broadcom Corporation. The "Broadcom Corporation" name may not be 191.1Smrg * used to endorse or promote products derived from this software 201.1Smrg * without the prior written permission of Broadcom Corporation. 211.1Smrg * 221.1Smrg * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED 231.1Smrg * WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF 241.1Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR 251.1Smrg * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE 261.1Smrg * FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE 271.1Smrg * LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 281.1Smrg * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 291.1Smrg * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 301.1Smrg * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 311.1Smrg * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 321.1Smrg * OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 331.1Smrg */ 341.1Smrg 351.1Smrg/* 361.1Smrg * Copyright (c) 2000 Soren S. Jorvang. All rights reserved. 371.1Smrg * 381.1Smrg * Redistribution and use in source and binary forms, with or without 391.1Smrg * modification, are permitted provided that the following conditions 401.1Smrg * are met: 411.1Smrg * 1. Redistributions of source code must retain the above copyright 421.1Smrg * notice, this list of conditions, and the following disclaimer. 431.1Smrg * 2. Redistributions in binary form must reproduce the above copyright 441.1Smrg * notice, this list of conditions and the following disclaimer in the 451.1Smrg * documentation and/or other materials provided with the distribution. 461.1Smrg * 471.1Smrg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 481.1Smrg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 491.1Smrg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 501.1Smrg * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 511.1Smrg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 521.1Smrg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 531.1Smrg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 541.1Smrg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 551.1Smrg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 561.1Smrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 571.1Smrg * SUCH DAMAGE. 581.1Smrg */ 591.1Smrg 601.1Smrg#include <sys/cdefs.h> 611.4Ssimonb__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.4 2019/03/29 00:24:56 simonb Exp $"); 621.1Smrg 631.1Smrg#include "opt_ddb.h" 641.1Smrg#include "opt_execfmt.h" 651.1Smrg#include "opt_modular.h" 661.1Smrg 671.1Smrg#include <sys/param.h> 681.1Smrg#include <sys/buf.h> 691.1Smrg#include <sys/conf.h> 701.1Smrg#include <sys/cpu.h> 711.1Smrg#include <sys/device.h> 721.1Smrg#include <sys/exec.h> 731.1Smrg#include <sys/file.h> 741.1Smrg#include <sys/intr.h> 751.1Smrg#include <sys/kcore.h> 761.1Smrg#include <sys/kernel.h> 771.1Smrg#include <sys/ksyms.h> 781.1Smrg#include <sys/malloc.h> 791.1Smrg#include <sys/mbuf.h> 801.1Smrg#include <sys/mount.h> 811.1Smrg#include <sys/msgbuf.h> 821.1Smrg#include <sys/proc.h> 831.1Smrg#include <sys/reboot.h> 841.1Smrg#include <sys/syscallargs.h> 851.1Smrg#include <sys/systm.h> 861.1Smrg 871.1Smrg#include <uvm/uvm_extern.h> 881.1Smrg 891.1Smrg#include <mips/locore.h> 901.1Smrg#include <mips/psl.h> 911.1Smrg#include <mips/pte.h> 921.1Smrg#include <mips/reg.h> 931.1Smrg 941.1Smrg#include <mips/cfe/cfe_api.h> 951.1Smrg 961.2Smrg#include <evbmips/sbmips/autoconf.h> 971.2Smrg#include <evbmips/sbmips/swarm.h> 981.2Smrg#include <evbmips/sbmips/systemsw.h> 991.1Smrg 1001.1Smrg#if 0 /* XXXCGD */ 1011.2Smrg#include <evbmips/sbmips/nvram.h> 1021.1Smrg#endif /* XXXCGD */ 1031.2Smrg#include <evbmips/sbmips/leds.h> 1041.1Smrg 1051.1Smrg#include <mips/sibyte/dev/sbbuswatchvar.h> 1061.1Smrg 1071.1Smrg#include "ksyms.h" 1081.1Smrg 1091.1Smrg#if NKSYMS || defined(DDB) || defined(MODULAR) 1101.1Smrg#include <mips/db_machdep.h> 1111.1Smrg#include <ddb/db_access.h> 1121.1Smrg#include <ddb/db_sym.h> 1131.1Smrg#include <ddb/db_extern.h> 1141.1Smrg#include <sys/exec_elf.h> 1151.1Smrg#endif 1161.1Smrg 1171.1Smrg#include <dev/cons.h> 1181.1Smrg 1191.1Smrg#if NKSYMS || defined(DDB) || defined(MODULAR) 1201.1Smrg/* start and end of kernel symbol table */ 1211.1Smrgvoid *ksym_start, *ksym_end; 1221.1Smrg#endif 1231.1Smrg 1241.1Smrg/* Maps for VM objects. */ 1251.1Smrgstruct vm_map *phys_map = NULL; 1261.1Smrg 1271.1Smrgchar bootstring[512]; /* Boot command */ 1281.1Smrgint netboot; /* Are we netbooting? */ 1291.1Smrgint cfe_present; 1301.1Smrg 1311.1Smrgstruct bootinfo_v1 bootinfo; 1321.1Smrg 1331.1Smrgphys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 1341.1Smrgint mem_cluster_cnt; 1351.1Smrg 1361.1Smrgvoid configure(void); 1371.1Smrgvoid mach_init(long, long, long, long); 1381.1Smrg 1391.1Smrgextern void *esym; 1401.1Smrg 1411.1Smrg/* 1421.1Smrg * Do all the stuff that locore normally does before calling main(). 1431.1Smrg */ 1441.1Smrgvoid 1451.1Smrgmach_init(long fwhandle, long magic, long bootdata, long reserved) 1461.1Smrg{ 1471.1Smrg void *kernend; 1481.1Smrg extern char edata[], end[]; 1491.1Smrg uint32_t config; 1501.1Smrg 1511.1Smrg /* XXX this code must run on the target CPU */ 1521.1Smrg config = mips3_cp0_config_read(); 1531.1Smrg config &= ~MIPS3_CONFIG_K0_MASK; 1541.1Smrg config |= 0x05; /* XXX. cacheable coherent */ 1551.1Smrg mips3_cp0_config_write(config); 1561.1Smrg 1571.1Smrg /* Zero BSS. XXXCGD: uh, is this really necessary still? */ 1581.1Smrg memset(edata, 0, end - edata); 1591.1Smrg 1601.1Smrg /* 1611.1Smrg * Copy the bootinfo structure from the boot loader. 1621.1Smrg * this has to be done before mips_vector_init is 1631.1Smrg * called because we may need CFE's TLB handler 1641.1Smrg */ 1651.1Smrg 1661.1Smrg if (magic == BOOTINFO_MAGIC) 1671.1Smrg memcpy(&bootinfo, (struct bootinfo_v1 *)bootdata, 1681.1Smrg sizeof bootinfo); 1691.1Smrg else if (reserved == CFE_EPTSEAL) { 1701.1Smrg magic = BOOTINFO_MAGIC; 1711.1Smrg memset(&bootinfo, 0, sizeof bootinfo); 1721.1Smrg bootinfo.version = BOOTINFO_VERSION; 1731.1Smrg bootinfo.fwhandle = fwhandle; 1741.1Smrg bootinfo.fwentry = bootdata; 1751.1Smrg bootinfo.ssym = (vaddr_t)end; 1761.1Smrg bootinfo.esym = (vaddr_t)end; 1771.1Smrg } 1781.1Smrg 1791.1Smrg kernend = (void *)mips_round_page(end); 1801.1Smrg#if NKSYMS || defined(DDB) || defined(MODULAR) 1811.1Smrg if (magic == BOOTINFO_MAGIC) { 1821.1Smrg ksym_start = (void *)(intptr_t)bootinfo.ssym; 1831.1Smrg ksym_end = (void *)(intptr_t)bootinfo.esym; 1841.1Smrg kernend = (void *)mips_round_page((vaddr_t)ksym_end); 1851.1Smrg } 1861.1Smrg#endif 1871.1Smrg 1881.1Smrg consinit(); 1891.1Smrg 1901.1Smrg uvm_md_init(); 1911.1Smrg 1921.1Smrg /* 1931.1Smrg * Copy exception-dispatch code down to exception vector. 1941.1Smrg * Initialize locore-function vector. 1951.1Smrg * Clear out the I and D caches. 1961.1Smrg */ 1971.1Smrg#ifdef MULTIPROCESSOR 1981.1Smrg mips_vector_init(NULL, true); 1991.1Smrg#else 2001.1Smrg mips_vector_init(NULL, false); 2011.1Smrg#endif 2021.1Smrg 2031.1Smrg mips_locoresw.lsw_bus_error = sibyte_bus_watch_check; 2041.1Smrg 2051.1Smrg sb1250_ipl_map_init(); 2061.1Smrg 2071.1Smrg#ifdef DEBUG 2081.1Smrg printf("fwhandle=%08X magic=%08X bootdata=%08X reserved=%08X\n", 2091.1Smrg (u_int)fwhandle, (u_int)magic, (u_int)bootdata, (u_int)reserved); 2101.1Smrg#endif 2111.1Smrg 2121.1Smrg cpu_setmodel("sb1250"); 2131.1Smrg 2141.1Smrg if (magic == BOOTINFO_MAGIC) { 2151.1Smrg int idx; 2161.1Smrg int added; 2171.1Smrg uint64_t start, len, type; 2181.1Smrg 2191.1Smrg cfe_init(bootinfo.fwhandle, bootinfo.fwentry); 2201.1Smrg cfe_present = 1; 2211.1Smrg 2221.1Smrg idx = 0; 2231.1Smrg physmem = 0; 2241.1Smrg mem_cluster_cnt = 0; 2251.1Smrg while (cfe_enummem(idx, 0, &start, &len, &type) == 0) { 2261.1Smrg added = 0; 2271.4Ssimonb printf("Memory Block #%d start %08"PRIx64" len %08"PRIx64": %s: ", 2281.1Smrg idx, start, len, (type == CFE_MI_AVAILABLE) ? 2291.1Smrg "Available" : "Reserved"); 2301.1Smrg if ((type == CFE_MI_AVAILABLE) && 2311.1Smrg (mem_cluster_cnt < VM_PHYSSEG_MAX)) { 2321.1Smrg /* 2331.1Smrg * XXX Ignore memory above 256MB for now, it 2341.1Smrg * XXX needs special handling. 2351.1Smrg */ 2361.1Smrg if (start < (256*1024*1024)) { 2371.1Smrg physmem += btoc(((int) len)); 2381.1Smrg mem_clusters[mem_cluster_cnt].start = 2391.1Smrg (long) start; 2401.1Smrg mem_clusters[mem_cluster_cnt].size = 2411.1Smrg (long) len; 2421.1Smrg mem_cluster_cnt++; 2431.1Smrg added = 1; 2441.1Smrg } 2451.1Smrg } 2461.1Smrg if (added) 2471.1Smrg printf("added to map\n"); 2481.1Smrg else 2491.1Smrg printf("not added to map\n"); 2501.1Smrg idx++; 2511.1Smrg } 2521.1Smrg 2531.1Smrg } else { 2541.1Smrg /* 2551.1Smrg * Handle the case of not being called from the firmware. 2561.1Smrg */ 2571.1Smrg /* XXX hardwire to 32MB; should be kernel config option */ 2581.1Smrg physmem = 32 * 1024 * 1024 / 4096; 2591.1Smrg mem_clusters[0].start = 0; 2601.1Smrg mem_clusters[0].size = ctob(physmem); 2611.1Smrg mem_cluster_cnt = 1; 2621.1Smrg } 2631.1Smrg 2641.1Smrg 2651.1Smrg for (u_int i = 0; i < sizeof(bootinfo.boot_flags); i++) { 2661.1Smrg switch (bootinfo.boot_flags[i]) { 2671.1Smrg case '\0': 2681.1Smrg break; 2691.1Smrg case ' ': 2701.1Smrg continue; 2711.1Smrg case '-': 2721.1Smrg while (bootinfo.boot_flags[i] != ' ' && 2731.1Smrg bootinfo.boot_flags[i] != '\0') { 2741.1Smrg switch (bootinfo.boot_flags[i]) { 2751.1Smrg case 'a': 2761.1Smrg boothowto |= RB_ASKNAME; 2771.1Smrg break; 2781.1Smrg case 'd': 2791.1Smrg boothowto |= RB_KDB; 2801.1Smrg break; 2811.1Smrg case 's': 2821.1Smrg boothowto |= RB_SINGLE; 2831.1Smrg break; 2841.1Smrg } 2851.1Smrg i++; 2861.1Smrg } 2871.1Smrg } 2881.1Smrg } 2891.1Smrg 2901.1Smrg /* 2911.1Smrg * Load the rest of the available pages into the VM system. 2921.1Smrg */ 2931.1Smrg mips_page_physload(MIPS_KSEG0_START, (vaddr_t) kernend, 2941.1Smrg mem_clusters, mem_cluster_cnt, NULL, 0); 2951.1Smrg 2961.1Smrg /* 2971.1Smrg * Initialize error message buffer (at end of core). 2981.1Smrg */ 2991.1Smrg mips_init_msgbuf(); 3001.1Smrg 3011.1Smrg pmap_bootstrap(); 3021.1Smrg 3031.1Smrg /* 3041.1Smrg * Allocate uarea for lwp0 and set it. 3051.1Smrg */ 3061.1Smrg mips_init_lwp0_uarea(); 3071.1Smrg 3081.1Smrg /* 3091.1Smrg * Initialize debuggers, and break into them, if appropriate. 3101.1Smrg */ 3111.1Smrg#if NKSYMS || defined(DDB) || defined(MODULAR) 3121.1Smrg ksyms_addsyms_elf(((uintptr_t)ksym_end - (uintptr_t)ksym_start), 3131.1Smrg ksym_start, ksym_end); 3141.1Smrg#endif 3151.1Smrg 3161.1Smrg if (boothowto & RB_KDB) { 3171.1Smrg#if defined(DDB) 3181.1Smrg Debugger(); 3191.1Smrg#endif 3201.1Smrg } 3211.1Smrg 3221.1Smrg#ifdef MULTIPROCESSOR 3231.1Smrg mips_fixup_exceptions(mips_fixup_zero_relative); 3241.1Smrg#endif 3251.1Smrg} 3261.1Smrg 3271.1Smrg/* 3281.1Smrg * Allocate memory for variable-sized tables, 3291.1Smrg */ 3301.1Smrgvoid 3311.1Smrgcpu_startup(void) 3321.1Smrg{ 3331.1Smrg /* 3341.1Smrg * Just do the common stuff. 3351.1Smrg */ 3361.1Smrg cpu_startup_common(); 3371.1Smrg} 3381.1Smrg 3391.1Smrgint waittime = -1; 3401.1Smrg 3411.1Smrgvoid 3421.1Smrgcpu_reboot(int howto, char *bootstr) 3431.1Smrg{ 3441.1Smrg 3451.1Smrg /* Take a snapshot before clobbering any registers. */ 3461.1Smrg savectx(curpcb); 3471.1Smrg 3481.1Smrg if (cold) { 3491.1Smrg howto |= RB_HALT; 3501.1Smrg goto haltsys; 3511.1Smrg } 3521.1Smrg 3531.1Smrg /* If "always halt" was specified as a boot flag, obey. */ 3541.1Smrg if (boothowto & RB_HALT) 3551.1Smrg howto |= RB_HALT; 3561.1Smrg 3571.1Smrg boothowto = howto; 3581.1Smrg if ((howto & RB_NOSYNC) == 0 && (waittime < 0)) { 3591.1Smrg waittime = 0; 3601.1Smrg vfs_shutdown(); 3611.1Smrg 3621.1Smrg /* 3631.1Smrg * If we've been adjusting the clock, the todr 3641.1Smrg * will be out of synch; adjust it now. 3651.1Smrg */ 3661.1Smrg resettodr(); 3671.1Smrg } 3681.1Smrg 3691.1Smrg splhigh(); 3701.1Smrg 3711.1Smrg if (howto & RB_DUMP) 3721.1Smrg dumpsys(); 3731.1Smrg 3741.1Smrghaltsys: 3751.1Smrg doshutdownhooks(); 3761.1Smrg 3771.1Smrg pmf_system_shutdown(boothowto); 3781.1Smrg 3791.1Smrg if (howto & RB_HALT) { 3801.1Smrg printf("\n"); 3811.1Smrg printf("The operating system has halted.\n"); 3821.1Smrg printf("Please press any key to reboot.\n\n"); 3831.1Smrg cnpollc(1); /* For proper keyboard command handling */ 3841.1Smrg cngetc(); 3851.1Smrg cnpollc(0); 3861.1Smrg } 3871.1Smrg 3881.1Smrg printf("rebooting...\n\n"); 3891.1Smrg 3901.1Smrg if (cfe_present) { 3911.1Smrg /* 3921.1Smrg * XXX 3931.1Smrg * For some reason we can't return to CFE with 3941.1Smrg * and do a warm start. Need to look into this... 3951.1Smrg */ 3961.1Smrg cfe_exit(0, (howto & RB_DUMP) ? 1 : 0); 3971.1Smrg printf("cfe_exit didn't!\n"); 3981.1Smrg } 3991.1Smrg 4001.1Smrg printf("WARNING: reboot failed!\n"); 4011.1Smrg 4021.1Smrg for (;;); 4031.1Smrg} 4041.1Smrg 4051.1Smrgstatic void 4061.1Smrgcswarm_setled(u_int index, char c) 4071.1Smrg{ 4081.1Smrg volatile u_char *led_ptr = 4091.1Smrg (void *)MIPS_PHYS_TO_KSEG1(SWARM_LEDS_PHYS); 4101.1Smrg 4111.1Smrg if (index < 4) 4121.1Smrg led_ptr[0x20 + ((3 - index) << 3)] = c; 4131.1Smrg} 4141.1Smrg 4151.1Smrgvoid 4161.1Smrgcswarm_setleds(const char *str) 4171.1Smrg{ 4181.1Smrg int i; 4191.1Smrg 4201.1Smrg for (i = 0; i < 4 && str[i]; i++) 4211.1Smrg cswarm_setled(i, str[i]); 4221.1Smrg for (; i < 4; i++) 4231.1Smrg cswarm_setled(' ', str[i]); 4241.1Smrg} 4251.1Smrg 4261.1Smrgint 4271.1Smrgsbmips_cca_for_pa(paddr_t pa) 4281.1Smrg{ 4291.1Smrg int rv; 4301.1Smrg 4311.1Smrg rv = 2; /* Uncached. */ 4321.1Smrg 4331.1Smrg /* Check each DRAM region. */ 4341.1Smrg if ((pa >= 0x0000000000 && pa <= 0x000fffffff) || /* DRAM 0 */ 4351.1Smrg (pa >= 0x0080000000 && pa <= 0x008fffffff) || /* DRAM 1 */ 4361.1Smrg (pa >= 0x0090000000 && pa <= 0x009fffffff) || /* DRAM 2 */ 4371.1Smrg (pa >= 0x00c0000000 && pa <= 0x00cfffffff) || /* DRAM 3 */ 4381.1Smrg#ifdef _MIPS_PADDR_T_64BIT 4391.1Smrg (pa >= 0x0100000000LL && pa <= 0x07ffffffffLL) || /* DRAM exp */ 4401.1Smrg#endif 4411.1Smrg 0) { 4421.1Smrg rv = 5; /* Cacheable coherent. */ 4431.1Smrg } 4441.1Smrg 4451.1Smrg return (rv); 4461.1Smrg} 447