intel_8254_timer.hh revision 7559:017baf09599f
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 <string> 37#include <iostream> 38 39#include "base/bitunion.hh" 40#include "base/types.hh" 41#include "sim/eventq.hh" 42#include "sim/serialize.hh" 43 44/** Programmable Interval Timer (Intel 8254) */ 45class Intel8254Timer : public EventManager 46{ 47 protected: 48 BitUnion8(CtrlReg) 49 Bitfield<7, 6> sel; 50 Bitfield<5, 4> rw; 51 Bitfield<3, 1> mode; 52 Bitfield<0> bcd; 53 EndBitUnion(CtrlReg) 54 55 enum SelectVal { 56 SelectCounter0, 57 SelectCounter1, 58 SelectCounter2, 59 ReadBackCommand 60 }; 61 62 enum ReadWriteVal { 63 LatchCommand, 64 LsbOnly, 65 MsbOnly, 66 TwoPhase 67 }; 68 69 enum ModeVal { 70 InitTc, 71 OneShot, 72 RateGen, 73 SquareWave, 74 SoftwareStrobe, 75 HardwareStrobe 76 }; 77 78 /** Counter element for PIT */ 79 class Counter 80 { 81 /** Event for counter interrupt */ 82 class CounterEvent : public Event 83 { 84 private: 85 /** Pointer back to Counter */ 86 Counter* counter; 87 Tick interval; 88 89 public: 90 CounterEvent(Counter*); 91 92 /** Event process */ 93 void process(); 94 95 /** Event description */ 96 virtual const char *description() const; 97 98 friend class Counter; 99 100 void setTo(int clocks); 101 102 int clocksLeft(); 103 }; 104 105 private: 106 std::string _name; 107 const std::string &name() const { return _name; } 108 109 unsigned int num; 110 111 CounterEvent event; 112 113 /** Initial count value */ 114 uint16_t initial_count; 115 116 /** Latched count */ 117 uint16_t latched_count; 118 119 /** Interrupt period */ 120 uint16_t period; 121 122 /** Current mode of operation */ 123 uint8_t mode; 124 125 /** Output goes high when the counter reaches zero */ 126 bool output_high; 127 128 /** State of the count latch */ 129 bool latch_on; 130 131 /** Set of values for read_byte and write_byte */ 132 enum {LSB, MSB}; 133 134 /** Determine which byte of a 16-bit count value to read/write */ 135 uint8_t read_byte, write_byte; 136 137 /** Pointer to container */ 138 Intel8254Timer *parent; 139 140 /** if non-zero, the scheduled tick of an event used for drain 141 serialization coordination */ 142 Tick event_tick; 143 144 public: 145 Counter(Intel8254Timer *p, const std::string &name, unsigned int num); 146 147 /** Latch the current count (if one is not already latched) */ 148 void latchCount(); 149 150 /** Get the current count for this counter */ 151 int currentCount(); 152 153 /** Set the read/write mode */ 154 void setRW(int rw_val); 155 156 /** Set operational mode */ 157 void setMode(int mode_val); 158 159 /** Set count encoding */ 160 void setBCD(int bcd_val); 161 162 /** Read a count byte */ 163 uint8_t read(); 164 165 /** Write a count byte */ 166 void write(const uint8_t data); 167 168 /** Is the output high? */ 169 bool outputHigh(); 170 171 /** 172 * Drain all associated events. 173 * @param drainEvent 174 */ 175 unsigned int drain(Event *de); 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, std::ostream &os); 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, Checkpoint *cp, 191 const std::string §ion); 192 }; 193 194 protected: 195 std::string _name; 196 const std::string &name() const { return _name; } 197 198 /** PIT has three seperate counters */ 199 Counter *counter[3]; 200 201 virtual void 202 counterInterrupt(unsigned int num) 203 { 204 DPRINTF(Intel8254Timer, "Timer interrupt from counter %d.\n", num); 205 } 206 207 public: 208 209 virtual 210 ~Intel8254Timer() 211 {} 212 213 Intel8254Timer(EventManager *em, const std::string &name, 214 Counter *counter0, Counter *counter1, Counter *counter2); 215 216 Intel8254Timer(EventManager *em, const std::string &name); 217 218 /** Write control word */ 219 void writeControl(const CtrlReg data); 220 221 uint8_t 222 readCounter(unsigned int num) 223 { 224 assert(num < 3); 225 return counter[num]->read(); 226 } 227 228 void 229 writeCounter(unsigned int num, const uint8_t data) 230 { 231 assert(num < 3); 232 counter[num]->write(data); 233 } 234 235 bool 236 outputHigh(unsigned int num) 237 { 238 assert(num < 3); 239 return counter[num]->outputHigh(); 240 } 241 242 unsigned int drain(Event *de); 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, std::ostream &os); 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, Checkpoint *cp, 258 const std::string §ion); 259}; 260 261#endif // __DEV_8254_HH__ 262