Rev 305 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
42 | pj | 1 | /* Project: OSLib |
2 | * Description: The OS Construction Kit |
||
3 | * Date: 1.6.2000 |
||
4 | * Idea by: Luca Abeni & Gerardo Lamastra |
||
5 | * |
||
6 | * OSLib is an SO project aimed at developing a common, easy-to-use |
||
7 | * low-level infrastructure for developing OS kernels and Embedded |
||
8 | * Applications; it partially derives from the HARTIK project but it |
||
9 | * currently is independently developed. |
||
10 | * |
||
11 | * OSLib is distributed under GPL License, and some of its code has |
||
12 | * been derived from the Linux kernel source; also some important |
||
13 | * ideas come from studying the DJGPP go32 extender. |
||
14 | * |
||
15 | * We acknowledge the Linux Community, Free Software Foundation, |
||
16 | * D.J. Delorie and all the other developers who believe in the |
||
17 | * freedom of software and ideas. |
||
18 | * |
||
19 | * For legalese, check out the included GPL license. |
||
20 | */ |
||
21 | |||
22 | /* The Programmable Interrupt Timer management code */ |
||
23 | |||
24 | #ifndef __PIT_H__ |
||
25 | #define __PIT_H__ |
||
26 | |||
27 | #include <ll/i386/defs.h> |
||
28 | BEGIN_DEF |
||
29 | |||
30 | #include <ll/i386/hw-data.h> |
||
31 | #include <ll/i386/hw-instr.h> |
||
32 | |||
46 | trimarchi | 33 | #define MIN_INT 100 |
42 | pj | 34 | |
35 | #define TMR_CTRL 0x43 /* PIT Control port*/ |
||
36 | #define TMR_CNT0 0x40 /* Counter 0 port */ |
||
37 | #define TMR_CNT1 0x41 /* Counter 1 port */ |
||
38 | #define TMR_CNT2 0x42 /* Counter 2 port */ |
||
39 | |||
40 | #define TMR_SC0 0x00 /* Select Channel 0 */ |
||
41 | #define TMR_SC1 0x40 /* Select Channel 1 */ |
||
42 | #define TMR_SC2 0x80 /* Select Channel 2 */ |
||
43 | |||
44 | #define TMR_LSB 0x10 /* R/W Least Significative Byte */ |
||
45 | #define TMR_MSB 0x20 /* R/W Most Significative Byte */ |
||
46 | #define TMR_BOTH 0x30 /* R/W Both Bytes */ |
||
47 | #define TMR_LATCH 0x00 /* Latch Command */ |
||
48 | #define TMR_READ 0xF0 /* Read Command */ |
||
49 | #define TMR_CNT 0x20 /* Read Counter */ |
||
50 | #define TMR_STAT 0x10 /* Read Status */ |
||
51 | #define TMR_CH2 0x08 /* Read Channel 2 Counter/Status */ |
||
52 | #define TMR_CH1 0x04 /* Read Channel 1 Counter/Status */ |
||
53 | #define TMR_CH0 0x02 /* Read Channel 0 Counter/Status */ |
||
54 | |||
55 | |||
56 | #define TMR_MD0 0x00 /* Mode 0 */ |
||
57 | #define TMR_MD1 0x02 /* Mode 1 */ |
||
58 | #define TMR_MD2 0x04 /* Mode 2 */ |
||
59 | #define TMR_MD3 0x06 /* Mode 3 */ |
||
60 | #define TMR_MD4 0x08 /* Mode 4 */ |
||
61 | #define TMR_MD5 0x0A /* Mode 5 */ |
||
62 | |||
63 | |||
64 | INLINE_OP int pit_init(BYTE channel, BYTE mode, WORD tconst) |
||
65 | { |
||
66 | BYTE v, ch; |
||
67 | WORD cnt; |
||
68 | |||
69 | switch (channel) { |
||
70 | case 0: |
||
71 | cnt = TMR_CNT0; |
||
72 | ch = TMR_SC0; |
||
73 | break; |
||
74 | case 1: |
||
75 | cnt = TMR_CNT1; |
||
76 | ch = TMR_SC1; |
||
77 | break; |
||
78 | case 2: |
||
79 | cnt = TMR_CNT2; |
||
80 | ch = TMR_SC2; |
||
81 | break; |
||
82 | default: |
||
83 | return -1; |
||
84 | } |
||
85 | |||
86 | /* VM_out(TMR_CTRL, 0x34); */ |
||
87 | outp(TMR_CTRL, ch | TMR_BOTH | mode); |
||
88 | /* Load Time_const with 2 access to CTR */ |
||
89 | v = (BYTE)(tconst); |
||
90 | outp(cnt, v); |
||
91 | v = (BYTE)(tconst >> 8); |
||
92 | outp(cnt, v); |
||
93 | |||
94 | return 1; |
||
95 | } |
||
96 | |||
97 | INLINE_OP int pit_setconstant(BYTE channel, DWORD c) |
||
98 | { |
||
99 | BYTE v; |
||
100 | WORD cnt; |
||
101 | WORD tconst; |
||
102 | |||
103 | if (c > 0xF000) { |
||
104 | tconst = 0xF000; |
||
105 | } else { |
||
106 | if (c < MIN_INT) { |
||
107 | tconst = MIN_INT; |
||
108 | } else { |
||
109 | tconst = c; |
||
110 | } |
||
111 | } |
||
112 | |||
113 | switch (channel) { |
||
114 | case 0: |
||
115 | cnt = TMR_CNT0; |
||
116 | break; |
||
117 | case 1: |
||
118 | cnt = TMR_CNT1; |
||
119 | break; |
||
120 | case 2: |
||
121 | cnt = TMR_CNT2; |
||
122 | break; |
||
123 | default: |
||
124 | return -1; |
||
125 | } |
||
126 | |||
127 | /* Load Time_const with 2 access to CTR */ |
||
128 | v = (BYTE)(tconst); |
||
129 | outp(cnt, v); |
||
130 | v = (BYTE)(tconst >> 8); |
||
131 | outp(cnt, v); |
||
132 | |||
133 | return 1; |
||
134 | } |
||
135 | |||
136 | |||
137 | INLINE_OP WORD pit_read(BYTE channel) |
||
138 | { |
||
139 | WORD result; |
||
140 | WORD cnt; |
||
141 | BYTE ch; |
||
142 | BYTE str_msb, str_lsb; |
||
143 | |||
144 | switch (channel) { |
||
145 | case 0: |
||
146 | cnt = TMR_CNT0; |
||
147 | ch = TMR_CH0; |
||
148 | break; |
||
149 | case 1: |
||
150 | cnt = TMR_CNT1; |
||
151 | ch = TMR_CH1; |
||
152 | break; |
||
153 | case 2: |
||
154 | cnt = TMR_CNT2; |
||
155 | ch = TMR_CH2; |
||
156 | break; |
||
157 | default: |
||
158 | return 0; |
||
159 | } |
||
160 | |||
161 | /* Read Back Command on counter 0 */ |
||
162 | #if 0 |
||
163 | outp(TMR_CTRL, ch | TMR_LATCH | TMR_BOTH); |
||
164 | #else |
||
165 | outp(TMR_CTRL, TMR_READ - TMR_CNT + ch /*0xD2*/); |
||
166 | #endif |
||
167 | /* Read the latched value from STR */ |
||
168 | str_lsb = inp(cnt); |
||
169 | str_msb = inp(cnt); |
||
170 | /* Combine the byte values to obtain a word */ |
||
171 | result = ((WORD)str_msb << 8) | (WORD)str_lsb; |
||
172 | return result; |
||
173 | } |
||
174 | |||
175 | struct pitspec { |
||
176 | long units; |
||
177 | long gigas; |
||
178 | }; |
||
179 | |||
180 | #define ADDPITSPEC(n, t) ((t)->units += (n), \ |
||
330 | giacomo | 181 | (t)->gigas += (t)->units / 1423249, \ |
182 | (t)->units %= 1423249) |
||
42 | pj | 183 | #define NULLPITSPEC(t) (t)->units = 0, (t)->gigas = 0 |
330 | giacomo | 184 | #define PITSPEC2USEC(t) ((((t)->units * 1000) / 1193) \ |
185 | + (((t)->gigas * 1000) * 1193)) |
||
42 | pj | 186 | #define CPPITSPEC(a, b) (b)->units = (a)->units, (b)->gigas = (a)->gigas |
305 | giacomo | 187 | |
42 | pj | 188 | #endif /* __PIT_H__ */ |