intel_8254_timer.hh revision 6214:1ec0ec8933ae
15651Sgblack@eecs.umich.edu/*
25651Sgblack@eecs.umich.edu * Copyright (c) 2004, 2005
35651Sgblack@eecs.umich.edu * The Regents of The University of Michigan
45651Sgblack@eecs.umich.edu * All Rights Reserved
55651Sgblack@eecs.umich.edu *
65651Sgblack@eecs.umich.edu * This code is part of the M5 simulator.
75651Sgblack@eecs.umich.edu *
85651Sgblack@eecs.umich.edu * Permission is granted to use, copy, create derivative works and
95651Sgblack@eecs.umich.edu * redistribute this software and such derivative works for any
105651Sgblack@eecs.umich.edu * purpose, so long as the copyright notice above, this grant of
115651Sgblack@eecs.umich.edu * permission, and the disclaimer below appear in all copies made; and
125651Sgblack@eecs.umich.edu * so long as the name of The University of Michigan is not used in
135651Sgblack@eecs.umich.edu * any advertising or publicity pertaining to the use or distribution
145651Sgblack@eecs.umich.edu * of this software without specific, written prior authorization.
155651Sgblack@eecs.umich.edu *
165651Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE
175651Sgblack@eecs.umich.edu * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND
185651Sgblack@eecs.umich.edu * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER
195651Sgblack@eecs.umich.edu * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
205651Sgblack@eecs.umich.edu * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
215651Sgblack@eecs.umich.edu * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE
225651Sgblack@eecs.umich.edu * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT,
235651Sgblack@eecs.umich.edu * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM
245651Sgblack@eecs.umich.edu * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
255651Sgblack@eecs.umich.edu * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH
265651Sgblack@eecs.umich.edu * DAMAGES.
275651Sgblack@eecs.umich.edu *
285651Sgblack@eecs.umich.edu * Authors: Ali G. Saidi
295651Sgblack@eecs.umich.edu *          Andrew L. Schultz
305651Sgblack@eecs.umich.edu *          Miguel J. Serrano
315651Sgblack@eecs.umich.edu */
325651Sgblack@eecs.umich.edu
335651Sgblack@eecs.umich.edu#ifndef __DEV_8254_HH__
345651Sgblack@eecs.umich.edu#define __DEV_8254_HH__
355651Sgblack@eecs.umich.edu
366216Snate@binkert.org#include <string>
375651Sgblack@eecs.umich.edu#include <iostream>
386046Sgblack@eecs.umich.edu
395651Sgblack@eecs.umich.edu#include "base/bitunion.hh"
405651Sgblack@eecs.umich.edu#include "sim/eventq.hh"
415651Sgblack@eecs.umich.edu#include "base/types.hh"
425651Sgblack@eecs.umich.edu#include "sim/serialize.hh"
435651Sgblack@eecs.umich.edu
445651Sgblack@eecs.umich.edu/** Programmable Interval Timer (Intel 8254) */
455651Sgblack@eecs.umich.educlass Intel8254Timer : public EventManager
465651Sgblack@eecs.umich.edu{
475651Sgblack@eecs.umich.edu  protected:
485654Sgblack@eecs.umich.edu    BitUnion8(CtrlReg)
495654Sgblack@eecs.umich.edu        Bitfield<7, 6> sel;
505651Sgblack@eecs.umich.edu        Bitfield<5, 4> rw;
515651Sgblack@eecs.umich.edu        Bitfield<3, 1> mode;
525654Sgblack@eecs.umich.edu        Bitfield<0> bcd;
535654Sgblack@eecs.umich.edu    EndBitUnion(CtrlReg)
545654Sgblack@eecs.umich.edu
555654Sgblack@eecs.umich.edu    enum SelectVal {
565654Sgblack@eecs.umich.edu        SelectCounter0,
575654Sgblack@eecs.umich.edu        SelectCounter1,
585654Sgblack@eecs.umich.edu        SelectCounter2,
595654Sgblack@eecs.umich.edu        ReadBackCommand
606050Sgblack@eecs.umich.edu    };
615654Sgblack@eecs.umich.edu
625654Sgblack@eecs.umich.edu    enum ReadWriteVal {
635654Sgblack@eecs.umich.edu        LatchCommand,
645654Sgblack@eecs.umich.edu        LsbOnly,
655654Sgblack@eecs.umich.edu        MsbOnly,
665654Sgblack@eecs.umich.edu        TwoPhase
676050Sgblack@eecs.umich.edu    };
685654Sgblack@eecs.umich.edu
695654Sgblack@eecs.umich.edu    enum ModeVal {
705654Sgblack@eecs.umich.edu        InitTc,
715654Sgblack@eecs.umich.edu        OneShot,
725654Sgblack@eecs.umich.edu        RateGen,
736050Sgblack@eecs.umich.edu        SquareWave,
745654Sgblack@eecs.umich.edu        SoftwareStrobe,
755654Sgblack@eecs.umich.edu        HardwareStrobe
765654Sgblack@eecs.umich.edu    };
775651Sgblack@eecs.umich.edu
785651Sgblack@eecs.umich.edu    /** Counter element for PIT */
795651Sgblack@eecs.umich.edu    class Counter
805651Sgblack@eecs.umich.edu    {
815651Sgblack@eecs.umich.edu        /** Event for counter interrupt */
8212749Sgiacomo.travaglini@arm.com        class CounterEvent : public Event
8312749Sgiacomo.travaglini@arm.com        {
8412749Sgiacomo.travaglini@arm.com          private:
8512749Sgiacomo.travaglini@arm.com            /** Pointer back to Counter */
8612749Sgiacomo.travaglini@arm.com            Counter* counter;
878949Sandreas.hansson@arm.com            Tick interval;
885651Sgblack@eecs.umich.edu
895651Sgblack@eecs.umich.edu          public:
905651Sgblack@eecs.umich.edu            CounterEvent(Counter*);
915651Sgblack@eecs.umich.edu
925651Sgblack@eecs.umich.edu            /** Event process */
935651Sgblack@eecs.umich.edu            void process();
945651Sgblack@eecs.umich.edu
955651Sgblack@eecs.umich.edu            /** Event description */
965651Sgblack@eecs.umich.edu            virtual const char *description() const;
975651Sgblack@eecs.umich.edu
985651Sgblack@eecs.umich.edu            friend class Counter;
995651Sgblack@eecs.umich.edu
1005651Sgblack@eecs.umich.edu            void setTo(int clocks);
1015651Sgblack@eecs.umich.edu
1025651Sgblack@eecs.umich.edu            int clocksLeft();
1035651Sgblack@eecs.umich.edu        };
1045651Sgblack@eecs.umich.edu
1055651Sgblack@eecs.umich.edu      private:
1065651Sgblack@eecs.umich.edu        std::string _name;
1075651Sgblack@eecs.umich.edu        const std::string &name() const { return _name; }
1085651Sgblack@eecs.umich.edu
1095651Sgblack@eecs.umich.edu        unsigned int num;
1105651Sgblack@eecs.umich.edu
1115651Sgblack@eecs.umich.edu        CounterEvent event;
1125651Sgblack@eecs.umich.edu
1135651Sgblack@eecs.umich.edu        /** Initial count value */
1145651Sgblack@eecs.umich.edu        uint16_t initial_count;
1155651Sgblack@eecs.umich.edu
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      public:
141        Counter(Intel8254Timer *p, const std::string &name, unsigned int num);
142
143        /** Latch the current count (if one is not already latched) */
144        void latchCount();
145
146        /** Get the current count for this counter */
147        int currentCount();
148
149        /** Set the read/write mode */
150        void setRW(int rw_val);
151
152        /** Set operational mode */
153        void setMode(int mode_val);
154
155        /** Set count encoding */
156        void setBCD(int bcd_val);
157
158        /** Read a count byte */
159        uint8_t read();
160
161        /** Write a count byte */
162        void write(const uint8_t data);
163
164        /** Is the output high? */
165        bool outputHigh();
166
167        /**
168         * Serialize this object to the given output stream.
169         * @param base The base name of the counter object.
170         * @param os   The stream to serialize to.
171         */
172        void serialize(const std::string &base, std::ostream &os);
173
174        /**
175         * Reconstruct the state of this object from a checkpoint.
176         * @param base The base name of the counter object.
177         * @param cp The checkpoint use.
178         * @param section The section name of this object
179         */
180        void unserialize(const std::string &base, Checkpoint *cp,
181                         const std::string &section);
182    };
183
184  protected:
185    std::string _name;
186    const std::string &name() const { return _name; }
187
188    /** PIT has three seperate counters */
189    Counter *counter[3];
190
191    virtual void
192    counterInterrupt(unsigned int num)
193    {
194        DPRINTF(Intel8254Timer, "Timer interrupt from counter %d.\n", num);
195    }
196
197  public:
198
199    virtual
200    ~Intel8254Timer()
201    {}
202
203    Intel8254Timer(EventManager *em, const std::string &name,
204            Counter *counter0, Counter *counter1, Counter *counter2);
205
206    Intel8254Timer(EventManager *em, const std::string &name);
207
208    /** Write control word */
209    void writeControl(const CtrlReg data);
210
211    uint8_t
212    readCounter(unsigned int num)
213    {
214        assert(num < 3);
215        return counter[num]->read();
216    }
217
218    void
219    writeCounter(unsigned int num, const uint8_t data)
220    {
221        assert(num < 3);
222        counter[num]->write(data);
223    }
224
225    bool
226    outputHigh(unsigned int num)
227    {
228        assert(num < 3);
229        return counter[num]->outputHigh();
230    }
231
232    /**
233     * Serialize this object to the given output stream.
234     * @param base The base name of the counter object.
235     * @param os The stream to serialize to.
236     */
237    void serialize(const std::string &base, std::ostream &os);
238
239    /**
240     * Reconstruct the state of this object from a checkpoint.
241     * @param base The base name of the counter object.
242     * @param cp The checkpoint use.
243     * @param section The section name of this object
244     */
245    void unserialize(const std::string &base, Checkpoint *cp,
246                     const std::string &section);
247};
248
249#endif // __DEV_8254_HH__
250