|
|
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.