|
|
1.1 ! root 1: #include "u.h" ! 2: #include "lib.h" ! 3: #include "mem.h" ! 4: #include "dat.h" ! 5: #include "fns.h" ! 6: #include "io.h" ! 7: #include "ureg.h" ! 8: ! 9: /* ! 10: * 8253 timer ! 11: */ ! 12: enum ! 13: { ! 14: T0cntr= 0x40, /* counter ports */ ! 15: T1cntr= 0x41, /* ... */ ! 16: T2cntr= 0x42, /* ... */ ! 17: Tmode= 0x43, /* mode port */ ! 18: ! 19: /* commands */ ! 20: Latch0= 0x00, /* latch counter 0's value */ ! 21: Load0= 0x30, /* load counter 0 with 2 bytes */ ! 22: ! 23: /* modes */ ! 24: Square= 0x36, /* perioic square wave */ ! 25: ! 26: Freq= 1193182, /* Real clock frequency */ ! 27: }; ! 28: ! 29: static int cpufreq = 66000000; ! 30: static int cpumhz = 66; ! 31: static int cputype = 486; ! 32: static int loopconst = 100; ! 33: ! 34: /* ! 35: * delay for l milliseconds more or less. delayloop is set by ! 36: * clockinit() to match the actual CPU speed. ! 37: */ ! 38: void ! 39: delay(int l) ! 40: { ! 41: aamloop(l*loopconst); ! 42: } ! 43: ! 44: static void ! 45: clock(Ureg*, void*) ! 46: { ! 47: m->ticks++; ! 48: checkalarms(); ! 49: } ! 50: ! 51: void ! 52: clockinit(void) ! 53: { ! 54: ulong x, y; /* change in counter */ ! 55: ulong cycles, loops; ! 56: ! 57: switch(cputype = x86()){ ! 58: case 386: ! 59: loops = 10000; ! 60: cycles = 32; ! 61: break; ! 62: case 486: ! 63: loops = 10000; ! 64: cycles = 22; ! 65: break; ! 66: default: ! 67: loops = 30000; ! 68: cycles = 23; ! 69: break; ! 70: } ! 71: ! 72: /* ! 73: * set vector for clock interrupts ! 74: */ ! 75: setvec(Clockvec, clock, 0); ! 76: ! 77: /* ! 78: * set clock for 1/HZ seconds ! 79: */ ! 80: outb(Tmode, Load0|Square); ! 81: outb(T0cntr, (Freq/HZ)); /* low byte */ ! 82: outb(T0cntr, (Freq/HZ)>>8); /* high byte */ ! 83: ! 84: ! 85: /* ! 86: * measure time for the loop ! 87: * ! 88: * MOVL loops,CX ! 89: * aaml1: AAM ! 90: * LOOP aaml1 ! 91: * ! 92: * the time for the loop should be independent from external ! 93: * cache's and memory system since it fits in the execution ! 94: * prefetch buffer. ! 95: * ! 96: */ ! 97: outb(Tmode, Latch0); ! 98: x = inb(T0cntr); ! 99: x |= inb(T0cntr)<<8; ! 100: aamloop(loops); ! 101: outb(Tmode, Latch0); ! 102: y = inb(T0cntr); ! 103: y |= inb(T0cntr)<<8; ! 104: x -= y; ! 105: ! 106: /* ! 107: * counter goes at twice the frequency, once per transition, ! 108: * i.e., twice per square wave ! 109: */ ! 110: x >>= 1; ! 111: ! 112: /* ! 113: * figure out clock frequency and a loop multiplier for delay(). ! 114: */ ! 115: cpufreq = loops*((cycles*Freq)/x); ! 116: loopconst = (cpufreq/1000)/cycles; /* AAM+LOOP's for 1 ms */ ! 117: ! 118: /* ! 119: * add in possible .1% error and convert to MHz ! 120: */ ! 121: cpumhz = (cpufreq + cpufreq/1000)/1000000; ! 122: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.