123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- /*
- * sheevaplug clock
- */
- #include "u.h"
- #include "../port/lib.h"
- #include "mem.h"
- #include "dat.h"
- #include "fns.h"
- #include "io.h"
- #include "ureg.h"
- enum {
- Tcycles = CLOCKFREQ / HZ, /* cycles per clock tick */
- };
- static void
- clockintr(Ureg *ureg, void*)
- {
- m->fastclock++;
- timerintr(ureg, 0);
- intrclear(Irqbridge, IRQcputimer0);
- }
- void
- clockinit(void)
- {
- int s;
- long cyc;
- TimerReg *tmr = TIMERREG;
- tmr->ctl = 0;
- intrenable(Irqbridge, IRQcputimer0, clockintr, nil, "clock");
- s = spllo(); /* risky */
- /* take any deferred clock (& other) interrupts here */
- splx(s);
- /* adjust m->bootdelay, used by delay()? */
- m->ticks = 0;
- m->fastclock = 0;
- tmr->timer0 = Tcycles;
- tmr->ctl = Tmr0enable; /* just once */
- s = spllo(); /* risky */
- /* one iteration seems to take about 40 ns. */
- for (cyc = Tcycles; cyc > 0 && m->fastclock == 0; cyc--)
- ;
- splx(s);
- if (m->fastclock == 0) {
- serialputc('?');
- if (tmr->timer0 == 0)
- panic("clock not interrupting");
- else if (tmr->timer0 == tmr->reload0)
- panic("clock not ticking");
- else
- panic("clock running very slowly");
- }
- tmr->ctl = 0;
- tmr->timer0 = Tcycles;
- tmr->reload0 = Tcycles;
- tmr->ctl = Tmr0enable | Tmr0periodic;
- }
- void
- timerset(uvlong next)
- {
- #ifdef FANCYTIMERS
- Tn *tn;
- Tval offset;
- ilock(&timers.tn1lock);
- tn = (Tn*)Tn1;
- tn->cr = Tm;
- offset = next + tn->cv;
- if(offset < timers.tn1minperiod)
- offset = timers.tn1minperiod;
- else if(offset > timers.tn1maxperiod)
- offset = timers.tn1maxperiod;
- tn->lc = offset;
- tn->cr = Tm|Te;
- iunlock(&timers.tn1lock);
- #else
- USED(next);
- #endif
- }
- uvlong
- fastticks(uvlong *hz)
- {
- if(hz)
- *hz = HZ;
- return m->fastclock;
- }
- ulong
- µs(void)
- {
- return fastticks2us(fastticks(nil));
- }
- void
- microdelay(int l)
- {
- int i;
- l *= m->delayloop;
- l /= 1000;
- if(l <= 0)
- l = 1;
- for(i = 0; i < l; i++)
- ;
- }
- void
- delay(int l)
- {
- ulong i, j;
- j = m->delayloop;
- while(l-- > 0)
- for(i=0; i < j; i++)
- ;
- }
- ulong
- perfticks(void)
- {
- // return ((Tn*)Tn0)->cv; // TODO: FANCYTIMERS
- return (ulong)fastticks(nil);
- }
|