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