1/*- 2 * Copyright (c) 2006 Wojciech A. Koszek <wkoszek@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26#include <sys/cdefs.h> 27__FBSDID("$FreeBSD$"); 28 29#include "opt_ddb.h" 30 31#include <sys/param.h> 32#include <sys/conf.h> 33#include <sys/kernel.h> 34#include <sys/systm.h> 35#include <sys/imgact.h> 36#include <sys/bio.h> 37#include <sys/buf.h> 38#include <sys/bus.h> 39#include <sys/cpu.h> 40#include <sys/cons.h> 41#include <sys/exec.h> 42#include <sys/ucontext.h> 43#include <sys/proc.h> 44#include <sys/kdb.h> 45#include <sys/ptrace.h> 46#include <sys/reboot.h> 47#include <sys/signalvar.h> 48#include <sys/sysent.h> 49#include <sys/sysproto.h> 50#include <sys/user.h> 51 52#include <vm/vm.h> 53#include <vm/vm_object.h> 54#include <vm/vm_page.h> 55 56#include <machine/clock.h> 57#include <machine/cpu.h> 58#include <machine/cpuregs.h> 59#include <machine/hwfunc.h> 60#include <machine/md_var.h> 61#include <machine/pmap.h> 62#include <machine/trap.h> 63 64#ifdef SMP 65#include <sys/smp.h> 66#include <machine/smp.h> 67#endif 68 69#include <mips/gxemul/mpreg.h> 70 71extern int *edata; 72extern int *end; 73 74void 75platform_cpu_init() 76{ 77 /* Nothing special */ 78} 79 80static void 81mips_init(void) 82{ 83 int i; 84 85 for (i = 0; i < 10; i++) { 86 phys_avail[i] = 0; 87 } 88 89 /* phys_avail regions are in bytes */ 90 phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end); 91 phys_avail[1] = ctob(realmem); 92 93 dump_avail[0] = phys_avail[0]; 94 dump_avail[1] = phys_avail[1]; 95 96 physmem = realmem; 97 98 init_param1(); 99 init_param2(physmem); 100 mips_cpu_init(); 101 pmap_bootstrap(); 102 mips_proc0_init(); 103 mutex_init(); 104 kdb_init(); 105#ifdef KDB 106 if (boothowto & RB_KDB) 107 kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); 108#endif 109} 110 111/* 112 * Perform a board-level soft-reset. 113 * 114 * XXXRW: Does gxemul have a moral equivalent to board-level reset? 115 */ 116void 117platform_reset(void) 118{ 119 120 panic("%s: not yet", __func__); 121} 122 123void 124platform_start(__register_t a0, __register_t a1, __register_t a2, 125 __register_t a3) 126{ 127 vm_offset_t kernend; 128 uint64_t platform_counter_freq; 129 int argc = a0; 130 char **argv = (char **)a1; 131 char **envp = (char **)a2; 132 int i; 133 134 /* clear the BSS and SBSS segments */ 135 kernend = (vm_offset_t)&end; 136 memset(&edata, 0, kernend - (vm_offset_t)(&edata)); 137 138 mips_postboot_fixup(); 139 140 mips_pcpu0_init(); 141 142 /* 143 * XXXRW: Support for the gxemul real-time clock required in order to 144 * usefully determine our emulated timer frequency. Go with something 145 * classic as the default in the mean time. 146 */ 147 platform_counter_freq = MIPS_DEFAULT_HZ; 148 mips_timer_early_init(platform_counter_freq); 149 150 cninit(); 151 printf("entry: platform_start()\n"); 152 153 bootverbose = 1; 154 if (bootverbose) { 155 printf("cmd line: "); 156 for (i = 0; i < argc; i++) 157 printf("%s ", argv[i]); 158 printf("\n"); 159 160 if (envp != NULL) { 161 printf("envp:\n"); 162 for (i = 0; envp[i]; i += 2) 163 printf("\t%s = %s\n", envp[i], envp[i+1]); 164 } else { 165 printf("no envp.\n"); 166 } 167 } 168 169 realmem = btoc(GXEMUL_MP_DEV_READ(GXEMUL_MP_DEV_MEMORY)); 170 mips_init(); 171 172 mips_timer_init_params(platform_counter_freq, 0); 173} 174 175#ifdef SMP 176void 177platform_ipi_send(int cpuid) 178{ 179 GXEMUL_MP_DEV_WRITE(GXEMUL_MP_DEV_IPI_ONE, (1 << 16) | cpuid); 180} 181 182void 183platform_ipi_clear(void) 184{ 185 GXEMUL_MP_DEV_WRITE(GXEMUL_MP_DEV_IPI_READ, 0); 186} 187 188int 189platform_ipi_intrnum(void) 190{ 191 return (GXEMUL_MP_DEV_IPI_INTERRUPT - 2); 192} 193 194struct cpu_group * 195platform_smp_topo(void) 196{ 197 return (smp_topo_none()); 198} 199 200void 201platform_init_ap(int cpuid) 202{ 203 int ipi_int_mask, clock_int_mask; 204 205 /* 206 * Unmask the clock and ipi interrupts. 207 */ 208 clock_int_mask = hard_int_mask(5); 209 ipi_int_mask = hard_int_mask(platform_ipi_intrnum()); 210 set_intr_mask(ipi_int_mask | clock_int_mask); 211} 212 213void 214platform_cpu_mask(cpuset_t *mask) 215{ 216 unsigned i, n; 217 218 n = GXEMUL_MP_DEV_READ(GXEMUL_MP_DEV_NCPUS); 219 CPU_ZERO(mask); 220 for (i = 0; i < n; i++) 221 CPU_SET(i, mask); 222} 223 224int 225platform_processor_id(void) 226{ 227 return (GXEMUL_MP_DEV_READ(GXEMUL_MP_DEV_WHOAMI)); 228} 229 230int 231platform_start_ap(int cpuid) 232{ 233 GXEMUL_MP_DEV_WRITE(GXEMUL_MP_DEV_STARTADDR, (intptr_t)mpentry); 234 GXEMUL_MP_DEV_WRITE(GXEMUL_MP_DEV_START, cpuid); 235 return (0); 236} 237#endif /* SMP */ 238