interrupts.hh revision 5647
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{
464009Ssaidi@eecs.umich.edu
474009Ssaidi@eecs.umich.edu  private:
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:
535647Sgblack@eecs.umich.edu    typedef SparcInterruptsParams Params;
545647Sgblack@eecs.umich.edu
555647Sgblack@eecs.umich.edu    const Params *
565647Sgblack@eecs.umich.edu    params() const
575647Sgblack@eecs.umich.edu    {
585647Sgblack@eecs.umich.edu        return dynamic_cast<const Params *>(_params);
595647Sgblack@eecs.umich.edu    }
605647Sgblack@eecs.umich.edu
615647Sgblack@eecs.umich.edu    Interrupts(Params * p) : SimObject(p)
624009Ssaidi@eecs.umich.edu    {
634103Ssaidi@eecs.umich.edu        clear_all();
644009Ssaidi@eecs.umich.edu    }
654009Ssaidi@eecs.umich.edu
664103Ssaidi@eecs.umich.edu    int InterruptLevel(uint64_t softint)
674009Ssaidi@eecs.umich.edu    {
684103Ssaidi@eecs.umich.edu        if (softint & 0x10000 || softint & 0x1)
694103Ssaidi@eecs.umich.edu            return 14;
704103Ssaidi@eecs.umich.edu
714103Ssaidi@eecs.umich.edu        int level = 15;
724103Ssaidi@eecs.umich.edu        while (level > 0 && !(1 << level & softint))
734103Ssaidi@eecs.umich.edu            level--;
744103Ssaidi@eecs.umich.edu        if (1 << level & softint)
754103Ssaidi@eecs.umich.edu            return level;
764103Ssaidi@eecs.umich.edu        return 0;
774009Ssaidi@eecs.umich.edu    }
784009Ssaidi@eecs.umich.edu
794009Ssaidi@eecs.umich.edu    void post(int int_num, int index)
803537Sgblack@eecs.umich.edu    {
814103Ssaidi@eecs.umich.edu        DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
824103Ssaidi@eecs.umich.edu        assert(int_num >= 0 && int_num < NumInterruptTypes);
834103Ssaidi@eecs.umich.edu        assert(index >= 0 && index < 64);
843827Shsul@eecs.umich.edu
854103Ssaidi@eecs.umich.edu        interrupts[int_num] |= ULL(1) << index;
864103Ssaidi@eecs.umich.edu        intStatus |= ULL(1) << int_num;
874009Ssaidi@eecs.umich.edu    }
883894Shsul@eecs.umich.edu
894009Ssaidi@eecs.umich.edu    void clear(int int_num, int index)
904009Ssaidi@eecs.umich.edu    {
914103Ssaidi@eecs.umich.edu        DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
924103Ssaidi@eecs.umich.edu        assert(int_num >= 0 && int_num < NumInterruptTypes);
934103Ssaidi@eecs.umich.edu        assert(index >= 0 && index < 64);
943537Sgblack@eecs.umich.edu
954103Ssaidi@eecs.umich.edu        interrupts[int_num] &= ~(ULL(1) << index);
964103Ssaidi@eecs.umich.edu        if (!interrupts[int_num])
974103Ssaidi@eecs.umich.edu            intStatus &= ~(ULL(1) << int_num);
984009Ssaidi@eecs.umich.edu    }
993827Shsul@eecs.umich.edu
1004009Ssaidi@eecs.umich.edu    void clear_all()
1014009Ssaidi@eecs.umich.edu    {
1024103Ssaidi@eecs.umich.edu        for (int i = 0; i < NumInterruptTypes; ++i) {
1034103Ssaidi@eecs.umich.edu            interrupts[i] = 0;
1044103Ssaidi@eecs.umich.edu        }
1054103Ssaidi@eecs.umich.edu        intStatus = 0;
1064009Ssaidi@eecs.umich.edu    }
1073537Sgblack@eecs.umich.edu
1084009Ssaidi@eecs.umich.edu    bool check_interrupts(ThreadContext * tc) const
1094009Ssaidi@eecs.umich.edu    {
1104103Ssaidi@eecs.umich.edu        return intStatus;
1114009Ssaidi@eecs.umich.edu    }
1123537Sgblack@eecs.umich.edu
1134009Ssaidi@eecs.umich.edu    Fault getInterrupt(ThreadContext * tc)
1144009Ssaidi@eecs.umich.edu    {
1154172Ssaidi@eecs.umich.edu        int hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
1164172Ssaidi@eecs.umich.edu        int pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
1174009Ssaidi@eecs.umich.edu        bool ie = pstate & PSTATE::ie;
1183827Shsul@eecs.umich.edu
1194009Ssaidi@eecs.umich.edu        // THESE ARE IN ORDER OF PRIORITY
1204009Ssaidi@eecs.umich.edu        // since there are early returns, and the highest
1214009Ssaidi@eecs.umich.edu        // priority interrupts should get serviced,
1224009Ssaidi@eecs.umich.edu        // it is v. important that new interrupts are inserted
1234009Ssaidi@eecs.umich.edu        // in the right order of processing
1244009Ssaidi@eecs.umich.edu        if (hpstate & HPSTATE::hpriv) {
1254009Ssaidi@eecs.umich.edu            if (ie) {
1264103Ssaidi@eecs.umich.edu                if (interrupts[IT_HINTP]) {
1274103Ssaidi@eecs.umich.edu                    // This will be cleaned by a HINTP write
1284103Ssaidi@eecs.umich.edu                    return new HstickMatch;
1293894Shsul@eecs.umich.edu                }
1304103Ssaidi@eecs.umich.edu                if (interrupts[IT_INT_VEC]) {
1314103Ssaidi@eecs.umich.edu                    // this will be cleared by an ASI read (or write)
1324103Ssaidi@eecs.umich.edu                    return new InterruptVector;
1334009Ssaidi@eecs.umich.edu                }
1344103Ssaidi@eecs.umich.edu            }
1354103Ssaidi@eecs.umich.edu        } else {
1364103Ssaidi@eecs.umich.edu            if (interrupts[IT_TRAP_LEVEL_ZERO]) {
1374103Ssaidi@eecs.umich.edu                    // this is cleared by deasserting HPSTATE::tlz
1384103Ssaidi@eecs.umich.edu                    return new TrapLevelZero;
1394103Ssaidi@eecs.umich.edu            }
1404103Ssaidi@eecs.umich.edu            // HStick matches always happen in priv mode (ie doesn't matter)
1414103Ssaidi@eecs.umich.edu            if (interrupts[IT_HINTP]) {
1424103Ssaidi@eecs.umich.edu                return new HstickMatch;
1434103Ssaidi@eecs.umich.edu            }
1444103Ssaidi@eecs.umich.edu            if (interrupts[IT_INT_VEC]) {
1454103Ssaidi@eecs.umich.edu                // this will be cleared by an ASI read (or write)
1464103Ssaidi@eecs.umich.edu                return new InterruptVector;
1474103Ssaidi@eecs.umich.edu            }
1484103Ssaidi@eecs.umich.edu            if (ie) {
1494103Ssaidi@eecs.umich.edu                if (interrupts[IT_CPU_MONDO]) {
1504103Ssaidi@eecs.umich.edu                    return new CpuMondo;
1514103Ssaidi@eecs.umich.edu                }
1524103Ssaidi@eecs.umich.edu                if (interrupts[IT_DEV_MONDO]) {
1534103Ssaidi@eecs.umich.edu                    return new DevMondo;
1544103Ssaidi@eecs.umich.edu                }
1554103Ssaidi@eecs.umich.edu                if (interrupts[IT_SOFT_INT]) {
1564103Ssaidi@eecs.umich.edu                    return new
1574103Ssaidi@eecs.umich.edu                        InterruptLevelN(InterruptLevel(interrupts[IT_SOFT_INT]));
1584009Ssaidi@eecs.umich.edu                }
1594009Ssaidi@eecs.umich.edu
1604103Ssaidi@eecs.umich.edu                if (interrupts[IT_RES_ERROR]) {
1614009Ssaidi@eecs.umich.edu                    return new ResumableError;
1623894Shsul@eecs.umich.edu                }
1634103Ssaidi@eecs.umich.edu            } // !hpriv && ie
1644103Ssaidi@eecs.umich.edu        }  // !hpriv
1654009Ssaidi@eecs.umich.edu        return NoFault;
1664009Ssaidi@eecs.umich.edu    }
1673537Sgblack@eecs.umich.edu
1684009Ssaidi@eecs.umich.edu    void updateIntrInfo(ThreadContext * tc)
1694009Ssaidi@eecs.umich.edu    {
1703654Shsul@eecs.umich.edu
1714009Ssaidi@eecs.umich.edu    }
1723654Shsul@eecs.umich.edu
1734103Ssaidi@eecs.umich.edu    uint64_t get_vec(int int_num)
1744103Ssaidi@eecs.umich.edu    {
1754103Ssaidi@eecs.umich.edu        assert(int_num >= 0 && int_num < NumInterruptTypes);
1764103Ssaidi@eecs.umich.edu        return interrupts[int_num];
1774103Ssaidi@eecs.umich.edu    }
1784103Ssaidi@eecs.umich.edu
1794009Ssaidi@eecs.umich.edu    void serialize(std::ostream &os)
1804009Ssaidi@eecs.umich.edu    {
1814103Ssaidi@eecs.umich.edu        SERIALIZE_ARRAY(interrupts,NumInterruptTypes);
1824103Ssaidi@eecs.umich.edu        SERIALIZE_SCALAR(intStatus);
1834009Ssaidi@eecs.umich.edu    }
1843537Sgblack@eecs.umich.edu
1854009Ssaidi@eecs.umich.edu    void unserialize(Checkpoint *cp, const std::string &section)
1864009Ssaidi@eecs.umich.edu    {
1874103Ssaidi@eecs.umich.edu        UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes);
1884103Ssaidi@eecs.umich.edu        UNSERIALIZE_SCALAR(intStatus);
1894009Ssaidi@eecs.umich.edu    }
1904009Ssaidi@eecs.umich.edu};
1914009Ssaidi@eecs.umich.edu} // namespace SPARC_ISA
1923537Sgblack@eecs.umich.edu
1933537Sgblack@eecs.umich.edu#endif // __ARCH_SPARC_INTERRUPT_HH__
194