1239671Srwatson/*- 2239671Srwatson * Copyright (c) 2006 Wojciech A. Koszek <wkoszek@FreeBSD.org> 3244899Srwatson * Copyright (c) 2012 Robert N. M. Watson 4239671Srwatson * All rights reserved. 5239671Srwatson * 6244899Srwatson * This software was developed by SRI International and the University of 7244899Srwatson * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) 8244899Srwatson * ("CTSRD"), as part of the DARPA CRASH research programme. 9244899Srwatson * 10239671Srwatson * Redistribution and use in source and binary forms, with or without 11239671Srwatson * modification, are permitted provided that the following conditions 12239671Srwatson * are met: 13239671Srwatson * 1. Redistributions of source code must retain the above copyright 14239671Srwatson * notice, this list of conditions and the following disclaimer. 15239671Srwatson * 2. Redistributions in binary form must reproduce the above copyright 16239671Srwatson * notice, this list of conditions and the following disclaimer in the 17239671Srwatson * documentation and/or other materials provided with the distribution. 18239671Srwatson * 19239671Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20239671Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21239671Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22239671Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23239671Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24239671Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25239671Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26239671Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27239671Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28239671Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29239671Srwatson * SUCH DAMAGE. 30239671Srwatson */ 31239671Srwatson#include <sys/cdefs.h> 32239671Srwatson__FBSDID("$FreeBSD$"); 33239671Srwatson 34239671Srwatson#include "opt_ddb.h" 35244899Srwatson#include "opt_platform.h" 36239671Srwatson 37239671Srwatson#include <sys/param.h> 38239671Srwatson#include <sys/conf.h> 39239671Srwatson#include <sys/kernel.h> 40239671Srwatson#include <sys/systm.h> 41239671Srwatson#include <sys/imgact.h> 42239671Srwatson#include <sys/bio.h> 43239671Srwatson#include <sys/buf.h> 44239671Srwatson#include <sys/bus.h> 45239671Srwatson#include <sys/cpu.h> 46239671Srwatson#include <sys/cons.h> 47239671Srwatson#include <sys/exec.h> 48245330Srwatson#include <sys/linker.h> 49239671Srwatson#include <sys/ucontext.h> 50239671Srwatson#include <sys/proc.h> 51239671Srwatson#include <sys/kdb.h> 52239671Srwatson#include <sys/ptrace.h> 53239671Srwatson#include <sys/reboot.h> 54239671Srwatson#include <sys/signalvar.h> 55239671Srwatson#include <sys/sysent.h> 56239671Srwatson#include <sys/sysproto.h> 57239671Srwatson#include <sys/user.h> 58239671Srwatson 59244942Srwatson#ifdef FDT 60244899Srwatson#include <dev/fdt/fdt_common.h> 61244899Srwatson#include <dev/ofw/openfirm.h> 62244942Srwatson#endif 63244899Srwatson 64239671Srwatson#include <vm/vm.h> 65239671Srwatson#include <vm/vm_object.h> 66239671Srwatson#include <vm/vm_page.h> 67239671Srwatson 68239671Srwatson#include <machine/clock.h> 69239671Srwatson#include <machine/cpu.h> 70239671Srwatson#include <machine/cpuregs.h> 71239671Srwatson#include <machine/hwfunc.h> 72239671Srwatson#include <machine/md_var.h> 73245330Srwatson#include <machine/metadata.h> 74239671Srwatson#include <machine/pmap.h> 75239671Srwatson#include <machine/trap.h> 76239671Srwatson 77239671Srwatsonextern int *edata; 78239671Srwatsonextern int *end; 79239671Srwatson 80239671Srwatsonvoid 81239671Srwatsonplatform_cpu_init() 82239671Srwatson{ 83239671Srwatson /* Nothing special */ 84239671Srwatson} 85239671Srwatson 86239671Srwatsonstatic void 87239671Srwatsonmips_init(void) 88239671Srwatson{ 89239671Srwatson int i; 90239671Srwatson 91239671Srwatson for (i = 0; i < 10; i++) { 92239671Srwatson phys_avail[i] = 0; 93239671Srwatson } 94239671Srwatson 95239671Srwatson /* phys_avail regions are in bytes */ 96239671Srwatson phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end); 97239671Srwatson phys_avail[1] = ctob(realmem); 98239671Srwatson 99239671Srwatson dump_avail[0] = phys_avail[0]; 100239671Srwatson dump_avail[1] = phys_avail[1]; 101239671Srwatson 102239671Srwatson physmem = realmem; 103239671Srwatson 104239671Srwatson init_param1(); 105239671Srwatson init_param2(physmem); 106239671Srwatson mips_cpu_init(); 107239671Srwatson pmap_bootstrap(); 108239671Srwatson mips_proc0_init(); 109239671Srwatson mutex_init(); 110239671Srwatson kdb_init(); 111239671Srwatson#ifdef KDB 112239671Srwatson if (boothowto & RB_KDB) 113239671Srwatson kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); 114239671Srwatson#endif 115239671Srwatson} 116239671Srwatson 117239671Srwatson/* 118239671Srwatson * Perform a board-level soft-reset. 119239671Srwatson */ 120239671Srwatsonvoid 121239671Srwatsonplatform_reset(void) 122239671Srwatson{ 123239671Srwatson 124261274Sbrooks /* XXX SMP will likely require us to do more. */ 125261274Sbrooks __asm__ __volatile__( 126261274Sbrooks "mfc0 $k0, $12\n\t" 127261274Sbrooks "li $k1, 0x00100000\n\t" 128261274Sbrooks "or $k0, $k0, $k1\n\t" 129261274Sbrooks "mtc0 $k0, $12\n"); 130261274Sbrooks for( ; ; ) 131261274Sbrooks __asm__ __volatile("wait"); 132239671Srwatson} 133239671Srwatson 134270058Sbz#ifdef FDT 135270058Sbz/* Parse cmd line args as env - copied from xlp_machdep. */ 136270058Sbz/* XXX-BZ this should really be centrally provided for all (boot) code. */ 137270058Sbzstatic void 138270058Sbz_parse_bootargs(char *cmdline) 139270058Sbz{ 140270058Sbz char *n, *v; 141270058Sbz 142270058Sbz while ((v = strsep(&cmdline, " \n")) != NULL) { 143270058Sbz if (*v == '\0') 144270058Sbz continue; 145270058Sbz if (*v == '-') { 146270058Sbz while (*v != '\0') { 147270058Sbz v++; 148270058Sbz switch (*v) { 149270058Sbz case 'a': boothowto |= RB_ASKNAME; break; 150270058Sbz /* Someone should simulate that ;-) */ 151270058Sbz case 'C': boothowto |= RB_CDROM; break; 152270058Sbz case 'd': boothowto |= RB_KDB; break; 153270058Sbz case 'D': boothowto |= RB_MULTIPLE; break; 154270058Sbz case 'm': boothowto |= RB_MUTE; break; 155270058Sbz case 'g': boothowto |= RB_GDB; break; 156270058Sbz case 'h': boothowto |= RB_SERIAL; break; 157270058Sbz case 'p': boothowto |= RB_PAUSE; break; 158270058Sbz case 'r': boothowto |= RB_DFLTROOT; break; 159270058Sbz case 's': boothowto |= RB_SINGLE; break; 160270058Sbz case 'v': boothowto |= RB_VERBOSE; break; 161270058Sbz } 162270058Sbz } 163270058Sbz } else { 164270058Sbz n = strsep(&v, "="); 165270058Sbz if (v == NULL) 166270058Sbz setenv(n, "1"); 167270058Sbz else 168270058Sbz setenv(n, v); 169270058Sbz } 170270058Sbz } 171270058Sbz} 172270058Sbz#endif 173270058Sbz 174239671Srwatsonvoid 175239671Srwatsonplatform_start(__register_t a0, __register_t a1, __register_t a2, 176239671Srwatson __register_t a3) 177239671Srwatson{ 178239671Srwatson vm_offset_t kernend; 179239671Srwatson uint64_t platform_counter_freq; 180239671Srwatson int argc = a0; 181239671Srwatson char **argv = (char **)a1; 182239671Srwatson char **envp = (char **)a2; 183239671Srwatson unsigned int memsize = a3; 184245330Srwatson#ifdef FDT 185270058Sbz char buf[2048]; /* early stack supposedly big enough */ 186245330Srwatson vm_offset_t dtbp; 187270058Sbz phandle_t chosen; 188245330Srwatson void *kmdp; 189245330Srwatson#endif 190239671Srwatson int i; 191239671Srwatson 192239671Srwatson /* clear the BSS and SBSS segments */ 193239671Srwatson kernend = (vm_offset_t)&end; 194239671Srwatson memset(&edata, 0, kernend - (vm_offset_t)(&edata)); 195239671Srwatson 196239671Srwatson mips_postboot_fixup(); 197239671Srwatson 198239671Srwatson mips_pcpu0_init(); 199239671Srwatson 200245329Srwatson#ifdef FDT 201245330Srwatson /* 202245330Srwatson * Find the dtb passed in by the boot loader (currently fictional). 203245330Srwatson */ 204245330Srwatson kmdp = preload_search_by_type("elf kernel"); 205245330Srwatson if (kmdp != NULL) 206245330Srwatson dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t); 207245330Srwatson else 208245330Srwatson dtbp = (vm_offset_t)NULL; 209245330Srwatson 210245330Srwatson#if defined(FDT_DTB_STATIC) 211245330Srwatson /* 212245330Srwatson * In case the device tree blob was not retrieved (from metadata) try 213245330Srwatson * to use the statically embedded one. 214245330Srwatson */ 215245330Srwatson if (dtbp == (vm_offset_t)NULL) 216245330Srwatson dtbp = (vm_offset_t)&fdt_static_dtb; 217245330Srwatson#else 218245330Srwatson#error "Non-static FDT not yet supported on BERI" 219245329Srwatson#endif 220245329Srwatson 221245329Srwatson if (OF_install(OFW_FDT, 0) == FALSE) 222245329Srwatson while (1); 223259898Sbz if (OF_init((void *)dtbp) != 0) 224245329Srwatson while (1); 225270058Sbz 226270058Sbz /* 227270058Sbz * Get bootargs from FDT if specified. 228270058Sbz */ 229270058Sbz chosen = OF_finddevice("/chosen"); 230270058Sbz if (OF_getprop(chosen, "bootargs", buf, sizeof(buf)) != -1) 231270058Sbz _parse_bootargs(buf); 232245329Srwatson#endif 233245329Srwatson 234239671Srwatson /* 235239671Srwatson * XXXRW: We have no way to compare wallclock time to cycle rate on 236239671Srwatson * BERI, so for now assume we run at the MALTA default (100MHz). 237239671Srwatson */ 238239671Srwatson platform_counter_freq = MIPS_DEFAULT_HZ; 239239671Srwatson mips_timer_early_init(platform_counter_freq); 240239671Srwatson 241239671Srwatson cninit(); 242239671Srwatson printf("entry: platform_start()\n"); 243239671Srwatson 244239671Srwatson bootverbose = 1; 245239671Srwatson if (bootverbose) { 246239671Srwatson printf("cmd line: "); 247239671Srwatson for (i = 0; i < argc; i++) 248239671Srwatson printf("%s ", argv[i]); 249239671Srwatson printf("\n"); 250239671Srwatson 251239671Srwatson printf("envp:\n"); 252239671Srwatson for (i = 0; envp[i]; i += 2) 253239671Srwatson printf("\t%s = %s\n", envp[i], envp[i+1]); 254239671Srwatson 255239671Srwatson printf("memsize = %08x\n", memsize); 256239671Srwatson } 257239671Srwatson 258239671Srwatson realmem = btoc(memsize); 259239671Srwatson mips_init(); 260239671Srwatson 261239671Srwatson mips_timer_init_params(platform_counter_freq, 0); 262239671Srwatson} 263