machdep.c revision 1.5
11.5Ssimonb/* $NetBSD: machdep.c,v 1.5 2019/04/01 06:33:57 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.5Ssimonb__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.5 2019/04/01 06:33:57 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.5Ssimonb#ifdef _LP64 1421.5Ssimonb/* 1431.5Ssimonb * We do this KSEG0 to PHYS to KSEG0 dance if running 64-bit because 1441.5Ssimonb * CFE passes in parameters as 32-bit addresses. When used as a 64-bit 1451.5Ssimonb * address these CFE parameters are in user (XKUSEG) space and can't be 1461.5Ssimonb * accessed! Convert these to a physical address and and then to the 1471.5Ssimonb * proper KSEG0 address so we can use them in the kernel. 1481.5Ssimonb */ 1491.5Ssimonb#define CFE_TO_KERNEL_PTR(x) MIPS_PHYS_TO_KSEG0(MIPS_KSEG0_TO_PHYS(x)) 1501.5Ssimonb#else 1511.5Ssimonb#define CFE_TO_KERNEL_PTR(x) (x) 1521.5Ssimonb#endif 1531.5Ssimonb 1541.1Smrg/* 1551.1Smrg * Do all the stuff that locore normally does before calling main(). 1561.1Smrg */ 1571.1Smrgvoid 1581.1Smrgmach_init(long fwhandle, long magic, long bootdata, long reserved) 1591.1Smrg{ 1601.1Smrg void *kernend; 1611.1Smrg extern char edata[], end[]; 1621.1Smrg uint32_t config; 1631.1Smrg 1641.1Smrg /* XXX this code must run on the target CPU */ 1651.1Smrg config = mips3_cp0_config_read(); 1661.1Smrg config &= ~MIPS3_CONFIG_K0_MASK; 1671.1Smrg config |= 0x05; /* XXX. cacheable coherent */ 1681.1Smrg mips3_cp0_config_write(config); 1691.1Smrg 1701.1Smrg /* Zero BSS. XXXCGD: uh, is this really necessary still? */ 1711.1Smrg memset(edata, 0, end - edata); 1721.1Smrg 1731.1Smrg /* 1741.1Smrg * Copy the bootinfo structure from the boot loader. 1751.1Smrg * this has to be done before mips_vector_init is 1761.1Smrg * called because we may need CFE's TLB handler 1771.1Smrg */ 1781.1Smrg 1791.1Smrg if (magic == BOOTINFO_MAGIC) 1801.1Smrg memcpy(&bootinfo, (struct bootinfo_v1 *)bootdata, 1811.1Smrg sizeof bootinfo); 1821.1Smrg else if (reserved == CFE_EPTSEAL) { 1831.1Smrg magic = BOOTINFO_MAGIC; 1841.1Smrg memset(&bootinfo, 0, sizeof bootinfo); 1851.1Smrg bootinfo.version = BOOTINFO_VERSION; 1861.1Smrg bootinfo.fwhandle = fwhandle; 1871.1Smrg bootinfo.fwentry = bootdata; 1881.1Smrg bootinfo.ssym = (vaddr_t)end; 1891.1Smrg bootinfo.esym = (vaddr_t)end; 1901.1Smrg } 1911.1Smrg 1921.1Smrg kernend = (void *)mips_round_page(end); 1931.1Smrg#if NKSYMS || defined(DDB) || defined(MODULAR) 1941.1Smrg if (magic == BOOTINFO_MAGIC) { 1951.5Ssimonb ksym_start = (void *)CFE_TO_KERNEL_PTR(bootinfo.ssym); 1961.5Ssimonb ksym_end = (void *)CFE_TO_KERNEL_PTR(bootinfo.esym); 1971.1Smrg kernend = (void *)mips_round_page((vaddr_t)ksym_end); 1981.1Smrg } 1991.1Smrg#endif 2001.1Smrg 2011.1Smrg consinit(); 2021.1Smrg 2031.1Smrg uvm_md_init(); 2041.1Smrg 2051.1Smrg /* 2061.1Smrg * Copy exception-dispatch code down to exception vector. 2071.1Smrg * Initialize locore-function vector. 2081.1Smrg * Clear out the I and D caches. 2091.1Smrg */ 2101.1Smrg#ifdef MULTIPROCESSOR 2111.1Smrg mips_vector_init(NULL, true); 2121.1Smrg#else 2131.1Smrg mips_vector_init(NULL, false); 2141.1Smrg#endif 2151.1Smrg 2161.1Smrg mips_locoresw.lsw_bus_error = sibyte_bus_watch_check; 2171.1Smrg 2181.1Smrg sb1250_ipl_map_init(); 2191.1Smrg 2201.1Smrg#ifdef DEBUG 2211.1Smrg printf("fwhandle=%08X magic=%08X bootdata=%08X reserved=%08X\n", 2221.1Smrg (u_int)fwhandle, (u_int)magic, (u_int)bootdata, (u_int)reserved); 2231.1Smrg#endif 2241.1Smrg 2251.1Smrg cpu_setmodel("sb1250"); 2261.1Smrg 2271.1Smrg if (magic == BOOTINFO_MAGIC) { 2281.1Smrg int idx; 2291.1Smrg int added; 2301.1Smrg uint64_t start, len, type; 2311.1Smrg 2321.5Ssimonb cfe_init(CFE_TO_KERNEL_PTR(bootinfo.fwhandle), 2331.5Ssimonb CFE_TO_KERNEL_PTR(bootinfo.fwentry)); 2341.1Smrg cfe_present = 1; 2351.1Smrg 2361.1Smrg idx = 0; 2371.1Smrg physmem = 0; 2381.1Smrg mem_cluster_cnt = 0; 2391.1Smrg while (cfe_enummem(idx, 0, &start, &len, &type) == 0) { 2401.1Smrg added = 0; 2411.4Ssimonb printf("Memory Block #%d start %08"PRIx64" len %08"PRIx64": %s: ", 2421.1Smrg idx, start, len, (type == CFE_MI_AVAILABLE) ? 2431.1Smrg "Available" : "Reserved"); 2441.1Smrg if ((type == CFE_MI_AVAILABLE) && 2451.1Smrg (mem_cluster_cnt < VM_PHYSSEG_MAX)) { 2461.1Smrg /* 2471.1Smrg * XXX Ignore memory above 256MB for now, it 2481.1Smrg * XXX needs special handling. 2491.1Smrg */ 2501.1Smrg if (start < (256*1024*1024)) { 2511.1Smrg physmem += btoc(((int) len)); 2521.1Smrg mem_clusters[mem_cluster_cnt].start = 2531.1Smrg (long) start; 2541.1Smrg mem_clusters[mem_cluster_cnt].size = 2551.1Smrg (long) len; 2561.1Smrg mem_cluster_cnt++; 2571.1Smrg added = 1; 2581.1Smrg } 2591.1Smrg } 2601.1Smrg if (added) 2611.1Smrg printf("added to map\n"); 2621.1Smrg else 2631.1Smrg printf("not added to map\n"); 2641.1Smrg idx++; 2651.1Smrg } 2661.1Smrg 2671.1Smrg } else { 2681.1Smrg /* 2691.1Smrg * Handle the case of not being called from the firmware. 2701.1Smrg */ 2711.1Smrg /* XXX hardwire to 32MB; should be kernel config option */ 2721.1Smrg physmem = 32 * 1024 * 1024 / 4096; 2731.1Smrg mem_clusters[0].start = 0; 2741.1Smrg mem_clusters[0].size = ctob(physmem); 2751.1Smrg mem_cluster_cnt = 1; 2761.1Smrg } 2771.1Smrg 2781.1Smrg 2791.1Smrg for (u_int i = 0; i < sizeof(bootinfo.boot_flags); i++) { 2801.1Smrg switch (bootinfo.boot_flags[i]) { 2811.1Smrg case '\0': 2821.1Smrg break; 2831.1Smrg case ' ': 2841.1Smrg continue; 2851.1Smrg case '-': 2861.1Smrg while (bootinfo.boot_flags[i] != ' ' && 2871.1Smrg bootinfo.boot_flags[i] != '\0') { 2881.1Smrg switch (bootinfo.boot_flags[i]) { 2891.1Smrg case 'a': 2901.1Smrg boothowto |= RB_ASKNAME; 2911.1Smrg break; 2921.1Smrg case 'd': 2931.1Smrg boothowto |= RB_KDB; 2941.1Smrg break; 2951.1Smrg case 's': 2961.1Smrg boothowto |= RB_SINGLE; 2971.1Smrg break; 2981.1Smrg } 2991.1Smrg i++; 3001.1Smrg } 3011.1Smrg } 3021.1Smrg } 3031.1Smrg 3041.1Smrg /* 3051.1Smrg * Load the rest of the available pages into the VM system. 3061.1Smrg */ 3071.1Smrg mips_page_physload(MIPS_KSEG0_START, (vaddr_t) kernend, 3081.1Smrg mem_clusters, mem_cluster_cnt, NULL, 0); 3091.1Smrg 3101.1Smrg /* 3111.1Smrg * Initialize error message buffer (at end of core). 3121.1Smrg */ 3131.1Smrg mips_init_msgbuf(); 3141.1Smrg 3151.1Smrg pmap_bootstrap(); 3161.1Smrg 3171.1Smrg /* 3181.1Smrg * Allocate uarea for lwp0 and set it. 3191.1Smrg */ 3201.1Smrg mips_init_lwp0_uarea(); 3211.1Smrg 3221.1Smrg /* 3231.1Smrg * Initialize debuggers, and break into them, if appropriate. 3241.1Smrg */ 3251.1Smrg#if NKSYMS || defined(DDB) || defined(MODULAR) 3261.1Smrg ksyms_addsyms_elf(((uintptr_t)ksym_end - (uintptr_t)ksym_start), 3271.1Smrg ksym_start, ksym_end); 3281.1Smrg#endif 3291.1Smrg 3301.1Smrg if (boothowto & RB_KDB) { 3311.1Smrg#if defined(DDB) 3321.1Smrg Debugger(); 3331.1Smrg#endif 3341.1Smrg } 3351.1Smrg 3361.1Smrg#ifdef MULTIPROCESSOR 3371.1Smrg mips_fixup_exceptions(mips_fixup_zero_relative); 3381.1Smrg#endif 3391.1Smrg} 3401.1Smrg 3411.1Smrg/* 3421.1Smrg * Allocate memory for variable-sized tables, 3431.1Smrg */ 3441.1Smrgvoid 3451.1Smrgcpu_startup(void) 3461.1Smrg{ 3471.1Smrg /* 3481.1Smrg * Just do the common stuff. 3491.1Smrg */ 3501.1Smrg cpu_startup_common(); 3511.1Smrg} 3521.1Smrg 3531.1Smrgint waittime = -1; 3541.1Smrg 3551.1Smrgvoid 3561.1Smrgcpu_reboot(int howto, char *bootstr) 3571.1Smrg{ 3581.1Smrg 3591.1Smrg /* Take a snapshot before clobbering any registers. */ 3601.1Smrg savectx(curpcb); 3611.1Smrg 3621.1Smrg if (cold) { 3631.1Smrg howto |= RB_HALT; 3641.1Smrg goto haltsys; 3651.1Smrg } 3661.1Smrg 3671.1Smrg /* If "always halt" was specified as a boot flag, obey. */ 3681.1Smrg if (boothowto & RB_HALT) 3691.1Smrg howto |= RB_HALT; 3701.1Smrg 3711.1Smrg boothowto = howto; 3721.1Smrg if ((howto & RB_NOSYNC) == 0 && (waittime < 0)) { 3731.1Smrg waittime = 0; 3741.1Smrg vfs_shutdown(); 3751.1Smrg 3761.1Smrg /* 3771.1Smrg * If we've been adjusting the clock, the todr 3781.1Smrg * will be out of synch; adjust it now. 3791.1Smrg */ 3801.1Smrg resettodr(); 3811.1Smrg } 3821.1Smrg 3831.1Smrg splhigh(); 3841.1Smrg 3851.1Smrg if (howto & RB_DUMP) 3861.1Smrg dumpsys(); 3871.1Smrg 3881.1Smrghaltsys: 3891.1Smrg doshutdownhooks(); 3901.1Smrg 3911.1Smrg pmf_system_shutdown(boothowto); 3921.1Smrg 3931.1Smrg if (howto & RB_HALT) { 3941.1Smrg printf("\n"); 3951.1Smrg printf("The operating system has halted.\n"); 3961.1Smrg printf("Please press any key to reboot.\n\n"); 3971.1Smrg cnpollc(1); /* For proper keyboard command handling */ 3981.1Smrg cngetc(); 3991.1Smrg cnpollc(0); 4001.1Smrg } 4011.1Smrg 4021.1Smrg printf("rebooting...\n\n"); 4031.1Smrg 4041.1Smrg if (cfe_present) { 4051.1Smrg /* 4061.1Smrg * XXX 4071.1Smrg * For some reason we can't return to CFE with 4081.1Smrg * and do a warm start. Need to look into this... 4091.1Smrg */ 4101.1Smrg cfe_exit(0, (howto & RB_DUMP) ? 1 : 0); 4111.1Smrg printf("cfe_exit didn't!\n"); 4121.1Smrg } 4131.1Smrg 4141.1Smrg printf("WARNING: reboot failed!\n"); 4151.1Smrg 4161.1Smrg for (;;); 4171.1Smrg} 4181.1Smrg 4191.1Smrgstatic void 4201.1Smrgcswarm_setled(u_int index, char c) 4211.1Smrg{ 4221.1Smrg volatile u_char *led_ptr = 4231.1Smrg (void *)MIPS_PHYS_TO_KSEG1(SWARM_LEDS_PHYS); 4241.1Smrg 4251.1Smrg if (index < 4) 4261.1Smrg led_ptr[0x20 + ((3 - index) << 3)] = c; 4271.1Smrg} 4281.1Smrg 4291.1Smrgvoid 4301.1Smrgcswarm_setleds(const char *str) 4311.1Smrg{ 4321.1Smrg int i; 4331.1Smrg 4341.1Smrg for (i = 0; i < 4 && str[i]; i++) 4351.1Smrg cswarm_setled(i, str[i]); 4361.1Smrg for (; i < 4; i++) 4371.1Smrg cswarm_setled(' ', str[i]); 4381.1Smrg} 4391.1Smrg 4401.1Smrgint 4411.1Smrgsbmips_cca_for_pa(paddr_t pa) 4421.1Smrg{ 4431.1Smrg int rv; 4441.1Smrg 4451.1Smrg rv = 2; /* Uncached. */ 4461.1Smrg 4471.1Smrg /* Check each DRAM region. */ 4481.1Smrg if ((pa >= 0x0000000000 && pa <= 0x000fffffff) || /* DRAM 0 */ 4491.1Smrg (pa >= 0x0080000000 && pa <= 0x008fffffff) || /* DRAM 1 */ 4501.1Smrg (pa >= 0x0090000000 && pa <= 0x009fffffff) || /* DRAM 2 */ 4511.1Smrg (pa >= 0x00c0000000 && pa <= 0x00cfffffff) || /* DRAM 3 */ 4521.1Smrg#ifdef _MIPS_PADDR_T_64BIT 4531.1Smrg (pa >= 0x0100000000LL && pa <= 0x07ffffffffLL) || /* DRAM exp */ 4541.1Smrg#endif 4551.1Smrg 0) { 4561.1Smrg rv = 5; /* Cacheable coherent. */ 4571.1Smrg } 4581.1Smrg 4591.1Smrg return (rv); 4601.1Smrg} 461