sb_machdep.c revision 203000
150276Speter/*- 262449Speter * Copyright (c) 2007 Bruce M. Simpson. 350276Speter * All rights reserved. 450276Speter * 550276Speter * Redistribution and use in source and binary forms, with or without 650276Speter * modification, are permitted provided that the following conditions 750276Speter * are met: 850276Speter * 1. Redistributions of source code must retain the above copyright 950276Speter * notice, this list of conditions and the following disclaimer. 1050276Speter * 2. Redistributions in binary form must reproduce the above copyright 1150276Speter * notice, this list of conditions and the following disclaimer in the 1250276Speter * documentation and/or other materials provided with the distribution. 1350276Speter * 1450276Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1550276Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1650276Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1750276Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1850276Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1950276Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2050276Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2150276Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2250276Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2350276Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2450276Speter * SUCH DAMAGE. 2550276Speter */ 2650276Speter 2750276Speter#include <sys/cdefs.h> 2850276Speter__FBSDID("$FreeBSD: head/sys/mips/sibyte/sb_machdep.c 203000 2010-01-26 03:39:10Z neel $"); 2950276Speter 3050276Speter#include <sys/param.h> 3150276Speter#include <machine/cpuregs.h> 3250276Speter 3350276Speter#include "opt_ddb.h" 3450276Speter#include "opt_kdb.h" 3550276Speter 3650276Speter#include <sys/param.h> 3750276Speter#include <sys/conf.h> 3850276Speter#include <sys/kernel.h> 3950276Speter#include <sys/systm.h> 4050276Speter#include <sys/imgact.h> 4150276Speter#include <sys/bio.h> 4266963Speter#include <sys/buf.h> 4366963Speter#include <sys/bus.h> 4450276Speter#include <sys/cpu.h> 4550276Speter#include <sys/cons.h> 4666963Speter#include <sys/exec.h> 4750276Speter#include <sys/ucontext.h> 4866963Speter#include <sys/proc.h> 4950276Speter#include <sys/kdb.h> 5050276Speter#include <sys/ptrace.h> 5150276Speter#include <sys/reboot.h> 5250276Speter#include <sys/signalvar.h> 5350276Speter#include <sys/sysent.h> 5466963Speter#include <sys/sysproto.h> 5566963Speter#include <sys/user.h> 5666963Speter 5766963Speter#include <vm/vm.h> 5866963Speter#include <vm/vm_object.h> 5966963Speter#include <vm/vm_page.h> 6050276Speter#include <vm/vm_pager.h> 6166963Speter 6266963Speter#include <machine/cache.h> 6350276Speter#include <machine/clock.h> 6462449Speter#include <machine/cpu.h> 6562449Speter#include <machine/cpuinfo.h> 6650276Speter#include <machine/cpufunc.h> 6762449Speter#include <machine/cpuregs.h> 6850276Speter#include <machine/hwfunc.h> 6962449Speter#include <machine/intr_machdep.h> 7062449Speter#include <machine/locore.h> 7162449Speter#include <machine/md_var.h> 7262449Speter#include <machine/pte.h> 7362449Speter#include <machine/sigframe.h> 7450276Speter#include <machine/trap.h> 7550276Speter#include <machine/vmparam.h> 7662449Speter 7762449Speter#ifdef CFE 7850276Speter#include <dev/cfe/cfe_api.h> 7966963Speter#endif 8062449Speter 8150276Speter#include "sb_scd.h" 8250276Speter 8366963Speter#ifdef DDB 8466963Speter#ifndef KDB 8566963Speter#error KDB must be enabled in order for DDB to work! 8666963Speter#endif 8766963Speter#endif 8866963Speter 8966963Speter#ifdef CFE_ENV 9066963Speterextern void cfe_env_init(void); 9166963Speter#endif 9266963Speter 9366963Speterextern int *edata; 9466963Speterextern int *end; 9566963Speter 9666963Speterextern char MipsTLBMiss[], MipsTLBMissEnd[]; 9766963Speter 9866963Spetervoid 9966963Speterplatform_cpu_init() 10066963Speter{ 10166963Speter /* Nothing special */ 10266963Speter} 10366963Speter 10466963Speterstatic void 10566963Spetermips_init(void) 10666963Speter{ 10766963Speter int i, cfe_mem_idx, tmp; 10866963Speter uint64_t maxmem; 10966963Speter 11066963Speter#ifdef CFE_ENV 11166963Speter cfe_env_init(); 11266963Speter#endif 11366963Speter 11466963Speter TUNABLE_INT_FETCH("boothowto", &boothowto); 11566963Speter 11666963Speter if (boothowto & RB_VERBOSE) 11766963Speter bootverbose++; 11866963Speter 11966963Speter#ifdef MAXMEM 12066963Speter tmp = MAXMEM; 12166963Speter#else 12266963Speter tmp = 0; 12366963Speter#endif 12466963Speter TUNABLE_INT_FETCH("hw.physmem", &tmp); 12566963Speter maxmem = (uint64_t)tmp * 1024; 12662449Speter 12762449Speter#ifdef CFE 12850276Speter /* 12962449Speter * Query DRAM memory map from CFE. 13062449Speter */ 13162449Speter physmem = 0; 13266963Speter cfe_mem_idx = 0; 13362449Speter for (i = 0; i < 10; i += 2) { 13450276Speter int result; 13566963Speter uint64_t addr, len, type; 13666963Speter 13762449Speter result = cfe_enummem(cfe_mem_idx++, 0, &addr, &len, &type); 13862449Speter if (result < 0) { 13950276Speter phys_avail[i] = phys_avail[i + 1] = 0; 14062449Speter break; 14150276Speter } 14266963Speter 14362449Speter KASSERT(type == CFE_MI_AVAILABLE, 14462449Speter ("CFE DRAM region is not available?")); 14562449Speter 14662449Speter if (bootverbose) 14762449Speter printf("cfe_enummem: 0x%016jx/%llu.\n", addr, len); 14850276Speter 14966963Speter if (maxmem != 0) { 15062449Speter if (addr >= maxmem) { 15162449Speter printf("Ignoring %llu bytes of memory at 0x%jx " 15262449Speter "that is above maxmem %dMB\n", 15362449Speter len, addr, 15462449Speter (int)(maxmem / (1024 * 1024))); 15550276Speter continue; 15662449Speter } 15762449Speter 15862449Speter if (addr + len > maxmem) { 15966963Speter printf("Ignoring %llu bytes of memory " 16062449Speter "that is above maxmem %dMB\n", 16162449Speter (addr + len) - maxmem, 16262449Speter (int)(maxmem / (1024 * 1024))); 16366963Speter len = maxmem - addr; 16466963Speter } 16562449Speter } 16662449Speter 16762449Speter phys_avail[i] = addr; 16862449Speter if (i == 0 && addr == 0) { 16962449Speter /* 17062449Speter * If this is the first physical memory segment probed 17162449Speter * from CFE, omit the region at the start of physical 17262449Speter * memory where the kernel has been loaded. 17362449Speter */ 17462449Speter phys_avail[i] += MIPS_KSEG0_TO_PHYS(kernel_kseg0_end); 17562449Speter } 17662449Speter phys_avail[i + 1] = addr + len; 17750276Speter physmem += len; 17862449Speter } 17962449Speter 18062449Speter realmem = btoc(physmem); 18162449Speter#endif 18262449Speter 18362449Speter physmem = realmem; 18462449Speter 18562449Speter init_param1(); 18662449Speter init_param2(physmem); 18750276Speter mips_cpu_init(); 18862449Speter 18962449Speter /* 19062449Speter * XXX 19162449Speter * The kernel is running in 32-bit mode but the CFE is running in 19262449Speter * 64-bit mode. So the SR_KX bit in the status register is turned 19362449Speter * on by the CFE every time we call into it - for e.g. CFE_CONSOLE. 19462449Speter * 19562449Speter * This means that if get a TLB miss for any address above 0xc0000000 19662449Speter * and the SR_KX bit is set then we will end up in the XTLB exception 19762449Speter * vector. 19850276Speter * 19950276Speter * For now work around this by copying the TLB exception handling 20062449Speter * code to the XTLB exception vector. 20162449Speter */ 20250276Speter { 20366963Speter bcopy(MipsTLBMiss, (void *)XTLB_MISS_EXC_VEC, 20462449Speter MipsTLBMissEnd - MipsTLBMiss); 20562449Speter 20662449Speter mips_icache_sync_all(); 20762449Speter mips_dcache_wbinv_all(); 20862449Speter } 20962449Speter 21062449Speter pmap_bootstrap(); 21162449Speter mips_proc0_init(); 21262449Speter mutex_init(); 21362449Speter 21462449Speter kdb_init(); 21562449Speter#ifdef KDB 21662449Speter if (boothowto & RB_KDB) 21762449Speter kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); 21862449Speter#endif 21962449Speter} 22062449Speter 22150276Spetervoid 22262449Speterplatform_halt(void) 22350276Speter{ 22466963Speter 22562449Speter} 22662449Speter 22762449Speter 22850276Spetervoid 22962449Speterplatform_identify(void) 23062449Speter{ 23162449Speter 23250276Speter} 23362449Speter 23462449Spetervoid 23562449Speterplatform_reset(void) 23662449Speter{ 23766963Speter 23862449Speter /* 23962449Speter * XXX SMP 24050276Speter * XXX flush data caches 24162449Speter */ 24262449Speter sb_system_reset(); 24362449Speter} 24462449Speter 24562449Spetervoid 24662449Speterplatform_trap_enter(void) 24750276Speter{ 24862449Speter 24962449Speter} 25062449Speter 25162449Spetervoid 25250276Speterplatform_trap_exit(void) 25362449Speter{ 25462449Speter 25562449Speter} 25662449Speter 25762449Speterstatic void 25862449Speterkseg0_map_coherent(void) 25950276Speter{ 26050276Speter uint32_t config; 26162449Speter const int CFG_K0_COHERENT = 5; 26262449Speter 26362449Speter config = mips_rd_config(); 26462449Speter config &= ~CFG_K0_MASK; 26562449Speter config |= CFG_K0_COHERENT; 26662449Speter mips_wr_config(config); 26762449Speter} 26866963Speter 26962449Spetervoid 27062449Speterplatform_start(__register_t a0, __register_t a1, __register_t a2, 27166963Speter __register_t a3) 27266963Speter{ 27350276Speter /* 27462449Speter * Make sure that kseg0 is mapped cacheable-coherent 27562449Speter */ 27662449Speter kseg0_map_coherent(); 27762449Speter 27850276Speter /* clear the BSS and SBSS segments */ 27962449Speter memset(&edata, 0, (vm_offset_t)&end - (vm_offset_t)&edata); 28066963Speter mips_postboot_fixup(); 28166963Speter 28266963Speter /* Initialize pcpu stuff */ 28366963Speter mips_pcpu0_init(); 28466963Speter 28562449Speter#ifdef CFE 28666963Speter /* 28766963Speter * Initialize CFE firmware trampolines before 28866963Speter * we initialize the low-level console. 28966963Speter * 29050276Speter * CFE passes the following values in registers: 29166963Speter * a0: firmware handle 29266963Speter * a2: firmware entry point 29366963Speter * a3: entry point seal 29466963Speter */ 29566963Speter if (a3 == CFE_EPTSEAL) 29666963Speter cfe_init(a0, a2); 29766963Speter#endif 29866963Speter cninit(); 29966963Speter 30066963Speter mips_init(); 30166963Speter 30266963Speter mips_timer_init_params(sb_cpu_speed(), 0); 30366963Speter} 30466963Speter