interrupts.hh revision 8232
13537Sgblack@eecs.umich.edu/*
23537Sgblack@eecs.umich.edu * Copyright (c) 2006 The Regents of The University of Michigan
33537Sgblack@eecs.umich.edu * All rights reserved.
43537Sgblack@eecs.umich.edu *
53537Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
63537Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
73537Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
83537Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
93537Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
103537Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
113537Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
123537Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
133537Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
143537Sgblack@eecs.umich.edu * this software without specific prior written permission.
153537Sgblack@eecs.umich.edu *
163537Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173537Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183537Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193537Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203537Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213537Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223537Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233537Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243537Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253537Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263537Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
274103Ssaidi@eecs.umich.edu *
284103Ssaidi@eecs.umich.edu * Authors: Ali Saidi
294103Ssaidi@eecs.umich.edu *          Lisa Hsu
303537Sgblack@eecs.umich.edu */
313537Sgblack@eecs.umich.edu
323537Sgblack@eecs.umich.edu#ifndef __ARCH_SPARC_INTERRUPT_HH__
333537Sgblack@eecs.umich.edu#define __ARCH_SPARC_INTERRUPT_HH__
343537Sgblack@eecs.umich.edu
353537Sgblack@eecs.umich.edu#include "arch/sparc/faults.hh"
364103Ssaidi@eecs.umich.edu#include "arch/sparc/isa_traits.hh"
376335Sgblack@eecs.umich.edu#include "arch/sparc/registers.hh"
383827Shsul@eecs.umich.edu#include "cpu/thread_context.hh"
398232Snate@binkert.org#include "debug/Interrupt.hh"
405647Sgblack@eecs.umich.edu#include "params/SparcInterrupts.hh"
415647Sgblack@eecs.umich.edu#include "sim/sim_object.hh"
423827Shsul@eecs.umich.edu
433537Sgblack@eecs.umich.edunamespace SparcISA
443537Sgblack@eecs.umich.edu{
453894Shsul@eecs.umich.edu
465647Sgblack@eecs.umich.educlass Interrupts : public SimObject
474009Ssaidi@eecs.umich.edu{
485810Sgblack@eecs.umich.edu  private:
495810Sgblack@eecs.umich.edu    BaseCPU * cpu;
504009Ssaidi@eecs.umich.edu
514103Ssaidi@eecs.umich.edu    uint64_t interrupts[NumInterruptTypes];
524103Ssaidi@eecs.umich.edu    uint64_t intStatus;
534009Ssaidi@eecs.umich.edu
544009Ssaidi@eecs.umich.edu  public:
555810Sgblack@eecs.umich.edu
565810Sgblack@eecs.umich.edu    void
575810Sgblack@eecs.umich.edu    setCPU(BaseCPU * _cpu)
585810Sgblack@eecs.umich.edu    {
595810Sgblack@eecs.umich.edu        cpu = _cpu;
605810Sgblack@eecs.umich.edu    }
615810Sgblack@eecs.umich.edu
625647Sgblack@eecs.umich.edu    typedef SparcInterruptsParams Params;
635647Sgblack@eecs.umich.edu
645647Sgblack@eecs.umich.edu    const Params *
655647Sgblack@eecs.umich.edu    params() const
665647Sgblack@eecs.umich.edu    {
675647Sgblack@eecs.umich.edu        return dynamic_cast<const Params *>(_params);
685647Sgblack@eecs.umich.edu    }
695647Sgblack@eecs.umich.edu
705810Sgblack@eecs.umich.edu    Interrupts(Params * p) : SimObject(p), cpu(NULL)
714009Ssaidi@eecs.umich.edu    {
725704Snate@binkert.org        clearAll();
734009Ssaidi@eecs.umich.edu    }
744009Ssaidi@eecs.umich.edu
755704Snate@binkert.org    int
765704Snate@binkert.org    InterruptLevel(uint64_t softint)
774009Ssaidi@eecs.umich.edu    {
784103Ssaidi@eecs.umich.edu        if (softint & 0x10000 || softint & 0x1)
794103Ssaidi@eecs.umich.edu            return 14;
804103Ssaidi@eecs.umich.edu
814103Ssaidi@eecs.umich.edu        int level = 15;
824103Ssaidi@eecs.umich.edu        while (level > 0 && !(1 << level & softint))
834103Ssaidi@eecs.umich.edu            level--;
844103Ssaidi@eecs.umich.edu        if (1 << level & softint)
854103Ssaidi@eecs.umich.edu            return level;
864103Ssaidi@eecs.umich.edu        return 0;
874009Ssaidi@eecs.umich.edu    }
884009Ssaidi@eecs.umich.edu
895704Snate@binkert.org    void
905704Snate@binkert.org    post(int int_num, int index)
913537Sgblack@eecs.umich.edu    {
924103Ssaidi@eecs.umich.edu        DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
934103Ssaidi@eecs.umich.edu        assert(int_num >= 0 && int_num < NumInterruptTypes);
944103Ssaidi@eecs.umich.edu        assert(index >= 0 && index < 64);
953827Shsul@eecs.umich.edu
964103Ssaidi@eecs.umich.edu        interrupts[int_num] |= ULL(1) << index;
974103Ssaidi@eecs.umich.edu        intStatus |= ULL(1) << int_num;
984009Ssaidi@eecs.umich.edu    }
993894Shsul@eecs.umich.edu
1005704Snate@binkert.org    void
1015704Snate@binkert.org    clear(int int_num, int index)
1024009Ssaidi@eecs.umich.edu    {
1034103Ssaidi@eecs.umich.edu        DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
1044103Ssaidi@eecs.umich.edu        assert(int_num >= 0 && int_num < NumInterruptTypes);
1054103Ssaidi@eecs.umich.edu        assert(index >= 0 && index < 64);
1063537Sgblack@eecs.umich.edu
1074103Ssaidi@eecs.umich.edu        interrupts[int_num] &= ~(ULL(1) << index);
1084103Ssaidi@eecs.umich.edu        if (!interrupts[int_num])
1094103Ssaidi@eecs.umich.edu            intStatus &= ~(ULL(1) << int_num);
1104009Ssaidi@eecs.umich.edu    }
1113827Shsul@eecs.umich.edu
1125704Snate@binkert.org    void
1135704Snate@binkert.org    clearAll()
1144009Ssaidi@eecs.umich.edu    {
1154103Ssaidi@eecs.umich.edu        for (int i = 0; i < NumInterruptTypes; ++i) {
1164103Ssaidi@eecs.umich.edu            interrupts[i] = 0;
1174103Ssaidi@eecs.umich.edu        }
1184103Ssaidi@eecs.umich.edu        intStatus = 0;
1194009Ssaidi@eecs.umich.edu    }
1203537Sgblack@eecs.umich.edu
1215704Snate@binkert.org    bool
1225704Snate@binkert.org    checkInterrupts(ThreadContext *tc) const
1234009Ssaidi@eecs.umich.edu    {
1244103Ssaidi@eecs.umich.edu        return intStatus;
1254009Ssaidi@eecs.umich.edu    }
1263537Sgblack@eecs.umich.edu
1275704Snate@binkert.org    Fault
1285704Snate@binkert.org    getInterrupt(ThreadContext *tc)
1294009Ssaidi@eecs.umich.edu    {
1304172Ssaidi@eecs.umich.edu        int hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
1314172Ssaidi@eecs.umich.edu        int pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
1324009Ssaidi@eecs.umich.edu        bool ie = pstate & PSTATE::ie;
1333827Shsul@eecs.umich.edu
1344009Ssaidi@eecs.umich.edu        // THESE ARE IN ORDER OF PRIORITY
1354009Ssaidi@eecs.umich.edu        // since there are early returns, and the highest
1364009Ssaidi@eecs.umich.edu        // priority interrupts should get serviced,
1374009Ssaidi@eecs.umich.edu        // it is v. important that new interrupts are inserted
1384009Ssaidi@eecs.umich.edu        // in the right order of processing
1394009Ssaidi@eecs.umich.edu        if (hpstate & HPSTATE::hpriv) {
1404009Ssaidi@eecs.umich.edu            if (ie) {
1414103Ssaidi@eecs.umich.edu                if (interrupts[IT_HINTP]) {
1424103Ssaidi@eecs.umich.edu                    // This will be cleaned by a HINTP write
1434103Ssaidi@eecs.umich.edu                    return new HstickMatch;
1443894Shsul@eecs.umich.edu                }
1454103Ssaidi@eecs.umich.edu                if (interrupts[IT_INT_VEC]) {
1464103Ssaidi@eecs.umich.edu                    // this will be cleared by an ASI read (or write)
1474103Ssaidi@eecs.umich.edu                    return new InterruptVector;
1484009Ssaidi@eecs.umich.edu                }
1494103Ssaidi@eecs.umich.edu            }
1504103Ssaidi@eecs.umich.edu        } else {
1514103Ssaidi@eecs.umich.edu            if (interrupts[IT_TRAP_LEVEL_ZERO]) {
1524103Ssaidi@eecs.umich.edu                    // this is cleared by deasserting HPSTATE::tlz
1534103Ssaidi@eecs.umich.edu                    return new TrapLevelZero;
1544103Ssaidi@eecs.umich.edu            }
1554103Ssaidi@eecs.umich.edu            // HStick matches always happen in priv mode (ie doesn't matter)
1564103Ssaidi@eecs.umich.edu            if (interrupts[IT_HINTP]) {
1574103Ssaidi@eecs.umich.edu                return new HstickMatch;
1584103Ssaidi@eecs.umich.edu            }
1594103Ssaidi@eecs.umich.edu            if (interrupts[IT_INT_VEC]) {
1604103Ssaidi@eecs.umich.edu                // this will be cleared by an ASI read (or write)
1614103Ssaidi@eecs.umich.edu                return new InterruptVector;
1624103Ssaidi@eecs.umich.edu            }
1634103Ssaidi@eecs.umich.edu            if (ie) {
1644103Ssaidi@eecs.umich.edu                if (interrupts[IT_CPU_MONDO]) {
1654103Ssaidi@eecs.umich.edu                    return new CpuMondo;
1664103Ssaidi@eecs.umich.edu                }
1674103Ssaidi@eecs.umich.edu                if (interrupts[IT_DEV_MONDO]) {
1684103Ssaidi@eecs.umich.edu                    return new DevMondo;
1694103Ssaidi@eecs.umich.edu                }
1704103Ssaidi@eecs.umich.edu                if (interrupts[IT_SOFT_INT]) {
1715704Snate@binkert.org                    int level = InterruptLevel(interrupts[IT_SOFT_INT]);
1725704Snate@binkert.org                    return new InterruptLevelN(level);
1734009Ssaidi@eecs.umich.edu                }
1744009Ssaidi@eecs.umich.edu
1754103Ssaidi@eecs.umich.edu                if (interrupts[IT_RES_ERROR]) {
1764009Ssaidi@eecs.umich.edu                    return new ResumableError;
1773894Shsul@eecs.umich.edu                }
1784103Ssaidi@eecs.umich.edu            } // !hpriv && ie
1794103Ssaidi@eecs.umich.edu        }  // !hpriv
1804009Ssaidi@eecs.umich.edu        return NoFault;
1814009Ssaidi@eecs.umich.edu    }
1823537Sgblack@eecs.umich.edu
1835704Snate@binkert.org    void
1845704Snate@binkert.org    updateIntrInfo(ThreadContext *tc)
1857741Sgblack@eecs.umich.edu    {}
1863654Shsul@eecs.umich.edu
1875704Snate@binkert.org    uint64_t
1885704Snate@binkert.org    get_vec(int int_num)
1894103Ssaidi@eecs.umich.edu    {
1904103Ssaidi@eecs.umich.edu        assert(int_num >= 0 && int_num < NumInterruptTypes);
1914103Ssaidi@eecs.umich.edu        return interrupts[int_num];
1924103Ssaidi@eecs.umich.edu    }
1934103Ssaidi@eecs.umich.edu
1945704Snate@binkert.org    void
1955704Snate@binkert.org    serialize(std::ostream &os)
1964009Ssaidi@eecs.umich.edu    {
1974103Ssaidi@eecs.umich.edu        SERIALIZE_ARRAY(interrupts,NumInterruptTypes);
1984103Ssaidi@eecs.umich.edu        SERIALIZE_SCALAR(intStatus);
1994009Ssaidi@eecs.umich.edu    }
2003537Sgblack@eecs.umich.edu
2015704Snate@binkert.org    void
2025704Snate@binkert.org    unserialize(Checkpoint *cp, const std::string &section)
2034009Ssaidi@eecs.umich.edu    {
2044103Ssaidi@eecs.umich.edu        UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes);
2054103Ssaidi@eecs.umich.edu        UNSERIALIZE_SCALAR(intStatus);
2064009Ssaidi@eecs.umich.edu    }
2074009Ssaidi@eecs.umich.edu};
2084009Ssaidi@eecs.umich.edu} // namespace SPARC_ISA
2093537Sgblack@eecs.umich.edu
2103537Sgblack@eecs.umich.edu#endif // __ARCH_SPARC_INTERRUPT_HH__
211