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