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