Example #1
0
static void
localclockintr(Ureg *ureg, void *)
{
	if(m->machno == 0)
		panic("cpu0: Unexpected local generic timer interrupt");
	cpwrsc(0, CpTIMER, CpTIMERphys, CpTIMERphysctl, Imask|Enable);
	timerintr(ureg, 0);
}
Example #2
0
void
timerset(uvlong next)
{
	Systimers *tn;
	uvlong now;
	long period;

	now = fastticks(nil);
	period = next - now;
	if(period < MinPeriod)
		period = MinPeriod;
	else if(period > MaxPeriod)
		period = MaxPeriod;
	if(m->machno > 0){
		cpwrsc(0, CpTIMER, CpTIMERphys, CpTIMERphysval, period);
		cpwrsc(0, CpTIMER, CpTIMERphys, CpTIMERphysctl, Enable);
	}else{
		tn = (Systimers*)SYSTIMERS;
		tn->c3 = (ulong)(now + period);
	}
}
Example #3
0
static void
errata(void)
{
	ulong reg, r, p;

	/* apply cortex-a9 errata workarounds */
	r = cpidget();			/* main id register */
	assert((r >> 24) == 'A');
	p = r & MASK(4);		/* minor revision */
	r >>= 20;
	r &= MASK(4);			/* major revision */

	/* this is an undocumented `diagnostic register' that linux knows */
	reg = cprdsc(0, CpDTLB, 0, 1);
	if (r < 2 || r == 2 && p <= 2)
		reg |= 1<<4;			/* 742230 */
	if (r == 2 && p <= 2)
		reg |= 1<<6 | 1<<12 | 1<<22;	/* 743622, 2×742231 */
	if (r < 3)
		reg |= 1<<11;			/* 751472 */
	cpwrsc(0, CpDTLB, 0, 1, reg);
}
Example #4
0
void
clockinit(void)
{
	Systimers *tn;
	Armtimer *tm;
	u32int t0, t1, tstart, tend;

	if(((cprdsc(0, CpID, CpIDfeat, 1) >> 16) & 0xF) != 0) {
		/* generic timer supported */
		if(m->machno == 0){
			*(ulong*)(ARMLOCAL + Localctl) = 0;				/* magic */
			*(ulong*)(ARMLOCAL + Prescaler) = 0x06aaaaab;	/* magic for 1 Mhz */
		}
		cpwrsc(0, CpTIMER, CpTIMERphys, CpTIMERphysctl, Imask);
	}

	tn = (Systimers*)SYSTIMERS;
	tstart = tn->clo;
	do{
		t0 = lcycles();
	}while(tn->clo == tstart);
	tend = tstart + 10000;
	do{
		t1 = lcycles();
	}while(tn->clo != tend);
	t1 -= t0;
	m->cpuhz = 100 * t1;
	m->cpumhz = (m->cpuhz + Mhz/2 - 1) / Mhz;
	m->cyclefreq = m->cpuhz;
	if(m->machno == 0){
		tn->c3 = tn->clo - 1;
		tm = (Armtimer*)ARMTIMER;
		tm->load = 0;
		tm->ctl = TmrPrescale1|CntEnable|CntWidth32;
		intrenable(IRQtimer3, clockintr, nil, 0, "clock");
	}else
		intrenable(IRQcntpns, localclockintr, nil, 0, "clock");
}
Example #5
0
File: clock.c Project: CoryXie/NxM
void
clockinit(void)
{
	int i, s;
	Timerregs *tn;

	clockshutdown();

	/* turn cycle counter on */
	cpwrsc(0, CpCLD, CpCLDena, CpCLDenacyc, 1<<31);

	/* turn all counters on and clear the cycle counter */
	cpwrsc(0, CpCLD, CpCLDena, CpCLDenapmnc, 1<<2 | 1);

	/* let users read the cycle counter directly */
	cpwrsc(0, CpCLD, CpCLDena, CpCLDenapmnc, 1);

	ilock(&clklck);
	m->fastclock = 1;
	m->ticks = ticks = 0;

	/*
	 * T0 is a freerunning timer (cycle counter); it wraps,
	 * automatically reloads, and does not dispatch interrupts.
	 */
	tn = (Timerregs *)Tn0;
	tn->tcrr = Freebase;			/* count up to 0 */
	tn->tldr = Freebase;
	coherence();
	tn->tclr = Ar | St;
	iunlock(&clklck);

	/*
	 * T1 is the interrupting timer and does not participate
	 * in measuring time.  It is initially set to HZ.
	 */
	tn = (Timerregs *)Tn1;
	irqenable(Tn0irq+1, clockintr, tn, "clock");
	ilock(&clklck);
	tn->tcrr = -Tcycles;			/* approx.; count up to 0 */
	tn->tldr = -Tcycles;
	coherence();
	tn->tclr = Ar | St;
	coherence();
	tn->tier = Ovf_it;
	coherence();
	iunlock(&clklck);

	/*
	 * verify sanity of timer1
	 */
	s = spllo();			/* risky */
	for (i = 0; i < 5 && ticks == 0; i++) {
		delay(10);
		cachedwbinvse(&ticks, sizeof ticks);
	}
	splx(s);
	if (ticks == 0) {
		if (tn->tcrr == 0)
			panic("clock not interrupting");
		else if (tn->tcrr == tn->tldr)
			panic("clock not ticking at all");
#ifdef PARANOID
		else
			panic("clock running very slowly");
#endif
	}

	guessmips(issue1loop, "single");
	if (Debug)
		iprint(", ");
	guessmips(issue2loop, "dual");
	if (Debug)
		iprint("\n");

	/*
	 * m->delayloop should be the number of delay loop iterations
	 * needed to consume 1 ms.  2 is min. instructions in the delay loop.
	 */
	m->delayloop = m->cpuhz / (1000 * 2);
//	iprint("m->delayloop = %lud\n", m->delayloop);

	/*
	 *  desynchronize the processor clocks so that they all don't
	 *  try to resched at the same time.
	 */
	delay(m->machno*2);
}