tsunami_io.hh revision 1854
15703SN/A/*
25703SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
35703SN/A * All rights reserved.
48825Snilay@cs.wisc.edu *
57935SN/A * Redistribution and use in source and binary forms, with or without
67935SN/A * modification, are permitted provided that the following conditions are
77935SN/A * met: redistributions of source code must retain the above copyright
85703SN/A * notice, this list of conditions and the following disclaimer;
95703SN/A * redistributions in binary form must reproduce the above copyright
105703SN/A * notice, this list of conditions and the following disclaimer in the
115703SN/A * documentation and/or other materials provided with the distribution;
125703SN/A * neither the name of the copyright holders nor the names of its
135703SN/A * contributors may be used to endorse or promote products derived from
149348SAli.Saidi@ARM.com * this software without specific prior written permission.
159348SAli.Saidi@ARM.com *
165703SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
179348SAli.Saidi@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
187670SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195703SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
208464SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
218721SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
229348SAli.Saidi@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235703SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245703SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255703SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265703SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
277935SN/A */
287935SN/A
297935SN/A/** @file
307935SN/A * Tsunami I/O Space mapping including RTC/timer interrupts
317935SN/A */
327935SN/A
337935SN/A#ifndef __DEV_TSUNAMI_IO_HH__
348983Snate@binkert.org#define __DEV_TSUNAMI_IO_HH__
355703SN/A
365703SN/A#include "dev/io_device.hh"
375703SN/A#include "base/range.hh"
389348SAli.Saidi@ARM.com#include "dev/tsunami.hh"
395703SN/A#include "sim/eventq.hh"
408721SN/A
418721SN/A/**
428721SN/A * Tsunami I/O device is a catch all for all the south bridge stuff we care
438983Snate@binkert.org * to implement.
448983Snate@binkert.org */
455703SN/Aclass TsunamiIO : public PioDevice
465703SN/A{
475703SN/A  private:
489348SAli.Saidi@ARM.com    /** The base address of this device */
495703SN/A    Addr addr;
505703SN/A
515703SN/A    /** The size of mappad from the above address */
525703SN/A    static const Addr size = 0xff;
538241SN/A
548241SN/A    struct tm tm;
555703SN/A
565703SN/A  protected:
575703SN/A    /** Real-Time Clock (MC146818) */
585703SN/A    class RTC
595703SN/A    {
605703SN/A      private:
615876SN/A        /** Event for RTC periodic interrupt */
625703SN/A        struct RTCEvent : public Event
635703SN/A        {
645703SN/A            /** A pointer back to tsunami to create interrupt the processor. */
655703SN/A            Tsunami* tsunami;
665703SN/A            Tick interval;
675703SN/A
685703SN/A            RTCEvent(Tsunami* t, Tick i);
695703SN/A
705703SN/A            /** Schedule the RTC periodic interrupt */
715703SN/A            void scheduleIntr();
725703SN/A
735703SN/A            /** Event process to occur at interrupt*/
745703SN/A            virtual void process();
755703SN/A
765703SN/A            /** Event description */
775703SN/A            virtual const char *description();
785703SN/A        };
795703SN/A
805703SN/A      private:
815703SN/A        std::string _name;
825703SN/A        const std::string &name() const { return _name; }
835703SN/A
845703SN/A        /** RTC periodic interrupt event */
855703SN/A        RTCEvent event;
865703SN/A
875703SN/A        /** Current RTC register address/index */
885703SN/A        int addr;
895703SN/A
905703SN/A        /** Data for real-time clock function */
915703SN/A        union {
925703SN/A            uint8_t clock_data[10];
935703SN/A
945703SN/A            struct {
955703SN/A                uint8_t sec;
969348SAli.Saidi@ARM.com                uint8_t sec_alrm;
975703SN/A                uint8_t min;
985703SN/A                uint8_t min_alrm;
995703SN/A                uint8_t hour;
1005703SN/A                uint8_t hour_alrm;
1015703SN/A                uint8_t wday;
1025703SN/A                uint8_t mday;
1035703SN/A                uint8_t mon;
1045703SN/A                uint8_t year;
1055703SN/A            };
1065703SN/A        };
1075703SN/A
1088825Snilay@cs.wisc.edu        /** RTC status register A */
1095703SN/A        uint8_t stat_regA;
1105703SN/A
1115703SN/A        /** RTC status register B */
1125703SN/A        uint8_t stat_regB;
1135703SN/A
1145703SN/A      public:
1155703SN/A        RTC(const std::string &name, Tsunami* t, Tick i);
1165703SN/A
1175703SN/A        /** Set the initial RTC time/date */
1185703SN/A        void set_time(time_t t);
1195703SN/A
1205703SN/A        /** RTC address port: write address of RTC RAM data to access */
1215703SN/A        void writeAddr(const uint8_t *data);
1225703SN/A
1235703SN/A        /** RTC write data */
1245703SN/A        void writeData(const uint8_t *data);
1255703SN/A
1265703SN/A        /** RTC read data */
1275703SN/A        void readData(uint8_t *data);
1285703SN/A
1295703SN/A        /**
1305703SN/A          * Serialize this object to the given output stream.
1315703SN/A          * @param os The stream to serialize to.
1325703SN/A          */
1338521SN/A        void serialize(const std::string &base, std::ostream &os);
1345703SN/A
1355703SN/A        /**
1365703SN/A         * Reconstruct the state of this object from a checkpoint.
1375703SN/A         * @param cp The checkpoint use.
1385703SN/A         * @param section The section name of this object
1398825Snilay@cs.wisc.edu         */
1405703SN/A        void unserialize(const std::string &base, Checkpoint *cp,
1415703SN/A                         const std::string &section);
1425703SN/A    };
1435703SN/A
1445703SN/A    /** Programmable Interval Timer (Intel 8254) */
1458983Snate@binkert.org    class PITimer
1465703SN/A    {
1475703SN/A        /** Counter element for PIT */
1489348SAli.Saidi@ARM.com        class Counter
1496123SN/A        {
1505703SN/A            /** Event for counter interrupt */
1519348SAli.Saidi@ARM.com            class CounterEvent : public Event
1528135SN/A            {
1535703SN/A              private:
1545703SN/A                /** Pointer back to Counter */
1555876SN/A                Counter* counter;
1568835SAli.Saidi@ARM.com                Tick interval;
1575703SN/A
1585703SN/A              public:
1599348SAli.Saidi@ARM.com                CounterEvent(Counter*);
1605703SN/A
1615703SN/A                /** Event process */
1628835SAli.Saidi@ARM.com                virtual void process();
1635703SN/A
1645703SN/A                /** Event description */
1655703SN/A                virtual const char *description();
1665703SN/A
1675703SN/A                friend class Counter;
1688983Snate@binkert.org            };
1695703SN/A
1705703SN/A          private:
1716024SN/A            std::string _name;
1725703SN/A            const std::string &name() const { return _name; }
1735703SN/A
1745703SN/A            CounterEvent event;
1755703SN/A
1767761SN/A            /** Current count value */
1777761SN/A            uint16_t count;
1785703SN/A
1795703SN/A            /** Latched count */
1805703SN/A            uint16_t latched_count;
1815703SN/A
1825703SN/A            /** Interrupt period */
1835703SN/A            uint16_t period;
1845703SN/A
1855703SN/A            /** Current mode of operation */
1865703SN/A            uint8_t mode;
1875703SN/A
1885703SN/A            /** Output goes high when the counter reaches zero */
1895703SN/A            bool output_high;
1905703SN/A
1915703SN/A            /** State of the count latch */
1925703SN/A            bool latch_on;
1935703SN/A
1945703SN/A            /** Set of values for read_byte and write_byte */
1955703SN/A            enum {LSB, MSB};
1965703SN/A
1975703SN/A            /** Determine which byte of a 16-bit count value to read/write */
1985703SN/A            uint8_t read_byte, write_byte;
1995703SN/A
2005703SN/A          public:
2015703SN/A            Counter(const std::string &name);
2025703SN/A
2035703SN/A            /** Latch the current count (if one is not already latched) */
2045703SN/A            void latchCount();
2055703SN/A
2065703SN/A            /** Set the read/write mode */
2075703SN/A            void setRW(int rw_val);
2085703SN/A
2095703SN/A            /** Set operational mode */
2105703SN/A            void setMode(int mode_val);
2115703SN/A
2125703SN/A            /** Set count encoding */
2135703SN/A            void setBCD(int bcd_val);
2145703SN/A
2155703SN/A            /** Read a count byte */
2165703SN/A            void read(uint8_t *data);
2175703SN/A
2185703SN/A            /** Write a count byte */
2195703SN/A            void write(const uint8_t *data);
2205703SN/A
2215703SN/A            /** Is the output high? */
2225703SN/A            bool outputHigh();
2235703SN/A
2245703SN/A            /**
2255703SN/A             * Serialize this object to the given output stream.
2265703SN/A             * @param os The stream to serialize to.
2275703SN/A             */
2285703SN/A            void serialize(const std::string &base, std::ostream &os);
2295703SN/A
2305703SN/A            /**
2315703SN/A             * Reconstruct the state of this object from a checkpoint.
2325703SN/A             * @param cp The checkpoint use.
2335703SN/A             * @param section The section name of this object
2345703SN/A             */
2355703SN/A            void unserialize(const std::string &base, Checkpoint *cp,
2365703SN/A                             const std::string &section);
2375703SN/A        };
2385703SN/A
2395703SN/A      private:
2405703SN/A        std::string _name;
2415703SN/A        const std::string &name() const { return _name; }
2425703SN/A
2435703SN/A        /** PIT has three seperate counters */
2445703SN/A        Counter *counter[3];
2455703SN/A
2465703SN/A      public:
2475703SN/A        /** Public way to access individual counters (avoid array accesses) */
2485703SN/A        Counter counter0;
2495703SN/A        Counter counter1;
2505703SN/A        Counter counter2;
2515703SN/A
2525703SN/A        PITimer(const std::string &name);
2535703SN/A
2545703SN/A        /** Write control word */
2555703SN/A        void writeControl(const uint8_t* data);
2565703SN/A
2575703SN/A        /**
2585703SN/A         * Serialize this object to the given output stream.
2595703SN/A         * @param os The stream to serialize to.
2605703SN/A         */
2615703SN/A        void serialize(const std::string &base, std::ostream &os);
2625703SN/A
2635703SN/A        /**
2645703SN/A         * Reconstruct the state of this object from a checkpoint.
2655703SN/A         * @param cp The checkpoint use.
2665703SN/A         * @param section The section name of this object
2675703SN/A         */
2685703SN/A        void unserialize(const std::string &base, Checkpoint *cp,
2695703SN/A                         const std::string &section);
2705703SN/A    };
2717761SN/A
2727761SN/A    /** Mask of the PIC1 */
2737761SN/A    uint8_t mask1;
2745703SN/A
2757761SN/A    /** Mask of the PIC2 */
2765703SN/A    uint8_t mask2;
2775703SN/A
2787761SN/A    /** Mode of PIC1. Not used for anything */
2797761SN/A    uint8_t mode1;
2807761SN/A
2817761SN/A    /** Mode of PIC2. Not used for anything */
2827761SN/A    uint8_t mode2;
2837761SN/A
2847761SN/A    /** Raw PIC interrupt register before masking */
2857761SN/A    uint8_t picr; //Raw PIC interrput register
2867761SN/A
2877761SN/A    /** Is the pic interrupting right now or not. */
2887761SN/A    bool picInterrupting;
2897761SN/A
2907761SN/A    Tick clockInterval;
2917761SN/A
2927761SN/A    /** A pointer to the Tsunami device which be belong to */
2937761SN/A    Tsunami *tsunami;
2947761SN/A
2957761SN/A    /** Intel 8253 Periodic Interval Timer */
2967761SN/A    PITimer pitimer;
2977761SN/A
2987761SN/A    RTC rtc;
2997761SN/A
3007761SN/A    /** The interval is set via two writes to the PIT.
3017761SN/A     * This variable contains a flag as to how many writes have happened, and
3027761SN/A     * the time so far.
3037761SN/A     */
3047761SN/A    uint16_t timerData;
3057761SN/A
3067761SN/A  public:
3077761SN/A    /**
3087761SN/A     * Return the freqency of the RTC
3097761SN/A     * @return interrupt rate of the RTC
3107761SN/A     */
3117761SN/A    Tick frequency() const;
3127761SN/A
3137761SN/A    /**
3147761SN/A     * Initialize all the data for devices supported by Tsunami I/O.
3157761SN/A     * @param name name of this device.
3167761SN/A     * @param t pointer back to the Tsunami object that we belong to.
3177761SN/A     * @param init_time Time (as in seconds since 1970) to set RTC to.
3187761SN/A     * @param a address we are mapped at.
3197761SN/A     * @param mmu pointer to the memory controller that sends us events.
3207761SN/A     */
3217761SN/A    TsunamiIO(const std::string &name, Tsunami *t, time_t init_time,
3227761SN/A              Addr a, MemoryController *mmu, HierParams *hier, Bus *bus,
3237761SN/A              Tick pio_latency, Tick ci);
3247761SN/A
3257761SN/A    /**
3267761SN/A      * Process a read to one of the devices we are emulating.
3277761SN/A      * @param req Contains the address to read from.
3287761SN/A      * @param data A pointer to write the read data to.
3297761SN/A      * @return The fault condition of the access.
3307761SN/A      */
3317761SN/A    virtual Fault read(MemReqPtr &req, uint8_t *data);
3327761SN/A
3337761SN/A    /**
3347761SN/A      * Process a write to one of the devices we emulate.
3357761SN/A      * @param req Contains the address to write to.
3367761SN/A      * @param data The data to write.
3377761SN/A      * @return The fault condition of the access.
3387761SN/A      */
3397761SN/A    virtual Fault write(MemReqPtr &req, const uint8_t *data);
3407761SN/A
3417761SN/A    /**
3427761SN/A     * Post an PIC interrupt to the CPU via the CChip
3437761SN/A     * @param bitvector interrupt to post.
3447761SN/A     */
3457761SN/A    void postPIC(uint8_t bitvector);
3467761SN/A
3477761SN/A    /**
3487761SN/A     * Clear a posted interrupt
3497761SN/A     * @param bitvector interrupt to clear
3507761SN/A     */
3517761SN/A    void clearPIC(uint8_t bitvector);
3527761SN/A
3537761SN/A    /**
3547761SN/A     * Serialize this object to the given output stream.
3557761SN/A     * @param os The stream to serialize to.
3567761SN/A     */
3577761SN/A    virtual void serialize(std::ostream &os);
3587761SN/A
3597761SN/A    /**
3607761SN/A     * Reconstruct the state of this object from a checkpoint.
3617761SN/A     * @param cp The checkpoint use.
3627761SN/A     * @param section The section name of this object
3637761SN/A     */
3647761SN/A    virtual void unserialize(Checkpoint *cp, const std::string &section);
3657761SN/A
3667761SN/A    Tick cacheAccess(MemReqPtr &req);
3677761SN/A};
3687761SN/A
3697761SN/A#endif // __DEV_TSUNAMI_IO_HH__
3707761SN/A