/*
 * 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();
        };

      private:
        std::string _name;
        const std::string &name() const { return _name; }

        unsigned int num;

        CounterEvent event;

        /** Initial count value */
        uint16_t initial_count;

        /** Latched count */
        uint16_t latched_count;

        /** Interrupt period */
        uint16_t period;

        /** 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, std::ostream &os);

        /**
         * 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, Checkpoint *cp,
                         const std::string &section);
    };

  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, std::ostream &os);

    /**
     * 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, Checkpoint *cp,
                     const std::string &section);
};

#endif // __DEV_8254_HH__
