interrupts.hh revision 4009
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.
273537Sgblack@eecs.umich.edu */
283537Sgblack@eecs.umich.edu
293537Sgblack@eecs.umich.edu#ifndef __ARCH_SPARC_INTERRUPT_HH__
303537Sgblack@eecs.umich.edu#define __ARCH_SPARC_INTERRUPT_HH__
313537Sgblack@eecs.umich.edu
323537Sgblack@eecs.umich.edu#include "arch/sparc/faults.hh"
333827Shsul@eecs.umich.edu#include "cpu/thread_context.hh"
343827Shsul@eecs.umich.edu
353537Sgblack@eecs.umich.edunamespace SparcISA
363537Sgblack@eecs.umich.edu{
373894Shsul@eecs.umich.edu
383894Shsul@eecs.umich.eduenum interrupts_t {
393894Shsul@eecs.umich.edu    trap_level_zero,
403894Shsul@eecs.umich.edu    hstick_match,
413894Shsul@eecs.umich.edu    interrupt_vector,
423894Shsul@eecs.umich.edu    cpu_mondo,
433894Shsul@eecs.umich.edu    dev_mondo,
443894Shsul@eecs.umich.edu    resumable_error,
453894Shsul@eecs.umich.edu    soft_interrupt,
463894Shsul@eecs.umich.edu    num_interrupt_types
473894Shsul@eecs.umich.edu};
483894Shsul@eecs.umich.edu
494009Ssaidi@eecs.umich.educlass Interrupts
504009Ssaidi@eecs.umich.edu{
514009Ssaidi@eecs.umich.edu
524009Ssaidi@eecs.umich.edu  private:
534009Ssaidi@eecs.umich.edu
544009Ssaidi@eecs.umich.edu    bool interrupts[num_interrupt_types];
554009Ssaidi@eecs.umich.edu    int numPosted;
564009Ssaidi@eecs.umich.edu
574009Ssaidi@eecs.umich.edu  public:
584009Ssaidi@eecs.umich.edu    Interrupts()
594009Ssaidi@eecs.umich.edu    {
604009Ssaidi@eecs.umich.edu        for (int i = 0; i < num_interrupt_types; ++i) {
614009Ssaidi@eecs.umich.edu            interrupts[i] = false;
624009Ssaidi@eecs.umich.edu        }
634009Ssaidi@eecs.umich.edu        numPosted = 0;
644009Ssaidi@eecs.umich.edu    }
654009Ssaidi@eecs.umich.edu
664009Ssaidi@eecs.umich.edu    void post(int int_type)
674009Ssaidi@eecs.umich.edu    {
684009Ssaidi@eecs.umich.edu        if (int_type < 0 || int_type >= num_interrupt_types)
694009Ssaidi@eecs.umich.edu            panic("posting unknown interrupt!\n");
704009Ssaidi@eecs.umich.edu        interrupts[int_type] = true;
714009Ssaidi@eecs.umich.edu        ++numPosted;
724009Ssaidi@eecs.umich.edu    }
734009Ssaidi@eecs.umich.edu
744009Ssaidi@eecs.umich.edu    void post(int int_num, int index)
753537Sgblack@eecs.umich.edu    {
763827Shsul@eecs.umich.edu
774009Ssaidi@eecs.umich.edu    }
783894Shsul@eecs.umich.edu
794009Ssaidi@eecs.umich.edu    void clear(int int_num, int index)
804009Ssaidi@eecs.umich.edu    {
813537Sgblack@eecs.umich.edu
824009Ssaidi@eecs.umich.edu    }
833827Shsul@eecs.umich.edu
844009Ssaidi@eecs.umich.edu    void clear_all()
854009Ssaidi@eecs.umich.edu    {
863894Shsul@eecs.umich.edu
874009Ssaidi@eecs.umich.edu    }
883537Sgblack@eecs.umich.edu
894009Ssaidi@eecs.umich.edu    bool check_interrupts(ThreadContext * tc) const
904009Ssaidi@eecs.umich.edu    {
914009Ssaidi@eecs.umich.edu        if (numPosted)
924009Ssaidi@eecs.umich.edu            return true;
934009Ssaidi@eecs.umich.edu        else
944009Ssaidi@eecs.umich.edu            return false;
954009Ssaidi@eecs.umich.edu    }
963537Sgblack@eecs.umich.edu
974009Ssaidi@eecs.umich.edu    Fault getInterrupt(ThreadContext * tc)
984009Ssaidi@eecs.umich.edu    {
994009Ssaidi@eecs.umich.edu        int hpstate = tc->readMiscReg(MISCREG_HPSTATE);
1004009Ssaidi@eecs.umich.edu        int pstate = tc->readMiscReg(MISCREG_PSTATE);
1014009Ssaidi@eecs.umich.edu        bool ie = pstate & PSTATE::ie;
1023827Shsul@eecs.umich.edu
1034009Ssaidi@eecs.umich.edu        // THESE ARE IN ORDER OF PRIORITY
1044009Ssaidi@eecs.umich.edu        // since there are early returns, and the highest
1054009Ssaidi@eecs.umich.edu        // priority interrupts should get serviced,
1064009Ssaidi@eecs.umich.edu        // it is v. important that new interrupts are inserted
1074009Ssaidi@eecs.umich.edu        // in the right order of processing
1084009Ssaidi@eecs.umich.edu        if (hpstate & HPSTATE::hpriv) {
1094009Ssaidi@eecs.umich.edu            if (ie) {
1103894Shsul@eecs.umich.edu                if (interrupts[hstick_match]) {
1113921Shsul@eecs.umich.edu                    if (tc->readMiscReg(MISCREG_HINTP) & 1) {
1123921Shsul@eecs.umich.edu                        interrupts[hstick_match] = false;
1133921Shsul@eecs.umich.edu                        --numPosted;
1143921Shsul@eecs.umich.edu                        return new HstickMatch;
1154009Ssaidi@eecs.umich.edu                    }
1163894Shsul@eecs.umich.edu                }
1174009Ssaidi@eecs.umich.edu                if (interrupts[interrupt_vector]) {
1184009Ssaidi@eecs.umich.edu                    interrupts[interrupt_vector] = false;
1194009Ssaidi@eecs.umich.edu                    --numPosted;
1204009Ssaidi@eecs.umich.edu                    //HAVEN'T IMPLed THIS YET
1214009Ssaidi@eecs.umich.edu                    return NoFault;
1224009Ssaidi@eecs.umich.edu                }
1234009Ssaidi@eecs.umich.edu            } else {
1244009Ssaidi@eecs.umich.edu                if (interrupts[hstick_match]) {
1254009Ssaidi@eecs.umich.edu                    return NoFault;
1264009Ssaidi@eecs.umich.edu                }
1274009Ssaidi@eecs.umich.edu
1284009Ssaidi@eecs.umich.edu            }
1294009Ssaidi@eecs.umich.edu        } else {
1304009Ssaidi@eecs.umich.edu            if (interrupts[trap_level_zero]) {
1314009Ssaidi@eecs.umich.edu                if ((pstate & HPSTATE::tlz) && (tc->readMiscReg(MISCREG_TL) == 0)) {
1324009Ssaidi@eecs.umich.edu                    interrupts[trap_level_zero] = false;
1334009Ssaidi@eecs.umich.edu                    --numPosted;
1344009Ssaidi@eecs.umich.edu                    return new TrapLevelZero;
1354009Ssaidi@eecs.umich.edu                }
1364009Ssaidi@eecs.umich.edu            }
1374009Ssaidi@eecs.umich.edu            if (interrupts[hstick_match]) {
1384009Ssaidi@eecs.umich.edu                if (tc->readMiscReg(MISCREG_HINTP) & 1) {
1394009Ssaidi@eecs.umich.edu                    interrupts[hstick_match] = false;
1404009Ssaidi@eecs.umich.edu                    --numPosted;
1414009Ssaidi@eecs.umich.edu                    return new HstickMatch;
1423894Shsul@eecs.umich.edu                    }
1434009Ssaidi@eecs.umich.edu            }
1444009Ssaidi@eecs.umich.edu            if (ie) {
1454009Ssaidi@eecs.umich.edu                if (interrupts[cpu_mondo]) {
1464009Ssaidi@eecs.umich.edu                    interrupts[cpu_mondo] = false;
1474009Ssaidi@eecs.umich.edu                    --numPosted;
1484009Ssaidi@eecs.umich.edu                    return new CpuMondo;
1494009Ssaidi@eecs.umich.edu                }
1504009Ssaidi@eecs.umich.edu                if (interrupts[dev_mondo]) {
1514009Ssaidi@eecs.umich.edu                    interrupts[dev_mondo] = false;
1524009Ssaidi@eecs.umich.edu                    --numPosted;
1534009Ssaidi@eecs.umich.edu                    return new DevMondo;
1544009Ssaidi@eecs.umich.edu                }
1554009Ssaidi@eecs.umich.edu                if (interrupts[soft_interrupt]) {
1564009Ssaidi@eecs.umich.edu                    int il = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT));
1574009Ssaidi@eecs.umich.edu                    // it seems that interrupt vectors are right in
1584009Ssaidi@eecs.umich.edu                    // the middle of interrupt levels with regard to
1594009Ssaidi@eecs.umich.edu                    // priority, so have to check
1604009Ssaidi@eecs.umich.edu                    if ((il < 6) &&
1614009Ssaidi@eecs.umich.edu                        interrupts[interrupt_vector]) {
1624009Ssaidi@eecs.umich.edu                            // may require more details here since there
1634009Ssaidi@eecs.umich.edu                            // may be lots of interrupts embedded in an
1644009Ssaidi@eecs.umich.edu                            // platform interrupt vector
1654009Ssaidi@eecs.umich.edu                            interrupts[interrupt_vector] = false;
1664009Ssaidi@eecs.umich.edu                            --numPosted;
1674009Ssaidi@eecs.umich.edu                            //HAVEN'T IMPLed YET
1684009Ssaidi@eecs.umich.edu                            return NoFault;
1694009Ssaidi@eecs.umich.edu                    } else {
1704009Ssaidi@eecs.umich.edu                        if (il > tc->readMiscReg(MISCREG_PIL)) {
1714009Ssaidi@eecs.umich.edu                            uint64_t si = tc->readMiscReg(MISCREG_SOFTINT);
1724009Ssaidi@eecs.umich.edu                            uint64_t more = si & ~(1 << (il + 1));
1734009Ssaidi@eecs.umich.edu                            if (!InterruptLevel(more)) {
1744009Ssaidi@eecs.umich.edu                                interrupts[soft_interrupt] = false;
1753894Shsul@eecs.umich.edu                                --numPosted;
1763894Shsul@eecs.umich.edu                            }
1774009Ssaidi@eecs.umich.edu                            return new InterruptLevelN(il);
1783894Shsul@eecs.umich.edu                        }
1793894Shsul@eecs.umich.edu                    }
1804009Ssaidi@eecs.umich.edu                }
1814009Ssaidi@eecs.umich.edu                if (interrupts[resumable_error]) {
1824009Ssaidi@eecs.umich.edu                    interrupts[resumable_error] = false;
1834009Ssaidi@eecs.umich.edu                    --numPosted;
1844009Ssaidi@eecs.umich.edu                    return new ResumableError;
1853894Shsul@eecs.umich.edu                }
1863894Shsul@eecs.umich.edu            }
1873537Sgblack@eecs.umich.edu        }
1884009Ssaidi@eecs.umich.edu        return NoFault;
1894009Ssaidi@eecs.umich.edu    }
1903537Sgblack@eecs.umich.edu
1914009Ssaidi@eecs.umich.edu    void updateIntrInfo(ThreadContext * tc)
1924009Ssaidi@eecs.umich.edu    {
1933654Shsul@eecs.umich.edu
1944009Ssaidi@eecs.umich.edu    }
1953654Shsul@eecs.umich.edu
1964009Ssaidi@eecs.umich.edu    void serialize(std::ostream &os)
1974009Ssaidi@eecs.umich.edu    {
1984009Ssaidi@eecs.umich.edu        SERIALIZE_ARRAY(interrupts,num_interrupt_types);
1994009Ssaidi@eecs.umich.edu        SERIALIZE_SCALAR(numPosted);
2004009Ssaidi@eecs.umich.edu    }
2013537Sgblack@eecs.umich.edu
2024009Ssaidi@eecs.umich.edu    void unserialize(Checkpoint *cp, const std::string &section)
2034009Ssaidi@eecs.umich.edu    {
2044009Ssaidi@eecs.umich.edu        UNSERIALIZE_ARRAY(interrupts,num_interrupt_types);
2054009Ssaidi@eecs.umich.edu        UNSERIALIZE_SCALAR(numPosted);
2064009Ssaidi@eecs.umich.edu    }
2074009Ssaidi@eecs.umich.edu};
2084009Ssaidi@eecs.umich.edu} // namespace SPARC_ISA
2093537Sgblack@eecs.umich.edu
2103537Sgblack@eecs.umich.edu#endif // __ARCH_SPARC_INTERRUPT_HH__
211