1234920Srwatson/*- 2234920Srwatson * Copyright (c) 2006 Wojciech A. Koszek <wkoszek@FreeBSD.org> 3234920Srwatson * All rights reserved. 4234920Srwatson * 5234920Srwatson * Redistribution and use in source and binary forms, with or without 6234920Srwatson * modification, are permitted provided that the following conditions 7234920Srwatson * are met: 8234920Srwatson * 1. Redistributions of source code must retain the above copyright 9234920Srwatson * notice, this list of conditions and the following disclaimer. 10234920Srwatson * 2. Redistributions in binary form must reproduce the above copyright 11234920Srwatson * notice, this list of conditions and the following disclaimer in the 12234920Srwatson * documentation and/or other materials provided with the distribution. 13234920Srwatson * 14234920Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15234920Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16234920Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17234920Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18234920Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19234920Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20234920Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21234920Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22234920Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23234920Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24234920Srwatson * SUCH DAMAGE. 25234920Srwatson */ 26234920Srwatson#include <sys/cdefs.h> 27234920Srwatson__FBSDID("$FreeBSD: releng/10.3/sys/mips/gxemul/gxemul_machdep.c 247297 2013-02-26 01:00:11Z attilio $"); 28234920Srwatson 29234920Srwatson#include "opt_ddb.h" 30234920Srwatson 31234920Srwatson#include <sys/param.h> 32234920Srwatson#include <sys/conf.h> 33234920Srwatson#include <sys/kernel.h> 34234920Srwatson#include <sys/systm.h> 35234920Srwatson#include <sys/imgact.h> 36234920Srwatson#include <sys/bio.h> 37234920Srwatson#include <sys/buf.h> 38234920Srwatson#include <sys/bus.h> 39234920Srwatson#include <sys/cpu.h> 40234920Srwatson#include <sys/cons.h> 41234920Srwatson#include <sys/exec.h> 42234920Srwatson#include <sys/ucontext.h> 43234920Srwatson#include <sys/proc.h> 44234920Srwatson#include <sys/kdb.h> 45234920Srwatson#include <sys/ptrace.h> 46234920Srwatson#include <sys/reboot.h> 47234920Srwatson#include <sys/signalvar.h> 48234920Srwatson#include <sys/sysent.h> 49234920Srwatson#include <sys/sysproto.h> 50234920Srwatson#include <sys/user.h> 51234920Srwatson 52234920Srwatson#include <vm/vm.h> 53234920Srwatson#include <vm/vm_object.h> 54234920Srwatson#include <vm/vm_page.h> 55234920Srwatson 56234920Srwatson#include <machine/clock.h> 57234920Srwatson#include <machine/cpu.h> 58234920Srwatson#include <machine/cpuregs.h> 59234920Srwatson#include <machine/hwfunc.h> 60234920Srwatson#include <machine/md_var.h> 61234920Srwatson#include <machine/pmap.h> 62234920Srwatson#include <machine/trap.h> 63234920Srwatson 64235118Sjmallett#ifdef SMP 65235118Sjmallett#include <sys/smp.h> 66235118Sjmallett#include <machine/smp.h> 67235118Sjmallett#endif 68235118Sjmallett 69235070Sjmallett#include <mips/gxemul/mpreg.h> 70235070Sjmallett 71234920Srwatsonextern int *edata; 72234920Srwatsonextern int *end; 73234920Srwatson 74234920Srwatsonvoid 75234920Srwatsonplatform_cpu_init() 76234920Srwatson{ 77234920Srwatson /* Nothing special */ 78234920Srwatson} 79234920Srwatson 80234920Srwatsonstatic void 81234920Srwatsonmips_init(void) 82234920Srwatson{ 83234920Srwatson int i; 84234920Srwatson 85234920Srwatson for (i = 0; i < 10; i++) { 86234920Srwatson phys_avail[i] = 0; 87234920Srwatson } 88234920Srwatson 89234920Srwatson /* phys_avail regions are in bytes */ 90234920Srwatson phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end); 91234920Srwatson phys_avail[1] = ctob(realmem); 92234920Srwatson 93234920Srwatson dump_avail[0] = phys_avail[0]; 94234920Srwatson dump_avail[1] = phys_avail[1]; 95234920Srwatson 96234920Srwatson physmem = realmem; 97234920Srwatson 98234920Srwatson init_param1(); 99234920Srwatson init_param2(physmem); 100234920Srwatson mips_cpu_init(); 101234920Srwatson pmap_bootstrap(); 102234920Srwatson mips_proc0_init(); 103234920Srwatson mutex_init(); 104234920Srwatson kdb_init(); 105234920Srwatson#ifdef KDB 106234920Srwatson if (boothowto & RB_KDB) 107234920Srwatson kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); 108234920Srwatson#endif 109234920Srwatson} 110234920Srwatson 111234920Srwatson/* 112234920Srwatson * Perform a board-level soft-reset. 113234920Srwatson * 114234920Srwatson * XXXRW: Does gxemul have a moral equivalent to board-level reset? 115234920Srwatson */ 116234920Srwatsonvoid 117234920Srwatsonplatform_reset(void) 118234920Srwatson{ 119234920Srwatson 120234920Srwatson panic("%s: not yet", __func__); 121234920Srwatson} 122234920Srwatson 123234920Srwatsonvoid 124234920Srwatsonplatform_start(__register_t a0, __register_t a1, __register_t a2, 125234920Srwatson __register_t a3) 126234920Srwatson{ 127234920Srwatson vm_offset_t kernend; 128234920Srwatson uint64_t platform_counter_freq; 129234920Srwatson int argc = a0; 130234920Srwatson char **argv = (char **)a1; 131234920Srwatson char **envp = (char **)a2; 132234920Srwatson int i; 133234920Srwatson 134234920Srwatson /* clear the BSS and SBSS segments */ 135234920Srwatson kernend = (vm_offset_t)&end; 136234920Srwatson memset(&edata, 0, kernend - (vm_offset_t)(&edata)); 137234920Srwatson 138234920Srwatson mips_postboot_fixup(); 139234920Srwatson 140234920Srwatson mips_pcpu0_init(); 141234920Srwatson 142234920Srwatson /* 143234920Srwatson * XXXRW: Support for the gxemul real-time clock required in order to 144234920Srwatson * usefully determine our emulated timer frequency. Go with something 145234920Srwatson * classic as the default in the mean time. 146234920Srwatson */ 147234920Srwatson platform_counter_freq = MIPS_DEFAULT_HZ; 148234920Srwatson mips_timer_early_init(platform_counter_freq); 149234920Srwatson 150234920Srwatson cninit(); 151234920Srwatson printf("entry: platform_start()\n"); 152234920Srwatson 153234920Srwatson bootverbose = 1; 154234920Srwatson if (bootverbose) { 155234920Srwatson printf("cmd line: "); 156234920Srwatson for (i = 0; i < argc; i++) 157234920Srwatson printf("%s ", argv[i]); 158234920Srwatson printf("\n"); 159234920Srwatson 160235070Sjmallett if (envp != NULL) { 161235070Sjmallett printf("envp:\n"); 162235070Sjmallett for (i = 0; envp[i]; i += 2) 163235070Sjmallett printf("\t%s = %s\n", envp[i], envp[i+1]); 164235070Sjmallett } else { 165235070Sjmallett printf("no envp.\n"); 166235070Sjmallett } 167234920Srwatson } 168234920Srwatson 169235070Sjmallett realmem = btoc(GXEMUL_MP_DEV_READ(GXEMUL_MP_DEV_MEMORY)); 170234920Srwatson mips_init(); 171234920Srwatson 172234920Srwatson mips_timer_init_params(platform_counter_freq, 0); 173234920Srwatson} 174235118Sjmallett 175235118Sjmallett#ifdef SMP 176235118Sjmallettvoid 177235118Sjmallettplatform_ipi_send(int cpuid) 178235118Sjmallett{ 179235118Sjmallett GXEMUL_MP_DEV_WRITE(GXEMUL_MP_DEV_IPI_ONE, (1 << 16) | cpuid); 180235118Sjmallett} 181235118Sjmallett 182235118Sjmallettvoid 183235118Sjmallettplatform_ipi_clear(void) 184235118Sjmallett{ 185235118Sjmallett GXEMUL_MP_DEV_WRITE(GXEMUL_MP_DEV_IPI_READ, 0); 186235118Sjmallett} 187235118Sjmallett 188235118Sjmallettint 189235118Sjmallettplatform_ipi_intrnum(void) 190235118Sjmallett{ 191235118Sjmallett return (GXEMUL_MP_DEV_IPI_INTERRUPT - 2); 192235118Sjmallett} 193235118Sjmallett 194235118Sjmallettstruct cpu_group * 195235118Sjmallettplatform_smp_topo(void) 196235118Sjmallett{ 197235118Sjmallett return (smp_topo_none()); 198235118Sjmallett} 199235118Sjmallett 200235118Sjmallettvoid 201235118Sjmallettplatform_init_ap(int cpuid) 202235118Sjmallett{ 203235118Sjmallett int ipi_int_mask, clock_int_mask; 204235118Sjmallett 205235118Sjmallett /* 206235118Sjmallett * Unmask the clock and ipi interrupts. 207235118Sjmallett */ 208235118Sjmallett clock_int_mask = hard_int_mask(5); 209235118Sjmallett ipi_int_mask = hard_int_mask(platform_ipi_intrnum()); 210235118Sjmallett set_intr_mask(ipi_int_mask | clock_int_mask); 211235118Sjmallett} 212235118Sjmallett 213235118Sjmallettvoid 214235118Sjmallettplatform_cpu_mask(cpuset_t *mask) 215235118Sjmallett{ 216235118Sjmallett unsigned i, n; 217235118Sjmallett 218235118Sjmallett n = GXEMUL_MP_DEV_READ(GXEMUL_MP_DEV_NCPUS); 219235118Sjmallett CPU_ZERO(mask); 220235118Sjmallett for (i = 0; i < n; i++) 221235118Sjmallett CPU_SET(i, mask); 222235118Sjmallett} 223235118Sjmallett 224235118Sjmallettint 225235118Sjmallettplatform_processor_id(void) 226235118Sjmallett{ 227235118Sjmallett return (GXEMUL_MP_DEV_READ(GXEMUL_MP_DEV_WHOAMI)); 228235118Sjmallett} 229235118Sjmallett 230235118Sjmallettint 231235118Sjmallettplatform_start_ap(int cpuid) 232235118Sjmallett{ 233235118Sjmallett GXEMUL_MP_DEV_WRITE(GXEMUL_MP_DEV_STARTADDR, (intptr_t)mpentry); 234235118Sjmallett GXEMUL_MP_DEV_WRITE(GXEMUL_MP_DEV_START, cpuid); 235235118Sjmallett return (0); 236235118Sjmallett} 237235118Sjmallett#endif /* SMP */ 238