gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
intel_8254_timer.cc
Go to the documentation of this file.
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 #include "dev/intel_8254_timer.hh"
34 
35 #include "base/misc.hh"
36 #include "debug/Intel8254Timer.hh"
37 
38 using namespace std;
39 
41  Counter *counter0, Counter *counter1, Counter *counter2) :
42  EventManager(em), _name(name)
43 {
44  counter[0] = counter0;
45  counter[1] = counter1;
46  counter[2] = counter2;
47 }
48 
50  EventManager(em), _name(name)
51 {
52  counter[0] = new Counter(this, name + ".counter0", 0);
53  counter[1] = new Counter(this, name + ".counter1", 1);
54  counter[2] = new Counter(this, name + ".counter2", 2);
55 }
56 
57 void
59 {
60  int sel = data.sel;
61 
62  if (sel == ReadBackCommand)
63  panic("PITimer Read-Back Command is not implemented.\n");
64 
65  if (data.rw == LatchCommand)
67  else {
68  counter[sel]->setRW(data.rw);
69  counter[sel]->setMode(data.mode);
70  counter[sel]->setBCD(data.bcd);
71  }
72 }
73 
74 void
75 Intel8254Timer::serialize(const string &base, CheckpointOut &cp) const
76 {
77  // serialize the counters
78  counter[0]->serialize(base + ".counter0", cp);
79  counter[1]->serialize(base + ".counter1", cp);
80  counter[2]->serialize(base + ".counter2", cp);
81 }
82 
83 void
85 {
86  // unserialze the counters
87  counter[0]->unserialize(base + ".counter0", cp);
88  counter[1]->unserialize(base + ".counter1", cp);
89  counter[2]->unserialize(base + ".counter2", cp);
90 }
91 
92 void
94 {
95  counter[0]->startup();
96  counter[1]->startup();
97  counter[2]->startup();
98 }
99 
101  const string &name, unsigned int _num)
102  : _name(name), num(_num), event(this), running(false),
103  initial_count(0), latched_count(0), period(0), mode(0),
104  output_high(false), latch_on(false), read_byte(LSB),
105  write_byte(LSB), parent(p)
106 {
107  offset = period * event.getInterval();
108 }
109 
110 void
112 {
113  // behave like a real latch
114  if (!latch_on) {
115  latch_on = true;
116  read_byte = LSB;
117  latched_count = currentCount();
118  }
119 }
120 
121 int
123 {
124  int clocks = event.clocksLeft();
125  if (clocks == -1) {
126  warn_once("Reading current count from inactive timer.\n");
127  return 0;
128  }
129  if (mode == RateGen || mode == SquareWave)
130  return clocks + 1;
131  else
132  return clocks;
133 }
134 
135 uint8_t
137 {
138  if (latch_on) {
139  switch (read_byte) {
140  case LSB:
141  read_byte = MSB;
142  return (uint8_t)latched_count;
143  break;
144  case MSB:
145  read_byte = LSB;
146  latch_on = false;
147  return latched_count >> 8;
148  break;
149  default:
150  panic("Shouldn't be here");
151  }
152  } else {
153  uint16_t count = currentCount();
154  switch (read_byte) {
155  case LSB:
156  read_byte = MSB;
157  return (uint8_t)count;
158  break;
159  case MSB:
160  read_byte = LSB;
161  return count >> 8;
162  break;
163  default:
164  panic("Shouldn't be here");
165  }
166  }
167 }
168 
169 void
171 {
172  switch (write_byte) {
173  case LSB:
174  initial_count = (initial_count & 0xFF00) | data;
175 
176  if (event.scheduled())
177  parent->deschedule(event);
178  output_high = false;
179  write_byte = MSB;
180  break;
181 
182  case MSB:
183  initial_count = (initial_count & 0x00FF) | (data << 8);
184  // In the RateGen or SquareWave modes, the timer wraps around and
185  // triggers on a value of 1, not 0.
186  if (mode == RateGen || mode == SquareWave)
187  period = initial_count - 1;
188  else
189  period = initial_count;
190 
191  offset = period * event.getInterval();
192 
193  if (running && (period > 0))
194  event.setTo(period);
195 
196  write_byte = LSB;
197  break;
198  }
199 }
200 
201 void
203 {
204  if (rw_val != TwoPhase)
205  panic("Only LSB/MSB read/write is implemented.\n");
206 }
207 
208 void
210 {
211  if (mode_val != InitTc && mode_val != RateGen &&
212  mode_val != SquareWave)
213  panic("PIT mode %#x is not implemented: \n", mode_val);
214 
215  mode = mode_val;
216 }
217 
218 void
220 {
221  if (bcd_val)
222  panic("PITimer does not implement BCD counts.\n");
223 }
224 
225 bool
227 {
228  return output_high;
229 }
230 
231 void
233 {
234  paramOut(cp, base + ".initial_count", initial_count);
235  paramOut(cp, base + ".latched_count", latched_count);
236  paramOut(cp, base + ".period", period);
237  paramOut(cp, base + ".mode", mode);
238  paramOut(cp, base + ".output_high", output_high);
239  paramOut(cp, base + ".latch_on", latch_on);
240  paramOut(cp, base + ".read_byte", read_byte);
241  paramOut(cp, base + ".write_byte", write_byte);
242 
243  Tick event_tick_offset = 0;
244  if (event.scheduled())
245  event_tick_offset = event.when() - curTick();
246  paramOut(cp, base + ".event_tick_offset", event_tick_offset);
247 }
248 
249 void
251 {
252  paramIn(cp, base + ".initial_count", initial_count);
253  paramIn(cp, base + ".latched_count", latched_count);
254  paramIn(cp, base + ".period", period);
255  paramIn(cp, base + ".mode", mode);
256  paramIn(cp, base + ".output_high", output_high);
257  paramIn(cp, base + ".latch_on", latch_on);
258  paramIn(cp, base + ".read_byte", read_byte);
259  paramIn(cp, base + ".write_byte", write_byte);
260 
261  Tick event_tick_offset = 0;
262  assert(!event.scheduled());
263  paramIn(cp, base + ".event_tick_offset", event_tick_offset);
264  offset = event_tick_offset;
265 }
266 
267 void
269 {
270  running = true;
271  if ((period > 0) && (offset > 0))
272  {
273  parent->schedule(event, curTick() + offset);
274  }
275 }
276 
278 {
279  interval = (Tick)(SimClock::Float::s / 1193180.0);
280  counter = c_ptr;
281 }
282 
283 void
285 {
286  switch (counter->mode) {
287  case InitTc:
288  counter->output_high = true;
289  break;
290  case RateGen:
291  case SquareWave:
292  setTo(counter->period);
293  break;
294  default:
295  panic("Unimplemented PITimer mode.\n");
296  }
298 }
299 
300 void
302 {
303  if (clocks == 0)
304  panic("Timer can't be set to go off instantly.\n");
305  DPRINTF(Intel8254Timer, "Timer set to curTick() + %d\n",
306  clocks * interval);
307  counter->parent->schedule(this, curTick() + clocks * interval);
308 }
309 
310 int
312 {
313  if (!scheduled())
314  return -1;
315  return (when() - curTick() + interval - 1) / interval;
316 }
317 
318 const char *
320 {
321  return "Intel 8254 Interval timer";
322 }
323 
324 Tick
326 {
327  return interval;
328 }
329 
count
Definition: misc.hh:704
#define DPRINTF(x,...)
Definition: trace.hh:212
void setBCD(int bcd_val)
Set count encoding.
void writeControl(const CtrlReg data)
Write control word.
const std::string & name()
Definition: trace.cc:49
#define panic(...)
Definition: misc.hh:153
Programmable Interval Timer (Intel 8254)
Counter element for PIT.
Intel8254Timer * parent
Pointer to container.
Bitfield< 2 > em
Definition: misc.hh:603
Intel8254Timer(EventManager *em, const std::string &name, Counter *counter0, Counter *counter1, Counter *counter2)
void serialize(const std::string &base, CheckpointOut &cp) const
Serialize this object to the given output stream.
#define warn_once(...)
Definition: misc.hh:226
Bitfield< 23, 0 > offset
Definition: types.hh:149
double s
These variables equal the number of ticks in the unit of time they're named after in a double...
Definition: core.cc:50
void latchCount()
Latch the current count (if one is not already latched)
Bitfield< 4, 0 > mode
Definition: miscregs.hh:1385
void setRW(int rw_val)
Set the read/write mode.
void startup()
Start ticking.
const char data[]
Definition: circlebuf.cc:43
void startup()
Start ticking.
Tick curTick()
The current simulated tick.
Definition: core.hh:47
virtual void counterInterrupt(unsigned int num)
uint8_t mode
Current mode of operation.
bool output_high
Output goes high when the counter reaches zero.
uint64_t Tick
Tick count type.
Definition: types.hh:63
void paramOut(CheckpointOut &cp, const string &name, ExtMachInst const &machInst)
Definition: types.cc:40
Bitfield< 51, 12 > base
Definition: pagetable.hh:85
Bitfield< 3, 1 > mode
virtual const char * description() const
Event description.
int64_t Counter
Statistics counter type.
Definition: types.hh:58
Bitfield< 10, 5 > event
void setMode(int mode_val)
Set operational mode.
Counter(Intel8254Timer *p, const std::string &name, unsigned int num)
void unserialize(const std::string &base, CheckpointIn &cp)
Reconstruct the state of this object from a checkpoint.
bool outputHigh()
Is the output high?
std::ostream CheckpointOut
Definition: serialize.hh:67
void serialize(const std::string &base, CheckpointOut &cp) const
Serialize this object to the given output stream.
Counter * counter[3]
PIT has three seperate counters.
int currentCount()
Get the current count for this counter.
void schedule(Event &event, Tick when)
Definition: eventq.hh:728
void paramIn(CheckpointIn &cp, const string &name, ExtMachInst &machInst)
Definition: types.cc:71
Bitfield< 0 > p
uint8_t read()
Read a count byte.
void write(const uint8_t data)
Write a count byte.
uint16_t period
Interrupt period.
void unserialize(const std::string &base, CheckpointIn &cp)
Reconstruct the state of this object from a checkpoint.
Tick offset
When to start ticking.

Generated on Fri Jun 9 2017 13:03:46 for gem5 by doxygen 1.8.6