Esempio n. 1
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;
#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, exit. */
	if (!(cfg0 & MIPS_CONFIG_CM))
		return;

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

#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
Esempio n. 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