sb_machdep.c revision 203510
1195333Simp/*- 2195333Simp * Copyright (c) 2007 Bruce M. Simpson. 3195333Simp * All rights reserved. 4195333Simp * 5195333Simp * Redistribution and use in source and binary forms, with or without 6195333Simp * modification, are permitted provided that the following conditions 7195333Simp * are met: 8195333Simp * 1. Redistributions of source code must retain the above copyright 9195333Simp * notice, this list of conditions and the following disclaimer. 10195333Simp * 2. Redistributions in binary form must reproduce the above copyright 11195333Simp * notice, this list of conditions and the following disclaimer in the 12195333Simp * documentation and/or other materials provided with the distribution. 13195333Simp * 14195333Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15195333Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16195333Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17195333Simp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18195333Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19195333Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20195333Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21195333Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22195333Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23195333Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24195333Simp * SUCH DAMAGE. 25195333Simp */ 26195333Simp 27195333Simp#include <sys/cdefs.h> 28195333Simp__FBSDID("$FreeBSD: head/sys/mips/sibyte/sb_machdep.c 203510 2010-02-05 03:22:04Z neel $"); 29195333Simp 30195333Simp#include <sys/param.h> 31195333Simp#include <machine/cpuregs.h> 32195333Simp 33195333Simp#include "opt_ddb.h" 34195333Simp#include "opt_kdb.h" 35195333Simp 36195333Simp#include <sys/param.h> 37195333Simp#include <sys/conf.h> 38195333Simp#include <sys/kernel.h> 39195333Simp#include <sys/systm.h> 40195333Simp#include <sys/imgact.h> 41195333Simp#include <sys/bio.h> 42195333Simp#include <sys/buf.h> 43195333Simp#include <sys/bus.h> 44195333Simp#include <sys/cpu.h> 45195333Simp#include <sys/cons.h> 46195333Simp#include <sys/exec.h> 47195333Simp#include <sys/ucontext.h> 48195333Simp#include <sys/proc.h> 49195333Simp#include <sys/kdb.h> 50195333Simp#include <sys/ptrace.h> 51195333Simp#include <sys/reboot.h> 52195333Simp#include <sys/signalvar.h> 53195333Simp#include <sys/sysent.h> 54195333Simp#include <sys/sysproto.h> 55195333Simp#include <sys/user.h> 56195333Simp 57195333Simp#include <vm/vm.h> 58195333Simp#include <vm/vm_object.h> 59195333Simp#include <vm/vm_page.h> 60195333Simp#include <vm/vm_pager.h> 61195333Simp 62195333Simp#include <machine/cache.h> 63195333Simp#include <machine/clock.h> 64195333Simp#include <machine/cpu.h> 65195333Simp#include <machine/cpuinfo.h> 66195333Simp#include <machine/cpufunc.h> 67195333Simp#include <machine/cpuregs.h> 68195333Simp#include <machine/hwfunc.h> 69195333Simp#include <machine/intr_machdep.h> 70195333Simp#include <machine/locore.h> 71195333Simp#include <machine/md_var.h> 72195333Simp#include <machine/pte.h> 73195333Simp#include <machine/sigframe.h> 74195333Simp#include <machine/trap.h> 75195333Simp#include <machine/vmparam.h> 76195333Simp 77195333Simp#ifdef CFE 78195333Simp#include <dev/cfe/cfe_api.h> 79195333Simp#endif 80195333Simp 81195333Simp#include "sb_scd.h" 82195333Simp 83195333Simp#ifdef DDB 84195333Simp#ifndef KDB 85195333Simp#error KDB must be enabled in order for DDB to work! 86195333Simp#endif 87195333Simp#endif 88195333Simp 89195333Simp#ifdef CFE_ENV 90195333Simpextern void cfe_env_init(void); 91195333Simp#endif 92195333Simp 93195333Simpextern int *edata; 94195333Simpextern int *end; 95195333Simp 96203000Sneelextern char MipsTLBMiss[], MipsTLBMissEnd[]; 97203000Sneel 98198669Srrsvoid 99198669Srrsplatform_cpu_init() 100198669Srrs{ 101198669Srrs /* Nothing special */ 102198669Srrs} 103198669Srrs 104195333Simpstatic void 105203510Sneelsb_intr_init(int cpuid) 106203510Sneel{ 107203510Sneel int intrnum, intsrc; 108203510Sneel 109203510Sneel /* 110203510Sneel * Disable all sources to the interrupt mapper and setup the mapping 111203510Sneel * between an interrupt source and the mips hard interrupt number. 112203510Sneel */ 113203510Sneel for (intsrc = 0; intsrc < NUM_INTSRC; ++intsrc) { 114203510Sneel intrnum = sb_route_intsrc(intsrc); 115203510Sneel sb_disable_intsrc(cpuid, intsrc); 116203510Sneel sb_write_intmap(cpuid, intsrc, intrnum); 117203510Sneel } 118203510Sneel} 119203510Sneel 120203510Sneelstatic void 121195333Simpmips_init(void) 122195333Simp{ 123195333Simp int i, cfe_mem_idx, tmp; 124195333Simp uint64_t maxmem; 125195333Simp 126195333Simp#ifdef CFE_ENV 127195333Simp cfe_env_init(); 128195333Simp#endif 129195333Simp 130195333Simp TUNABLE_INT_FETCH("boothowto", &boothowto); 131195333Simp 132195333Simp if (boothowto & RB_VERBOSE) 133195333Simp bootverbose++; 134195333Simp 135195333Simp#ifdef MAXMEM 136195333Simp tmp = MAXMEM; 137195333Simp#else 138195333Simp tmp = 0; 139195333Simp#endif 140195333Simp TUNABLE_INT_FETCH("hw.physmem", &tmp); 141195333Simp maxmem = (uint64_t)tmp * 1024; 142195333Simp 143195333Simp#ifdef CFE 144195333Simp /* 145195333Simp * Query DRAM memory map from CFE. 146195333Simp */ 147195333Simp physmem = 0; 148195333Simp cfe_mem_idx = 0; 149195333Simp for (i = 0; i < 10; i += 2) { 150195333Simp int result; 151195333Simp uint64_t addr, len, type; 152195333Simp 153195333Simp result = cfe_enummem(cfe_mem_idx++, 0, &addr, &len, &type); 154195333Simp if (result < 0) { 155195333Simp phys_avail[i] = phys_avail[i + 1] = 0; 156195333Simp break; 157195333Simp } 158195333Simp 159195333Simp KASSERT(type == CFE_MI_AVAILABLE, 160195333Simp ("CFE DRAM region is not available?")); 161195333Simp 162195333Simp if (bootverbose) 163195333Simp printf("cfe_enummem: 0x%016jx/%llu.\n", addr, len); 164195333Simp 165195333Simp if (maxmem != 0) { 166195333Simp if (addr >= maxmem) { 167195333Simp printf("Ignoring %llu bytes of memory at 0x%jx " 168195333Simp "that is above maxmem %dMB\n", 169195333Simp len, addr, 170195333Simp (int)(maxmem / (1024 * 1024))); 171195333Simp continue; 172195333Simp } 173195333Simp 174195333Simp if (addr + len > maxmem) { 175195333Simp printf("Ignoring %llu bytes of memory " 176195333Simp "that is above maxmem %dMB\n", 177195333Simp (addr + len) - maxmem, 178195333Simp (int)(maxmem / (1024 * 1024))); 179195333Simp len = maxmem - addr; 180195333Simp } 181195333Simp } 182195333Simp 183195333Simp phys_avail[i] = addr; 184195333Simp if (i == 0 && addr == 0) { 185195333Simp /* 186195333Simp * If this is the first physical memory segment probed 187195333Simp * from CFE, omit the region at the start of physical 188195333Simp * memory where the kernel has been loaded. 189195333Simp */ 190202954Sgonzo phys_avail[i] += MIPS_KSEG0_TO_PHYS(kernel_kseg0_end); 191195333Simp } 192195333Simp phys_avail[i + 1] = addr + len; 193195333Simp physmem += len; 194195333Simp } 195195333Simp 196195333Simp realmem = btoc(physmem); 197195333Simp#endif 198195333Simp 199195333Simp physmem = realmem; 200195333Simp 201195333Simp init_param1(); 202195333Simp init_param2(physmem); 203195333Simp mips_cpu_init(); 204203000Sneel 205203000Sneel /* 206203000Sneel * XXX 207203000Sneel * The kernel is running in 32-bit mode but the CFE is running in 208203000Sneel * 64-bit mode. So the SR_KX bit in the status register is turned 209203000Sneel * on by the CFE every time we call into it - for e.g. CFE_CONSOLE. 210203000Sneel * 211203000Sneel * This means that if get a TLB miss for any address above 0xc0000000 212203000Sneel * and the SR_KX bit is set then we will end up in the XTLB exception 213203000Sneel * vector. 214203000Sneel * 215203000Sneel * For now work around this by copying the TLB exception handling 216203000Sneel * code to the XTLB exception vector. 217203000Sneel */ 218203000Sneel { 219203000Sneel bcopy(MipsTLBMiss, (void *)XTLB_MISS_EXC_VEC, 220203000Sneel MipsTLBMissEnd - MipsTLBMiss); 221203000Sneel 222203000Sneel mips_icache_sync_all(); 223203000Sneel mips_dcache_wbinv_all(); 224203000Sneel } 225203000Sneel 226195333Simp pmap_bootstrap(); 227195333Simp mips_proc0_init(); 228195333Simp mutex_init(); 229195333Simp 230195333Simp kdb_init(); 231195333Simp#ifdef KDB 232195333Simp if (boothowto & RB_KDB) 233195333Simp kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); 234195333Simp#endif 235195333Simp} 236195333Simp 237195333Simpvoid 238195333Simpplatform_halt(void) 239195333Simp{ 240195333Simp 241195333Simp} 242195333Simp 243195333Simp 244195333Simpvoid 245195333Simpplatform_identify(void) 246195333Simp{ 247195333Simp 248195333Simp} 249195333Simp 250195333Simpvoid 251195333Simpplatform_reset(void) 252195333Simp{ 253195333Simp 254195333Simp /* 255195333Simp * XXX SMP 256195333Simp * XXX flush data caches 257195333Simp */ 258195333Simp sb_system_reset(); 259195333Simp} 260195333Simp 261195333Simpvoid 262195333Simpplatform_trap_enter(void) 263195333Simp{ 264195333Simp 265195333Simp} 266195333Simp 267195333Simpvoid 268195333Simpplatform_trap_exit(void) 269195333Simp{ 270195333Simp 271195333Simp} 272195333Simp 273202864Sneelstatic void 274202864Sneelkseg0_map_coherent(void) 275202864Sneel{ 276202864Sneel uint32_t config; 277202864Sneel const int CFG_K0_COHERENT = 5; 278202864Sneel 279202864Sneel config = mips_rd_config(); 280202864Sneel config &= ~CFG_K0_MASK; 281202864Sneel config |= CFG_K0_COHERENT; 282202864Sneel mips_wr_config(config); 283202864Sneel} 284202864Sneel 285195333Simpvoid 286201631Sneelplatform_start(__register_t a0, __register_t a1, __register_t a2, 287201631Sneel __register_t a3) 288195333Simp{ 289202864Sneel /* 290202864Sneel * Make sure that kseg0 is mapped cacheable-coherent 291202864Sneel */ 292202864Sneel kseg0_map_coherent(); 293202864Sneel 294195333Simp /* clear the BSS and SBSS segments */ 295195333Simp memset(&edata, 0, (vm_offset_t)&end - (vm_offset_t)&edata); 296202954Sgonzo mips_postboot_fixup(); 297195333Simp 298203510Sneel sb_intr_init(0); 299203510Sneel 300201845Simp /* Initialize pcpu stuff */ 301201881Simp mips_pcpu0_init(); 302201845Simp 303195333Simp#ifdef CFE 304195333Simp /* 305195333Simp * Initialize CFE firmware trampolines before 306195333Simp * we initialize the low-level console. 307201631Sneel * 308201631Sneel * CFE passes the following values in registers: 309201631Sneel * a0: firmware handle 310201631Sneel * a2: firmware entry point 311201631Sneel * a3: entry point seal 312195333Simp */ 313201631Sneel if (a3 == CFE_EPTSEAL) 314201631Sneel cfe_init(a0, a2); 315195333Simp#endif 316195333Simp cninit(); 317195333Simp 318195333Simp mips_init(); 319195333Simp 320195333Simp mips_timer_init_params(sb_cpu_speed(), 0); 321195333Simp} 322