/*
 * 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.
 */

#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__
