interrupts.hh revision 5810
112810Sandreas.sandberg@arm.com/*
212810Sandreas.sandberg@arm.com * Copyright (c) 2006 The Regents of The University of Michigan
312810Sandreas.sandberg@arm.com * All rights reserved.
412810Sandreas.sandberg@arm.com *
512810Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
612810Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
712810Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
812810Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
912810Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
1012810Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
1112810Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
1212810Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
1312810Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from
1412810Sandreas.sandberg@arm.com * this software without specific prior written permission.
1512810Sandreas.sandberg@arm.com *
1612810Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712810Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812810Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912810Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012810Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112810Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212810Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312810Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412810Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512810Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612810Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712810Sandreas.sandberg@arm.com *
2812810Sandreas.sandberg@arm.com * Authors: Ali Saidi
2912810Sandreas.sandberg@arm.com *          Lisa Hsu
3012810Sandreas.sandberg@arm.com */
3112810Sandreas.sandberg@arm.com
3212810Sandreas.sandberg@arm.com#ifndef __ARCH_SPARC_INTERRUPT_HH__
3312810Sandreas.sandberg@arm.com#define __ARCH_SPARC_INTERRUPT_HH__
3412810Sandreas.sandberg@arm.com
3512810Sandreas.sandberg@arm.com#include "arch/sparc/faults.hh"
3612810Sandreas.sandberg@arm.com#include "arch/sparc/isa_traits.hh"
3712810Sandreas.sandberg@arm.com#include "cpu/thread_context.hh"
3812810Sandreas.sandberg@arm.com#include "params/SparcInterrupts.hh"
3912810Sandreas.sandberg@arm.com#include "sim/sim_object.hh"
4012810Sandreas.sandberg@arm.com
4112810Sandreas.sandberg@arm.comnamespace SparcISA
4212810Sandreas.sandberg@arm.com{
4312810Sandreas.sandberg@arm.com
4412810Sandreas.sandberg@arm.comclass Interrupts : public SimObject
4512810Sandreas.sandberg@arm.com{
4612810Sandreas.sandberg@arm.com  private:
4712810Sandreas.sandberg@arm.com    BaseCPU * cpu;
4812810Sandreas.sandberg@arm.com
4912810Sandreas.sandberg@arm.com    uint64_t interrupts[NumInterruptTypes];
5012810Sandreas.sandberg@arm.com    uint64_t intStatus;
5112810Sandreas.sandberg@arm.com
5212810Sandreas.sandberg@arm.com  public:
5312919Sgiacomo.travaglini@arm.com
5412810Sandreas.sandberg@arm.com    void
5512810Sandreas.sandberg@arm.com    setCPU(BaseCPU * _cpu)
5612810Sandreas.sandberg@arm.com    {
5712810Sandreas.sandberg@arm.com        cpu = _cpu;
5812810Sandreas.sandberg@arm.com    }
5912810Sandreas.sandberg@arm.com
6012810Sandreas.sandberg@arm.com    typedef SparcInterruptsParams Params;
6112810Sandreas.sandberg@arm.com
6212810Sandreas.sandberg@arm.com    const Params *
6312810Sandreas.sandberg@arm.com    params() const
6412810Sandreas.sandberg@arm.com    {
6512810Sandreas.sandberg@arm.com        return dynamic_cast<const Params *>(_params);
6612810Sandreas.sandberg@arm.com    }
6712810Sandreas.sandberg@arm.com
6812811Sandreas.sandberg@arm.com    Interrupts(Params * p) : SimObject(p), cpu(NULL)
6912811Sandreas.sandberg@arm.com    {
7012810Sandreas.sandberg@arm.com        clearAll();
7112810Sandreas.sandberg@arm.com    }
7212810Sandreas.sandberg@arm.com
7312810Sandreas.sandberg@arm.com    int
7412810Sandreas.sandberg@arm.com    InterruptLevel(uint64_t softint)
7512810Sandreas.sandberg@arm.com    {
7612810Sandreas.sandberg@arm.com        if (softint & 0x10000 || softint & 0x1)
7712810Sandreas.sandberg@arm.com            return 14;
7812810Sandreas.sandberg@arm.com
7912810Sandreas.sandberg@arm.com        int level = 15;
8012810Sandreas.sandberg@arm.com        while (level > 0 && !(1 << level & softint))
8112810Sandreas.sandberg@arm.com            level--;
8212810Sandreas.sandberg@arm.com        if (1 << level & softint)
8312810Sandreas.sandberg@arm.com            return level;
8412810Sandreas.sandberg@arm.com        return 0;
8512810Sandreas.sandberg@arm.com    }
8612810Sandreas.sandberg@arm.com
8712810Sandreas.sandberg@arm.com    void
8812810Sandreas.sandberg@arm.com    post(int int_num, int index)
8912810Sandreas.sandberg@arm.com    {
9012810Sandreas.sandberg@arm.com        DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
9112810Sandreas.sandberg@arm.com        assert(int_num >= 0 && int_num < NumInterruptTypes);
9212810Sandreas.sandberg@arm.com        assert(index >= 0 && index < 64);
9312810Sandreas.sandberg@arm.com
9412810Sandreas.sandberg@arm.com        interrupts[int_num] |= ULL(1) << index;
9512810Sandreas.sandberg@arm.com        intStatus |= ULL(1) << int_num;
9612810Sandreas.sandberg@arm.com    }
9712810Sandreas.sandberg@arm.com
9812810Sandreas.sandberg@arm.com    void
9912810Sandreas.sandberg@arm.com    clear(int int_num, int index)
10012810Sandreas.sandberg@arm.com    {
10112810Sandreas.sandberg@arm.com        DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
10212810Sandreas.sandberg@arm.com        assert(int_num >= 0 && int_num < NumInterruptTypes);
10312810Sandreas.sandberg@arm.com        assert(index >= 0 && index < 64);
10412810Sandreas.sandberg@arm.com
10512810Sandreas.sandberg@arm.com        interrupts[int_num] &= ~(ULL(1) << index);
10612810Sandreas.sandberg@arm.com        if (!interrupts[int_num])
10712810Sandreas.sandberg@arm.com            intStatus &= ~(ULL(1) << int_num);
10812810Sandreas.sandberg@arm.com    }
10912810Sandreas.sandberg@arm.com
11012810Sandreas.sandberg@arm.com    void
11112810Sandreas.sandberg@arm.com    clearAll()
11212810Sandreas.sandberg@arm.com    {
11312810Sandreas.sandberg@arm.com        for (int i = 0; i < NumInterruptTypes; ++i) {
11412810Sandreas.sandberg@arm.com            interrupts[i] = 0;
11512810Sandreas.sandberg@arm.com        }
11612810Sandreas.sandberg@arm.com        intStatus = 0;
11712810Sandreas.sandberg@arm.com    }
11812810Sandreas.sandberg@arm.com
11912810Sandreas.sandberg@arm.com    bool
12012810Sandreas.sandberg@arm.com    checkInterrupts(ThreadContext *tc) const
12112810Sandreas.sandberg@arm.com    {
12212810Sandreas.sandberg@arm.com        return intStatus;
12312810Sandreas.sandberg@arm.com    }
12412810Sandreas.sandberg@arm.com
12512810Sandreas.sandberg@arm.com    Fault
12612810Sandreas.sandberg@arm.com    getInterrupt(ThreadContext *tc)
12712810Sandreas.sandberg@arm.com    {
12812810Sandreas.sandberg@arm.com        int hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
12912810Sandreas.sandberg@arm.com        int pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
13012810Sandreas.sandberg@arm.com        bool ie = pstate & PSTATE::ie;
13112810Sandreas.sandberg@arm.com
13212810Sandreas.sandberg@arm.com        // THESE ARE IN ORDER OF PRIORITY
13312810Sandreas.sandberg@arm.com        // since there are early returns, and the highest
13412810Sandreas.sandberg@arm.com        // priority interrupts should get serviced,
13512810Sandreas.sandberg@arm.com        // it is v. important that new interrupts are inserted
13612810Sandreas.sandberg@arm.com        // in the right order of processing
13712810Sandreas.sandberg@arm.com        if (hpstate & HPSTATE::hpriv) {
13812810Sandreas.sandberg@arm.com            if (ie) {
13912810Sandreas.sandberg@arm.com                if (interrupts[IT_HINTP]) {
14012810Sandreas.sandberg@arm.com                    // This will be cleaned by a HINTP write
14112810Sandreas.sandberg@arm.com                    return new HstickMatch;
14212810Sandreas.sandberg@arm.com                }
14312810Sandreas.sandberg@arm.com                if (interrupts[IT_INT_VEC]) {
14412810Sandreas.sandberg@arm.com                    // this will be cleared by an ASI read (or write)
14512810Sandreas.sandberg@arm.com                    return new InterruptVector;
14612810Sandreas.sandberg@arm.com                }
14712810Sandreas.sandberg@arm.com            }
14812810Sandreas.sandberg@arm.com        } else {
14912810Sandreas.sandberg@arm.com            if (interrupts[IT_TRAP_LEVEL_ZERO]) {
15012810Sandreas.sandberg@arm.com                    // this is cleared by deasserting HPSTATE::tlz
15112810Sandreas.sandberg@arm.com                    return new TrapLevelZero;
15212810Sandreas.sandberg@arm.com            }
15312810Sandreas.sandberg@arm.com            // HStick matches always happen in priv mode (ie doesn't matter)
15412810Sandreas.sandberg@arm.com            if (interrupts[IT_HINTP]) {
15512810Sandreas.sandberg@arm.com                return new HstickMatch;
15612810Sandreas.sandberg@arm.com            }
15712810Sandreas.sandberg@arm.com            if (interrupts[IT_INT_VEC]) {
15812810Sandreas.sandberg@arm.com                // this will be cleared by an ASI read (or write)
15912810Sandreas.sandberg@arm.com                return new InterruptVector;
16012810Sandreas.sandberg@arm.com            }
16112810Sandreas.sandberg@arm.com            if (ie) {
16212810Sandreas.sandberg@arm.com                if (interrupts[IT_CPU_MONDO]) {
16312810Sandreas.sandberg@arm.com                    return new CpuMondo;
16412810Sandreas.sandberg@arm.com                }
16512810Sandreas.sandberg@arm.com                if (interrupts[IT_DEV_MONDO]) {
16612810Sandreas.sandberg@arm.com                    return new DevMondo;
16712918SMichiel.VanTol@arm.com                }
16812918SMichiel.VanTol@arm.com                if (interrupts[IT_SOFT_INT]) {
16912810Sandreas.sandberg@arm.com                    int level = InterruptLevel(interrupts[IT_SOFT_INT]);
17012810Sandreas.sandberg@arm.com                    return new InterruptLevelN(level);
17112810Sandreas.sandberg@arm.com                }
17212810Sandreas.sandberg@arm.com
17312810Sandreas.sandberg@arm.com                if (interrupts[IT_RES_ERROR]) {
17412810Sandreas.sandberg@arm.com                    return new ResumableError;
17512810Sandreas.sandberg@arm.com                }
17612810Sandreas.sandberg@arm.com            } // !hpriv && ie
17712810Sandreas.sandberg@arm.com        }  // !hpriv
17812810Sandreas.sandberg@arm.com        return NoFault;
17912810Sandreas.sandberg@arm.com    }
18012810Sandreas.sandberg@arm.com
18112810Sandreas.sandberg@arm.com    void
18212810Sandreas.sandberg@arm.com    updateIntrInfo(ThreadContext *tc)
18312919Sgiacomo.travaglini@arm.com    {
18412810Sandreas.sandberg@arm.com
18512810Sandreas.sandberg@arm.com    }
18612810Sandreas.sandberg@arm.com
18712810Sandreas.sandberg@arm.com    uint64_t
18812810Sandreas.sandberg@arm.com    get_vec(int int_num)
18912810Sandreas.sandberg@arm.com    {
19012810Sandreas.sandberg@arm.com        assert(int_num >= 0 && int_num < NumInterruptTypes);
19112810Sandreas.sandberg@arm.com        return interrupts[int_num];
19212810Sandreas.sandberg@arm.com    }
19312810Sandreas.sandberg@arm.com
19412810Sandreas.sandberg@arm.com    void
19512810Sandreas.sandberg@arm.com    serialize(std::ostream &os)
19612810Sandreas.sandberg@arm.com    {
19712810Sandreas.sandberg@arm.com        SERIALIZE_ARRAY(interrupts,NumInterruptTypes);
19812811Sandreas.sandberg@arm.com        SERIALIZE_SCALAR(intStatus);
19912811Sandreas.sandberg@arm.com    }
20012811Sandreas.sandberg@arm.com
20112811Sandreas.sandberg@arm.com    void
20212811Sandreas.sandberg@arm.com    unserialize(Checkpoint *cp, const std::string &section)
20312811Sandreas.sandberg@arm.com    {
20412811Sandreas.sandberg@arm.com        UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes);
20512811Sandreas.sandberg@arm.com        UNSERIALIZE_SCALAR(intStatus);
20612811Sandreas.sandberg@arm.com    }
20712811Sandreas.sandberg@arm.com};
20812811Sandreas.sandberg@arm.com} // namespace SPARC_ISA
20912811Sandreas.sandberg@arm.com
21012811Sandreas.sandberg@arm.com#endif // __ARCH_SPARC_INTERRUPT_HH__
21112811Sandreas.sandberg@arm.com