util: Add the m5_loadsymbol pseudo op to the m5 tool
[gem5.git] / src / dev / intel_8254_timer.hh
1 /*
2 * Copyright (c) 2004, 2005
3 * The Regents of The University of Michigan
4 * All Rights Reserved
5 *
6 * This code is part of the M5 simulator.
7 *
8 * Permission is granted to use, copy, create derivative works and
9 * redistribute this software and such derivative works for any
10 * purpose, so long as the copyright notice above, this grant of
11 * permission, and the disclaimer below appear in all copies made; and
12 * so long as the name of The University of Michigan is not used in
13 * any advertising or publicity pertaining to the use or distribution
14 * of this software without specific, written prior authorization.
15 *
16 * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE
17 * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND
18 * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER
19 * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE
22 * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT,
23 * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM
24 * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
25 * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH
26 * DAMAGES.
27 *
28 * Authors: Ali G. Saidi
29 * Andrew L. Schultz
30 * Miguel J. Serrano
31 */
32
33 #ifndef __DEV_8254_HH__
34 #define __DEV_8254_HH__
35
36 #include <iostream>
37 #include <string>
38
39 #include "base/bitunion.hh"
40 #include "base/types.hh"
41 #include "base/trace.hh"
42 #include "debug/Intel8254Timer.hh"
43 #include "sim/eventq_impl.hh"
44 #include "sim/serialize.hh"
45
46 /** Programmable Interval Timer (Intel 8254) */
47 class Intel8254Timer : public EventManager
48 {
49 protected:
50 BitUnion8(CtrlReg)
51 Bitfield<7, 6> sel;
52 Bitfield<5, 4> rw;
53 Bitfield<3, 1> mode;
54 Bitfield<0> bcd;
55 EndBitUnion(CtrlReg)
56
57 enum SelectVal {
58 SelectCounter0,
59 SelectCounter1,
60 SelectCounter2,
61 ReadBackCommand
62 };
63
64 enum ReadWriteVal {
65 LatchCommand,
66 LsbOnly,
67 MsbOnly,
68 TwoPhase
69 };
70
71 enum ModeVal {
72 InitTc,
73 OneShot,
74 RateGen,
75 SquareWave,
76 SoftwareStrobe,
77 HardwareStrobe
78 };
79
80 /** Counter element for PIT */
81 class Counter
82 {
83 /** Event for counter interrupt */
84 class CounterEvent : public Event
85 {
86 private:
87 /** Pointer back to Counter */
88 Counter* counter;
89 Tick interval;
90
91 public:
92 CounterEvent(Counter*);
93
94 /** Event process */
95 void process();
96
97 /** Event description */
98 virtual const char *description() const;
99
100 friend class Counter;
101
102 void setTo(int clocks);
103
104 int clocksLeft();
105
106 Tick getInterval();
107 };
108
109 private:
110 std::string _name;
111 const std::string &name() const { return _name; }
112
113 unsigned int num;
114
115 CounterEvent event;
116
117 /** True after startup is called. */
118 bool running;
119
120 /** Initial count value */
121 uint16_t initial_count;
122
123 /** Latched count */
124 uint16_t latched_count;
125
126 /** Interrupt period */
127 uint16_t period;
128
129 /** When to start ticking */
130 Tick offset;
131
132 /** Current mode of operation */
133 uint8_t mode;
134
135 /** Output goes high when the counter reaches zero */
136 bool output_high;
137
138 /** State of the count latch */
139 bool latch_on;
140
141 /** Set of values for read_byte and write_byte */
142 enum {LSB, MSB};
143
144 /** Determine which byte of a 16-bit count value to read/write */
145 uint8_t read_byte, write_byte;
146
147 /** Pointer to container */
148 Intel8254Timer *parent;
149
150 public:
151 Counter(Intel8254Timer *p, const std::string &name, unsigned int num);
152
153 /** Latch the current count (if one is not already latched) */
154 void latchCount();
155
156 /** Get the current count for this counter */
157 int currentCount();
158
159 /** Set the read/write mode */
160 void setRW(int rw_val);
161
162 /** Set operational mode */
163 void setMode(int mode_val);
164
165 /** Set count encoding */
166 void setBCD(int bcd_val);
167
168 /** Read a count byte */
169 uint8_t read();
170
171 /** Write a count byte */
172 void write(const uint8_t data);
173
174 /** Is the output high? */
175 bool outputHigh();
176
177 /**
178 * Serialize this object to the given output stream.
179 * @param base The base name of the counter object.
180 * @param os The stream to serialize to.
181 */
182 void serialize(const std::string &base, CheckpointOut &cp) const;
183
184 /**
185 * Reconstruct the state of this object from a checkpoint.
186 * @param base The base name of the counter object.
187 * @param cp The checkpoint use.
188 * @param section The section name of this object
189 */
190 void unserialize(const std::string &base, CheckpointIn &cp);
191
192 /** Start ticking */
193 void startup();
194 };
195
196 protected:
197 std::string _name;
198 const std::string &name() const { return _name; }
199
200 /** PIT has three seperate counters */
201 Counter *counter[3];
202
203 virtual void
204 counterInterrupt(unsigned int num)
205 {
206 DPRINTF(Intel8254Timer, "Timer interrupt from counter %d.\n", num);
207 }
208
209 public:
210
211 virtual
212 ~Intel8254Timer()
213 {}
214
215 Intel8254Timer(EventManager *em, const std::string &name,
216 Counter *counter0, Counter *counter1, Counter *counter2);
217
218 Intel8254Timer(EventManager *em, const std::string &name);
219
220 /** Write control word */
221 void writeControl(const CtrlReg data);
222
223 uint8_t
224 readCounter(unsigned int num)
225 {
226 assert(num < 3);
227 return counter[num]->read();
228 }
229
230 void
231 writeCounter(unsigned int num, const uint8_t data)
232 {
233 assert(num < 3);
234 counter[num]->write(data);
235 }
236
237 bool
238 outputHigh(unsigned int num)
239 {
240 assert(num < 3);
241 return counter[num]->outputHigh();
242 }
243
244 /**
245 * Serialize this object to the given output stream.
246 * @param base The base name of the counter object.
247 * @param os The stream to serialize to.
248 */
249 void serialize(const std::string &base, CheckpointOut &cp) const;
250
251 /**
252 * Reconstruct the state of this object from a checkpoint.
253 * @param base The base name of the counter object.
254 * @param cp The checkpoint use.
255 * @param section The section name of this object
256 */
257 void unserialize(const std::string &base, CheckpointIn &cp);
258
259 /** Start ticking */
260 void startup();
261 };
262
263 #endif // __DEV_8254_HH__