Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 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
 
33
#define        MIN_INT 200
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), \
181
                (t)->gigas += (t)->units / 1432809, \
182
                (t)->units %= 1432809)
183
#define NULLPITSPEC(t)   (t)->units = 0, (t)->gigas = 0
184
#define PITSPEC2USEC(t) ((((t)->units * 1000) / 1197) \
185
                         + (((t)->gigas * 1000) * 1197))
186
#define CPPITSPEC(a, b) (b)->units = (a)->units, (b)->gigas = (a)->gigas
187
END_DEF
188
#endif        /* __PIT_H__ */