1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6
7 void
delay(int l)8 delay(int l)
9 {
10 ulong i, j;
11
12 j = m->delayloop;
13 while(l-- > 0)
14 for(i=0; i < j; i++)
15 ;
16 }
17
18 void
microdelay(int l)19 microdelay(int l)
20 {
21 ulong i;
22
23 l *= m->delayloop;
24 l /= 1000;
25 if(l <= 0)
26 l = 1;
27 for(i = 0; i < l; i++)
28 ;
29 }
30
31 enum {
32 Timebase = 1, /* system clock cycles per time base cycle */
33
34 Wp17= 0<<30, /* watchdog period (2^x clocks) */
35 Wp21= 1<<30,
36 Wp25= 2<<30,
37 Wp29= 3<<30,
38 Wrnone= 0<<28, /* no watchdog reset */
39 Wrcore= 1<<28, /* core reset */
40 Wrchip= 2<<28, /* chip reset */
41 Wrsys= 3<<28, /* system reset */
42 Wie= 1<<27, /* watchdog interrupt enable */
43 Pie= 1<<26, /* enable PIT interrupt */
44 Fit9= 0<<24, /* fit period (2^x clocks) */
45 Fit13= 1<<24,
46 Fit17= 2<<24,
47 Fit21= 3<<24,
48 Fie= 1<<23, /* fit interrupt enable */
49 Are= 1<<22, /* auto reload enable */
50
51 /* dcr */
52 Boot= 0x0F1,
53 Epctl= 0x0F3,
54 Pllmr0= 0x0F0,
55 Pllmr1= 0x0F4,
56 Ucr= 0x0F5,
57 };
58
59 void (*archclocktick)(void); /* set by arch*.c if used */
60
61 void
clockinit(void)62 clockinit(void)
63 {
64 long x;
65
66 assert(m->cpuhz != 0);
67 m->delayloop = m->cpuhz/1000; /* initial estimate */
68 do {
69 x = gettbl();
70 delay(10);
71 x = gettbl() - x;
72 } while(x < 0);
73 assert(x != 0);
74
75 /*
76 * fix count
77 */
78 m->delayloop = ((vlong)m->delayloop*(10*(vlong)m->clockgen/1000))/(x*Timebase);
79 if((int)m->delayloop <= 0)
80 m->delayloop = 20000;
81
82 x = (m->clockgen/Timebase)/HZ;
83 //iprint("initial PIT %ld\n", x);
84 assert(x != 0);
85 putpit(x);
86 puttsr(~0);
87 /* not sure if we want Wrnone or Wrcore */
88 // puttcr(Pie|Are|Wie|Wrcore|Wp29);
89 puttcr(Pie|Are|Wrnone);
90 }
91
92 void
clockintr(Ureg * ureg)93 clockintr(Ureg *ureg)
94 {
95 /* PIT was set to reload automatically */
96 puttsr(~0);
97 m->fastclock++;
98 timerintr(ureg, 0);
99 if(archclocktick != nil)
100 archclocktick();
101 }
102
103 uvlong
fastticks(uvlong * hz)104 fastticks(uvlong *hz)
105 {
106 if(hz)
107 *hz = HZ;
108 return m->fastclock;
109 }
110
111 ulong
s(void)112 µs(void)
113 {
114 return fastticks2us(m->fastclock);
115 }
116
117 void
timerset(uvlong)118 timerset(uvlong)
119 {
120 }
121
122 ulong
perfticks(void)123 perfticks(void)
124 {
125 return (ulong)fastticks(nil);
126 }
127
128 long
lcycles(void)129 lcycles(void)
130 {
131 return perfticks();
132 }
133