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