interrupts.hh revision 5704
11060SN/A/*
22702Sktlim@umich.edu * Copyright (c) 2006 The Regents of The University of Michigan
31060SN/A * All rights reserved.
41060SN/A *
51060SN/A * Redistribution and use in source and binary forms, with or without
61060SN/A * modification, are permitted provided that the following conditions are
71060SN/A * met: redistributions of source code must retain the above copyright
81060SN/A * notice, this list of conditions and the following disclaimer;
91060SN/A * redistributions in binary form must reproduce the above copyright
101060SN/A * notice, this list of conditions and the following disclaimer in the
111060SN/A * documentation and/or other materials provided with the distribution;
121060SN/A * neither the name of the copyright holders nor the names of its
131060SN/A * contributors may be used to endorse or promote products derived from
141060SN/A * this software without specific prior written permission.
151060SN/A *
161060SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171060SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181060SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191060SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201060SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211060SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221060SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231060SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241060SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251060SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261060SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Steve Reinhardt
291060SN/A *          Kevin Lim
301060SN/A */
311464SN/A
321464SN/A#ifndef __ARCH_ALPHA_INTERRUPT_HH__
331060SN/A#define __ARCH_ALPHA_INTERRUPT_HH__
342731Sktlim@umich.edu
352292SN/A#include "arch/alpha/faults.hh"
361464SN/A#include "arch/alpha/isa_traits.hh"
371060SN/A#include "base/compiler.hh"
382669Sktlim@umich.edu#include "base/trace.hh"
391060SN/A#include "cpu/thread_context.hh"
401060SN/A#include "params/AlphaInterrupts.hh"
411858SN/A#include "sim/sim_object.hh"
421464SN/A
431464SN/Anamespace AlphaISA {
442669Sktlim@umich.edu
451060SN/Aclass Interrupts : public SimObject
462669Sktlim@umich.edu{
472292SN/A  private:
481060SN/A    bool newInfoSet;
491060SN/A    int newIpl;
501060SN/A    int newSummary;
511060SN/A
521060SN/A  protected:
531060SN/A    uint64_t interrupts[NumInterruptLevels];
541061SN/A    uint64_t intstatus;
551061SN/A
561060SN/A  public:
571060SN/A    typedef AlphaInterruptsParams Params;
581061SN/A
591060SN/A    const Params *
601060SN/A    params() const
611060SN/A    {
622733Sktlim@umich.edu        return dynamic_cast<const Params *>(_params);
632733Sktlim@umich.edu    }
641060SN/A
652292SN/A    Interrupts(Params * p) : SimObject(p)
662107SN/A    {
672292SN/A        memset(interrupts, 0, sizeof(interrupts));
682292SN/A        intstatus = 0;
692292SN/A        newInfoSet = false;
702107SN/A    }
712690Sktlim@umich.edu
722107SN/A    void
732690Sktlim@umich.edu    post(int int_num, int index)
742690Sktlim@umich.edu    {
751060SN/A        DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
762292SN/A
772292SN/A        if (int_num < 0 || int_num >= NumInterruptLevels)
782292SN/A            panic("int_num out of bounds\n");
792292SN/A
802292SN/A        if (index < 0 || index >= (int)sizeof(uint64_t) * 8)
812292SN/A            panic("int_num out of bounds\n");
821060SN/A
832292SN/A        interrupts[int_num] |= 1 << index;
842292SN/A        intstatus |= (ULL(1) << int_num);
851060SN/A    }
861060SN/A
872292SN/A    void
882107SN/A    clear(int int_num, int index)
891060SN/A    {
901060SN/A        DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
911060SN/A
921060SN/A        if (int_num < 0 || int_num >= NumInterruptLevels)
931060SN/A            panic("int_num out of bounds\n");
941060SN/A
952292SN/A        if (index < 0 || index >= (int)sizeof(uint64_t) * 8)
961060SN/A            panic("int_num out of bounds\n");
971060SN/A
982292SN/A        interrupts[int_num] &= ~(1 << index);
992292SN/A        if (interrupts[int_num] == 0)
1002292SN/A            intstatus &= ~(ULL(1) << int_num);
1012292SN/A    }
1022292SN/A
1032292SN/A    void
1042292SN/A    clearAll()
1051060SN/A    {
1062132SN/A        DPRINTF(Interrupt, "Interrupts all cleared\n");
1071060SN/A
1082292SN/A        memset(interrupts, 0, sizeof(interrupts));
1092292SN/A        intstatus = 0;
1102292SN/A    }
1112292SN/A
1122292SN/A    void
1132292SN/A    serialize(std::ostream &os)
1142292SN/A    {
1152292SN/A        SERIALIZE_ARRAY(interrupts, NumInterruptLevels);
1161060SN/A        SERIALIZE_SCALAR(intstatus);
1172132SN/A    }
1181060SN/A
1191060SN/A    void
1201060SN/A    unserialize(Checkpoint *cp, const std::string &section)
1211060SN/A    {
1222132SN/A        UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels);
1232132SN/A        UNSERIALIZE_SCALAR(intstatus);
1241060SN/A    }
1251684SN/A
1261060SN/A    bool
1271060SN/A    checkInterrupts(ThreadContext *tc) const
1281060SN/A    {
1291060SN/A        return (intstatus != 0) && !(tc->readPC() & 0x3);
1302731Sktlim@umich.edu    }
1312731Sktlim@umich.edu
1322731Sktlim@umich.edu    Fault
1332731Sktlim@umich.edu    getInterrupt(ThreadContext *tc)
1342731Sktlim@umich.edu    {
1352731Sktlim@umich.edu        int ipl = 0;
1362731Sktlim@umich.edu        int summary = 0;
1372731Sktlim@umich.edu
1382731Sktlim@umich.edu        if (tc->readMiscRegNoEffect(IPR_ASTRR))
1392731Sktlim@umich.edu            panic("asynchronous traps not implemented\n");
1402731Sktlim@umich.edu
1412731Sktlim@umich.edu        if (tc->readMiscRegNoEffect(IPR_SIRR)) {
1422731Sktlim@umich.edu            for (int i = INTLEVEL_SOFTWARE_MIN;
1432731Sktlim@umich.edu                 i < INTLEVEL_SOFTWARE_MAX; i++) {
1442731Sktlim@umich.edu                if (tc->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) {
1452731Sktlim@umich.edu                    // See table 4-19 of 21164 hardware reference
1462731Sktlim@umich.edu                    ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
1472731Sktlim@umich.edu                    summary |= (ULL(1) << i);
1482731Sktlim@umich.edu                }
1492731Sktlim@umich.edu            }
1502731Sktlim@umich.edu        }
1512731Sktlim@umich.edu
1522731Sktlim@umich.edu        uint64_t interrupts = intstatus;
1532731Sktlim@umich.edu        if (interrupts) {
1542731Sktlim@umich.edu            for (int i = INTLEVEL_EXTERNAL_MIN;
1552292SN/A                 i < INTLEVEL_EXTERNAL_MAX; i++) {
1562731Sktlim@umich.edu                if (interrupts & (ULL(1) << i)) {
1572731Sktlim@umich.edu                    // See table 4-19 of 21164 hardware reference
1581060SN/A                    ipl = i;
1591060SN/A                    summary |= (ULL(1) << i);
1601060SN/A                }
1611060SN/A            }
1621060SN/A        }
1631060SN/A
1641060SN/A        if (ipl && ipl > tc->readMiscRegNoEffect(IPR_IPLR)) {
1652292SN/A            newIpl = ipl;
1662292SN/A            newSummary = summary;
1672292SN/A            newInfoSet = true;
1682733Sktlim@umich.edu            DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
1692733Sktlim@umich.edu                    tc->readMiscRegNoEffect(IPR_IPLR), ipl, summary);
1701060SN/A
1712680Sktlim@umich.edu            return new InterruptFault;
1722292SN/A        } else {
1731060SN/A            return NoFault;
1741060SN/A        }
1752132SN/A    }
1761060SN/A
1772292SN/A    void
1782669Sktlim@umich.edu    updateIntrInfo(ThreadContext *tc)
1792669Sktlim@umich.edu    {
1802702Sktlim@umich.edu        assert(newInfoSet);
1812669Sktlim@umich.edu        tc->setMiscRegNoEffect(IPR_ISR, newSummary);
1822292SN/A        tc->setMiscRegNoEffect(IPR_INTID, newIpl);
1831060SN/A        newInfoSet = false;
1841060SN/A    }
1851060SN/A};
1861060SN/A
1871060SN/A} // namespace AlphaISA
1881060SN/A
1891060SN/A#endif // __ARCH_ALPHA_INTERRUPT_HH__
1901060SN/A
1911060SN/A