Beispiel #1
0
void
platform_init_ap(int cpuid)
{
	uint32_t status;
	register_t hwrena;
	u_int clock_int_mask;

	KASSERT(cpuid < MAXCPU, ("%s: invalid CPU id %d", __func__, cpuid));

	/* Make sure coprocessors are enabled. */
	status = mips_rd_status();
	status |= (MIPS_SR_COP_0_BIT | MIPS_SR_COP_1_BIT);
#if defined(CPU_CHERI)
	status |= MIPS_SR_COP_2_BIT;
#endif
	mips_wr_status(status);

	/* Enable HDWRD instruction in userspace. */
	hwrena = mips_rd_hwrena();
	hwrena |= (MIPS_HWRENA_CC | MIPS_HWRENA_CCRES | MIPS_HWRENA_CPUNUM);
	mips_wr_hwrena(hwrena);

	/*
	 * Enable per-thread timer.
	 */
	clock_int_mask = hard_int_mask(5);
	set_intr_mask(clock_int_mask);
}
Beispiel #2
0
/*
 * Attempt to identify the MIPS CPU as much as possible.
 *
 * XXX: Assumes the CPU is MIPS{32,64}{,r2} compliant.
 * XXX: For now, skip config register selections 2 and 3
 * as we don't currently use L2/L3 cache or additional
 * MIPS32 processor features.
 */
static void
mips_get_identity(struct mips_cpuinfo *cpuinfo)
{
	u_int32_t prid;
	u_int32_t cfg0;
	u_int32_t cfg1;
	u_int32_t cfg2;
	u_int32_t cfg3;
#if defined(CPU_CNMIPS)
	u_int32_t cfg4;
#endif
	u_int32_t tmp;

	memset(cpuinfo, 0, sizeof(struct mips_cpuinfo));

	/* Read and store the PrID ID for CPU identification. */
	prid = mips_rd_prid();
	cpuinfo->cpu_vendor = MIPS_PRID_CID(prid);
	cpuinfo->cpu_rev = MIPS_PRID_REV(prid);
	cpuinfo->cpu_impl = MIPS_PRID_IMPL(prid);

	/* Read config register selection 0 to learn TLB type. */
	cfg0 = mips_rd_config();

	cpuinfo->tlb_type = 
	    ((cfg0 & MIPS_CONFIG0_MT_MASK) >> MIPS_CONFIG0_MT_SHIFT);
	cpuinfo->icache_virtual = cfg0 & MIPS_CONFIG0_VI;

	/* If config register selection 1 does not exist, return. */
	if (!(cfg0 & MIPS_CONFIG0_M))
		return;

	/* Learn TLB size and L1 cache geometry. */
	cfg1 = mips_rd_config1();

	/* Get the Config2 and Config3 registers as well. */
	if (cfg1 & MIPS_CONFIG1_M) {
		cfg2 = mips_rd_config2();
		if (cfg2 & MIPS_CONFIG2_M)
			cfg3 = mips_rd_config3();
	}

	/* Check to see if UserLocal register is implemented. */
	if (cfg3 & MIPS_CONFIG3_ULR) {
		/* UserLocal register is implemented, enable it. */
		cpuinfo->userlocal_reg = true;
		tmp = mips_rd_hwrena();
		mips_wr_hwrena(tmp | MIPS_HWRENA_UL);
	} else {
		/*
		 * UserLocal register is not implemented. Patch
		 * cpu_switch() and remove unsupported code.
		 */
		cpuinfo->userlocal_reg = false;
		remove_userlocal_code((uint32_t *)cpu_switch);
	}


#if defined(CPU_NLM)
	/* Account for Extended TLB entries in XLP */
	tmp = mips_rd_config6();
	cpuinfo->tlb_nentries = ((tmp >> 16) & 0xffff) + 1;
#elif defined(BERI_LARGE_TLB)
	/* Check if we support extended TLB entries and if so activate. */
	tmp = mips_rd_config5();
#define	BERI_CP5_LTLB_SUPPORTED	0x1
	if (tmp & BERI_CP5_LTLB_SUPPORTED) {
		/* See how many extra TLB entries we have. */
		tmp = mips_rd_config6();
		cpuinfo->tlb_nentries = (tmp >> 16) + 1;
		/* Activate the extended entries. */
		mips_wr_config6(tmp|0x4);
	} else