interrupts.hh revision 8232
113559Snikos.nikoleris@arm.com/*
212109SRekai.GonzalezAlberquilla@arm.com * Copyright (c) 2006 The Regents of The University of Michigan
312109SRekai.GonzalezAlberquilla@arm.com * All rights reserved.
412109SRekai.GonzalezAlberquilla@arm.com *
512109SRekai.GonzalezAlberquilla@arm.com * Redistribution and use in source and binary forms, with or without
612109SRekai.GonzalezAlberquilla@arm.com * modification, are permitted provided that the following conditions are
712109SRekai.GonzalezAlberquilla@arm.com * met: redistributions of source code must retain the above copyright
812109SRekai.GonzalezAlberquilla@arm.com * notice, this list of conditions and the following disclaimer;
912109SRekai.GonzalezAlberquilla@arm.com * redistributions in binary form must reproduce the above copyright
1012109SRekai.GonzalezAlberquilla@arm.com * notice, this list of conditions and the following disclaimer in the
1112109SRekai.GonzalezAlberquilla@arm.com * documentation and/or other materials provided with the distribution;
1212109SRekai.GonzalezAlberquilla@arm.com * neither the name of the copyright holders nor the names of its
134486Sbinkertn@umich.edu * contributors may be used to endorse or promote products derived from
144486Sbinkertn@umich.edu * this software without specific prior written permission.
154486Sbinkertn@umich.edu *
164486Sbinkertn@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
174486Sbinkertn@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
184486Sbinkertn@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
194486Sbinkertn@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
204486Sbinkertn@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
214486Sbinkertn@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
224486Sbinkertn@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
234486Sbinkertn@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
244486Sbinkertn@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
254486Sbinkertn@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
264486Sbinkertn@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
274486Sbinkertn@umich.edu *
284486Sbinkertn@umich.edu * Authors: Ali Saidi
294486Sbinkertn@umich.edu *          Lisa Hsu
304486Sbinkertn@umich.edu */
314486Sbinkertn@umich.edu
324486Sbinkertn@umich.edu#ifndef __ARCH_SPARC_INTERRUPT_HH__
334486Sbinkertn@umich.edu#define __ARCH_SPARC_INTERRUPT_HH__
344486Sbinkertn@umich.edu
354486Sbinkertn@umich.edu#include "arch/sparc/faults.hh"
364486Sbinkertn@umich.edu#include "arch/sparc/isa_traits.hh"
374486Sbinkertn@umich.edu#include "arch/sparc/registers.hh"
384486Sbinkertn@umich.edu#include "cpu/thread_context.hh"
394486Sbinkertn@umich.edu#include "debug/Interrupt.hh"
404486Sbinkertn@umich.edu#include "params/SparcInterrupts.hh"
4112563Sgabeblack@google.com#include "sim/sim_object.hh"
4212563Sgabeblack@google.com
436654Snate@binkert.orgnamespace SparcISA
443102SN/A{
453102SN/A
461681SN/Aclass Interrupts : public SimObject
473223SN/A{
488887Sgeoffrey.blake@arm.com  private:
4910785Sgope@wisc.edu    BaseCPU * cpu;
504486Sbinkertn@umich.edu
5113559Snikos.nikoleris@arm.com    uint64_t interrupts[NumInterruptTypes];
5213559Snikos.nikoleris@arm.com    uint64_t intStatus;
5313559Snikos.nikoleris@arm.com
542817SN/A  public:
552817SN/A
569341SAndreas.Sandberg@arm.com    void
579341SAndreas.Sandberg@arm.com    setCPU(BaseCPU * _cpu)
589518SAndreas.Sandberg@ARM.com    {
599518SAndreas.Sandberg@ARM.com        cpu = _cpu;
609518SAndreas.Sandberg@ARM.com    }
619518SAndreas.Sandberg@ARM.com
629518SAndreas.Sandberg@ARM.com    typedef SparcInterruptsParams Params;
639518SAndreas.Sandberg@ARM.com
649518SAndreas.Sandberg@ARM.com    const Params *
659518SAndreas.Sandberg@ARM.com    params() const
669518SAndreas.Sandberg@ARM.com    {
679518SAndreas.Sandberg@ARM.com        return dynamic_cast<const Params *>(_params);
689518SAndreas.Sandberg@ARM.com    }
699518SAndreas.Sandberg@ARM.com
702932SN/A    Interrupts(Params * p) : SimObject(p), cpu(NULL)
711681SN/A    {
7211780Sarthur.perais@inria.fr        clearAll();
7311780Sarthur.perais@inria.fr    }
741681SN/A
759184Sandreas.hansson@arm.com    int
769184Sandreas.hansson@arm.com    InterruptLevel(uint64_t softint)
779184Sandreas.hansson@arm.com    {
789184Sandreas.hansson@arm.com        if (softint & 0x10000 || softint & 0x1)
799184Sandreas.hansson@arm.com            return 14;
802932SN/A
819982Satgutier@umich.edu        int level = 15;
8210331Smitch.hayenga@arm.com        while (level > 0 && !(1 << level & softint))
8310331Smitch.hayenga@arm.com            level--;
842932SN/A        if (1 << level & softint)
859184Sandreas.hansson@arm.com            return level;
869184Sandreas.hansson@arm.com        return 0;
879184Sandreas.hansson@arm.com    }
889184Sandreas.hansson@arm.com
899184Sandreas.hansson@arm.com    void
902932SN/A    post(int int_num, int index)
911681SN/A    {
929184Sandreas.hansson@arm.com        DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
939184Sandreas.hansson@arm.com        assert(int_num >= 0 && int_num < NumInterruptTypes);
949184Sandreas.hansson@arm.com        assert(index >= 0 && index < 64);
959184Sandreas.hansson@arm.com
962932SN/A        interrupts[int_num] |= ULL(1) << index;
971681SN/A        intStatus |= ULL(1) << int_num;
989184Sandreas.hansson@arm.com    }
992932SN/A
1009184Sandreas.hansson@arm.com    void
1012932SN/A    clear(int int_num, int index)
1029184Sandreas.hansson@arm.com    {
1032932SN/A        DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
1042932SN/A        assert(int_num >= 0 && int_num < NumInterruptTypes);
1052932SN/A        assert(index >= 0 && index < 64);
1062932SN/A
1073223SN/A        interrupts[int_num] &= ~(ULL(1) << index);
1082932SN/A        if (!interrupts[int_num])
1099184Sandreas.hansson@arm.com            intStatus &= ~(ULL(1) << int_num);
1101681SN/A    }
1119184Sandreas.hansson@arm.com
1122932SN/A    void
1132932SN/A    clearAll()
1149184Sandreas.hansson@arm.com    {
1159184Sandreas.hansson@arm.com        for (int i = 0; i < NumInterruptTypes; ++i) {
1161681SN/A            interrupts[i] = 0;
1172932SN/A        }
1182932SN/A        intStatus = 0;
1191681SN/A    }
1202932SN/A
1212932SN/A    bool
1228199SAli.Saidi@ARM.com    checkInterrupts(ThreadContext *tc) const
1238199SAli.Saidi@ARM.com    {
1248199SAli.Saidi@ARM.com        return intStatus;
1258519SAli.Saidi@ARM.com    }
1268519SAli.Saidi@ARM.com
1272932SN/A    Fault
1282932SN/A    getInterrupt(ThreadContext *tc)
1291681SN/A    {
1302932SN/A        int hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
1311681SN/A        int pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
1322932SN/A        bool ie = pstate & PSTATE::ie;
1332932SN/A
1342932SN/A        // THESE ARE IN ORDER OF PRIORITY
1359921Syasuko.eckert@amd.com        // since there are early returns, and the highest
1369921Syasuko.eckert@amd.com        // priority interrupts should get serviced,
13710338SCurtis.Dunham@arm.com        // it is v. important that new interrupts are inserted
1389921Syasuko.eckert@amd.com        // in the right order of processing
1399921Syasuko.eckert@amd.com        if (hpstate & HPSTATE::hpriv) {
1409921Syasuko.eckert@amd.com            if (ie) {
1419921Syasuko.eckert@amd.com                if (interrupts[IT_HINTP]) {
1429921Syasuko.eckert@amd.com                    // This will be cleaned by a HINTP write
1439921Syasuko.eckert@amd.com                    return new HstickMatch;
1449921Syasuko.eckert@amd.com                }
14512109SRekai.GonzalezAlberquilla@arm.com                if (interrupts[IT_INT_VEC]) {
14612109SRekai.GonzalezAlberquilla@arm.com                    // this will be cleared by an ASI read (or write)
1479921Syasuko.eckert@amd.com                    return new InterruptVector;
1489921Syasuko.eckert@amd.com                }
1492932SN/A            }
1502932SN/A        } else {
1511681SN/A            if (interrupts[IT_TRAP_LEVEL_ZERO]) {
1524597Sbinkertn@umich.edu                    // this is cleared by deasserting HPSTATE::tlz
15313559Snikos.nikoleris@arm.com                    return new TrapLevelZero;
1544597Sbinkertn@umich.edu            }
1554597Sbinkertn@umich.edu            // HStick matches always happen in priv mode (ie doesn't matter)
1564597Sbinkertn@umich.edu            if (interrupts[IT_HINTP]) {
1574597Sbinkertn@umich.edu                return new HstickMatch;
1584597Sbinkertn@umich.edu            }
1594597Sbinkertn@umich.edu            if (interrupts[IT_INT_VEC]) {
1604597Sbinkertn@umich.edu                // this will be cleared by an ASI read (or write)
1614303SN/A                return new InterruptVector;
16210785Sgope@wisc.edu            }
1639849Sandreas.hansson@arm.com            if (ie) {
1649849Sandreas.hansson@arm.com                if (interrupts[IT_CPU_MONDO]) {
1658727Snilay@cs.wisc.edu                    return new CpuMondo;
1668727Snilay@cs.wisc.edu                }
1678887Sgeoffrey.blake@arm.com                if (interrupts[IT_DEV_MONDO]) {
1688887Sgeoffrey.blake@arm.com                    return new DevMondo;
1698887Sgeoffrey.blake@arm.com                }
1708887Sgeoffrey.blake@arm.com                if (interrupts[IT_SOFT_INT]) {
1718887Sgeoffrey.blake@arm.com                    int level = InterruptLevel(interrupts[IT_SOFT_INT]);
1728887Sgeoffrey.blake@arm.com                    return new InterruptLevelN(level);
1738887Sgeoffrey.blake@arm.com                }
1748887Sgeoffrey.blake@arm.com
1758887Sgeoffrey.blake@arm.com                if (interrupts[IT_RES_ERROR]) {
1768887Sgeoffrey.blake@arm.com                    return new ResumableError;
1778887Sgeoffrey.blake@arm.com                }
1789132Satgutier@umich.edu            } // !hpriv && ie
1798887Sgeoffrey.blake@arm.com        }  // !hpriv
1808887Sgeoffrey.blake@arm.com        return NoFault;
18112563Sgabeblack@google.com    }
1828887Sgeoffrey.blake@arm.com
183    void
184    updateIntrInfo(ThreadContext *tc)
185    {}
186
187    uint64_t
188    get_vec(int int_num)
189    {
190        assert(int_num >= 0 && int_num < NumInterruptTypes);
191        return interrupts[int_num];
192    }
193
194    void
195    serialize(std::ostream &os)
196    {
197        SERIALIZE_ARRAY(interrupts,NumInterruptTypes);
198        SERIALIZE_SCALAR(intStatus);
199    }
200
201    void
202    unserialize(Checkpoint *cp, const std::string &section)
203    {
204        UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes);
205        UNSERIALIZE_SCALAR(intStatus);
206    }
207};
208} // namespace SPARC_ISA
209
210#endif // __ARCH_SPARC_INTERRUPT_HH__
211