interrupts.hh revision 5647
17405SAli.Saidi@ARM.com/*
210844Sandreas.sandberg@arm.com * Copyright (c) 2006 The Regents of The University of Michigan
37405SAli.Saidi@ARM.com * All rights reserved.
47405SAli.Saidi@ARM.com *
57405SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without
67405SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are
77405SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright
87405SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer;
97405SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright
107405SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the
117405SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution;
127405SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its
137405SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from
147405SAli.Saidi@ARM.com * this software without specific prior written permission.
157405SAli.Saidi@ARM.com *
167405SAli.Saidi@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
177405SAli.Saidi@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
187405SAli.Saidi@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
197405SAli.Saidi@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
207405SAli.Saidi@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
217405SAli.Saidi@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
227405SAli.Saidi@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
237405SAli.Saidi@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
247405SAli.Saidi@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
257405SAli.Saidi@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
267405SAli.Saidi@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
277405SAli.Saidi@ARM.com *
287405SAli.Saidi@ARM.com * Authors: Ali Saidi
297405SAli.Saidi@ARM.com *          Lisa Hsu
307405SAli.Saidi@ARM.com */
317405SAli.Saidi@ARM.com
327405SAli.Saidi@ARM.com#ifndef __ARCH_SPARC_INTERRUPT_HH__
337405SAli.Saidi@ARM.com#define __ARCH_SPARC_INTERRUPT_HH__
347405SAli.Saidi@ARM.com
357405SAli.Saidi@ARM.com#include "arch/sparc/faults.hh"
367405SAli.Saidi@ARM.com#include "arch/sparc/isa_traits.hh"
377405SAli.Saidi@ARM.com#include "cpu/thread_context.hh"
387405SAli.Saidi@ARM.com#include "params/SparcInterrupts.hh"
397405SAli.Saidi@ARM.com#include "sim/sim_object.hh"
407405SAli.Saidi@ARM.com
417405SAli.Saidi@ARM.comnamespace SparcISA
4210461SAndreas.Sandberg@ARM.com{
439050Schander.sudanthi@arm.com
448887Sgeoffrey.blake@arm.comclass Interrupts : public SimObject
4510461SAndreas.Sandberg@ARM.com{
468232Snate@binkert.org
478232Snate@binkert.org  private:
4810844Sandreas.sandberg@arm.com
499384SAndreas.Sandberg@arm.com    uint64_t interrupts[NumInterruptTypes];
507678Sgblack@eecs.umich.edu    uint64_t intStatus;
518059SAli.Saidi@ARM.com
528284SAli.Saidi@ARM.com  public:
537405SAli.Saidi@ARM.com    typedef SparcInterruptsParams Params;
547405SAli.Saidi@ARM.com
557405SAli.Saidi@ARM.com    const Params *
567405SAli.Saidi@ARM.com    params() const
5710037SARM gem5 Developers    {
5810037SARM gem5 Developers        return dynamic_cast<const Params *>(_params);
5910037SARM gem5 Developers    }
6010037SARM gem5 Developers
6110037SARM gem5 Developers    Interrupts(Params * p) : SimObject(p)
6210037SARM gem5 Developers    {
6310037SARM gem5 Developers        clear_all();
6410037SARM gem5 Developers    }
6510037SARM gem5 Developers
6610037SARM gem5 Developers    int InterruptLevel(uint64_t softint)
6710037SARM gem5 Developers    {
6810037SARM gem5 Developers        if (softint & 0x10000 || softint & 0x1)
6910037SARM gem5 Developers            return 14;
7010037SARM gem5 Developers
7110037SARM gem5 Developers        int level = 15;
7210037SARM gem5 Developers        while (level > 0 && !(1 << level & softint))
7310037SARM gem5 Developers            level--;
7410037SARM gem5 Developers        if (1 << level & softint)
7510037SARM gem5 Developers            return level;
7610037SARM gem5 Developers        return 0;
7710037SARM gem5 Developers    }
7810037SARM gem5 Developers
7910037SARM gem5 Developers    void post(int int_num, int index)
8010037SARM gem5 Developers    {
8110037SARM gem5 Developers        DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
8210037SARM gem5 Developers        assert(int_num >= 0 && int_num < NumInterruptTypes);
8310037SARM gem5 Developers        assert(index >= 0 && index < 64);
8410037SARM gem5 Developers
8510037SARM gem5 Developers        interrupts[int_num] |= ULL(1) << index;
8610037SARM gem5 Developers        intStatus |= ULL(1) << int_num;
8710037SARM gem5 Developers    }
8810037SARM gem5 Developers
8910037SARM gem5 Developers    void clear(int int_num, int index)
9010037SARM gem5 Developers    {
9110037SARM gem5 Developers        DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
9210037SARM gem5 Developers        assert(int_num >= 0 && int_num < NumInterruptTypes);
9310037SARM gem5 Developers        assert(index >= 0 && index < 64);
9410037SARM gem5 Developers
9510037SARM gem5 Developers        interrupts[int_num] &= ~(ULL(1) << index);
9610037SARM gem5 Developers        if (!interrupts[int_num])
9710037SARM gem5 Developers            intStatus &= ~(ULL(1) << int_num);
9810037SARM gem5 Developers    }
9910037SARM gem5 Developers
10010037SARM gem5 Developers    void clear_all()
10110037SARM gem5 Developers    {
10210037SARM gem5 Developers        for (int i = 0; i < NumInterruptTypes; ++i) {
10310037SARM gem5 Developers            interrupts[i] = 0;
10410037SARM gem5 Developers        }
10510037SARM gem5 Developers        intStatus = 0;
10610037SARM gem5 Developers    }
10710037SARM gem5 Developers
10810037SARM gem5 Developers    bool check_interrupts(ThreadContext * tc) const
10910037SARM gem5 Developers    {
11010037SARM gem5 Developers        return intStatus;
11110037SARM gem5 Developers    }
11210037SARM gem5 Developers
11310037SARM gem5 Developers    Fault getInterrupt(ThreadContext * tc)
11410037SARM gem5 Developers    {
11510037SARM gem5 Developers        int hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
11610037SARM gem5 Developers        int pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
11710037SARM gem5 Developers        bool ie = pstate & PSTATE::ie;
11810037SARM gem5 Developers
11910037SARM gem5 Developers        // THESE ARE IN ORDER OF PRIORITY
12010037SARM gem5 Developers        // since there are early returns, and the highest
12110037SARM gem5 Developers        // priority interrupts should get serviced,
12210037SARM gem5 Developers        // it is v. important that new interrupts are inserted
12310037SARM gem5 Developers        // in the right order of processing
12410037SARM gem5 Developers        if (hpstate & HPSTATE::hpriv) {
12510037SARM gem5 Developers            if (ie) {
12610037SARM gem5 Developers                if (interrupts[IT_HINTP]) {
1279384SAndreas.Sandberg@arm.com                    // This will be cleaned by a HINTP write
12810461SAndreas.Sandberg@ARM.com                    return new HstickMatch;
12910461SAndreas.Sandberg@ARM.com                }
13011165SRekai.GonzalezAlberquilla@arm.com                if (interrupts[IT_INT_VEC]) {
13110461SAndreas.Sandberg@ARM.com                    // this will be cleared by an ASI read (or write)
13210461SAndreas.Sandberg@ARM.com                    return new InterruptVector;
1339384SAndreas.Sandberg@arm.com                }
1349384SAndreas.Sandberg@arm.com            }
1359384SAndreas.Sandberg@arm.com        } else {
1369384SAndreas.Sandberg@arm.com            if (interrupts[IT_TRAP_LEVEL_ZERO]) {
13710037SARM gem5 Developers                    // this is cleared by deasserting HPSTATE::tlz
13810461SAndreas.Sandberg@ARM.com                    return new TrapLevelZero;
13910461SAndreas.Sandberg@ARM.com            }
14010461SAndreas.Sandberg@ARM.com            // HStick matches always happen in priv mode (ie doesn't matter)
14110461SAndreas.Sandberg@ARM.com            if (interrupts[IT_HINTP]) {
14210461SAndreas.Sandberg@ARM.com                return new HstickMatch;
14310461SAndreas.Sandberg@ARM.com            }
14410609Sandreas.sandberg@arm.com            if (interrupts[IT_INT_VEC]) {
14510609Sandreas.sandberg@arm.com                // this will be cleared by an ASI read (or write)
14610609Sandreas.sandberg@arm.com                return new InterruptVector;
14710037SARM gem5 Developers            }
14810037SARM gem5 Developers            if (ie) {
14910037SARM gem5 Developers                if (interrupts[IT_CPU_MONDO]) {
15010037SARM gem5 Developers                    return new CpuMondo;
15110037SARM gem5 Developers                }
15210037SARM gem5 Developers                if (interrupts[IT_DEV_MONDO]) {
15310037SARM gem5 Developers                    return new DevMondo;
15410037SARM gem5 Developers                }
15510037SARM gem5 Developers                if (interrupts[IT_SOFT_INT]) {
15610037SARM gem5 Developers                    return new
15710037SARM gem5 Developers                        InterruptLevelN(InterruptLevel(interrupts[IT_SOFT_INT]));
15810037SARM gem5 Developers                }
15910037SARM gem5 Developers
16010037SARM gem5 Developers                if (interrupts[IT_RES_ERROR]) {
16110037SARM gem5 Developers                    return new ResumableError;
16210037SARM gem5 Developers                }
16310037SARM gem5 Developers            } // !hpriv && ie
16410037SARM gem5 Developers        }  // !hpriv
16510037SARM gem5 Developers        return NoFault;
16610037SARM gem5 Developers    }
16710037SARM gem5 Developers
16810037SARM gem5 Developers    void updateIntrInfo(ThreadContext * tc)
16910037SARM gem5 Developers    {
17010037SARM gem5 Developers
17110037SARM gem5 Developers    }
17210037SARM gem5 Developers
17310037SARM gem5 Developers    uint64_t get_vec(int int_num)
1749384SAndreas.Sandberg@arm.com    {
1759384SAndreas.Sandberg@arm.com        assert(int_num >= 0 && int_num < NumInterruptTypes);
1769384SAndreas.Sandberg@arm.com        return interrupts[int_num];
1779384SAndreas.Sandberg@arm.com    }
1789384SAndreas.Sandberg@arm.com
1799384SAndreas.Sandberg@arm.com    void serialize(std::ostream &os)
1809384SAndreas.Sandberg@arm.com    {
1819384SAndreas.Sandberg@arm.com        SERIALIZE_ARRAY(interrupts,NumInterruptTypes);
1829384SAndreas.Sandberg@arm.com        SERIALIZE_SCALAR(intStatus);
1837427Sgblack@eecs.umich.edu    }
1847427Sgblack@eecs.umich.edu
1857427Sgblack@eecs.umich.edu    void unserialize(Checkpoint *cp, const std::string &section)
1869385SAndreas.Sandberg@arm.com    {
1879385SAndreas.Sandberg@arm.com        UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes);
1887427Sgblack@eecs.umich.edu        UNSERIALIZE_SCALAR(intStatus);
1897427Sgblack@eecs.umich.edu    }
19010037SARM gem5 Developers};
19110037SARM gem5 Developers} // namespace SPARC_ISA
19210037SARM gem5 Developers
19310037SARM gem5 Developers#endif // __ARCH_SPARC_INTERRUPT_HH__
19410037SARM gem5 Developers