interrupts.hh revision 5647
113224Sodanrc@yahoo.com.br/*
213224Sodanrc@yahoo.com.br * Copyright (c) 2006 The Regents of The University of Michigan
313224Sodanrc@yahoo.com.br * All rights reserved.
413224Sodanrc@yahoo.com.br *
513224Sodanrc@yahoo.com.br * Redistribution and use in source and binary forms, with or without
613224Sodanrc@yahoo.com.br * modification, are permitted provided that the following conditions are
713224Sodanrc@yahoo.com.br * met: redistributions of source code must retain the above copyright
813224Sodanrc@yahoo.com.br * notice, this list of conditions and the following disclaimer;
913224Sodanrc@yahoo.com.br * redistributions in binary form must reproduce the above copyright
1013224Sodanrc@yahoo.com.br * notice, this list of conditions and the following disclaimer in the
1113224Sodanrc@yahoo.com.br * documentation and/or other materials provided with the distribution;
1213224Sodanrc@yahoo.com.br * neither the name of the copyright holders nor the names of its
1313224Sodanrc@yahoo.com.br * contributors may be used to endorse or promote products derived from
1413224Sodanrc@yahoo.com.br * this software without specific prior written permission.
1513224Sodanrc@yahoo.com.br *
1613224Sodanrc@yahoo.com.br * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1713224Sodanrc@yahoo.com.br * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1813224Sodanrc@yahoo.com.br * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1913224Sodanrc@yahoo.com.br * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2013224Sodanrc@yahoo.com.br * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2113224Sodanrc@yahoo.com.br * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2213224Sodanrc@yahoo.com.br * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2313224Sodanrc@yahoo.com.br * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2413224Sodanrc@yahoo.com.br * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2513224Sodanrc@yahoo.com.br * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2613224Sodanrc@yahoo.com.br * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2713224Sodanrc@yahoo.com.br *
2813224Sodanrc@yahoo.com.br * Authors: Ali Saidi
2913224Sodanrc@yahoo.com.br *          Lisa Hsu
3013224Sodanrc@yahoo.com.br */
3113224Sodanrc@yahoo.com.br
3213224Sodanrc@yahoo.com.br#ifndef __ARCH_SPARC_INTERRUPT_HH__
3313224Sodanrc@yahoo.com.br#define __ARCH_SPARC_INTERRUPT_HH__
3413224Sodanrc@yahoo.com.br
3513224Sodanrc@yahoo.com.br#include "arch/sparc/faults.hh"
3613224Sodanrc@yahoo.com.br#include "arch/sparc/isa_traits.hh"
3713224Sodanrc@yahoo.com.br#include "cpu/thread_context.hh"
3813224Sodanrc@yahoo.com.br#include "params/SparcInterrupts.hh"
3913224Sodanrc@yahoo.com.br#include "sim/sim_object.hh"
4013224Sodanrc@yahoo.com.br
4113224Sodanrc@yahoo.com.brnamespace SparcISA
4213224Sodanrc@yahoo.com.br{
4313224Sodanrc@yahoo.com.br
4413224Sodanrc@yahoo.com.brclass Interrupts : public SimObject
4513224Sodanrc@yahoo.com.br{
4613224Sodanrc@yahoo.com.br
4713224Sodanrc@yahoo.com.br  private:
4813224Sodanrc@yahoo.com.br
4913224Sodanrc@yahoo.com.br    uint64_t interrupts[NumInterruptTypes];
5013224Sodanrc@yahoo.com.br    uint64_t intStatus;
5113224Sodanrc@yahoo.com.br
5213224Sodanrc@yahoo.com.br  public:
5313224Sodanrc@yahoo.com.br    typedef SparcInterruptsParams Params;
5413224Sodanrc@yahoo.com.br
5513224Sodanrc@yahoo.com.br    const Params *
5613224Sodanrc@yahoo.com.br    params() const
5713224Sodanrc@yahoo.com.br    {
5813224Sodanrc@yahoo.com.br        return dynamic_cast<const Params *>(_params);
5913224Sodanrc@yahoo.com.br    }
6013224Sodanrc@yahoo.com.br
6113224Sodanrc@yahoo.com.br    Interrupts(Params * p) : SimObject(p)
6213224Sodanrc@yahoo.com.br    {
6313224Sodanrc@yahoo.com.br        clear_all();
6413224Sodanrc@yahoo.com.br    }
6513224Sodanrc@yahoo.com.br
6613224Sodanrc@yahoo.com.br    int InterruptLevel(uint64_t softint)
6713224Sodanrc@yahoo.com.br    {
6813224Sodanrc@yahoo.com.br        if (softint & 0x10000 || softint & 0x1)
6913224Sodanrc@yahoo.com.br            return 14;
7013224Sodanrc@yahoo.com.br
7113224Sodanrc@yahoo.com.br        int level = 15;
7213224Sodanrc@yahoo.com.br        while (level > 0 && !(1 << level & softint))
7313224Sodanrc@yahoo.com.br            level--;
7413224Sodanrc@yahoo.com.br        if (1 << level & softint)
7513224Sodanrc@yahoo.com.br            return level;
7613224Sodanrc@yahoo.com.br        return 0;
7713224Sodanrc@yahoo.com.br    }
7813224Sodanrc@yahoo.com.br
7913224Sodanrc@yahoo.com.br    void post(int int_num, int index)
8013224Sodanrc@yahoo.com.br    {
8113224Sodanrc@yahoo.com.br        DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
8213224Sodanrc@yahoo.com.br        assert(int_num >= 0 && int_num < NumInterruptTypes);
8313224Sodanrc@yahoo.com.br        assert(index >= 0 && index < 64);
8413224Sodanrc@yahoo.com.br
8513224Sodanrc@yahoo.com.br        interrupts[int_num] |= ULL(1) << index;
8613224Sodanrc@yahoo.com.br        intStatus |= ULL(1) << int_num;
8713224Sodanrc@yahoo.com.br    }
8813224Sodanrc@yahoo.com.br
8913224Sodanrc@yahoo.com.br    void clear(int int_num, int index)
9013224Sodanrc@yahoo.com.br    {
9113224Sodanrc@yahoo.com.br        DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
9213224Sodanrc@yahoo.com.br        assert(int_num >= 0 && int_num < NumInterruptTypes);
9313224Sodanrc@yahoo.com.br        assert(index >= 0 && index < 64);
9413224Sodanrc@yahoo.com.br
9513224Sodanrc@yahoo.com.br        interrupts[int_num] &= ~(ULL(1) << index);
9613224Sodanrc@yahoo.com.br        if (!interrupts[int_num])
9713224Sodanrc@yahoo.com.br            intStatus &= ~(ULL(1) << int_num);
9813224Sodanrc@yahoo.com.br    }
9913224Sodanrc@yahoo.com.br
10013224Sodanrc@yahoo.com.br    void clear_all()
10113224Sodanrc@yahoo.com.br    {
10213224Sodanrc@yahoo.com.br        for (int i = 0; i < NumInterruptTypes; ++i) {
10313224Sodanrc@yahoo.com.br            interrupts[i] = 0;
10413224Sodanrc@yahoo.com.br        }
10513224Sodanrc@yahoo.com.br        intStatus = 0;
10613224Sodanrc@yahoo.com.br    }
10713224Sodanrc@yahoo.com.br
10813224Sodanrc@yahoo.com.br    bool check_interrupts(ThreadContext * tc) const
10913224Sodanrc@yahoo.com.br    {
11013224Sodanrc@yahoo.com.br        return intStatus;
11113224Sodanrc@yahoo.com.br    }
11213224Sodanrc@yahoo.com.br
11313224Sodanrc@yahoo.com.br    Fault getInterrupt(ThreadContext * tc)
11413224Sodanrc@yahoo.com.br    {
11513224Sodanrc@yahoo.com.br        int hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
11613224Sodanrc@yahoo.com.br        int pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
11713224Sodanrc@yahoo.com.br        bool ie = pstate & PSTATE::ie;
11813224Sodanrc@yahoo.com.br
11913224Sodanrc@yahoo.com.br        // THESE ARE IN ORDER OF PRIORITY
12013224Sodanrc@yahoo.com.br        // since there are early returns, and the highest
12113224Sodanrc@yahoo.com.br        // priority interrupts should get serviced,
12213224Sodanrc@yahoo.com.br        // it is v. important that new interrupts are inserted
12313224Sodanrc@yahoo.com.br        // in the right order of processing
12413224Sodanrc@yahoo.com.br        if (hpstate & HPSTATE::hpriv) {
12513224Sodanrc@yahoo.com.br            if (ie) {
12613224Sodanrc@yahoo.com.br                if (interrupts[IT_HINTP]) {
12713224Sodanrc@yahoo.com.br                    // This will be cleaned by a HINTP write
12813224Sodanrc@yahoo.com.br                    return new HstickMatch;
12913224Sodanrc@yahoo.com.br                }
13013224Sodanrc@yahoo.com.br                if (interrupts[IT_INT_VEC]) {
13113224Sodanrc@yahoo.com.br                    // this will be cleared by an ASI read (or write)
13213224Sodanrc@yahoo.com.br                    return new InterruptVector;
13313224Sodanrc@yahoo.com.br                }
13413224Sodanrc@yahoo.com.br            }
13513224Sodanrc@yahoo.com.br        } else {
13613224Sodanrc@yahoo.com.br            if (interrupts[IT_TRAP_LEVEL_ZERO]) {
13713224Sodanrc@yahoo.com.br                    // this is cleared by deasserting HPSTATE::tlz
13813224Sodanrc@yahoo.com.br                    return new TrapLevelZero;
13913224Sodanrc@yahoo.com.br            }
14013224Sodanrc@yahoo.com.br            // HStick matches always happen in priv mode (ie doesn't matter)
14113224Sodanrc@yahoo.com.br            if (interrupts[IT_HINTP]) {
14213224Sodanrc@yahoo.com.br                return new HstickMatch;
14313224Sodanrc@yahoo.com.br            }
14413224Sodanrc@yahoo.com.br            if (interrupts[IT_INT_VEC]) {
14513224Sodanrc@yahoo.com.br                // this will be cleared by an ASI read (or write)
14613224Sodanrc@yahoo.com.br                return new InterruptVector;
14713224Sodanrc@yahoo.com.br            }
14813224Sodanrc@yahoo.com.br            if (ie) {
14913224Sodanrc@yahoo.com.br                if (interrupts[IT_CPU_MONDO]) {
15013224Sodanrc@yahoo.com.br                    return new CpuMondo;
15113224Sodanrc@yahoo.com.br                }
15213224Sodanrc@yahoo.com.br                if (interrupts[IT_DEV_MONDO]) {
15313224Sodanrc@yahoo.com.br                    return new DevMondo;
15413224Sodanrc@yahoo.com.br                }
15513224Sodanrc@yahoo.com.br                if (interrupts[IT_SOFT_INT]) {
15613224Sodanrc@yahoo.com.br                    return new
15713224Sodanrc@yahoo.com.br                        InterruptLevelN(InterruptLevel(interrupts[IT_SOFT_INT]));
15813224Sodanrc@yahoo.com.br                }
15913224Sodanrc@yahoo.com.br
16013224Sodanrc@yahoo.com.br                if (interrupts[IT_RES_ERROR]) {
16113224Sodanrc@yahoo.com.br                    return new ResumableError;
16213224Sodanrc@yahoo.com.br                }
16313224Sodanrc@yahoo.com.br            } // !hpriv && ie
16413224Sodanrc@yahoo.com.br        }  // !hpriv
16513224Sodanrc@yahoo.com.br        return NoFault;
16613224Sodanrc@yahoo.com.br    }
16713224Sodanrc@yahoo.com.br
16813224Sodanrc@yahoo.com.br    void updateIntrInfo(ThreadContext * tc)
16913224Sodanrc@yahoo.com.br    {
17013224Sodanrc@yahoo.com.br
17113224Sodanrc@yahoo.com.br    }
17213224Sodanrc@yahoo.com.br
17313224Sodanrc@yahoo.com.br    uint64_t get_vec(int int_num)
17413224Sodanrc@yahoo.com.br    {
17513224Sodanrc@yahoo.com.br        assert(int_num >= 0 && int_num < NumInterruptTypes);
17613224Sodanrc@yahoo.com.br        return interrupts[int_num];
17713224Sodanrc@yahoo.com.br    }
17813224Sodanrc@yahoo.com.br
179    void serialize(std::ostream &os)
180    {
181        SERIALIZE_ARRAY(interrupts,NumInterruptTypes);
182        SERIALIZE_SCALAR(intStatus);
183    }
184
185    void unserialize(Checkpoint *cp, const std::string &section)
186    {
187        UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes);
188        UNSERIALIZE_SCALAR(intStatus);
189    }
190};
191} // namespace SPARC_ISA
192
193#endif // __ARCH_SPARC_INTERRUPT_HH__
194