1*74a4d8c2SCharles.Forsyth #include "u.h" 2*74a4d8c2SCharles.Forsyth #include "../port/lib.h" 3*74a4d8c2SCharles.Forsyth #include "mem.h" 4*74a4d8c2SCharles.Forsyth #include "dat.h" 5*74a4d8c2SCharles.Forsyth #include "fns.h" 6*74a4d8c2SCharles.Forsyth #include "io.h" 7*74a4d8c2SCharles.Forsyth 8*74a4d8c2SCharles.Forsyth #include "ureg.h" 9*74a4d8c2SCharles.Forsyth 10*74a4d8c2SCharles.Forsyth typedef struct Clock0link Clock0link; 11*74a4d8c2SCharles.Forsyth typedef struct Clock0link { 12*74a4d8c2SCharles.Forsyth void (*clock)(void); 13*74a4d8c2SCharles.Forsyth Clock0link* link; 14*74a4d8c2SCharles.Forsyth } Clock0link; 15*74a4d8c2SCharles.Forsyth 16*74a4d8c2SCharles.Forsyth static Clock0link *clock0link; 17*74a4d8c2SCharles.Forsyth static Lock clock0lock; 18*74a4d8c2SCharles.Forsyth 19*74a4d8c2SCharles.Forsyth void microdelay(int ms)20*74a4d8c2SCharles.Forsythmicrodelay(int ms) 21*74a4d8c2SCharles.Forsyth { 22*74a4d8c2SCharles.Forsyth int i; 23*74a4d8c2SCharles.Forsyth 24*74a4d8c2SCharles.Forsyth ms *= 13334; /* experimentally indetermined */ 25*74a4d8c2SCharles.Forsyth for(i=0; i<ms; i++) 26*74a4d8c2SCharles.Forsyth ; 27*74a4d8c2SCharles.Forsyth } 28*74a4d8c2SCharles.Forsyth 29*74a4d8c2SCharles.Forsyth typedef struct Ctr Ctr; 30*74a4d8c2SCharles.Forsyth struct Ctr 31*74a4d8c2SCharles.Forsyth { 32*74a4d8c2SCharles.Forsyth ulong lim; 33*74a4d8c2SCharles.Forsyth ulong ctr; 34*74a4d8c2SCharles.Forsyth ulong limnr; /* non-resetting */ 35*74a4d8c2SCharles.Forsyth ulong ctl; 36*74a4d8c2SCharles.Forsyth }; 37*74a4d8c2SCharles.Forsyth Ctr *ctr; 38*74a4d8c2SCharles.Forsyth 39*74a4d8c2SCharles.Forsyth void clockinit(void)40*74a4d8c2SCharles.Forsythclockinit(void) 41*74a4d8c2SCharles.Forsyth { 42*74a4d8c2SCharles.Forsyth KMap *k; 43*74a4d8c2SCharles.Forsyth 44*74a4d8c2SCharles.Forsyth putphys(TIMECONFIG, 0); /* it's a processor counter */ 45*74a4d8c2SCharles.Forsyth k = kmappa(CLOCK, PTENOCACHE|PTEIO); 46*74a4d8c2SCharles.Forsyth ctr = (Ctr*)VA(k); 47*74a4d8c2SCharles.Forsyth ctr->lim = (CLOCKFREQ/HZ)<<10; 48*74a4d8c2SCharles.Forsyth } 49*74a4d8c2SCharles.Forsyth 50*74a4d8c2SCharles.Forsyth void clock(Ureg * ur)51*74a4d8c2SCharles.Forsythclock(Ureg *ur) 52*74a4d8c2SCharles.Forsyth { 53*74a4d8c2SCharles.Forsyth Clock0link *lp; 54*74a4d8c2SCharles.Forsyth ulong i; 55*74a4d8c2SCharles.Forsyth 56*74a4d8c2SCharles.Forsyth USED(ur); 57*74a4d8c2SCharles.Forsyth 58*74a4d8c2SCharles.Forsyth i = ctr->lim; /* clear interrupt */ 59*74a4d8c2SCharles.Forsyth USED(i); 60*74a4d8c2SCharles.Forsyth /* is this needed? page 6-43 801-3137-10 suggests so */ 61*74a4d8c2SCharles.Forsyth ctr->lim = (CLOCKFREQ/HZ)<<10; 62*74a4d8c2SCharles.Forsyth 63*74a4d8c2SCharles.Forsyth m->ticks++; 64*74a4d8c2SCharles.Forsyth 65*74a4d8c2SCharles.Forsyth if(up) 66*74a4d8c2SCharles.Forsyth up->pc = ur->pc; 67*74a4d8c2SCharles.Forsyth 68*74a4d8c2SCharles.Forsyth checkalarms(); 69*74a4d8c2SCharles.Forsyth 70*74a4d8c2SCharles.Forsyth lock(&clock0lock); 71*74a4d8c2SCharles.Forsyth for(lp = clock0link; lp; lp = lp->link) 72*74a4d8c2SCharles.Forsyth lp->clock(); 73*74a4d8c2SCharles.Forsyth unlock(&clock0lock); 74*74a4d8c2SCharles.Forsyth 75*74a4d8c2SCharles.Forsyth if(up && up->state == Running) { 76*74a4d8c2SCharles.Forsyth if(anyready()) 77*74a4d8c2SCharles.Forsyth sched(); 78*74a4d8c2SCharles.Forsyth } 79*74a4d8c2SCharles.Forsyth } 80*74a4d8c2SCharles.Forsyth 81*74a4d8c2SCharles.Forsyth Timer* addclock0link(void (* clockfunc)(void),int)82*74a4d8c2SCharles.Forsythaddclock0link(void (*clockfunc)(void), int) 83*74a4d8c2SCharles.Forsyth { 84*74a4d8c2SCharles.Forsyth Clock0link *lp; 85*74a4d8c2SCharles.Forsyth 86*74a4d8c2SCharles.Forsyth if((lp = malloc(sizeof(Clock0link))) == 0){ 87*74a4d8c2SCharles.Forsyth print("addclock0link: too many links\n"); 88*74a4d8c2SCharles.Forsyth return nil; 89*74a4d8c2SCharles.Forsyth } 90*74a4d8c2SCharles.Forsyth ilock(&clock0lock); 91*74a4d8c2SCharles.Forsyth lp->clock = clockfunc; 92*74a4d8c2SCharles.Forsyth lp->link = clock0link; 93*74a4d8c2SCharles.Forsyth clock0link = lp; 94*74a4d8c2SCharles.Forsyth iunlock(&clock0lock); 95*74a4d8c2SCharles.Forsyth return nil; 96*74a4d8c2SCharles.Forsyth } 97*74a4d8c2SCharles.Forsyth 98*74a4d8c2SCharles.Forsyth uvlong fastticks(uvlong * hz)99*74a4d8c2SCharles.Forsythfastticks(uvlong *hz) 100*74a4d8c2SCharles.Forsyth { 101*74a4d8c2SCharles.Forsyth if(hz) 102*74a4d8c2SCharles.Forsyth *hz = HZ; 103*74a4d8c2SCharles.Forsyth return m->ticks; 104*74a4d8c2SCharles.Forsyth } 105