interrupts.hh revision 5810
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"
373827Shsul@eecs.umich.edu#include "cpu/thread_context.hh"
385647Sgblack@eecs.umich.edu#include "params/SparcInterrupts.hh"
395647Sgblack@eecs.umich.edu#include "sim/sim_object.hh"
403827Shsul@eecs.umich.edu
413537Sgblack@eecs.umich.edunamespace SparcISA
423537Sgblack@eecs.umich.edu{
433894Shsul@eecs.umich.edu
445647Sgblack@eecs.umich.educlass Interrupts : public SimObject
454009Ssaidi@eecs.umich.edu{
465810Sgblack@eecs.umich.edu  private:
475810Sgblack@eecs.umich.edu    BaseCPU * cpu;
484009Ssaidi@eecs.umich.edu
494103Ssaidi@eecs.umich.edu    uint64_t interrupts[NumInterruptTypes];
504103Ssaidi@eecs.umich.edu    uint64_t intStatus;
514009Ssaidi@eecs.umich.edu
524009Ssaidi@eecs.umich.edu  public:
535810Sgblack@eecs.umich.edu
545810Sgblack@eecs.umich.edu    void
555810Sgblack@eecs.umich.edu    setCPU(BaseCPU * _cpu)
565810Sgblack@eecs.umich.edu    {
575810Sgblack@eecs.umich.edu        cpu = _cpu;
585810Sgblack@eecs.umich.edu    }
595810Sgblack@eecs.umich.edu
605647Sgblack@eecs.umich.edu    typedef SparcInterruptsParams Params;
615647Sgblack@eecs.umich.edu
625647Sgblack@eecs.umich.edu    const Params *
635647Sgblack@eecs.umich.edu    params() const
645647Sgblack@eecs.umich.edu    {
655647Sgblack@eecs.umich.edu        return dynamic_cast<const Params *>(_params);
665647Sgblack@eecs.umich.edu    }
675647Sgblack@eecs.umich.edu
685810Sgblack@eecs.umich.edu    Interrupts(Params * p) : SimObject(p), cpu(NULL)
694009Ssaidi@eecs.umich.edu    {
705704Snate@binkert.org        clearAll();
714009Ssaidi@eecs.umich.edu    }
724009Ssaidi@eecs.umich.edu
735704Snate@binkert.org    int
745704Snate@binkert.org    InterruptLevel(uint64_t softint)
754009Ssaidi@eecs.umich.edu    {
764103Ssaidi@eecs.umich.edu        if (softint & 0x10000 || softint & 0x1)
774103Ssaidi@eecs.umich.edu            return 14;
784103Ssaidi@eecs.umich.edu
794103Ssaidi@eecs.umich.edu        int level = 15;
804103Ssaidi@eecs.umich.edu        while (level > 0 && !(1 << level & softint))
814103Ssaidi@eecs.umich.edu            level--;
824103Ssaidi@eecs.umich.edu        if (1 << level & softint)
834103Ssaidi@eecs.umich.edu            return level;
844103Ssaidi@eecs.umich.edu        return 0;
854009Ssaidi@eecs.umich.edu    }
864009Ssaidi@eecs.umich.edu
875704Snate@binkert.org    void
885704Snate@binkert.org    post(int int_num, int index)
893537Sgblack@eecs.umich.edu    {
904103Ssaidi@eecs.umich.edu        DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
914103Ssaidi@eecs.umich.edu        assert(int_num >= 0 && int_num < NumInterruptTypes);
924103Ssaidi@eecs.umich.edu        assert(index >= 0 && index < 64);
933827Shsul@eecs.umich.edu
944103Ssaidi@eecs.umich.edu        interrupts[int_num] |= ULL(1) << index;
954103Ssaidi@eecs.umich.edu        intStatus |= ULL(1) << int_num;
964009Ssaidi@eecs.umich.edu    }
973894Shsul@eecs.umich.edu
985704Snate@binkert.org    void
995704Snate@binkert.org    clear(int int_num, int index)
1004009Ssaidi@eecs.umich.edu    {
1014103Ssaidi@eecs.umich.edu        DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
1024103Ssaidi@eecs.umich.edu        assert(int_num >= 0 && int_num < NumInterruptTypes);
1034103Ssaidi@eecs.umich.edu        assert(index >= 0 && index < 64);
1043537Sgblack@eecs.umich.edu
1054103Ssaidi@eecs.umich.edu        interrupts[int_num] &= ~(ULL(1) << index);
1064103Ssaidi@eecs.umich.edu        if (!interrupts[int_num])
1074103Ssaidi@eecs.umich.edu            intStatus &= ~(ULL(1) << int_num);
1084009Ssaidi@eecs.umich.edu    }
1093827Shsul@eecs.umich.edu
1105704Snate@binkert.org    void
1115704Snate@binkert.org    clearAll()
1124009Ssaidi@eecs.umich.edu    {
1134103Ssaidi@eecs.umich.edu        for (int i = 0; i < NumInterruptTypes; ++i) {
1144103Ssaidi@eecs.umich.edu            interrupts[i] = 0;
1154103Ssaidi@eecs.umich.edu        }
1164103Ssaidi@eecs.umich.edu        intStatus = 0;
1174009Ssaidi@eecs.umich.edu    }
1183537Sgblack@eecs.umich.edu
1195704Snate@binkert.org    bool
1205704Snate@binkert.org    checkInterrupts(ThreadContext *tc) const
1214009Ssaidi@eecs.umich.edu    {
1224103Ssaidi@eecs.umich.edu        return intStatus;
1234009Ssaidi@eecs.umich.edu    }
1243537Sgblack@eecs.umich.edu
1255704Snate@binkert.org    Fault
1265704Snate@binkert.org    getInterrupt(ThreadContext *tc)
1274009Ssaidi@eecs.umich.edu    {
1284172Ssaidi@eecs.umich.edu        int hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
1294172Ssaidi@eecs.umich.edu        int pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
1304009Ssaidi@eecs.umich.edu        bool ie = pstate & PSTATE::ie;
1313827Shsul@eecs.umich.edu
1324009Ssaidi@eecs.umich.edu        // THESE ARE IN ORDER OF PRIORITY
1334009Ssaidi@eecs.umich.edu        // since there are early returns, and the highest
1344009Ssaidi@eecs.umich.edu        // priority interrupts should get serviced,
1354009Ssaidi@eecs.umich.edu        // it is v. important that new interrupts are inserted
1364009Ssaidi@eecs.umich.edu        // in the right order of processing
1374009Ssaidi@eecs.umich.edu        if (hpstate & HPSTATE::hpriv) {
1384009Ssaidi@eecs.umich.edu            if (ie) {
1394103Ssaidi@eecs.umich.edu                if (interrupts[IT_HINTP]) {
1404103Ssaidi@eecs.umich.edu                    // This will be cleaned by a HINTP write
1414103Ssaidi@eecs.umich.edu                    return new HstickMatch;
1423894Shsul@eecs.umich.edu                }
1434103Ssaidi@eecs.umich.edu                if (interrupts[IT_INT_VEC]) {
1444103Ssaidi@eecs.umich.edu                    // this will be cleared by an ASI read (or write)
1454103Ssaidi@eecs.umich.edu                    return new InterruptVector;
1464009Ssaidi@eecs.umich.edu                }
1474103Ssaidi@eecs.umich.edu            }
1484103Ssaidi@eecs.umich.edu        } else {
1494103Ssaidi@eecs.umich.edu            if (interrupts[IT_TRAP_LEVEL_ZERO]) {
1504103Ssaidi@eecs.umich.edu                    // this is cleared by deasserting HPSTATE::tlz
1514103Ssaidi@eecs.umich.edu                    return new TrapLevelZero;
1524103Ssaidi@eecs.umich.edu            }
1534103Ssaidi@eecs.umich.edu            // HStick matches always happen in priv mode (ie doesn't matter)
1544103Ssaidi@eecs.umich.edu            if (interrupts[IT_HINTP]) {
1554103Ssaidi@eecs.umich.edu                return new HstickMatch;
1564103Ssaidi@eecs.umich.edu            }
1574103Ssaidi@eecs.umich.edu            if (interrupts[IT_INT_VEC]) {
1584103Ssaidi@eecs.umich.edu                // this will be cleared by an ASI read (or write)
1594103Ssaidi@eecs.umich.edu                return new InterruptVector;
1604103Ssaidi@eecs.umich.edu            }
1614103Ssaidi@eecs.umich.edu            if (ie) {
1624103Ssaidi@eecs.umich.edu                if (interrupts[IT_CPU_MONDO]) {
1634103Ssaidi@eecs.umich.edu                    return new CpuMondo;
1644103Ssaidi@eecs.umich.edu                }
1654103Ssaidi@eecs.umich.edu                if (interrupts[IT_DEV_MONDO]) {
1664103Ssaidi@eecs.umich.edu                    return new DevMondo;
1674103Ssaidi@eecs.umich.edu                }
1684103Ssaidi@eecs.umich.edu                if (interrupts[IT_SOFT_INT]) {
1695704Snate@binkert.org                    int level = InterruptLevel(interrupts[IT_SOFT_INT]);
1705704Snate@binkert.org                    return new InterruptLevelN(level);
1714009Ssaidi@eecs.umich.edu                }
1724009Ssaidi@eecs.umich.edu
1734103Ssaidi@eecs.umich.edu                if (interrupts[IT_RES_ERROR]) {
1744009Ssaidi@eecs.umich.edu                    return new ResumableError;
1753894Shsul@eecs.umich.edu                }
1764103Ssaidi@eecs.umich.edu            } // !hpriv && ie
1774103Ssaidi@eecs.umich.edu        }  // !hpriv
1784009Ssaidi@eecs.umich.edu        return NoFault;
1794009Ssaidi@eecs.umich.edu    }
1803537Sgblack@eecs.umich.edu
1815704Snate@binkert.org    void
1825704Snate@binkert.org    updateIntrInfo(ThreadContext *tc)
1834009Ssaidi@eecs.umich.edu    {
1843654Shsul@eecs.umich.edu
1854009Ssaidi@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