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