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