interrupts.hh revision 4172
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"
383827Shsul@eecs.umich.edu
393537Sgblack@eecs.umich.edunamespace SparcISA
403537Sgblack@eecs.umich.edu{
413894Shsul@eecs.umich.edu
424009Ssaidi@eecs.umich.educlass Interrupts
434009Ssaidi@eecs.umich.edu{
444009Ssaidi@eecs.umich.edu
454009Ssaidi@eecs.umich.edu  private:
464009Ssaidi@eecs.umich.edu
474103Ssaidi@eecs.umich.edu    uint64_t interrupts[NumInterruptTypes];
484103Ssaidi@eecs.umich.edu    uint64_t intStatus;
494009Ssaidi@eecs.umich.edu
504009Ssaidi@eecs.umich.edu  public:
514009Ssaidi@eecs.umich.edu    Interrupts()
524009Ssaidi@eecs.umich.edu    {
534103Ssaidi@eecs.umich.edu        clear_all();
544009Ssaidi@eecs.umich.edu    }
554009Ssaidi@eecs.umich.edu
564103Ssaidi@eecs.umich.edu    int InterruptLevel(uint64_t softint)
574009Ssaidi@eecs.umich.edu    {
584103Ssaidi@eecs.umich.edu        if (softint & 0x10000 || softint & 0x1)
594103Ssaidi@eecs.umich.edu            return 14;
604103Ssaidi@eecs.umich.edu
614103Ssaidi@eecs.umich.edu        int level = 15;
624103Ssaidi@eecs.umich.edu        while (level > 0 && !(1 << level & softint))
634103Ssaidi@eecs.umich.edu            level--;
644103Ssaidi@eecs.umich.edu        if (1 << level & softint)
654103Ssaidi@eecs.umich.edu            return level;
664103Ssaidi@eecs.umich.edu        return 0;
674009Ssaidi@eecs.umich.edu    }
684009Ssaidi@eecs.umich.edu
694009Ssaidi@eecs.umich.edu    void post(int int_num, int index)
703537Sgblack@eecs.umich.edu    {
714103Ssaidi@eecs.umich.edu        DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
724103Ssaidi@eecs.umich.edu        assert(int_num >= 0 && int_num < NumInterruptTypes);
734103Ssaidi@eecs.umich.edu        assert(index >= 0 && index < 64);
743827Shsul@eecs.umich.edu
754103Ssaidi@eecs.umich.edu        interrupts[int_num] |= ULL(1) << index;
764103Ssaidi@eecs.umich.edu        intStatus |= ULL(1) << int_num;
774009Ssaidi@eecs.umich.edu    }
783894Shsul@eecs.umich.edu
794009Ssaidi@eecs.umich.edu    void clear(int int_num, int index)
804009Ssaidi@eecs.umich.edu    {
814103Ssaidi@eecs.umich.edu        DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
824103Ssaidi@eecs.umich.edu        assert(int_num >= 0 && int_num < NumInterruptTypes);
834103Ssaidi@eecs.umich.edu        assert(index >= 0 && index < 64);
843537Sgblack@eecs.umich.edu
854103Ssaidi@eecs.umich.edu        interrupts[int_num] &= ~(ULL(1) << index);
864103Ssaidi@eecs.umich.edu        if (!interrupts[int_num])
874103Ssaidi@eecs.umich.edu            intStatus &= ~(ULL(1) << int_num);
884009Ssaidi@eecs.umich.edu    }
893827Shsul@eecs.umich.edu
904009Ssaidi@eecs.umich.edu    void clear_all()
914009Ssaidi@eecs.umich.edu    {
924103Ssaidi@eecs.umich.edu        for (int i = 0; i < NumInterruptTypes; ++i) {
934103Ssaidi@eecs.umich.edu            interrupts[i] = 0;
944103Ssaidi@eecs.umich.edu        }
954103Ssaidi@eecs.umich.edu        intStatus = 0;
964009Ssaidi@eecs.umich.edu    }
973537Sgblack@eecs.umich.edu
984009Ssaidi@eecs.umich.edu    bool check_interrupts(ThreadContext * tc) const
994009Ssaidi@eecs.umich.edu    {
1004103Ssaidi@eecs.umich.edu        return intStatus;
1014009Ssaidi@eecs.umich.edu    }
1023537Sgblack@eecs.umich.edu
1034009Ssaidi@eecs.umich.edu    Fault getInterrupt(ThreadContext * tc)
1044009Ssaidi@eecs.umich.edu    {
1054172Ssaidi@eecs.umich.edu        int hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
1064172Ssaidi@eecs.umich.edu        int pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
1074009Ssaidi@eecs.umich.edu        bool ie = pstate & PSTATE::ie;
1083827Shsul@eecs.umich.edu
1094009Ssaidi@eecs.umich.edu        // THESE ARE IN ORDER OF PRIORITY
1104009Ssaidi@eecs.umich.edu        // since there are early returns, and the highest
1114009Ssaidi@eecs.umich.edu        // priority interrupts should get serviced,
1124009Ssaidi@eecs.umich.edu        // it is v. important that new interrupts are inserted
1134009Ssaidi@eecs.umich.edu        // in the right order of processing
1144009Ssaidi@eecs.umich.edu        if (hpstate & HPSTATE::hpriv) {
1154009Ssaidi@eecs.umich.edu            if (ie) {
1164103Ssaidi@eecs.umich.edu                if (interrupts[IT_HINTP]) {
1174103Ssaidi@eecs.umich.edu                    // This will be cleaned by a HINTP write
1184103Ssaidi@eecs.umich.edu                    return new HstickMatch;
1193894Shsul@eecs.umich.edu                }
1204103Ssaidi@eecs.umich.edu                if (interrupts[IT_INT_VEC]) {
1214103Ssaidi@eecs.umich.edu                    // this will be cleared by an ASI read (or write)
1224103Ssaidi@eecs.umich.edu                    return new InterruptVector;
1234009Ssaidi@eecs.umich.edu                }
1244103Ssaidi@eecs.umich.edu            }
1254103Ssaidi@eecs.umich.edu        } else {
1264103Ssaidi@eecs.umich.edu            if (interrupts[IT_TRAP_LEVEL_ZERO]) {
1274103Ssaidi@eecs.umich.edu                    // this is cleared by deasserting HPSTATE::tlz
1284103Ssaidi@eecs.umich.edu                    return new TrapLevelZero;
1294103Ssaidi@eecs.umich.edu            }
1304103Ssaidi@eecs.umich.edu            // HStick matches always happen in priv mode (ie doesn't matter)
1314103Ssaidi@eecs.umich.edu            if (interrupts[IT_HINTP]) {
1324103Ssaidi@eecs.umich.edu                return new HstickMatch;
1334103Ssaidi@eecs.umich.edu            }
1344103Ssaidi@eecs.umich.edu            if (interrupts[IT_INT_VEC]) {
1354103Ssaidi@eecs.umich.edu                // this will be cleared by an ASI read (or write)
1364103Ssaidi@eecs.umich.edu                return new InterruptVector;
1374103Ssaidi@eecs.umich.edu            }
1384103Ssaidi@eecs.umich.edu            if (ie) {
1394103Ssaidi@eecs.umich.edu                if (interrupts[IT_CPU_MONDO]) {
1404103Ssaidi@eecs.umich.edu                    return new CpuMondo;
1414103Ssaidi@eecs.umich.edu                }
1424103Ssaidi@eecs.umich.edu                if (interrupts[IT_DEV_MONDO]) {
1434103Ssaidi@eecs.umich.edu                    return new DevMondo;
1444103Ssaidi@eecs.umich.edu                }
1454103Ssaidi@eecs.umich.edu                if (interrupts[IT_SOFT_INT]) {
1464103Ssaidi@eecs.umich.edu                    return new
1474103Ssaidi@eecs.umich.edu                        InterruptLevelN(InterruptLevel(interrupts[IT_SOFT_INT]));
1484009Ssaidi@eecs.umich.edu                }
1494009Ssaidi@eecs.umich.edu
1504103Ssaidi@eecs.umich.edu                if (interrupts[IT_RES_ERROR]) {
1514009Ssaidi@eecs.umich.edu                    return new ResumableError;
1523894Shsul@eecs.umich.edu                }
1534103Ssaidi@eecs.umich.edu            } // !hpriv && ie
1544103Ssaidi@eecs.umich.edu        }  // !hpriv
1554009Ssaidi@eecs.umich.edu        return NoFault;
1564009Ssaidi@eecs.umich.edu    }
1573537Sgblack@eecs.umich.edu
1584009Ssaidi@eecs.umich.edu    void updateIntrInfo(ThreadContext * tc)
1594009Ssaidi@eecs.umich.edu    {
1603654Shsul@eecs.umich.edu
1614009Ssaidi@eecs.umich.edu    }
1623654Shsul@eecs.umich.edu
1634103Ssaidi@eecs.umich.edu    uint64_t get_vec(int int_num)
1644103Ssaidi@eecs.umich.edu    {
1654103Ssaidi@eecs.umich.edu        assert(int_num >= 0 && int_num < NumInterruptTypes);
1664103Ssaidi@eecs.umich.edu        return interrupts[int_num];
1674103Ssaidi@eecs.umich.edu    }
1684103Ssaidi@eecs.umich.edu
1694009Ssaidi@eecs.umich.edu    void serialize(std::ostream &os)
1704009Ssaidi@eecs.umich.edu    {
1714103Ssaidi@eecs.umich.edu        SERIALIZE_ARRAY(interrupts,NumInterruptTypes);
1724103Ssaidi@eecs.umich.edu        SERIALIZE_SCALAR(intStatus);
1734009Ssaidi@eecs.umich.edu    }
1743537Sgblack@eecs.umich.edu
1754009Ssaidi@eecs.umich.edu    void unserialize(Checkpoint *cp, const std::string &section)
1764009Ssaidi@eecs.umich.edu    {
1774103Ssaidi@eecs.umich.edu        UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes);
1784103Ssaidi@eecs.umich.edu        UNSERIALIZE_SCALAR(intStatus);
1794009Ssaidi@eecs.umich.edu    }
1804009Ssaidi@eecs.umich.edu};
1814009Ssaidi@eecs.umich.edu} // namespace SPARC_ISA
1823537Sgblack@eecs.umich.edu
1833537Sgblack@eecs.umich.edu#endif // __ARCH_SPARC_INTERRUPT_HH__
184