sb_machdep.c revision 203510
1/*- 2 * Copyright (c) 2007 Bruce M. Simpson. 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 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: head/sys/mips/sibyte/sb_machdep.c 203510 2010-02-05 03:22:04Z neel $"); 29 30#include <sys/param.h> 31#include <machine/cpuregs.h> 32 33#include "opt_ddb.h" 34#include "opt_kdb.h" 35 36#include <sys/param.h> 37#include <sys/conf.h> 38#include <sys/kernel.h> 39#include <sys/systm.h> 40#include <sys/imgact.h> 41#include <sys/bio.h> 42#include <sys/buf.h> 43#include <sys/bus.h> 44#include <sys/cpu.h> 45#include <sys/cons.h> 46#include <sys/exec.h> 47#include <sys/ucontext.h> 48#include <sys/proc.h> 49#include <sys/kdb.h> 50#include <sys/ptrace.h> 51#include <sys/reboot.h> 52#include <sys/signalvar.h> 53#include <sys/sysent.h> 54#include <sys/sysproto.h> 55#include <sys/user.h> 56 57#include <vm/vm.h> 58#include <vm/vm_object.h> 59#include <vm/vm_page.h> 60#include <vm/vm_pager.h> 61 62#include <machine/cache.h> 63#include <machine/clock.h> 64#include <machine/cpu.h> 65#include <machine/cpuinfo.h> 66#include <machine/cpufunc.h> 67#include <machine/cpuregs.h> 68#include <machine/hwfunc.h> 69#include <machine/intr_machdep.h> 70#include <machine/locore.h> 71#include <machine/md_var.h> 72#include <machine/pte.h> 73#include <machine/sigframe.h> 74#include <machine/trap.h> 75#include <machine/vmparam.h> 76 77#ifdef CFE 78#include <dev/cfe/cfe_api.h> 79#endif 80 81#include "sb_scd.h" 82 83#ifdef DDB 84#ifndef KDB 85#error KDB must be enabled in order for DDB to work! 86#endif 87#endif 88 89#ifdef CFE_ENV 90extern void cfe_env_init(void); 91#endif 92 93extern int *edata; 94extern int *end; 95 96extern char MipsTLBMiss[], MipsTLBMissEnd[]; 97 98void 99platform_cpu_init() 100{ 101 /* Nothing special */ 102} 103 104static void 105sb_intr_init(int cpuid) 106{ 107 int intrnum, intsrc; 108 109 /* 110 * Disable all sources to the interrupt mapper and setup the mapping 111 * between an interrupt source and the mips hard interrupt number. 112 */ 113 for (intsrc = 0; intsrc < NUM_INTSRC; ++intsrc) { 114 intrnum = sb_route_intsrc(intsrc); 115 sb_disable_intsrc(cpuid, intsrc); 116 sb_write_intmap(cpuid, intsrc, intrnum); 117 } 118} 119 120static void 121mips_init(void) 122{ 123 int i, cfe_mem_idx, tmp; 124 uint64_t maxmem; 125 126#ifdef CFE_ENV 127 cfe_env_init(); 128#endif 129 130 TUNABLE_INT_FETCH("boothowto", &boothowto); 131 132 if (boothowto & RB_VERBOSE) 133 bootverbose++; 134 135#ifdef MAXMEM 136 tmp = MAXMEM; 137#else 138 tmp = 0; 139#endif 140 TUNABLE_INT_FETCH("hw.physmem", &tmp); 141 maxmem = (uint64_t)tmp * 1024; 142 143#ifdef CFE 144 /* 145 * Query DRAM memory map from CFE. 146 */ 147 physmem = 0; 148 cfe_mem_idx = 0; 149 for (i = 0; i < 10; i += 2) { 150 int result; 151 uint64_t addr, len, type; 152 153 result = cfe_enummem(cfe_mem_idx++, 0, &addr, &len, &type); 154 if (result < 0) { 155 phys_avail[i] = phys_avail[i + 1] = 0; 156 break; 157 } 158 159 KASSERT(type == CFE_MI_AVAILABLE, 160 ("CFE DRAM region is not available?")); 161 162 if (bootverbose) 163 printf("cfe_enummem: 0x%016jx/%llu.\n", addr, len); 164 165 if (maxmem != 0) { 166 if (addr >= maxmem) { 167 printf("Ignoring %llu bytes of memory at 0x%jx " 168 "that is above maxmem %dMB\n", 169 len, addr, 170 (int)(maxmem / (1024 * 1024))); 171 continue; 172 } 173 174 if (addr + len > maxmem) { 175 printf("Ignoring %llu bytes of memory " 176 "that is above maxmem %dMB\n", 177 (addr + len) - maxmem, 178 (int)(maxmem / (1024 * 1024))); 179 len = maxmem - addr; 180 } 181 } 182 183 phys_avail[i] = addr; 184 if (i == 0 && addr == 0) { 185 /* 186 * If this is the first physical memory segment probed 187 * from CFE, omit the region at the start of physical 188 * memory where the kernel has been loaded. 189 */ 190 phys_avail[i] += MIPS_KSEG0_TO_PHYS(kernel_kseg0_end); 191 } 192 phys_avail[i + 1] = addr + len; 193 physmem += len; 194 } 195 196 realmem = btoc(physmem); 197#endif 198 199 physmem = realmem; 200 201 init_param1(); 202 init_param2(physmem); 203 mips_cpu_init(); 204 205 /* 206 * XXX 207 * The kernel is running in 32-bit mode but the CFE is running in 208 * 64-bit mode. So the SR_KX bit in the status register is turned 209 * on by the CFE every time we call into it - for e.g. CFE_CONSOLE. 210 * 211 * This means that if get a TLB miss for any address above 0xc0000000 212 * and the SR_KX bit is set then we will end up in the XTLB exception 213 * vector. 214 * 215 * For now work around this by copying the TLB exception handling 216 * code to the XTLB exception vector. 217 */ 218 { 219 bcopy(MipsTLBMiss, (void *)XTLB_MISS_EXC_VEC, 220 MipsTLBMissEnd - MipsTLBMiss); 221 222 mips_icache_sync_all(); 223 mips_dcache_wbinv_all(); 224 } 225 226 pmap_bootstrap(); 227 mips_proc0_init(); 228 mutex_init(); 229 230 kdb_init(); 231#ifdef KDB 232 if (boothowto & RB_KDB) 233 kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); 234#endif 235} 236 237void 238platform_halt(void) 239{ 240 241} 242 243 244void 245platform_identify(void) 246{ 247 248} 249 250void 251platform_reset(void) 252{ 253 254 /* 255 * XXX SMP 256 * XXX flush data caches 257 */ 258 sb_system_reset(); 259} 260 261void 262platform_trap_enter(void) 263{ 264 265} 266 267void 268platform_trap_exit(void) 269{ 270 271} 272 273static void 274kseg0_map_coherent(void) 275{ 276 uint32_t config; 277 const int CFG_K0_COHERENT = 5; 278 279 config = mips_rd_config(); 280 config &= ~CFG_K0_MASK; 281 config |= CFG_K0_COHERENT; 282 mips_wr_config(config); 283} 284 285void 286platform_start(__register_t a0, __register_t a1, __register_t a2, 287 __register_t a3) 288{ 289 /* 290 * Make sure that kseg0 is mapped cacheable-coherent 291 */ 292 kseg0_map_coherent(); 293 294 /* clear the BSS and SBSS segments */ 295 memset(&edata, 0, (vm_offset_t)&end - (vm_offset_t)&edata); 296 mips_postboot_fixup(); 297 298 sb_intr_init(0); 299 300 /* Initialize pcpu stuff */ 301 mips_pcpu0_init(); 302 303#ifdef CFE 304 /* 305 * Initialize CFE firmware trampolines before 306 * we initialize the low-level console. 307 * 308 * CFE passes the following values in registers: 309 * a0: firmware handle 310 * a2: firmware entry point 311 * a3: entry point seal 312 */ 313 if (a3 == CFE_EPTSEAL) 314 cfe_init(a0, a2); 315#endif 316 cninit(); 317 318 mips_init(); 319 320 mips_timer_init_params(sb_cpu_speed(), 0); 321} 322