beri_machdep.c revision 273234
1239671Srwatson/*- 2239671Srwatson * Copyright (c) 2006 Wojciech A. Koszek <wkoszek@FreeBSD.org> 3264897Sbrooks * Copyright (c) 2012-2014 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: head/sys/mips/beri/beri_machdep.c 273234 2014-10-17 17:34:05Z davide $"); 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 68264897Sbrooks#include <machine/bootinfo.h> 69239671Srwatson#include <machine/clock.h> 70239671Srwatson#include <machine/cpu.h> 71239671Srwatson#include <machine/cpuregs.h> 72239671Srwatson#include <machine/hwfunc.h> 73239671Srwatson#include <machine/md_var.h> 74245330Srwatson#include <machine/metadata.h> 75239671Srwatson#include <machine/pmap.h> 76239671Srwatson#include <machine/trap.h> 77239671Srwatson 78239671Srwatsonextern int *edata; 79239671Srwatsonextern int *end; 80239671Srwatson 81239671Srwatsonvoid 82239671Srwatsonplatform_cpu_init() 83239671Srwatson{ 84239671Srwatson /* Nothing special */ 85239671Srwatson} 86239671Srwatson 87239671Srwatsonstatic void 88239671Srwatsonmips_init(void) 89239671Srwatson{ 90239671Srwatson int i; 91239671Srwatson 92239671Srwatson for (i = 0; i < 10; i++) { 93239671Srwatson phys_avail[i] = 0; 94239671Srwatson } 95239671Srwatson 96239671Srwatson /* phys_avail regions are in bytes */ 97239671Srwatson phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end); 98239671Srwatson phys_avail[1] = ctob(realmem); 99239671Srwatson 100239671Srwatson dump_avail[0] = phys_avail[0]; 101239671Srwatson dump_avail[1] = phys_avail[1]; 102239671Srwatson 103239671Srwatson physmem = realmem; 104239671Srwatson 105239671Srwatson init_param1(); 106239671Srwatson init_param2(physmem); 107239671Srwatson mips_cpu_init(); 108239671Srwatson pmap_bootstrap(); 109239671Srwatson mips_proc0_init(); 110239671Srwatson mutex_init(); 111239671Srwatson kdb_init(); 112239671Srwatson#ifdef KDB 113239671Srwatson if (boothowto & RB_KDB) 114239671Srwatson kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); 115239671Srwatson#endif 116239671Srwatson} 117239671Srwatson 118239671Srwatson/* 119239671Srwatson * Perform a board-level soft-reset. 120239671Srwatson */ 121239671Srwatsonvoid 122239671Srwatsonplatform_reset(void) 123239671Srwatson{ 124239671Srwatson 125256745Sbrooks /* XXX SMP will likely require us to do more. */ 126256745Sbrooks __asm__ __volatile__( 127256745Sbrooks "mfc0 $k0, $12\n\t" 128256745Sbrooks "li $k1, 0x00100000\n\t" 129256745Sbrooks "or $k0, $k0, $k1\n\t" 130256745Sbrooks "mtc0 $k0, $12\n"); 131256745Sbrooks for( ; ; ) 132256745Sbrooks __asm__ __volatile("wait"); 133239671Srwatson} 134239671Srwatson 135265089Sbz#ifdef FDT 136265089Sbz/* Parse cmd line args as env - copied from xlp_machdep. */ 137265089Sbz/* XXX-BZ this should really be centrally provided for all (boot) code. */ 138265089Sbzstatic void 139265089Sbz_parse_bootargs(char *cmdline) 140265089Sbz{ 141265089Sbz char *n, *v; 142265089Sbz 143265089Sbz while ((v = strsep(&cmdline, " \n")) != NULL) { 144265089Sbz if (*v == '\0') 145265089Sbz continue; 146265089Sbz if (*v == '-') { 147265089Sbz while (*v != '\0') { 148265089Sbz v++; 149265089Sbz switch (*v) { 150265089Sbz case 'a': boothowto |= RB_ASKNAME; break; 151265089Sbz /* Someone should simulate that ;-) */ 152265089Sbz case 'C': boothowto |= RB_CDROM; break; 153265089Sbz case 'd': boothowto |= RB_KDB; break; 154265089Sbz case 'D': boothowto |= RB_MULTIPLE; break; 155265089Sbz case 'm': boothowto |= RB_MUTE; break; 156265089Sbz case 'g': boothowto |= RB_GDB; break; 157265089Sbz case 'h': boothowto |= RB_SERIAL; break; 158265089Sbz case 'p': boothowto |= RB_PAUSE; break; 159265089Sbz case 'r': boothowto |= RB_DFLTROOT; break; 160265089Sbz case 's': boothowto |= RB_SINGLE; break; 161265089Sbz case 'v': boothowto |= RB_VERBOSE; break; 162265089Sbz } 163265089Sbz } 164265089Sbz } else { 165265089Sbz n = strsep(&v, "="); 166265089Sbz if (v == NULL) 167273234Sdavide kern_setenv(n, "1"); 168265089Sbz else 169273234Sdavide kern_setenv(n, v); 170265089Sbz } 171265089Sbz } 172265089Sbz} 173265089Sbz#endif 174265089Sbz 175239671Srwatsonvoid 176239671Srwatsonplatform_start(__register_t a0, __register_t a1, __register_t a2, 177239671Srwatson __register_t a3) 178239671Srwatson{ 179264897Sbrooks struct bootinfo *bootinfop; 180239671Srwatson vm_offset_t kernend; 181239671Srwatson uint64_t platform_counter_freq; 182239671Srwatson int argc = a0; 183239671Srwatson char **argv = (char **)a1; 184239671Srwatson char **envp = (char **)a2; 185264897Sbrooks long memsize; 186245330Srwatson#ifdef FDT 187265089Sbz char buf[2048]; /* early stack supposedly big enough */ 188245330Srwatson vm_offset_t dtbp; 189265089Sbz phandle_t chosen; 190245330Srwatson void *kmdp; 191245330Srwatson#endif 192239671Srwatson int i; 193239671Srwatson 194239671Srwatson /* clear the BSS and SBSS segments */ 195239671Srwatson kernend = (vm_offset_t)&end; 196239671Srwatson memset(&edata, 0, kernend - (vm_offset_t)(&edata)); 197239671Srwatson 198239671Srwatson mips_postboot_fixup(); 199239671Srwatson 200239671Srwatson mips_pcpu0_init(); 201239671Srwatson 202264897Sbrooks /* 203264897Sbrooks * Over time, we've changed out boot-time binary interface for the 204264897Sbrooks * kernel. Miniboot simply provides a 'memsize' in a3, whereas the 205264897Sbrooks * FreeBSD boot loader provides a 'bootinfo *' in a3. While slightly 206264897Sbrooks * grody, we support both here by detecting 'pointer-like' values in 207264897Sbrooks * a3 and assuming physical memory can never be that back. 208264897Sbrooks * 209264897Sbrooks * XXXRW: Pull more values than memsize out of bootinfop -- e.g., 210264897Sbrooks * module information. 211264897Sbrooks */ 212264897Sbrooks if (a3 >= 0x9800000000000000ULL) { 213264897Sbrooks bootinfop = (void *)a3; 214264897Sbrooks memsize = bootinfop->bi_memsize; 215264897Sbrooks preload_metadata = (caddr_t)bootinfop->bi_modulep; 216264897Sbrooks } else { 217264897Sbrooks bootinfop = NULL; 218264897Sbrooks memsize = a3; 219264897Sbrooks } 220264897Sbrooks 221245329Srwatson#ifdef FDT 222245330Srwatson /* 223245330Srwatson * Find the dtb passed in by the boot loader (currently fictional). 224245330Srwatson */ 225245330Srwatson kmdp = preload_search_by_type("elf kernel"); 226245330Srwatson if (kmdp != NULL) 227245330Srwatson dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t); 228245330Srwatson else 229245330Srwatson dtbp = (vm_offset_t)NULL; 230245330Srwatson 231245330Srwatson#if defined(FDT_DTB_STATIC) 232245330Srwatson /* 233245330Srwatson * In case the device tree blob was not retrieved (from metadata) try 234245330Srwatson * to use the statically embedded one. 235245330Srwatson */ 236245330Srwatson if (dtbp == (vm_offset_t)NULL) 237245330Srwatson dtbp = (vm_offset_t)&fdt_static_dtb; 238245330Srwatson#else 239245330Srwatson#error "Non-static FDT not yet supported on BERI" 240245329Srwatson#endif 241245329Srwatson 242245329Srwatson if (OF_install(OFW_FDT, 0) == FALSE) 243245329Srwatson while (1); 244259265Sbz if (OF_init((void *)dtbp) != 0) 245245329Srwatson while (1); 246264605Sbz 247264605Sbz /* 248264897Sbrooks * Configure more boot-time parameters passed in by loader. 249264605Sbz */ 250264897Sbrooks boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); 251264897Sbrooks kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *); 252245329Srwatson 253239671Srwatson /* 254265089Sbz * Get bootargs from FDT if specified. 255265089Sbz */ 256265089Sbz chosen = OF_finddevice("/chosen"); 257265089Sbz if (OF_getprop(chosen, "bootargs", buf, sizeof(buf)) != -1) 258265089Sbz _parse_bootargs(buf); 259265089Sbz#endif 260265089Sbz 261265089Sbz /* 262239671Srwatson * XXXRW: We have no way to compare wallclock time to cycle rate on 263239671Srwatson * BERI, so for now assume we run at the MALTA default (100MHz). 264239671Srwatson */ 265239671Srwatson platform_counter_freq = MIPS_DEFAULT_HZ; 266239671Srwatson mips_timer_early_init(platform_counter_freq); 267239671Srwatson 268239671Srwatson cninit(); 269239671Srwatson printf("entry: platform_start()\n"); 270239671Srwatson 271239671Srwatson bootverbose = 1; 272239671Srwatson if (bootverbose) { 273239671Srwatson printf("cmd line: "); 274239671Srwatson for (i = 0; i < argc; i++) 275239671Srwatson printf("%s ", argv[i]); 276239671Srwatson printf("\n"); 277239671Srwatson 278239671Srwatson printf("envp:\n"); 279239671Srwatson for (i = 0; envp[i]; i += 2) 280239671Srwatson printf("\t%s = %s\n", envp[i], envp[i+1]); 281239671Srwatson 282264897Sbrooks if (bootinfop != NULL) 283264897Sbrooks printf("bootinfo found at %p\n", bootinfop); 284264897Sbrooks 285264897Sbrooks printf("memsize = %p\n", (void *)memsize); 286239671Srwatson } 287239671Srwatson 288239671Srwatson realmem = btoc(memsize); 289239671Srwatson mips_init(); 290239671Srwatson 291239671Srwatson mips_timer_init_params(platform_counter_freq, 0); 292239671Srwatson} 293