| /* |
| * Copyright (c) 2004, 2005 |
| * The Regents of The University of Michigan |
| * All Rights Reserved |
| * |
| * This code is part of the M5 simulator. |
| * |
| * Permission is granted to use, copy, create derivative works and |
| * redistribute this software and such derivative works for any |
| * purpose, so long as the copyright notice above, this grant of |
| * permission, and the disclaimer below appear in all copies made; and |
| * so long as the name of The University of Michigan is not used in |
| * any advertising or publicity pertaining to the use or distribution |
| * of this software without specific, written prior authorization. |
| * |
| * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE |
| * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND |
| * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER |
| * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE |
| * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, |
| * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM |
| * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN |
| * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH |
| * DAMAGES. |
| * |
| * Authors: Ali G. Saidi |
| * Andrew L. Schultz |
| * Miguel J. Serrano |
| */ |
| |
| #ifndef __DEV_8254_HH__ |
| #define __DEV_8254_HH__ |
| |
| #include <iostream> |
| #include <string> |
| |
| #include "base/bitunion.hh" |
| #include "base/types.hh" |
| #include "base/trace.hh" |
| #include "debug/Intel8254Timer.hh" |
| #include "sim/eventq_impl.hh" |
| #include "sim/serialize.hh" |
| |
| /** Programmable Interval Timer (Intel 8254) */ |
| class Intel8254Timer : public EventManager |
| { |
| protected: |
| BitUnion8(CtrlReg) |
| Bitfield<7, 6> sel; |
| Bitfield<5, 4> rw; |
| Bitfield<3, 1> mode; |
| Bitfield<0> bcd; |
| EndBitUnion(CtrlReg) |
| |
| enum SelectVal { |
| SelectCounter0, |
| SelectCounter1, |
| SelectCounter2, |
| ReadBackCommand |
| }; |
| |
| enum ReadWriteVal { |
| LatchCommand, |
| LsbOnly, |
| MsbOnly, |
| TwoPhase |
| }; |
| |
| enum ModeVal { |
| InitTc, |
| OneShot, |
| RateGen, |
| SquareWave, |
| SoftwareStrobe, |
| HardwareStrobe |
| }; |
| |
| /** Counter element for PIT */ |
| class Counter |
| { |
| /** Event for counter interrupt */ |
| class CounterEvent : public Event |
| { |
| private: |
| /** Pointer back to Counter */ |
| Counter* counter; |
| Tick interval; |
| |
| public: |
| CounterEvent(Counter*); |
| |
| /** Event process */ |
| void process(); |
| |
| /** Event description */ |
| virtual const char *description() const; |
| |
| friend class Counter; |
| |
| void setTo(int clocks); |
| |
| int clocksLeft(); |
| |
| Tick getInterval(); |
| }; |
| |
| private: |
| std::string _name; |
| const std::string &name() const { return _name; } |
| |
| unsigned int num; |
| |
| CounterEvent event; |
| |
| /** True after startup is called. */ |
| bool running; |
| |
| /** Initial count value */ |
| uint16_t initial_count; |
| |
| /** Latched count */ |
| uint16_t latched_count; |
| |
| /** Interrupt period */ |
| uint16_t period; |
| |
| /** When to start ticking */ |
| Tick offset; |
| |
| /** Current mode of operation */ |
| uint8_t mode; |
| |
| /** Output goes high when the counter reaches zero */ |
| bool output_high; |
| |
| /** State of the count latch */ |
| bool latch_on; |
| |
| /** Set of values for read_byte and write_byte */ |
| enum {LSB, MSB}; |
| |
| /** Determine which byte of a 16-bit count value to read/write */ |
| uint8_t read_byte, write_byte; |
| |
| /** Pointer to container */ |
| Intel8254Timer *parent; |
| |
| public: |
| Counter(Intel8254Timer *p, const std::string &name, unsigned int num); |
| |
| /** Latch the current count (if one is not already latched) */ |
| void latchCount(); |
| |
| /** Get the current count for this counter */ |
| int currentCount(); |
| |
| /** Set the read/write mode */ |
| void setRW(int rw_val); |
| |
| /** Set operational mode */ |
| void setMode(int mode_val); |
| |
| /** Set count encoding */ |
| void setBCD(int bcd_val); |
| |
| /** Read a count byte */ |
| uint8_t read(); |
| |
| /** Write a count byte */ |
| void write(const uint8_t data); |
| |
| /** Is the output high? */ |
| bool outputHigh(); |
| |
| /** |
| * Serialize this object to the given output stream. |
| * @param base The base name of the counter object. |
| * @param os The stream to serialize to. |
| */ |
| void serialize(const std::string &base, CheckpointOut &cp) const; |
| |
| /** |
| * Reconstruct the state of this object from a checkpoint. |
| * @param base The base name of the counter object. |
| * @param cp The checkpoint use. |
| * @param section The section name of this object |
| */ |
| void unserialize(const std::string &base, CheckpointIn &cp); |
| |
| /** Start ticking */ |
| void startup(); |
| }; |
| |
| protected: |
| std::string _name; |
| const std::string &name() const { return _name; } |
| |
| /** PIT has three seperate counters */ |
| Counter *counter[3]; |
| |
| virtual void |
| counterInterrupt(unsigned int num) |
| { |
| DPRINTF(Intel8254Timer, "Timer interrupt from counter %d.\n", num); |
| } |
| |
| public: |
| |
| virtual |
| ~Intel8254Timer() |
| {} |
| |
| Intel8254Timer(EventManager *em, const std::string &name, |
| Counter *counter0, Counter *counter1, Counter *counter2); |
| |
| Intel8254Timer(EventManager *em, const std::string &name); |
| |
| /** Write control word */ |
| void writeControl(const CtrlReg data); |
| |
| uint8_t |
| readCounter(unsigned int num) |
| { |
| assert(num < 3); |
| return counter[num]->read(); |
| } |
| |
| void |
| writeCounter(unsigned int num, const uint8_t data) |
| { |
| assert(num < 3); |
| counter[num]->write(data); |
| } |
| |
| bool |
| outputHigh(unsigned int num) |
| { |
| assert(num < 3); |
| return counter[num]->outputHigh(); |
| } |
| |
| /** |
| * Serialize this object to the given output stream. |
| * @param base The base name of the counter object. |
| * @param os The stream to serialize to. |
| */ |
| void serialize(const std::string &base, CheckpointOut &cp) const; |
| |
| /** |
| * Reconstruct the state of this object from a checkpoint. |
| * @param base The base name of the counter object. |
| * @param cp The checkpoint use. |
| * @param section The section name of this object |
| */ |
| void unserialize(const std::string &base, CheckpointIn &cp); |
| |
| /** Start ticking */ |
| void startup(); |
| }; |
| |
| #endif // __DEV_8254_HH__ |