interrupts.hh revision 7087
12623SN/A/*
22623SN/A * Copyright (c) 2007 The Hewlett-Packard Development Company
32623SN/A * All rights reserved.
42623SN/A *
52623SN/A * The license below extends only to copyright in the software and shall
62623SN/A * not be construed as granting a license to any other intellectual
72623SN/A * property including but not limited to intellectual property relating
82623SN/A * to a hardware implementation of the functionality of the software
92623SN/A * licensed hereunder.  You may use the software subject to the license
102623SN/A * terms below provided that you ensure that this notice is replicated
112623SN/A * unmodified and in its entirety in all distributions of the software,
122623SN/A * modified or unmodified, in source code or in binary form.
132623SN/A *
142623SN/A * Redistribution and use in source and binary forms, with or without
152623SN/A * modification, are permitted provided that the following conditions are
162623SN/A * met: redistributions of source code must retain the above copyright
172623SN/A * notice, this list of conditions and the following disclaimer;
182623SN/A * redistributions in binary form must reproduce the above copyright
192623SN/A * notice, this list of conditions and the following disclaimer in the
202623SN/A * documentation and/or other materials provided with the distribution;
212623SN/A * neither the name of the copyright holders nor the names of its
222623SN/A * contributors may be used to endorse or promote products derived from
232623SN/A * this software without specific prior written permission.
242623SN/A *
252623SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
262623SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
272665Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
282665Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
292623SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
302623SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
312623SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
322623SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
332623SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
342623SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
352623SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
362623SN/A *
372623SN/A * Authors: Gabe Black
382623SN/A */
392623SN/A
402623SN/A#ifndef __ARCH_X86_INTERRUPTS_HH__
412623SN/A#define __ARCH_X86_INTERRUPTS_HH__
422623SN/A
432623SN/A#include "arch/x86/apicregs.hh"
442623SN/A#include "arch/x86/faults.hh"
452623SN/A#include "arch/x86/intmessage.hh"
462623SN/A#include "base/bitfield.hh"
472623SN/A#include "cpu/thread_context.hh"
482623SN/A#include "dev/io_device.hh"
492623SN/A#include "dev/x86/intdev.hh"
502623SN/A#include "params/X86LocalApic.hh"
512623SN/A#include "sim/eventq.hh"
522623SN/A
532623SN/Aclass ThreadContext;
542623SN/Aclass BaseCPU;
552623SN/A
562623SN/Anamespace X86ISA {
572623SN/A
582856Srdreslin@umich.educlass Interrupts : public BasicPioDevice, IntDev
592856Srdreslin@umich.edu{
602856Srdreslin@umich.edu  protected:
612856Srdreslin@umich.edu    // Storage for the APIC registers
622856Srdreslin@umich.edu    uint32_t regs[NUM_APIC_REGS];
632856Srdreslin@umich.edu
642856Srdreslin@umich.edu    BitUnion32(LVTEntry)
652856Srdreslin@umich.edu        Bitfield<7, 0> vector;
662856Srdreslin@umich.edu        Bitfield<10, 8> deliveryMode;
672856Srdreslin@umich.edu        Bitfield<12> status;
682623SN/A        Bitfield<13> polarity;
692623SN/A        Bitfield<14> remoteIRR;
702623SN/A        Bitfield<15> trigger;
712623SN/A        Bitfield<16> masked;
722623SN/A        Bitfield<17> periodic;
732856Srdreslin@umich.edu    EndBitUnion(LVTEntry)
742856Srdreslin@umich.edu
752856Srdreslin@umich.edu    /*
762623SN/A     * Timing related stuff.
772856Srdreslin@umich.edu     */
782856Srdreslin@umich.edu    Tick latency;
792856Srdreslin@umich.edu    Tick clock;
802623SN/A
812623SN/A    class ApicTimerEvent : public Event
822623SN/A    {
832680Sktlim@umich.edu      private:
842680Sktlim@umich.edu        Interrupts *localApic;
852623SN/A      public:
862623SN/A        ApicTimerEvent(Interrupts *_localApic) :
872680Sktlim@umich.edu            Event(), localApic(_localApic)
882623SN/A        {}
892623SN/A
902623SN/A        void process()
912623SN/A        {
922623SN/A            assert(localApic);
932630SN/A            if (localApic->triggerTimerInterrupt()) {
942623SN/A                localApic->setReg(APIC_INITIAL_COUNT,
952623SN/A                        localApic->readReg(APIC_INITIAL_COUNT));
962623SN/A            }
972623SN/A        }
982623SN/A    };
992623SN/A
1002630SN/A    ApicTimerEvent apicTimerEvent;
1012623SN/A
1022623SN/A    /*
1032623SN/A     * A set of variables to keep track of interrupts that don't go through
1042623SN/A     * the IRR.
1052623SN/A     */
1062623SN/A    bool pendingSmi;
1072630SN/A    uint8_t smiVector;
1082623SN/A    bool pendingNmi;
1092623SN/A    uint8_t nmiVector;
1102623SN/A    bool pendingExtInt;
1112623SN/A    uint8_t extIntVector;
1122623SN/A    bool pendingInit;
1132623SN/A    uint8_t initVector;
1142623SN/A    bool pendingStartup;
1152626SN/A    uint8_t startupVector;
1162626SN/A    bool startedUp;
1172626SN/A
1182623SN/A    // This is a quick check whether any of the above (except ExtInt) are set.
1192623SN/A    bool pendingUnmaskableInt;
1202623SN/A
1212657Ssaidi@eecs.umich.edu    // A count of how many IPIs are in flight.
1222623SN/A    int pendingIPIs;
1232623SN/A
1242623SN/A    /*
1252623SN/A     * IRR and ISR maintenance.
1262623SN/A     */
1272623SN/A    uint8_t IRRV;
1282623SN/A    uint8_t ISRV;
1292623SN/A
1302623SN/A    int
1312640Sstever@eecs.umich.edu    findRegArrayMSB(ApicRegIndex base)
1322623SN/A    {
1332623SN/A        int offset = 7;
1342623SN/A        do {
1352663Sstever@eecs.umich.edu            if (regs[base + offset] != 0) {
1362663Sstever@eecs.umich.edu                return offset * 32 + findMsbSet(regs[base + offset]);
1372827Srdreslin@umich.edu            }
1382641Sstever@eecs.umich.edu        } while (offset--);
1392623SN/A        return 0;
1402623SN/A    }
1412663Sstever@eecs.umich.edu
1422827Srdreslin@umich.edu    void
1432641Sstever@eecs.umich.edu    updateIRRV()
1442641Sstever@eecs.umich.edu    {
1452623SN/A        IRRV = findRegArrayMSB(APIC_INTERRUPT_REQUEST_BASE);
1462623SN/A    }
1472663Sstever@eecs.umich.edu
1482827Srdreslin@umich.edu    void
1492641Sstever@eecs.umich.edu    updateISRV()
1502641Sstever@eecs.umich.edu    {
1512623SN/A        ISRV = findRegArrayMSB(APIC_IN_SERVICE_BASE);
1522623SN/A    }
1532623SN/A
1542623SN/A    void
1552623SN/A    setRegArrayBit(ApicRegIndex base, uint8_t vector)
1562623SN/A    {
1572623SN/A        regs[base + (vector / 32)] |= (1 << (vector % 32));
1582623SN/A    }
1592623SN/A
1602623SN/A    void
1612915Sktlim@umich.edu    clearRegArrayBit(ApicRegIndex base, uint8_t vector)
1622915Sktlim@umich.edu    {
1632623SN/A        regs[base + (vector / 32)] &= ~(1 << (vector % 32));
1642623SN/A    }
1652915Sktlim@umich.edu
1662623SN/A    bool
1672623SN/A    getRegArrayBit(ApicRegIndex base, uint8_t vector)
1682623SN/A    {
1692623SN/A        return bits(regs[base + (vector / 32)], vector % 5);
1702623SN/A    }
1712915Sktlim@umich.edu
1722915Sktlim@umich.edu    void requestInterrupt(uint8_t vector, uint8_t deliveryMode, bool level);
1732915Sktlim@umich.edu
1742623SN/A    BaseCPU *cpu;
1752915Sktlim@umich.edu
1762915Sktlim@umich.edu    int initialApicId;
1772915Sktlim@umich.edu
1782915Sktlim@umich.edu  public:
1792915Sktlim@umich.edu    /*
1802915Sktlim@umich.edu     * Params stuff.
1812915Sktlim@umich.edu     */
1822915Sktlim@umich.edu    typedef X86LocalApicParams Params;
1832915Sktlim@umich.edu
1842623SN/A    void setCPU(BaseCPU * newCPU);
1852623SN/A
1862623SN/A    void
1872798Sktlim@umich.edu    setClock(Tick newClock)
1882623SN/A    {
1892798Sktlim@umich.edu        clock = newClock;
1902798Sktlim@umich.edu    }
1912623SN/A
1922798Sktlim@umich.edu    const Params *
1932623SN/A    params() const
1942623SN/A    {
1952623SN/A        return dynamic_cast<const Params *>(_params);
1962623SN/A    }
1972623SN/A
1982623SN/A    /*
1992623SN/A     * Initialize this object by registering it with the IO APIC.
2002623SN/A     */
2012623SN/A    void init();
2022623SN/A
2032680Sktlim@umich.edu    /*
2042623SN/A     * Functions to interact with the interrupt port from IntDev.
2052680Sktlim@umich.edu     */
2062680Sktlim@umich.edu    Tick read(PacketPtr pkt);
2072680Sktlim@umich.edu    Tick write(PacketPtr pkt);
2082623SN/A    Tick recvMessage(PacketPtr pkt);
2092623SN/A    Tick recvResponse(PacketPtr pkt);
2102623SN/A
2112623SN/A    bool
2122623SN/A    triggerTimerInterrupt()
2132623SN/A    {
2142623SN/A        LVTEntry entry = regs[APIC_LVT_TIMER];
2152623SN/A        if (!entry.masked)
2162623SN/A            requestInterrupt(entry.vector, entry.deliveryMode, entry.trigger);
2172623SN/A        return entry.periodic;
2182623SN/A    }
2192623SN/A
2202683Sktlim@umich.edu    void addressRanges(AddrRangeList &range_list);
2212623SN/A    void getIntAddrRange(AddrRangeList &range_list);
2222623SN/A
2232623SN/A    Port *getPort(const std::string &if_name, int idx = -1)
2242623SN/A    {
2252623SN/A        if (if_name == "int_port")
2262623SN/A            return intPort;
2272623SN/A        return BasicPioDevice::getPort(if_name, idx);
2282623SN/A    }
2292623SN/A
2302623SN/A    /*
2312623SN/A     * Functions to access and manipulate the APIC's registers.
2322623SN/A     */
2332623SN/A
2342623SN/A    uint32_t readReg(ApicRegIndex miscReg);
2352683Sktlim@umich.edu    void setReg(ApicRegIndex reg, uint32_t val);
2362623SN/A    void
2372623SN/A    setRegNoEffect(ApicRegIndex reg, uint32_t val)
2382626SN/A    {
2392626SN/A        regs[reg] = val;
2402626SN/A    }
2412626SN/A
2422626SN/A    /*
2432623SN/A     * Constructor.
2442623SN/A     */
2452623SN/A
2462623SN/A    Interrupts(Params * p);
2472623SN/A
2482623SN/A    /*
2492623SN/A     * Functions for retrieving interrupts for the CPU to handle.
2502623SN/A     */
2512623SN/A
2522623SN/A    bool checkInterrupts(ThreadContext *tc) const;
2532683Sktlim@umich.edu    Fault getInterrupt(ThreadContext *tc);
2542623SN/A    void updateIntrInfo(ThreadContext *tc);
2552623SN/A
2562623SN/A    /*
2572623SN/A     * Serialization.
2582623SN/A     */
2592623SN/A
2602683Sktlim@umich.edu    void
2612623SN/A    serialize(std::ostream &os)
2622623SN/A    {
2632623SN/A        panic("Interrupts::serialize unimplemented!\n");
2642641Sstever@eecs.umich.edu    }
2652623SN/A
2662662Sstever@eecs.umich.edu    void
2672623SN/A    unserialize(Checkpoint *cp, const std::string &section)
2682623SN/A    {
2692641Sstever@eecs.umich.edu        panic("Interrupts::unserialize unimplemented!\n");
2702623SN/A    }
2712623SN/A
2722623SN/A    /*
2732623SN/A     * Old functions needed for compatability but which will be phased out
2742623SN/A     * eventually.
2752623SN/A     */
2762623SN/A    void
2772623SN/A    post(int int_num, int index)
2782623SN/A    {
2792623SN/A        panic("Interrupts::post unimplemented!\n");
2802623SN/A    }
2812623SN/A
2822623SN/A    void
2832623SN/A    clear(int int_num, int index)
2842623SN/A    {
2852623SN/A        panic("Interrupts::clear unimplemented!\n");
2862623SN/A    }
2872623SN/A
2882623SN/A    void
2892623SN/A    clearAll()
2902623SN/A    {
2912623SN/A        panic("Interrupts::clearAll unimplemented!\n");
2922623SN/A    }
2932623SN/A};
2942623SN/A
2952623SN/A} // namespace X86ISA
2962623SN/A
2972623SN/A#endif // __ARCH_X86_INTERRUPTS_HH__
2982623SN/A