interrupts.hh revision 6335:a08470cb53e5
12501SN/A/*
22501SN/A * Copyright (c) 2006 The Regents of The University of Michigan
32501SN/A * All rights reserved.
42501SN/A *
52501SN/A * Redistribution and use in source and binary forms, with or without
62501SN/A * modification, are permitted provided that the following conditions are
72501SN/A * met: redistributions of source code must retain the above copyright
82501SN/A * notice, this list of conditions and the following disclaimer;
92501SN/A * redistributions in binary form must reproduce the above copyright
102501SN/A * notice, this list of conditions and the following disclaimer in the
112501SN/A * documentation and/or other materials provided with the distribution;
122501SN/A * neither the name of the copyright holders nor the names of its
132501SN/A * contributors may be used to endorse or promote products derived from
142501SN/A * this software without specific prior written permission.
152501SN/A *
162501SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172501SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182501SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192501SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202501SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212501SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222501SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232501SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242501SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252501SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262501SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Ali Saidi
292501SN/A *          Lisa Hsu
302501SN/A */
312501SN/A
322501SN/A#ifndef __ARCH_SPARC_INTERRUPT_HH__
332501SN/A#define __ARCH_SPARC_INTERRUPT_HH__
343532Sgblack@eecs.umich.edu
352501SN/A#include "arch/sparc/faults.hh"
363603Ssaidi@eecs.umich.edu#include "arch/sparc/isa_traits.hh"
372501SN/A#include "arch/sparc/registers.hh"
383278Sgblack@eecs.umich.edu#include "cpu/thread_context.hh"
393272Sgblack@eecs.umich.edu#include "params/SparcInterrupts.hh"
402501SN/A#include "sim/sim_object.hh"
412501SN/A
422501SN/Anamespace SparcISA
433577Sgblack@eecs.umich.edu{
443577Sgblack@eecs.umich.edu
453577Sgblack@eecs.umich.educlass Interrupts : public SimObject
463577Sgblack@eecs.umich.edu{
474172Ssaidi@eecs.umich.edu  private:
484172Ssaidi@eecs.umich.edu    BaseCPU * cpu;
493577Sgblack@eecs.umich.edu
503577Sgblack@eecs.umich.edu    uint64_t interrupts[NumInterruptTypes];
512501SN/A    uint64_t intStatus;
523272Sgblack@eecs.umich.edu
533918Ssaidi@eecs.umich.edu  public:
543272Sgblack@eecs.umich.edu
553272Sgblack@eecs.umich.edu    void
563272Sgblack@eecs.umich.edu    setCPU(BaseCPU * _cpu)
573272Sgblack@eecs.umich.edu    {
583272Sgblack@eecs.umich.edu        cpu = _cpu;
594172Ssaidi@eecs.umich.edu    }
603272Sgblack@eecs.umich.edu
613278Sgblack@eecs.umich.edu    typedef SparcInterruptsParams Params;
623278Sgblack@eecs.umich.edu
633278Sgblack@eecs.umich.edu    const Params *
643272Sgblack@eecs.umich.edu    params() const
652501SN/A    {
662501SN/A        return dynamic_cast<const Params *>(_params);
672501SN/A    }
682501SN/A
692501SN/A    Interrupts(Params * p) : SimObject(p), cpu(NULL)
702501SN/A    {
712501SN/A        clearAll();
722501SN/A    }
732501SN/A
742501SN/A    int
752501SN/A    InterruptLevel(uint64_t softint)
762501SN/A    {
772501SN/A        if (softint & 0x10000 || softint & 0x1)
782501SN/A            return 14;
792501SN/A
802501SN/A        int level = 15;
812501SN/A        while (level > 0 && !(1 << level & softint))
822501SN/A            level--;
832501SN/A        if (1 << level & softint)
842501SN/A            return level;
852501SN/A        return 0;
862501SN/A    }
872501SN/A
882501SN/A    void
892501SN/A    post(int int_num, int index)
902501SN/A    {
912501SN/A        DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
922501SN/A        assert(int_num >= 0 && int_num < NumInterruptTypes);
932501SN/A        assert(index >= 0 && index < 64);
942501SN/A
952501SN/A        interrupts[int_num] |= ULL(1) << index;
962501SN/A        intStatus |= ULL(1) << int_num;
972501SN/A    }
982501SN/A
992501SN/A    void
1002501SN/A    clear(int int_num, int index)
1012501SN/A    {
1022501SN/A        DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
1032501SN/A        assert(int_num >= 0 && int_num < NumInterruptTypes);
1042501SN/A        assert(index >= 0 && index < 64);
1052501SN/A
1062501SN/A        interrupts[int_num] &= ~(ULL(1) << index);
1072680Sktlim@umich.edu        if (!interrupts[int_num])
1082501SN/A            intStatus &= ~(ULL(1) << int_num);
1092680Sktlim@umich.edu    }
1102680Sktlim@umich.edu
1112501SN/A    void
1123532Sgblack@eecs.umich.edu    clearAll()
1133528Sgblack@eecs.umich.edu    {
1143532Sgblack@eecs.umich.edu        for (int i = 0; i < NumInterruptTypes; ++i) {
1154194Ssaidi@eecs.umich.edu            interrupts[i] = 0;
1164194Ssaidi@eecs.umich.edu        }
1174194Ssaidi@eecs.umich.edu        intStatus = 0;
1184194Ssaidi@eecs.umich.edu    }
1194194Ssaidi@eecs.umich.edu
1204194Ssaidi@eecs.umich.edu    bool
1214194Ssaidi@eecs.umich.edu    checkInterrupts(ThreadContext *tc) const
1224194Ssaidi@eecs.umich.edu    {
1234194Ssaidi@eecs.umich.edu        return intStatus;
1244194Ssaidi@eecs.umich.edu    }
1254194Ssaidi@eecs.umich.edu
1264194Ssaidi@eecs.umich.edu    Fault
1274194Ssaidi@eecs.umich.edu    getInterrupt(ThreadContext *tc)
1284194Ssaidi@eecs.umich.edu    {
1293528Sgblack@eecs.umich.edu        int hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
1303528Sgblack@eecs.umich.edu        int pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
1312501SN/A        bool ie = pstate & PSTATE::ie;
1322501SN/A
1332501SN/A        // THESE ARE IN ORDER OF PRIORITY
134        // since there are early returns, and the highest
135        // priority interrupts should get serviced,
136        // it is v. important that new interrupts are inserted
137        // in the right order of processing
138        if (hpstate & HPSTATE::hpriv) {
139            if (ie) {
140                if (interrupts[IT_HINTP]) {
141                    // This will be cleaned by a HINTP write
142                    return new HstickMatch;
143                }
144                if (interrupts[IT_INT_VEC]) {
145                    // this will be cleared by an ASI read (or write)
146                    return new InterruptVector;
147                }
148            }
149        } else {
150            if (interrupts[IT_TRAP_LEVEL_ZERO]) {
151                    // this is cleared by deasserting HPSTATE::tlz
152                    return new TrapLevelZero;
153            }
154            // HStick matches always happen in priv mode (ie doesn't matter)
155            if (interrupts[IT_HINTP]) {
156                return new HstickMatch;
157            }
158            if (interrupts[IT_INT_VEC]) {
159                // this will be cleared by an ASI read (or write)
160                return new InterruptVector;
161            }
162            if (ie) {
163                if (interrupts[IT_CPU_MONDO]) {
164                    return new CpuMondo;
165                }
166                if (interrupts[IT_DEV_MONDO]) {
167                    return new DevMondo;
168                }
169                if (interrupts[IT_SOFT_INT]) {
170                    int level = InterruptLevel(interrupts[IT_SOFT_INT]);
171                    return new InterruptLevelN(level);
172                }
173
174                if (interrupts[IT_RES_ERROR]) {
175                    return new ResumableError;
176                }
177            } // !hpriv && ie
178        }  // !hpriv
179        return NoFault;
180    }
181
182    void
183    updateIntrInfo(ThreadContext *tc)
184    {
185
186    }
187
188    uint64_t
189    get_vec(int int_num)
190    {
191        assert(int_num >= 0 && int_num < NumInterruptTypes);
192        return interrupts[int_num];
193    }
194
195    void
196    serialize(std::ostream &os)
197    {
198        SERIALIZE_ARRAY(interrupts,NumInterruptTypes);
199        SERIALIZE_SCALAR(intStatus);
200    }
201
202    void
203    unserialize(Checkpoint *cp, const std::string &section)
204    {
205        UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes);
206        UNSERIALIZE_SCALAR(intStatus);
207    }
208};
209} // namespace SPARC_ISA
210
211#endif // __ARCH_SPARC_INTERRUPT_HH__
212