| plan 9 kernel history: overview | file list | diff list |
2002/0410/pc/i8253.c (diff list | history)
| 1997/0327/sys/src/9/pc/i8253.c:98,100 – 1998/0710/sys/src/9/pc/i8253.c:98,114 (short | long) | ||
|
Add i8253read.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1997/0327 | { intrenable(VectorCLOCK, clockintr, 0, BUSUNKNOWN); } | |
| 1998/0710 | Lock i8253lock; /* * return time elapsed since clock start in * 10ths of nanoseconds */ uvlong i8253read(uvlong *hz) { if(hz) *hz = HZ; return m->ticks; } | |
| 1998/0710/sys/src/9/pc/i8253.c:99,106 – 1998/0819/sys/src/9/pc/i8253.c:99,104 (short | long) | ||
|
Remove unused i8253lock.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1997/0327 | intrenable(VectorCLOCK, clockintr, 0, BUSUNKNOWN); } | |
| 1998/0710 |
| |
| 1998/0819/sys/src/9/pc/i8253.c:40,45 – 1998/0903/sys/src/9/pc/i8253.c:40,60 (short | long) | ||
|
HW bug fix: wait for i8254 to start counting on fast machine.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1997/0327 | outb(Tmode, Load0|Square); outb(T0cntr, (Freq/HZ)); /* low byte */ outb(T0cntr, (Freq/HZ)>>8); /* high byte */ | |
| 1998/0903 | /* * Introduce a little delay to make sure the count is * latched and the timer is counting down; with a fast * enough processor this may not be the case. * The i8254 (which this probably is) has a read-back * command which can be used to make sure the counting * register has been written into the counting element. */ x = (Freq/HZ); for(loops = 0; loops < 100000 && x >= (Freq/HZ); loops++){ outb(Tmode, Latch0); x = inb(T0cntr); x |= inb(T0cntr)<<8; } | |
| 1997/0327 | } /* find biggest loop that doesn't wrap */ | |
| 1998/0903/sys/src/9/pc/i8253.c:111,117 – 1998/0910/sys/src/9/pc/i8253.c:111,117 (short | long) | ||
|
Change VectorCLOCK to IrqClock.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1997/0327 | void i8253enable(void) { | |
| 1998/0910 | intrenable(IrqCLOCK, clockintr, 0, BUSUNKNOWN); | |
| 1997/0327 | } | |
| 1998/0710 | /* | |
| 1998/0910/sys/src/9/pc/i8253.c:27,35 – 1999/0131/sys/src/9/pc/i8253.c:27,36 (short | long) | ||
| 1997/0327 | }; void | |
| 1999/0131 | i8253init(int aalcycles, int havecycleclock) | |
| 1997/0327 | { int cpufreq, loops, incr, x, y; | |
| 1999/0131 | vlong a, b; | |
| 1997/0327 | static int initialised; if(initialised == 0){ | |
| 1998/0910/sys/src/9/pc/i8253.c:75,84 – 1999/0131/sys/src/9/pc/i8253.c:76,89 | ||
| 1997/0327 | * */ outb(Tmode, Latch0); | |
| 1999/0131 | if(havecycleclock) rdmsr(0x10, &a); | |
| 1997/0327 | x = inb(T0cntr); x |= inb(T0cntr)<<8; aamloop(loops); outb(Tmode, Latch0); | |
| 1999/0131 | if(havecycleclock) rdmsr(0x10, &b); | |
| 1997/0327 | y = inb(T0cntr); y |= inb(T0cntr)<<8; x -= y; | |
| 1998/0910/sys/src/9/pc/i8253.c:91,111 – 1999/0131/sys/src/9/pc/i8253.c:96,126 | ||
| 1997/0327 | } /* | |
| 1999/0131 | * n.b. counter goes up by 2*Freq | |
| 1997/0327 | */ | |
| 1999/0131 | cpufreq = loops*((aalcycles*2*Freq)/x); | |
| 1997/0327 | m->loopconst = (cpufreq/1000)/aalcycles; /* AAM+LOOP's for 1 ms */ | |
| 1999/0131 | if(havecycleclock){ /* counter goes up by 2*Freq */ b = (b-a)<<1; b *= Freq; b /= x; /* * round to the nearest megahz */ m->cpumhz = (b+500000)/1000000L; m->cpuhz = b; } else { /* * add in possible 0.5% error and convert to MHz */ m->cpumhz = (cpufreq + cpufreq/200)/1000000; m->cpuhz = cpufreq; } | |
| 1997/0327 | } void | |
| 1999/0131/sys/src/9/pc/i8253.c:131,142 – 1999/0228/sys/src/9/pc/i8253.c:131,142 (short | long) | ||
| 1998/0710 | /* * return time elapsed since clock start in | |
| 1999/0228 | * 100 times hz | |
| 1998/0710 | */ uvlong i8253read(uvlong *hz) { if(hz) | |
| 1999/0228 | *hz = HZ*100; return m->ticks*100; | |
| 1998/0710 | } | |
| 1999/0228/sys/src/9/pc/i8253.c:35,40 – 1999/0714/sys/src/9/pc/i8253.c:35,41 (short | long) | ||
|
Use ioalloc.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1997/0327 | if(initialised == 0){ initialised = 1; | |
| 1999/0714 | ioalloc(T0cntr, 4, 0, "i8253"); | |
| 1997/0327 | /* * set clock for 1/HZ seconds */ | |
| 1999/0714/sys/src/9/pc/i8253.c:127,133 – 1999/0819/sys/src/9/pc/i8253.c:127,133 (short | long) | ||
| 1997/0327 | void i8253enable(void) { | |
| 1998/0910 |
| |
| 1999/0819 | intrenable(IrqCLOCK, clockintr, 0, BUSUNKNOWN, "clock"); | |
| 1997/0327 | } | |
| 1998/0710 | /* | |
| 1999/0819/sys/src/9/pc/i8253.c:124,133 – 2000/0621/sys/src/9/pc/i8253.c:124,140 (short | long) | ||
| 1999/0131 | } | |
| 1997/0327 | } | |
| 2000/0621 | static void clockintr0(Ureg* ureg, void *v) { loopbackintr(); clockintr(ureg, v); } | |
| 1997/0327 | void i8253enable(void) { | |
| 1999/0819 |
| |
| 2000/0621 | intrenable(IrqCLOCK, clockintr0, 0, BUSUNKNOWN, "clock"); | |
| 1997/0327 | } | |
| 1998/0710 | /* | |
| 2000/0621/sys/src/9/pc/i8253.c:13,31 – 2000/0622/sys/src/9/pc/i8253.c:13,35 (short | long) | ||
| 1997/0327 | T0cntr= 0x40, /* counter ports */ T1cntr= 0x41, /* ... */ T2cntr= 0x42, /* ... */ | |
| 2000/0622 | Tmode= 0x43, /* mode port (control word register) */ | |
| 1997/0327 | /* commands */ Latch0= 0x00, /* latch counter 0's value */ | |
| 2000/0622 | Load0l= 0x10, /* load counter 0's lsb */ Load0m= 0x20, /* load counter 0's msb */ | |
| 1997/0327 | Load0= 0x30, /* load counter 0 with 2 bytes */ /* modes */ | |
| 2000/0622 | Square= 0x6, /* periodic square wave */ Trigger= 0x0, /* interrupt on terminal count */ | |
| 1997/0327 | Freq= 1193182, /* Real clock frequency */ }; | |
| 2000/0622 | static Lock i8253lock; | |
| 1997/0327 | void | |
| 1999/0131 | i8253init(int aalcycles, int havecycleclock) | |
| 1997/0327 | { | |
| 2000/0621/sys/src/9/pc/i8253.c:124,133 – 2000/0622/sys/src/9/pc/i8253.c:128,144 | ||
| 1999/0131 | } | |
| 1997/0327 | } | |
| 2000/0622 | int i8253readcnt(void) { ilock(&i8253lock); iunlock(&i8253lock); } | |
| 2000/0621 | static void clockintr0(Ureg* ureg, void *v) { | |
| 2000/0622 | loopbackintr(ureg); | |
| 2000/0621 | clockintr(ureg, v); } | |
| 2000/0622/sys/src/9/pc/i8253.c:14,19 – 2000/0623/sys/src/9/pc/i8253.c:14,20 (short | long) | ||
| 1997/0327 | T1cntr= 0x41, /* ... */ T2cntr= 0x42, /* ... */ | |
| 2000/0622 | Tmode= 0x43, /* mode port (control word register) */ | |
| 2000/0623 | T2ctl= 0x61, /* counter 2 control port */ | |
| 1997/0327 | /* commands */ Latch0= 0x00, /* latch counter 0's value */ | |
| 2000/0622/sys/src/9/pc/i8253.c:20,34 – 2000/0623/sys/src/9/pc/i8253.c:21,62 | ||
| 2000/0622 | Load0l= 0x10, /* load counter 0's lsb */ Load0m= 0x20, /* load counter 0's msb */ | |
| 1997/0327 | Load0= 0x30, /* load counter 0 with 2 bytes */ | |
| 2000/0623 | Latch2= 0x80, /* latch counter 2's value */ Load2l= 0x90, /* load counter 2's lsb */ Load2m= 0xa0, /* load counter 2's msb */ Load2= 0xb0, /* load counter 2 with 2 bytes */ | |
| 1997/0327 | ||
| 2000/0623 | /* 8254 read-back command: everything > pc-at has an 8254 */ Rdback= 0xc0, /* readback counters & status */ Rdnstat=0x10, /* don't read status */ Rdncnt= 0x20, /* don't read counter value */ Rd0cntr=0x02, /* read back for which counter */ Rd1cntr=0x04, Rd2cntr=0x08, | |
| 1997/0327 | /* modes */ | |
| 2000/0623 | ModeMsk=0xe, | |
| 2000/0622 | Square= 0x6, /* periodic square wave */ | |
| 2000/0623 | Trigger=0x0, /* interrupt on terminal count */ Sstrobe=0x8, /* software triggered strobe */ | |
| 1997/0327 | ||
| 2000/0623 | /* counter 2 controls */ C2gate= 0x1, C2speak=0x2, C2out= 0x10, | |
| 1997/0327 | Freq= 1193182, /* Real clock frequency */ | |
| 2000/0623 | FreqMul=16, /* extra accuracy in fastticks/Freq calculation; ok up to ~8ghz */ | |
| 1997/0327 | }; | |
| 2000/0622 |
| |
| 2000/0623 | static struct { Lock lock; vlong when; /* next fastticks a clock interrupt should occur */ long fastperiod; /* fastticks/hz */ long fast2freq; /* fastticks*FreqMul/Freq */ }i8253; | |
| 2000/0622 | ||
| 1997/0327 | void | |
| 1999/0131 | i8253init(int aalcycles, int havecycleclock) | |
| 2000/0622/sys/src/9/pc/i8253.c:40,45 – 2000/0623/sys/src/9/pc/i8253.c:68,75 | ||
| 1997/0327 | if(initialised == 0){ initialised = 1; | |
| 1999/0714 | ioalloc(T0cntr, 4, 0, "i8253"); | |
| 2000/0623 | ioalloc(T2ctl, 1, 0, "i8253.cntr2ctl"); | |
| 1997/0327 | /* * set clock for 1/HZ seconds */ | |
| 2000/0622/sys/src/9/pc/i8253.c:126,144 – 2000/0623/sys/src/9/pc/i8253.c:156,239 | ||
| 1999/0131 | m->cpumhz = (cpufreq + cpufreq/200)/1000000; m->cpuhz = cpufreq; } | |
| 2000/0623 | outb(Tmode, Load0|Trigger); outb(T0cntr, (Freq/HZ)); /* low byte */ outb(T0cntr, (Freq/HZ)>>8); /* high byte */ | |
| 1997/0327 | } | |
| 2000/0623 | static vlong lastfast; | |
| 2000/0622 | int | |
| 2000/0623 | i8253readcnt(int cntr) | |
| 2000/0622 | { | |
| 2000/0623 | int v; ilock(&i8253.lock); if(cntr == 2){ outb(Tmode, Rdback|Rd2cntr); v = inb(T2cntr) << 16; v |= inb(T2cntr); v |= inb(T2cntr) << 8; }else if(cntr == 0){ outb(Tmode, Rdback|Rd0cntr); v = inb(T0cntr) << 16; v |= inb(T0cntr); v |= inb(T0cntr) << 8; }else if(cntr == 3){ vlong nf = fastticks(nil); long set; set = (long)(nf - lastfast) * 100 / (long)((vlong)m->cpuhz * 100 / Freq); set = (Freq/HZ) - set; set -= 3 - 1; /* outb, outb, wait - outb(mode) */ outb(Tmode, Rdback|Rdnstat|Rd0cntr); v = inb(T0cntr); v |= inb(T0cntr) << 8; v = set - v; }else if(cntr == 4){ vlong nf = fastticks(nil); long set; set = (long)(nf - lastfast) * 16 / (long)((vlong)m->cpuhz * 16 / Freq); set = (Freq/HZ) - set; set -= 3 - 1; /* outb, outb, wait - outb(mode) */ outb(Tmode, Rdback|Rdnstat|Rd0cntr); v = inb(T0cntr); v |= inb(T0cntr) << 8; v = set - v; }else{ vlong nf = fastticks(nil); long set; set = (nf - lastfast) * Freq / m->cpuhz; set = (Freq/HZ) - set; set -= 3 - 1; /* outb, outb, wait - outb(mode) */ outb(Tmode, Rdback|Rdnstat|Rd0cntr); v = inb(T0cntr); v |= inb(T0cntr) << 8; v = set - v; } iunlock(&i8253.lock); return v; | |
| 2000/0622 | } | |
| 2000/0621 | static void clockintr0(Ureg* ureg, void *v) { | |
| 2000/0622 |
| |
| 2000/0623 | vlong now; long set; now = fastticks(nil); while(i8253.when < now) i8253.when += i8253.fastperiod; set = (long)(i8253.when - now) * FreqMul / i8253.fast2freq; set -= 3; /* three cycles for the count to take effect: outb, outb, wait */ lastfast = now; outb(T0cntr, set); /* low byte */ outb(T0cntr, set>>8); /* high byte */ checkcycintr(ureg, v); | |
| 2000/0621 | clockintr(ureg, v); } | |
| 2000/0622/sys/src/9/pc/i8253.c:145,150 – 2000/0623/sys/src/9/pc/i8253.c:240,248 | ||
| 1997/0327 | void i8253enable(void) { | |
| 2000/0623 | i8253.when = fastticks(nil); i8253.fastperiod = (m->cpuhz + HZ/2) / HZ; i8253.fast2freq = (vlong)m->cpuhz * FreqMul / Freq; | |
| 2000/0621 | intrenable(IrqCLOCK, clockintr0, 0, BUSUNKNOWN, "clock"); | |
| 1997/0327 | } | |
| 1998/0710 | ||
| 2000/0623/sys/src/9/pc/i8253.c:156,226 – 2000/0624/sys/src/9/pc/i8253.c:156,174 (short | long) | ||
| 1999/0131 | m->cpumhz = (cpufreq + cpufreq/200)/1000000; m->cpuhz = cpufreq; } | |
| 2000/0623 |
| |
| 1997/0327 | } | |
| 2000/0623 |
| |
| 2000/0624 | #ifdef SETNEXT set up clock so it is reloaded every interrupt outb(Tmode, Load0|Trigger); outb(T0cntr, (Freq/HZ)); /* low byte */ outb(T0cntr, (Freq/HZ)>>8); /* high byte */ #endif | |
| 2000/0623 | ||
| 2000/0622 |
| |
| 2000/0623 |
| |
| 2000/0622 |
| |
| 2000/0623 |
| |
| 2000/0622 |
| |
| 2000/0621 | static void clockintr0(Ureg* ureg, void *v) { | |
| 2000/0624 | #ifdef SETNEXT | |
| 2000/0623 | vlong now; long set; | |
| 2000/0623/sys/src/9/pc/i8253.c:229,237 – 2000/0624/sys/src/9/pc/i8253.c:177,185 | ||
| 2000/0623 | i8253.when += i8253.fastperiod; set = (long)(i8253.when - now) * FreqMul / i8253.fast2freq; set -= 3; /* three cycles for the count to take effect: outb, outb, wait */ | |
| 2000/0624 | #endif | |
| 2000/0623 | checkcycintr(ureg, v); | |
| 2000/0621 | clockintr(ureg, v); | |
| 2000/0624/sys/src/9/pc/i8253.c:52,59 – 2000/0627/sys/src/9/pc/i8253.c:52,61 (short | long) | ||
| 1997/0327 | ||
| 2000/0623 | static struct { | |
| 2000/0627 | Lock; int mode; | |
| 2000/0623 | vlong when; /* next fastticks a clock interrupt should occur */ | |
| 2000/0627 | vlong cycwhen; /* next fastticks a cycintr happens; 0 == infinity */ | |
| 2000/0623 | long fastperiod; /* fastticks/hz */ long fast2freq; /* fastticks*FreqMul/Freq */ }i8253; | |
| 2000/0624/sys/src/9/pc/i8253.c:74,79 – 2000/0627/sys/src/9/pc/i8253.c:76,82 | ||
| 1997/0327 | * set clock for 1/HZ seconds */ outb(Tmode, Load0|Square); | |
| 2000/0627 | i8253.mode = Square; | |
| 1997/0327 | outb(T0cntr, (Freq/HZ)); /* low byte */ outb(T0cntr, (Freq/HZ)>>8); /* high byte */ | |
| 1998/0903 | ||
| 2000/0624/sys/src/9/pc/i8253.c:158,188 – 2000/0627/sys/src/9/pc/i8253.c:161,230 | ||
| 1999/0131 | } | |
| 1997/0327 | } | |
| 2000/0624 |
| |
| 2000/0623 | ||
| 2000/0627 | /* * schedule the next interrupt * cycwhen is the next time for the cycle counter routines */ | |
| 2000/0621 | static void | |
| 2000/0627 | clockintrsched0(vlong next) | |
| 2000/0621 | { | |
| 2000/0624 |
| |
| 2000/0623 | vlong now; long set; | |
| 2000/0627 | i8253.cycwhen = next; if(i8253.mode == Square && next == 0) return; | |
| 2000/0623 | now = fastticks(nil); | |
| 2000/0624 |
| |
| 2000/0627 | if(next || now < i8253.when - i8253.fastperiod || now > i8253.when - ((3*i8253.fastperiod)>>2)){ if(next > i8253.when) next = i8253.when; set = (long)(next - now) * FreqMul / i8253.fast2freq; set -= 3; /* three cycles for the count to take effect: outb, outb, wait */ if(i8253.mode != Trigger){ outb(Tmode, Load0|Trigger); i8253.mode = Trigger; set--; } if(set < 3) set = 5; outb(T0cntr, set); /* low byte */ outb(T0cntr, set>>8); /* high byte */ }else if(i8253.mode != Square){ i8253.mode = Square; outb(Tmode, Load0|Square); outb(T0cntr, (Freq/HZ)); /* low byte */ outb(T0cntr, (Freq/HZ)>>8); /* high byte */ } } | |
| 2000/0623 |
| |
| 2000/0621 |
| |
| 2000/0627 | void clockintrsched(void) { vlong next; ilock(&i8253); next = cycintrnext(); if(next != i8253.cycwhen) clockintrsched0(next); iunlock(&i8253); } static void clockintr0(Ureg* ureg, void *v) { vlong now, when; now = fastticks(nil); when = i8253.when; if(now >= i8253.when){ clockintr(ureg, v); do i8253.when += i8253.fastperiod; while(i8253.when < now); } if(i8253.cycwhen || i8253.mode != Square) clockintrsched0(checkcycintr(ureg, v)); | |
| 2000/0621 | } | |
| 1997/0327 | void | |
| 2000/0627/sys/src/9/pc/i8253.c:53,58 – 2000/0701/sys/src/9/pc/i8253.c:53,59 (short | long) | ||
| 2000/0623 | static struct { | |
| 2000/0627 | Lock; | |
| 2000/0701 | int enabled; | |
| 2000/0627 | int mode; | |
| 2000/0623 | vlong when; /* next fastticks a clock interrupt should occur */ | |
| 2000/0627 | vlong cycwhen; /* next fastticks a cycintr happens; 0 == infinity */ | |
| 2000/0627/sys/src/9/pc/i8253.c:198,203 – 2000/0701/sys/src/9/pc/i8253.c:199,210 | ||
| 2000/0627 | } } | |
| 2000/0623 | ||
| 2000/0701 | int havecycintr(void) { return i8253.enabled; } | |
| 2000/0627 | void clockintrsched(void) { | |
| 2000/0627/sys/src/9/pc/i8253.c:204,212 – 2000/0701/sys/src/9/pc/i8253.c:211,221 | ||
| 2000/0627 | vlong next; ilock(&i8253); | |
| 2000/0701 | if(i8253.enabled){ next = cycintrnext(); if(next != i8253.cycwhen) clockintrsched0(next); } | |
| 2000/0627 | iunlock(&i8253); } | |
| 2000/0627/sys/src/9/pc/i8253.c:233,238 – 2000/0701/sys/src/9/pc/i8253.c:242,248 | ||
| 2000/0623 | i8253.when = fastticks(nil); i8253.fastperiod = (m->cpuhz + HZ/2) / HZ; i8253.fast2freq = (vlong)m->cpuhz * FreqMul / Freq; | |
| 2000/0701 | i8253.enabled = 1; | |
| 2000/0621 | intrenable(IrqCLOCK, clockintr0, 0, BUSUNKNOWN, "clock"); | |
| 1997/0327 | } | |
| 1998/0710 | ||
| 2000/0701/sys/src/9/pc/i8253.c:47,52 – 2000/0706/sys/src/9/pc/i8253.c:47,54 (short | long) | ||
| 2000/0623 | ||
| 1997/0327 | Freq= 1193182, /* Real clock frequency */ | |
| 2000/0623 | ||
| 2000/0706 | Minusec=20, /* minimum cycles for a clock interrupt */ | |
| 2000/0623 | FreqMul=16, /* extra accuracy in fastticks/Freq calculation; ok up to ~8ghz */ | |
| 1997/0327 | }; | |
| 2000/0701/sys/src/9/pc/i8253.c:187,194 – 2000/0706/sys/src/9/pc/i8253.c:189,196 | ||
| 2000/0627 | i8253.mode = Trigger; set--; } | |
| 2000/0706 | if(set < Minusec) set = Minusec; | |
| 2000/0627 | outb(T0cntr, set); /* low byte */ outb(T0cntr, set>>8); /* high byte */ }else if(i8253.mode != Square){ | |
| 2000/0706/sys/src/9/pc/i8253.c:55,60 – 2000/0713/sys/src/9/pc/i8253.c:55,61 (short | long) | ||
| 2000/0623 | static struct { | |
| 2000/0627 | Lock; | |
| 2000/0713 | int havecyc; | |
| 2000/0701 | int enabled; | |
| 2000/0627 | int mode; | |
| 2000/0623 | vlong when; /* next fastticks a clock interrupt should occur */ | |
| 2000/0706/sys/src/9/pc/i8253.c:72,77 – 2000/0713/sys/src/9/pc/i8253.c:73,79 | ||
| 1997/0327 | if(initialised == 0){ initialised = 1; | |
| 2000/0713 | i8253.havecyc = havecycleclock; | |
| 1999/0714 | ioalloc(T0cntr, 4, 0, "i8253"); | |
| 2000/0623 | ioalloc(T2ctl, 1, 0, "i8253.cntr2ctl"); | |
| 2000/0706/sys/src/9/pc/i8253.c:204,210 – 2000/0713/sys/src/9/pc/i8253.c:206,212 | ||
| 2000/0701 | int havecycintr(void) { | |
| 2000/0713 | return i8253.havecyc && i8253.enabled; | |
| 2000/0701 | } | |
| 2000/0627 | void | |
| 2000/0706/sys/src/9/pc/i8253.c:213,219 – 2000/0713/sys/src/9/pc/i8253.c:215,221 | ||
| 2000/0627 | vlong next; ilock(&i8253); | |
| 2000/0701 |
| |
| 2000/0713 | if(i8253.enabled && i8253.havecyc){ | |
| 2000/0701 | next = cycintrnext(); if(next != i8253.cycwhen) clockintrsched0(next); | |
| 2000/0706/sys/src/9/pc/i8253.c:225,230 – 2000/0713/sys/src/9/pc/i8253.c:227,237 | ||
| 2000/0627 | clockintr0(Ureg* ureg, void *v) { vlong now, when; | |
| 2000/0713 | if(!i8253.havecyc){ clockintr(ureg, v); return; } | |
| 2000/0627 | now = fastticks(nil); when = i8253.when; | |
| 2000/0713/sys/src/9/pc/i8253.c:235,240 – 2001/0611/sys/src/9/pc/i8253.c:235,249 (short | long) | ||
| 2000/0627 | now = fastticks(nil); when = i8253.when; | |
| 2001/0611 | /* * If we suspend the machine and resume, the * processor cycle counter gets reset. Detect this * and deal with it. */ if(now < i8253.when && i8253.when-now > 3*i8253.fastperiod) i8253.when = now; | |
| 2000/0627 | if(now >= i8253.when){ clockintr(ureg, v); do | |
| 2001/0611/sys/src/9/pc/i8253.c:120,132 – 2001/1130/sys/src/9/pc/i8253.c:120,132 (short | long) | ||
| 1997/0327 | */ outb(Tmode, Latch0); | |
| 1999/0131 | if(havecycleclock) | |
| 2001/1130 | rdtsc(&a); | |
| 1997/0327 | x = inb(T0cntr); x |= inb(T0cntr)<<8; aamloop(loops); outb(Tmode, Latch0); | |
| 1999/0131 | if(havecycleclock) | |
| 2001/1130 | rdtsc(&b); | |
| 1997/0327 | y = inb(T0cntr); y |= inb(T0cntr)<<8; x -= y; | |
| 2001/1130/sys/src/9/pc/i8253.c:259,265 – 2002/0221/sys/src/9/pc/i8253.c:259,265 (short | long) | ||
| 1997/0327 | { | |
| 2000/0623 | i8253.when = fastticks(nil); i8253.fastperiod = (m->cpuhz + HZ/2) / HZ; | |
| 2002/0221 | i8253.fast2freq = m->cpuhz * FreqMul / Freq; | |
| 2000/0701 | i8253.enabled = 1; | |
| 2000/0621 | intrenable(IrqCLOCK, clockintr0, 0, BUSUNKNOWN, "clock"); | |
| 1997/0327 | } | |
| 2002/0221/sys/src/9/pc/i8253.c:259,265 – 2002/0314/sys/src/9/pc/i8253.c:259,265 (short | long) | ||
| 1997/0327 | { | |
| 2000/0623 | i8253.when = fastticks(nil); i8253.fastperiod = (m->cpuhz + HZ/2) / HZ; | |
| 2002/0221 |
| |
| 2002/0314 | i8253.fast2freq = (vlong)m->cpuhz * FreqMul / Freq; | |
| 2000/0701 | i8253.enabled = 1; | |
| 2000/0621 | intrenable(IrqCLOCK, clockintr0, 0, BUSUNKNOWN, "clock"); | |
| 1997/0327 | } | |
| 2002/0314/sys/src/9/pc/i8253.c:118,136 – 2002/0404/sys/src/9/pc/i8253.c:118,135 (short | long) | ||
| 1997/0327 | * prefetch buffer. * */ | |
| 1999/0131 | if(havecycleclock) | |
| 2001/1130 | rdtsc(&a); | |
| 2002/0404 | outb(Tmode, Latch0); | |
| 1997/0327 | x = inb(T0cntr); x |= inb(T0cntr)<<8; aamloop(loops); | |
| 1999/0131 | if(havecycleclock) | |
| 2001/1130 | rdtsc(&b); | |
| 1997/0327 | y = inb(T0cntr); y |= inb(T0cntr)<<8; x -= y; | |
| 2002/0404 | ||
| 1997/0327 | if(x < 0) x += Freq/HZ; | |
| 2002/0314/sys/src/9/pc/i8253.c:137,143 – 2002/0404/sys/src/9/pc/i8253.c:136,141 | ||
| 1997/0327 | if(x > Freq/(3*HZ)) break; } | |
| 1999/0131 | * n.b. counter goes up by 2*Freq | |
| 2002/0314/sys/src/9/pc/i8253.c:144,150 – 2002/0404/sys/src/9/pc/i8253.c:142,147 | ||
| 1997/0327 | */ | |
| 1999/0131 | cpufreq = loops*((aalcycles*2*Freq)/x); | |
| 1997/0327 | m->loopconst = (cpufreq/1000)/aalcycles; /* AAM+LOOP's for 1 ms */ | |
| 1999/0131 | if(havecycleclock){ /* counter goes up by 2*Freq */ | |
| 2002/0404/sys/src/9/pc/i8253.c:21,26 – 2002/0405/sys/src/9/pc/i8253.c:21,32 (short | long) | ||
| 2000/0622 | Load0l= 0x10, /* load counter 0's lsb */ Load0m= 0x20, /* load counter 0's msb */ | |
| 1997/0327 | Load0= 0x30, /* load counter 0 with 2 bytes */ | |
| 2002/0405 | Latch1= 0x40, /* latch counter 1's value */ Load1l= 0x50, /* load counter 1's lsb */ Load1m= 0x60, /* load counter 1's msb */ Load1= 0x70, /* load counter 1 with 2 bytes */ | |
| 2000/0623 | Latch2= 0x80, /* latch counter 2's value */ Load2l= 0x90, /* load counter 2's lsb */ Load2m= 0xa0, /* load counter 2's msb */ | |
| 2002/0404/sys/src/9/pc/i8253.c:55,106 – 2002/0405/sys/src/9/pc/i8253.c:61,124 | ||
| 2000/0623 | static struct { | |
| 2000/0627 | Lock; | |
| 2000/0713 |
| |
| 2000/0701 | int enabled; | |
| 2000/0627 | int mode; | |
| 2000/0623 | vlong when; /* next fastticks a clock interrupt should occur */ | |
| 2000/0627 |
| |
| 2002/0405 | vlong timerwhen; /* next fastticks a cycintr happens; 0 == infinity */ | |
| 2000/0623 | long fastperiod; /* fastticks/hz */ long fast2freq; /* fastticks*FreqMul/Freq */ | |
| 2002/0405 | Lock lock1; /* mutex for the following */ ushort last1; /* last value of clock 1 */ uvlong ticks1; /* cumulative ticks of counter 1 */ | |
| 2000/0623 | }i8253; | |
| 2000/0622 | ||
| 1997/0327 | void | |
| 1999/0131 |
| |
| 2002/0405 | i8253init(void) | |
| 1997/0327 | { | |
| 1999/0131 |
| |
| 1997/0327 |
| |
| 2002/0405 | int loops, x; | |
| 1997/0327 |
| |
| 2000/0713 |
| |
| 1999/0714 |
| |
| 2000/0623 |
| |
| 2002/0405 | ioalloc(T0cntr, 4, 0, "i8253"); ioalloc(T2ctl, 1, 0, "i8253.cntr2ctl"); | |
| 2000/0623 | ||
| 1997/0327 |
| |
| 2000/0627 |
| |
| 1997/0327 |
| |
| 2002/0405 | /* * set interrupting clock for 1/HZ seconds */ outb(Tmode, Load0|Square); i8253.mode = Square; outb(T0cntr, (Freq/HZ)); /* low byte */ outb(T0cntr, (Freq/HZ)>>8); /* high byte */ | |
| 1998/0903 |
| |
| 2002/0405 | /* * set time clock */ outb(Tmode, Load1|Square); i8253.mode = Square; outb(T1cntr, 0xfe); /* low byte */ outb(T1cntr, 0xff); /* high byte */ /* * Introduce a little delay to make sure the count is * latched and the timer is counting down; with a fast * enough processor this may not be the case. * The i8254 (which this probably is) has a read-back * command which can be used to make sure the counting * register has been written into the counting element. */ x = (Freq/HZ); for(loops = 0; loops < 100000 && x >= (Freq/HZ); loops++){ outb(Tmode, Latch0); x = inb(T0cntr); x |= inb(T0cntr)<<8; | |
| 1997/0327 | } | |
| 2002/0405 | } | |
| 1997/0327 | ||
| 2002/0405 | void guesscpuhz(int aalcycles) { int cpufreq, loops, incr, x, y; vlong a, b; | |
| 1997/0327 | /* find biggest loop that doesn't wrap */ incr = 16000000/(aalcycles*HZ*2); x = 2000; | |
| 2002/0404/sys/src/9/pc/i8253.c:118,135 – 2002/0405/sys/src/9/pc/i8253.c:136,154 | ||
| 1997/0327 | * prefetch buffer. * */ | |
| 1999/0131 |
| |
| 2001/1130 |
| |
| 2002/0404 | outb(Tmode, Latch0); | |
| 2002/0405 | if(m->havetsc) rdtsc(&a); | |
| 1997/0327 | x = inb(T0cntr); x |= inb(T0cntr)<<8; aamloop(loops); | |
| 1999/0131 |
| |
| 2002/0405 | outb(Tmode, Latch0); if(m->havetsc) | |
| 2001/1130 | rdtsc(&b); | |
| 1997/0327 | y = inb(T0cntr); y |= inb(T0cntr)<<8; x -= y; | |
| 2002/0404 | ||
| 2002/0405 | ||
| 1997/0327 | if(x < 0) x += Freq/HZ; | |
| 2002/0404/sys/src/9/pc/i8253.c:136,141 – 2002/0405/sys/src/9/pc/i8253.c:155,161 | ||
| 1997/0327 | if(x > Freq/(3*HZ)) break; } | |
| 2002/0405 | ||
| 1997/0327 | /* * figure out clock frequency and a loop multiplier for delay(). | |
| 1999/0131 | * n.b. counter goes up by 2*Freq | |
| 2002/0404/sys/src/9/pc/i8253.c:142,149 – 2002/0405/sys/src/9/pc/i8253.c:162,170 | ||
| 1997/0327 | */ | |
| 1999/0131 | cpufreq = loops*((aalcycles*2*Freq)/x); | |
| 1997/0327 | m->loopconst = (cpufreq/1000)/aalcycles; /* AAM+LOOP's for 1 ms */ | |
| 1999/0131 |
| |
| 2002/0405 | if(m->havetsc){ | |
| 1999/0131 | /* counter goes up by 2*Freq */ b = (b-a)<<1; b *= Freq; | |
| 2002/0404/sys/src/9/pc/i8253.c:165,171 – 2002/0405/sys/src/9/pc/i8253.c:186,192 | ||
| 1997/0327 | ||
| 2000/0627 | /* * schedule the next interrupt | |
| 2002/0405 | * timerwhen is the time of the next interrupt | |
| 2000/0627 | */ | |
| 2000/0621 | static void | |
| 2000/0627 | clockintrsched0(vlong next) | |
| 2002/0404/sys/src/9/pc/i8253.c:173,179 – 2002/0405/sys/src/9/pc/i8253.c:194,200 | ||
| 2000/0623 | vlong now; long set; | |
| 2000/0627 |
| |
| 2002/0405 | i8253.timerwhen = next; | |
| 2000/0627 | if(i8253.mode == Square && next == 0) return; | |
| 2002/0404/sys/src/9/pc/i8253.c:201,209 – 2002/0405/sys/src/9/pc/i8253.c:222,230 | ||
| 2000/0627 | } | |
| 2000/0623 | ||
| 2000/0701 | int | |
| 2002/0405 | havetimer(void) | |
| 2000/0701 | { | |
| 2000/0713 |
| |
| 2002/0405 | return i8253.enabled; | |
| 2000/0701 | } | |
| 2000/0627 | void | |
| 2002/0404/sys/src/9/pc/i8253.c:212,246 – 2002/0405/sys/src/9/pc/i8253.c:233,260 | ||
| 2000/0627 | vlong next; ilock(&i8253); | |
| 2000/0713 |
| |
| 2000/0701 |
| |
| 2002/0405 | if(i8253.enabled){ next = timernext(); if(next != i8253.timerwhen) | |
| 2000/0701 | clockintrsched0(next); } | |
| 2000/0627 | iunlock(&i8253); } | |
| 2002/0405 | int nclockintr0; | |
| 2000/0627 | static void clockintr0(Ureg* ureg, void *v) { vlong now, when; | |
| 2000/0713 |
| |
| 2002/0405 | nclockintr0++; /* goes with syncing in squidboy */ if(m->havetsc) rdtsc(&m->lasttsc); | |
| 2000/0627 | now = fastticks(nil); when = i8253.when; | |
| 2001/0611 |
| |
| 2000/0627 | if(now >= i8253.when){ clockintr(ureg, v); do | |
| 2002/0404/sys/src/9/pc/i8253.c:247,274 – 2002/0405/sys/src/9/pc/i8253.c:261,318 | ||
| 2000/0627 | i8253.when += i8253.fastperiod; while(i8253.when < now); } | |
| 2002/0405 | if(i8253.timerwhen || i8253.mode != Square) clockintrsched0(checktimer(ureg, v)); | |
| 2000/0621 | } | |
| 1997/0327 | void i8253enable(void) { | |
| 2000/0623 |
| |
| 2002/0314 |
| |
| 2002/0405 | uvlong hz; i8253.when = fastticks(&hz); i8253.fastperiod = (hz + HZ/2) / HZ; i8253.fast2freq = (hz * FreqMul) / Freq; | |
| 2000/0701 | i8253.enabled = 1; | |
| 2000/0621 | intrenable(IrqCLOCK, clockintr0, 0, BUSUNKNOWN, "clock"); | |
| 1997/0327 | } | |
| 1998/0710 | /* | |
| 1999/0228 |
| |
| 2002/0405 | * return the total ticks of counter 1. We shift by * 8 to give timesync more wriggle room for interpretation * of the frequency | |
| 1998/0710 | */ uvlong i8253read(uvlong *hz) { | |
| 2002/0405 | ushort y, x; uvlong ticks; | |
| 1998/0710 | if(hz) | |
| 1999/0228 |
| |
| 2002/0405 | *hz = Freq<<8; ilock(&i8253.lock1); outb(Tmode, Latch1); y = inb(T1cntr); y |= inb(T1cntr)<<8; if(y < i8253.last1) x = i8253.last1 - y; else x = i8253.last1 + (0xfffe - y); i8253.last1 = y; i8253.ticks1 += x>>1; ticks = i8253.ticks1; iunlock(&i8253.lock1); return ticks<<8; } /* * return value and speed of timer set in arch->clockenable */ vlong fastticks(uvlong *hz) { return (*arch->fastclock)(hz); | |
| 1998/0710 | } | |
| 2002/0405/sys/src/9/pc/i8253.c:241,253 – 2002/0406/sys/src/9/pc/i8253.c:241,253 (short | long) | ||
| 2000/0627 | iunlock(&i8253); } | |
| 2002/0405 |
| |
| 2002/0406 | ulong i8253ding[2]; | |
| 2000/0627 | static void clockintr0(Ureg* ureg, void *v) { vlong now, when; | |
| 2000/0713 | ||
| 2002/0405 |
| |
| 2002/0405/sys/src/9/pc/i8253.c:254,259 – 2002/0406/sys/src/9/pc/i8253.c:254,265 | ||
| 2000/0627 | now = fastticks(nil); when = i8253.when; | |
| 2002/0406 | if(i8253.last1 == 0 || i8253.last1 >= 0xffe0) i8253ding[1]++; else i8253ding[0]++; | |
| 2001/0611 | ||
| 2000/0627 | if(now >= i8253.when){ clockintr(ureg, v); | |
| 2002/0406/sys/src/9/pc/i8253.c:51,57 – 2002/0409/sys/src/9/pc/i8253.c:51,63 (short | long) | ||
| 2000/0623 | C2speak=0x2, C2out= 0x10, | |
| 2002/0409 | /* T2ctl bits */ T2gate= (1<<0), /* enable T2 counting */ T2spkr= (1<<1), /* connect T2 out to speaker */ T2out= (1<<5), /* output of T2 */ | |
| 1997/0327 | Freq= 1193182, /* Real clock frequency */ | |
| 2002/0409 | Tickshift= 8, /* increase tick wriggle room */ | |
| 2000/0623 | ||
| 2000/0706 | Minusec=20, /* minimum cycles for a clock interrupt */ | |
| 2002/0406/sys/src/9/pc/i8253.c:68,76 – 2002/0409/sys/src/9/pc/i8253.c:74,81 | ||
| 2000/0623 | long fastperiod; /* fastticks/hz */ long fast2freq; /* fastticks*FreqMul/Freq */ | |
| 2002/0405 |
| |
| 2002/0409 | ushort last; /* last value of clock 1 */ uvlong ticks; /* cumulative ticks of counter 1 */ | |
| 2000/0623 | }i8253; | |
| 2000/0622 | ||
| 1997/0327 | void | |
| 2002/0406/sys/src/9/pc/i8253.c:90,101 – 2002/0409/sys/src/9/pc/i8253.c:95,108 | ||
| 2002/0405 | outb(T0cntr, (Freq/HZ)>>8); /* high byte */ | |
| 1998/0903 | ||
| 2002/0405 | /* | |
| 2002/0409 | * enable a longer period counter to use as a clock | |
| 2002/0405 | */ | |
| 2002/0409 | outb(Tmode, Load2|Square); outb(T2cntr, 0); /* low byte */ outb(T2cntr, 0); /* high byte */ x = inb(T2ctl); x |= T2gate; outb(T2ctl, x); | |
| 2002/0405 | /* * Introduce a little delay to make sure the count is | |
| 2002/0406/sys/src/9/pc/i8253.c:241,248 – 2002/0409/sys/src/9/pc/i8253.c:248,253 | ||
| 2000/0627 | iunlock(&i8253); } | |
| 2002/0406 |
| |
| 2000/0627 | static void clockintr0(Ureg* ureg, void *v) { | |
| 2002/0406/sys/src/9/pc/i8253.c:255,266 – 2002/0409/sys/src/9/pc/i8253.c:260,265 | ||
| 2000/0627 | now = fastticks(nil); when = i8253.when; | |
| 2002/0406 |
| |
| 2001/0611 | ||
| 2000/0627 | if(now >= i8253.when){ clockintr(ureg, v); do | |
| 2002/0406/sys/src/9/pc/i8253.c:295,317 – 2002/0409/sys/src/9/pc/i8253.c:294,316 | ||
| 2002/0405 | uvlong ticks; | |
| 1998/0710 | if(hz) | |
| 2002/0405 |
| |
| 2002/0409 | *hz = Freq<<Tickshift; | |
| 2002/0405 |
| |
| 2002/0409 | ilock(&i8253); outb(Tmode, Latch2); y = inb(T2cntr); y |= inb(T2cntr)<<8; | |
| 2002/0405 |
| |
| 2002/0409 | if(y < i8253.last) x = i8253.last - y; | |
| 2002/0405 | else | |
| 2002/0409 | x = i8253.last + (0x1000 - y); i8253.last = y; i8253.ticks += x>>1; ticks = i8253.ticks; iunlock(&i8253); | |
| 2002/0405 |
| |
| 2002/0409 | return ticks<<Tickshift; | |
| 2002/0405 | } /* | |
| 2002/0409/sys/src/9/pc/i8253.c:46,56 – 2002/0410/sys/src/9/pc/i8253.c:46,51 (short | long) | ||
| 2000/0623 | Trigger=0x0, /* interrupt on terminal count */ Sstrobe=0x8, /* software triggered strobe */ | |
| 1997/0327 | ||
| 2000/0623 |
| |
| 2002/0409 | /* T2ctl bits */ T2gate= (1<<0), /* enable T2 counting */ T2spkr= (1<<1), /* connect T2 out to speaker */ | |
| 2002/0409/sys/src/9/pc/i8253.c:57,83 – 2002/0410/sys/src/9/pc/i8253.c:52,74 | ||
| 2002/0409 | T2out= (1<<5), /* output of T2 */ | |
| 1997/0327 | Freq= 1193182, /* Real clock frequency */ | |
| 2002/0409 |
| |
| 2000/0623 | ||
| 2000/0706 |
| |
| 2000/0623 |
| |
| 2002/0410 | Tickshift=8, /* extra accuracy */ MaxPeriod=Freq/HZ, MinPeriod=Freq/(100*HZ), | |
| 1997/0327 | }; | |
| 2000/0623 | static struct { | |
| 2000/0627 | Lock; | |
| 2002/0410 | ulong period; /* current clock period */ | |
| 2000/0701 | int enabled; | |
| 2000/0627 |
| |
| 2000/0623 |
| |
| 2002/0405 |
| |
| 2000/0623 |
| |
| 2002/0410 | uvlong hz; | |
| 2002/0405 | ||
| 2002/0409 | ushort last; /* last value of clock 1 */ uvlong ticks; /* cumulative ticks of counter 1 */ | |
| 2000/0623 | }i8253; | |
| 2000/0622 | ||
| 2002/0410 | ||
| 1997/0327 | void | |
| 2002/0405 | i8253init(void) | |
| 1997/0327 | { | |
| 2002/0409/sys/src/9/pc/i8253.c:87,98 – 2002/0410/sys/src/9/pc/i8253.c:78,89 | ||
| 2002/0405 | ioalloc(T2ctl, 1, 0, "i8253.cntr2ctl"); | |
| 2000/0623 | ||
| 2002/0405 | /* | |
| 2002/0410 | * enable a 1/HZ interrupt for providing scheduling interrupts | |
| 2002/0405 | */ outb(Tmode, Load0|Square); | |
| 2002/0410 | i8253.period = Freq/HZ; | |
| 1998/0903 | ||
| 2002/0405 | /* | |
| 2002/0409 | * enable a longer period counter to use as a clock | |
| 2002/0409/sys/src/9/pc/i8253.c:100,109 – 2002/0410/sys/src/9/pc/i8253.c:91,101 | ||
| 2002/0409 | outb(Tmode, Load2|Square); outb(T2cntr, 0); /* low byte */ outb(T2cntr, 0); /* high byte */ | |
| 2002/0410 | i8253.period = Freq/HZ; | |
| 2002/0409 | x = inb(T2ctl); x |= T2gate; outb(T2ctl, x); | |
| 2002/0405 | ||
| 2002/0410 | ||
| 2002/0405 | /* * Introduce a little delay to make sure the count is * latched and the timer is counting down; with a fast | |
| 2002/0409/sys/src/9/pc/i8253.c:189,285 – 2002/0410/sys/src/9/pc/i8253.c:181,238 | ||
| 1999/0131 | m->cpumhz = (cpufreq + cpufreq/200)/1000000; m->cpuhz = cpufreq; } | |
| 2002/0410 | i8253.hz = Freq<<Tickshift; | |
| 1997/0327 | } | |
| 2000/0627 |
| |
| 2002/0405 |
| |
| 2000/0627 |
| |
| 2000/0621 |
| |
| 2000/0627 |
| |
| 2002/0410 | ulong i8253periodset; void i8253timerset(uvlong next) | |
| 2000/0621 | { | |
| 2000/0623 |
| |
| 2002/0410 | ulong period; ulong want; ulong now; | |
| 2000/0623 | ||
| 2002/0405 |
| |
| 2000/0627 |
| |
| 2002/0410 | want = next>>Tickshift; now = i8253.ticks; /* assuming whomever called us just did fastticks() */ | |
| 2000/0627 | ||
| 2000/0623 |
| |
| 2000/0627 |
| |
| 2000/0706 |
| |
| 2000/0627 |
| |
| 2002/0410 | period = MaxPeriod; if(next != 0){ period = want - now; if(period < MinPeriod) period = MinPeriod; else if(period > (4*MaxPeriod)/5) /* strong attraction to MaxPeriod */ period = MaxPeriod; | |
| 2000/0627 | } | |
| 2000/0623 | ||
| 2000/0701 |
| |
| 2002/0405 |
| |
| 2000/0701 |
| |
| 2002/0405 |
| |
| 2000/0701 |
| |
| 2002/0410 | /* histeresis */ if(i8253.period != period){ ilock(&i8253); /* load new value */ outb(Tmode, Load0|Square); outb(T0cntr, period); /* low byte */ outb(T0cntr, period>>8); /* high byte */ | |
| 2000/0701 | ||
| 2000/0627 |
| |
| 2002/0405 |
| |
| 2000/0701 |
| |
| 2002/0410 | /* remember period */ i8253.period = period; i8253periodset++; iunlock(&i8253); | |
| 2000/0701 | } | |
| 2000/0627 |
| |
| 2002/0410 | i8253clock(Ureg* ureg, void*) | |
| 2000/0627 | { | |
| 2000/0713 | ||
| 2002/0405 |
| |
| 2000/0627 |
| |
| 2002/0406 | ||
| 2000/0627 |
| |
| 2002/0405 |
| |
| 2002/0410 | timerintr(ureg, 0); | |
| 2000/0621 | } | |
| 1997/0327 | void i8253enable(void) { | |
| 2002/0405 |
| |
| 2000/0701 | i8253.enabled = 1; | |
| 2000/0621 |
| |
| 2002/0410 | i8253.period = Freq/HZ; intrenable(IrqCLOCK, i8253clock, 0, BUSUNKNOWN, "clock"); | |
| 1997/0327 | } | |
| 1998/0710 | /* | |
| 2002/0409/sys/src/9/pc/i8253.c:294,300 – 2002/0410/sys/src/9/pc/i8253.c:247,253 | ||
| 2002/0405 | uvlong ticks; | |
| 1998/0710 | if(hz) | |
| 2002/0409 |
| |
| 2002/0410 | *hz = i8253.hz; | |
| 2002/0405 | ||
| 2002/0409 | ilock(&i8253); outb(Tmode, Latch2); | |
| 2002/0409/sys/src/9/pc/i8253.c:304,310 – 2002/0410/sys/src/9/pc/i8253.c:257,263 | ||
| 2002/0409 | if(y < i8253.last) x = i8253.last - y; | |
| 2002/0405 | else | |
| 2002/0409 |
| |
| 2002/0410 | x = i8253.last + (0x10000 - y); | |
| 2002/0409 | i8253.last = y; i8253.ticks += x>>1; ticks = i8253.ticks; | |
| 2002/0409/sys/src/9/pc/i8253.c:313,323 – 2002/0410/sys/src/9/pc/i8253.c:266,299 | ||
| 2002/0409 | return ticks<<Tickshift; | |
| 2002/0405 | } | |
| 2002/0410 | void delay(int millisecs) | |
| 2002/0405 | { | |
| 2002/0410 | millisecs *= m->loopconst; if(millisecs <= 0) millisecs = 1; aamloop(millisecs); } void microdelay(int microsecs) { microsecs *= m->loopconst; microsecs /= 1000; if(microsecs <= 0) microsecs = 1; aamloop(microsecs); } ulong TK2MS(ulong ticks) { uvlong t, hz; t = ticks; hz = HZ; t *= 1000L; t = t/hz; ticks = t; return ticks; | |
| 1998/0710 | } | |
| Too many diffs (26 > 25). Stopping. | ||