Exemplo n.º 1
0
void
caches_on(void)
{
	uint32 config1;
	uint start, end, size, lsize;

	/* Save cache config */
	config1 = MFC0(C0_CONFIG, 1);
	
	icache_probe(config1, &size, &lsize);
	icache_size = size;
	ic_lsize = lsize;
	
	dcache_probe(config1, &size, &lsize);
	dcache_size = size;
	dc_lsize = lsize;
	
	/* If caches are not in the default state then
	 * presume that caches are already init'd
	 */
	if ((MFC0(C0_CONFIG, 0) & CONF_CM_CMASK) != CONF_CM_UNCACHED) {
		blast_dcache();
		blast_icache();
		return;
	}

	/* init icache */
	start = KSEG0;
	end = (start + icache_size);
	MTC0(C0_TAGLO, 0, 0);
	MTC0(C0_TAGHI, 0, 0);
	while (start < end) {
		cache_op(start, Index_Store_Tag_I);
		start += ic_lsize;
	}
	
	/* init dcache */
	start = KSEG0;
	end = (start + dcache_size);
	MTC0(C0_TAGLO, 0, 0);
	MTC0(C0_TAGHI, 0, 0);
	while (start < end) {
		cache_op(start, Index_Store_Tag_D);
		start += dc_lsize;
	}

	/* Must be in KSEG1 to change cachability */
	change_cachability = (void (*)(uint32)) KSEG1ADDR(_change_cachability);
	change_cachability(CONF_CM_CACHABLE_NONCOHERENT);
}
Exemplo n.º 2
0
static void
_change_cachability(uint32 cm)
{
	uint32 prid, c0reg;

	c0reg = MFC0(C0_CONFIG, 0);
	c0reg &= ~CONF_CM_CMASK;
	c0reg |= (cm & CONF_CM_CMASK);
	MTC0(C0_CONFIG, 0, c0reg);
	prid = MFC0(C0_PRID, 0);
	if ((prid & (PRID_COMP_MASK | PRID_IMP_MASK)) ==
	    (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) {
		c0reg = MFC0(C0_BROADCOM, 0);
		/* Enable icache & dcache */
		c0reg |= BRCM_IC_ENABLE | BRCM_DC_ENABLE;
		MTC0(C0_BROADCOM, 0, c0reg);
	}
}	
Exemplo n.º 3
0
static void
ingenic_cpu_init(struct cpu_info *ci)
{
	uint32_t reg;

	/* enable IPIs for this core */
	reg = MFC0(12, 4);	/* reset entry and interrupts */
	if (cpu_index(ci) == 1) {
		reg |= REIM_MIRQ1_M;
	} else
		reg |= REIM_MIRQ0_M;
	MTC0(reg, 12, 4);
	printf("%s %d %08x\n", __func__, cpu_index(ci), reg);
}
Exemplo n.º 4
0
void *
osl_init()
{
	uint32 c0reg;
	sb_t *sbh;

	/* Disable interrupts */
	c0reg = MFC0(C0_STATUS, 0);
	c0reg &= ~ST0_IE;
	MTC0(C0_STATUS, 0, c0reg);

	/* Scan backplane */
	sbh = sb_kattach(SB_OSH);

	sb_mips_init(sbh, 0);
	sb_serial_init(sbh, serial_add);

	/* Init malloc */
	free_mem_ptr = (ulong) bss_end;
	free_mem_ptr_end = ((ulong)&c0reg) - 8192;	/* Enough stack? */

	return ((void *)sbh);
}
Exemplo n.º 5
0
void
cpu_initclocks(void)
{
	struct cpu_info * const ci = curcpu();
	uint32_t cnt;

	static struct timecounter tc =  {
		ingenic_count_read,		/* get_timecount */
		0,				/* no poll_pps */
		~0u,				/* counter_mask */
		12000000,			/* frequency */
		"Ingenic OS timer",		/* name */
		100,				/* quality */
	};

	curcpu()->ci_cctr_freq = tc.tc_frequency;

	tc_init(&tc);

	printf("starting timer interrupt...\n");
	/* start the timer interrupt */
	cnt = readreg(JZ_OST_CNT_LO);
	ci->ci_next_cp0_clk_intr = cnt + ci->ci_cycles_per_hz;
	writereg(JZ_TC_TFCR, TFR_OSTFLAG);
	writereg(JZ_OST_DATA, ci->ci_next_cp0_clk_intr);
	/*
	 * XXX
	 * We can use OST or one of the regular timers to generate the 100hz
	 * interrupt. OST interrupts need to be rescheduled every time and by
	 * only one core, the regular timer can be programmed to fire every
	 * 10ms without rescheduling and we'd still use the OST as time base.
	 * OST is supposed to fire on INT2 although I haven't been able to get
	 * that to work yet ( all I get is INT0 which is for hardware interrupts
	 * in general )
	 * So if we can get OST to fire on INT2 we can just block INT0 on core1
	 * and have a timer interrupt on both cores, if not the regular timer 
	 * would be more convenient but we'd have to shoot an IPI to core1 on
	 * every tick.
	 * For now, use OST and hope we'll figure out how to make it fire on
	 * INT2.
	 */
#ifdef USE_OST
	writereg(JZ_TC_TMCR, TFR_OSTFLAG);
#else
	writereg(JZ_TC_TECR, TESR_TCST5);	/* disable timer 5 */
	writereg(JZ_TC_TCNT(5), 0);
	writereg(JZ_TC_TDFR(5), 30000);	/* 10ms at 48MHz / 16 */
	writereg(JZ_TC_TDHR(5), 60000);	/* not reached */
	writereg(JZ_TC_TCSR(5), TCSR_EXT_EN| TCSR_DIV_16);
	writereg(JZ_TC_TMCR, TFR_FFLAG5);
	writereg(JZ_TC_TFCR, TFR_FFLAG5);
	writereg(JZ_TC_TESR, TESR_TCST5);	/* enable timer 5 */
#endif

#ifdef INGENIC_CLOCK_DEBUG
	printf("INTC %08x %08x\n", readreg(JZ_ICSR0), readreg(JZ_ICSR1));
	printf("ICMR0 %08x\n", readreg(JZ_ICMR0));
#endif
	writereg(JZ_ICMCR0, 0x0c000000); /* TCU2, OST */
	spl0();
#ifdef INGENIC_CLOCK_DEBUG
	printf("TFR: %08x\n", readreg(JZ_TC_TFR));
	printf("TMR: %08x\n", readreg(JZ_TC_TMR));
	printf("cnt5: %08x\n", readreg(JZ_TC_TCNT(5)));
	printf("CR: %08x\n", MFC0(MIPS_COP_0_CAUSE, 0));
	printf("SR: %08x\n", MFC0(MIPS_COP_0_STATUS, 0));
	delay(100000);
	printf("TFR: %08x\n", readreg(JZ_TC_TFR));
	printf("TMR: %08x\n", readreg(JZ_TC_TMR));
	printf("cnt5: %08x\n", readreg(JZ_TC_TCNT(5)));
	printf("CR: %08x\n", MFC0(MIPS_COP_0_CAUSE, 0));
	printf("SR: %08x\n", MFC0(MIPS_COP_0_STATUS, 0));
	printf("TFR: %08x\n", readreg(JZ_TC_TFR));
	printf("TMR: %08x\n", readreg(JZ_TC_TMR));
	printf("cnt5: %08x\n", readreg(JZ_TC_TCNT(5)));
	printf("CR: %08x\n", MFC0(MIPS_COP_0_CAUSE, 0));
	printf("SR: %08x\n", MFC0(MIPS_COP_0_STATUS, 0));
	
	printf("INTC %08x %08x\n", readreg(JZ_ICSR0), readreg(JZ_ICSR1));
	delay(3000000);
	printf("%s %d\n", __func__, MFC0(12, 3));
	printf("%s %08x\n", __func__, MFC0(12, 4));
#endif
}