interrupts.hh revision 6066
114184Sgabeblack@google.com/*
214184Sgabeblack@google.com * Copyright (c) 2007 The Hewlett-Packard Development Company
314184Sgabeblack@google.com * All rights reserved.
414184Sgabeblack@google.com *
514184Sgabeblack@google.com * Redistribution and use of this software in source and binary forms,
614184Sgabeblack@google.com * with or without modification, are permitted provided that the
714184Sgabeblack@google.com * following conditions are met:
814184Sgabeblack@google.com *
914184Sgabeblack@google.com * The software must be used only for Non-Commercial Use which means any
1014184Sgabeblack@google.com * use which is NOT directed to receiving any direct monetary
1114184Sgabeblack@google.com * compensation for, or commercial advantage from such use.  Illustrative
1214184Sgabeblack@google.com * examples of non-commercial use are academic research, personal study,
1314184Sgabeblack@google.com * teaching, education and corporate research & development.
1414184Sgabeblack@google.com * Illustrative examples of commercial use are distributing products for
1514184Sgabeblack@google.com * commercial advantage and providing services using the software for
1614184Sgabeblack@google.com * commercial advantage.
1714184Sgabeblack@google.com *
1814184Sgabeblack@google.com * If you wish to use this software or functionality therein that may be
1914184Sgabeblack@google.com * covered by patents for commercial use, please contact:
2014184Sgabeblack@google.com *     Director of Intellectual Property Licensing
2114184Sgabeblack@google.com *     Office of Strategy and Technology
2214184Sgabeblack@google.com *     Hewlett-Packard Company
2314184Sgabeblack@google.com *     1501 Page Mill Road
2414184Sgabeblack@google.com *     Palo Alto, California  94304
2514184Sgabeblack@google.com *
2614184Sgabeblack@google.com * Redistributions of source code must retain the above copyright notice,
2714184Sgabeblack@google.com * this list of conditions and the following disclaimer.  Redistributions
2814184Sgabeblack@google.com * in binary form must reproduce the above copyright notice, this list of
2914184Sgabeblack@google.com * conditions and the following disclaimer in the documentation and/or
3014184Sgabeblack@google.com * other materials provided with the distribution.  Neither the name of
3114184Sgabeblack@google.com * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
3214184Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
3314184Sgabeblack@google.com * this software without specific prior written permission.  No right of
3414184Sgabeblack@google.com * sublicense is granted herewith.  Derivatives of the software and
3514184Sgabeblack@google.com * output created using the software may be prepared, but only for
3614184Sgabeblack@google.com * Non-Commercial Uses.  Derivatives of the software may be shared with
3714184Sgabeblack@google.com * others provided: (i) the others agree to abide by the list of
3814184Sgabeblack@google.com * conditions herein which includes the Non-Commercial Use restrictions;
3914184Sgabeblack@google.com * and (ii) such Derivatives of the software include the above copyright
4014184Sgabeblack@google.com * notice to acknowledge the contribution from this software where
4114184Sgabeblack@google.com * applicable, this list of conditions and the disclaimer below.
4214184Sgabeblack@google.com *
4314184Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4414184Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
4514184Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
4614184Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
4714184Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4814184Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
4914184Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
5014184Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
5114184Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5214184Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
5314184Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5414184Sgabeblack@google.com *
5514184Sgabeblack@google.com * Authors: Gabe Black
5614184Sgabeblack@google.com */
5714184Sgabeblack@google.com
5814184Sgabeblack@google.com#ifndef __ARCH_X86_INTERRUPTS_HH__
5914184Sgabeblack@google.com#define __ARCH_X86_INTERRUPTS_HH__
6014184Sgabeblack@google.com
6114184Sgabeblack@google.com#include "arch/x86/apicregs.hh"
6214184Sgabeblack@google.com#include "arch/x86/faults.hh"
6314184Sgabeblack@google.com#include "arch/x86/intmessage.hh"
6414184Sgabeblack@google.com#include "base/bitfield.hh"
6514184Sgabeblack@google.com#include "cpu/thread_context.hh"
6614184Sgabeblack@google.com#include "dev/io_device.hh"
6714184Sgabeblack@google.com#include "dev/x86/intdev.hh"
6814184Sgabeblack@google.com#include "params/X86LocalApic.hh"
6914184Sgabeblack@google.com#include "sim/eventq.hh"
7014184Sgabeblack@google.com
7114184Sgabeblack@google.comclass ThreadContext;
7214184Sgabeblack@google.comclass BaseCPU;
7314184Sgabeblack@google.com
7414184Sgabeblack@google.comnamespace X86ISA {
7514184Sgabeblack@google.com
7614184Sgabeblack@google.comclass Interrupts : public BasicPioDevice, IntDev
7714184Sgabeblack@google.com{
7814184Sgabeblack@google.com  protected:
7914184Sgabeblack@google.com    // Storage for the APIC registers
8014184Sgabeblack@google.com    uint32_t regs[NUM_APIC_REGS];
8114184Sgabeblack@google.com
8214184Sgabeblack@google.com    BitUnion32(LVTEntry)
8314184Sgabeblack@google.com        Bitfield<7, 0> vector;
8414184Sgabeblack@google.com        Bitfield<10, 8> deliveryMode;
8514184Sgabeblack@google.com        Bitfield<12> status;
8614184Sgabeblack@google.com        Bitfield<13> polarity;
8714184Sgabeblack@google.com        Bitfield<14> remoteIRR;
8814184Sgabeblack@google.com        Bitfield<15> trigger;
8914184Sgabeblack@google.com        Bitfield<16> masked;
9014184Sgabeblack@google.com        Bitfield<17> periodic;
9114184Sgabeblack@google.com    EndBitUnion(LVTEntry)
9214184Sgabeblack@google.com
9314184Sgabeblack@google.com    /*
9414184Sgabeblack@google.com     * Timing related stuff.
9514184Sgabeblack@google.com     */
9614184Sgabeblack@google.com    Tick latency;
9714184Sgabeblack@google.com    Tick clock;
9814184Sgabeblack@google.com
9914184Sgabeblack@google.com    class ApicTimerEvent : public Event
10014184Sgabeblack@google.com    {
10114184Sgabeblack@google.com      private:
10214184Sgabeblack@google.com        Interrupts *localApic;
10314184Sgabeblack@google.com      public:
10414184Sgabeblack@google.com        ApicTimerEvent(Interrupts *_localApic) :
10514184Sgabeblack@google.com            Event(), localApic(_localApic)
10614184Sgabeblack@google.com        {}
10714184Sgabeblack@google.com
10814184Sgabeblack@google.com        void process()
10914184Sgabeblack@google.com        {
11014184Sgabeblack@google.com            assert(localApic);
11114184Sgabeblack@google.com            if (localApic->triggerTimerInterrupt()) {
11214184Sgabeblack@google.com                localApic->setReg(APIC_INITIAL_COUNT,
11314184Sgabeblack@google.com                        localApic->readReg(APIC_INITIAL_COUNT));
11414184Sgabeblack@google.com            }
11514184Sgabeblack@google.com        }
11614184Sgabeblack@google.com    };
11714184Sgabeblack@google.com
11814184Sgabeblack@google.com    ApicTimerEvent apicTimerEvent;
11914184Sgabeblack@google.com
12014184Sgabeblack@google.com    /*
12114184Sgabeblack@google.com     * A set of variables to keep track of interrupts that don't go through
12214184Sgabeblack@google.com     * the IRR.
12314184Sgabeblack@google.com     */
12414184Sgabeblack@google.com    bool pendingSmi;
12514184Sgabeblack@google.com    uint8_t smiVector;
12614184Sgabeblack@google.com    bool pendingNmi;
12714184Sgabeblack@google.com    uint8_t nmiVector;
12814184Sgabeblack@google.com    bool pendingExtInt;
12914184Sgabeblack@google.com    uint8_t extIntVector;
13014184Sgabeblack@google.com    bool pendingInit;
13114184Sgabeblack@google.com    uint8_t initVector;
13214184Sgabeblack@google.com    bool pendingStartup;
13314184Sgabeblack@google.com    uint8_t startupVector;
13414184Sgabeblack@google.com    bool startedUp;
13514184Sgabeblack@google.com
13614184Sgabeblack@google.com    // This is a quick check whether any of the above (except ExtInt) are set.
13714184Sgabeblack@google.com    bool pendingUnmaskableInt;
13814184Sgabeblack@google.com
13914184Sgabeblack@google.com    /*
14014184Sgabeblack@google.com     * IRR and ISR maintenance.
14114184Sgabeblack@google.com     */
14214184Sgabeblack@google.com    uint8_t IRRV;
14314184Sgabeblack@google.com    uint8_t ISRV;
14414184Sgabeblack@google.com
14514184Sgabeblack@google.com    int
14614184Sgabeblack@google.com    findRegArrayMSB(ApicRegIndex base)
14714184Sgabeblack@google.com    {
14814184Sgabeblack@google.com        int offset = 7;
14914184Sgabeblack@google.com        do {
15014184Sgabeblack@google.com            if (regs[base + offset] != 0) {
15114184Sgabeblack@google.com                return offset * 32 + findMsbSet(regs[base + offset]);
15214184Sgabeblack@google.com            }
15314184Sgabeblack@google.com        } while (offset--);
15414184Sgabeblack@google.com        return 0;
15514184Sgabeblack@google.com    }
15614184Sgabeblack@google.com
15714184Sgabeblack@google.com    void
15814184Sgabeblack@google.com    updateIRRV()
15914184Sgabeblack@google.com    {
16014184Sgabeblack@google.com        IRRV = findRegArrayMSB(APIC_INTERRUPT_REQUEST_BASE);
16114184Sgabeblack@google.com    }
16214184Sgabeblack@google.com
16314184Sgabeblack@google.com    void
16414184Sgabeblack@google.com    updateISRV()
16514184Sgabeblack@google.com    {
16614184Sgabeblack@google.com        ISRV = findRegArrayMSB(APIC_IN_SERVICE_BASE);
16714184Sgabeblack@google.com    }
16814184Sgabeblack@google.com
16914184Sgabeblack@google.com    void
17014184Sgabeblack@google.com    setRegArrayBit(ApicRegIndex base, uint8_t vector)
17114184Sgabeblack@google.com    {
17214184Sgabeblack@google.com        regs[base + (vector % 32)] |= (1 << (vector >> 5));
17314184Sgabeblack@google.com    }
17414184Sgabeblack@google.com
17514184Sgabeblack@google.com    void
17614184Sgabeblack@google.com    clearRegArrayBit(ApicRegIndex base, uint8_t vector)
17714184Sgabeblack@google.com    {
17814184Sgabeblack@google.com        regs[base + (vector % 32)] &= ~(1 << (vector >> 5));
17914184Sgabeblack@google.com    }
18014184Sgabeblack@google.com
18114184Sgabeblack@google.com    bool
18214184Sgabeblack@google.com    getRegArrayBit(ApicRegIndex base, uint8_t vector)
18314184Sgabeblack@google.com    {
18414184Sgabeblack@google.com        return bits(regs[base + (vector % 32)], vector >> 5);
18514184Sgabeblack@google.com    }
18614184Sgabeblack@google.com
18714184Sgabeblack@google.com    void requestInterrupt(uint8_t vector, uint8_t deliveryMode, bool level);
18814184Sgabeblack@google.com
18914184Sgabeblack@google.com    BaseCPU *cpu;
19014184Sgabeblack@google.com
19114184Sgabeblack@google.com  public:
19214184Sgabeblack@google.com    /*
19314184Sgabeblack@google.com     * Params stuff.
19414184Sgabeblack@google.com     */
19514184Sgabeblack@google.com    typedef X86LocalApicParams Params;
19614184Sgabeblack@google.com
19714184Sgabeblack@google.com    void setCPU(BaseCPU * newCPU);
19814184Sgabeblack@google.com
19914184Sgabeblack@google.com    void
20014184Sgabeblack@google.com    setClock(Tick newClock)
20114184Sgabeblack@google.com    {
20214184Sgabeblack@google.com        clock = newClock;
20314184Sgabeblack@google.com    }
20414184Sgabeblack@google.com
20514184Sgabeblack@google.com    const Params *
20614184Sgabeblack@google.com    params() const
20714184Sgabeblack@google.com    {
20814184Sgabeblack@google.com        return dynamic_cast<const Params *>(_params);
20914184Sgabeblack@google.com    }
21014184Sgabeblack@google.com
21114184Sgabeblack@google.com    /*
21214184Sgabeblack@google.com     * Functions to interact with the interrupt port from IntDev.
21314184Sgabeblack@google.com     */
21414184Sgabeblack@google.com    Tick read(PacketPtr pkt);
21514184Sgabeblack@google.com    Tick write(PacketPtr pkt);
21614184Sgabeblack@google.com    Tick recvMessage(PacketPtr pkt);
21714184Sgabeblack@google.com    Tick recvResponse(PacketPtr pkt);
21814184Sgabeblack@google.com
21914184Sgabeblack@google.com    bool
22014184Sgabeblack@google.com    triggerTimerInterrupt()
22114184Sgabeblack@google.com    {
22214184Sgabeblack@google.com        LVTEntry entry = regs[APIC_LVT_TIMER];
22314184Sgabeblack@google.com        if (!entry.masked)
22414184Sgabeblack@google.com            requestInterrupt(entry.vector, entry.deliveryMode, entry.trigger);
22514184Sgabeblack@google.com        return entry.periodic;
22614184Sgabeblack@google.com    }
22714184Sgabeblack@google.com
22814184Sgabeblack@google.com    void addressRanges(AddrRangeList &range_list);
22914184Sgabeblack@google.com    void getIntAddrRange(AddrRangeList &range_list);
23014184Sgabeblack@google.com
23114184Sgabeblack@google.com    Port *getPort(const std::string &if_name, int idx = -1)
23214184Sgabeblack@google.com    {
23314184Sgabeblack@google.com        if (if_name == "int_port")
23414184Sgabeblack@google.com            return intPort;
23514184Sgabeblack@google.com        return BasicPioDevice::getPort(if_name, idx);
23614184Sgabeblack@google.com    }
23714184Sgabeblack@google.com
23814184Sgabeblack@google.com    /*
23914184Sgabeblack@google.com     * Functions to access and manipulate the APIC's registers.
24014184Sgabeblack@google.com     */
24114184Sgabeblack@google.com
24214184Sgabeblack@google.com    uint32_t readReg(ApicRegIndex miscReg);
24314184Sgabeblack@google.com    void setReg(ApicRegIndex reg, uint32_t val);
24414184Sgabeblack@google.com    void
24514184Sgabeblack@google.com    setRegNoEffect(ApicRegIndex reg, uint32_t val)
24614184Sgabeblack@google.com    {
24714184Sgabeblack@google.com        regs[reg] = val;
24814184Sgabeblack@google.com    }
24914184Sgabeblack@google.com
25014184Sgabeblack@google.com    /*
25114184Sgabeblack@google.com     * Constructor.
25214184Sgabeblack@google.com     */
25314184Sgabeblack@google.com
25414184Sgabeblack@google.com    Interrupts(Params * p);
25514184Sgabeblack@google.com
25614184Sgabeblack@google.com    /*
25714184Sgabeblack@google.com     * Functions for retrieving interrupts for the CPU to handle.
25814184Sgabeblack@google.com     */
25914184Sgabeblack@google.com
26014184Sgabeblack@google.com    bool checkInterrupts(ThreadContext *tc) const;
26114184Sgabeblack@google.com    Fault getInterrupt(ThreadContext *tc);
26214184Sgabeblack@google.com    void updateIntrInfo(ThreadContext *tc);
26314184Sgabeblack@google.com
26414184Sgabeblack@google.com    /*
26514184Sgabeblack@google.com     * Serialization.
26614184Sgabeblack@google.com     */
26714184Sgabeblack@google.com
26814184Sgabeblack@google.com    void
26914184Sgabeblack@google.com    serialize(std::ostream &os)
27014184Sgabeblack@google.com    {
27114184Sgabeblack@google.com        panic("Interrupts::serialize unimplemented!\n");
27214184Sgabeblack@google.com    }
27314184Sgabeblack@google.com
27414184Sgabeblack@google.com    void
27514184Sgabeblack@google.com    unserialize(Checkpoint *cp, const std::string &section)
27614184Sgabeblack@google.com    {
27714184Sgabeblack@google.com        panic("Interrupts::unserialize unimplemented!\n");
27814184Sgabeblack@google.com    }
27914184Sgabeblack@google.com
28014184Sgabeblack@google.com    /*
28114184Sgabeblack@google.com     * Old functions needed for compatability but which will be phased out
28214184Sgabeblack@google.com     * eventually.
28314184Sgabeblack@google.com     */
28414184Sgabeblack@google.com    void
28514184Sgabeblack@google.com    post(int int_num, int index)
28614184Sgabeblack@google.com    {
28714184Sgabeblack@google.com        panic("Interrupts::post unimplemented!\n");
28814184Sgabeblack@google.com    }
28914184Sgabeblack@google.com
29014184Sgabeblack@google.com    void
29114184Sgabeblack@google.com    clear(int int_num, int index)
29214184Sgabeblack@google.com    {
29314184Sgabeblack@google.com        panic("Interrupts::clear unimplemented!\n");
29414184Sgabeblack@google.com    }
29514184Sgabeblack@google.com
29614184Sgabeblack@google.com    void
29714184Sgabeblack@google.com    clearAll()
29814184Sgabeblack@google.com    {
29914184Sgabeblack@google.com        panic("Interrupts::clearAll unimplemented!\n");
30014184Sgabeblack@google.com    }
30114184Sgabeblack@google.com};
30214184Sgabeblack@google.com
30314184Sgabeblack@google.com} // namespace X86ISA
30414184Sgabeblack@google.com
30514184Sgabeblack@google.com#endif // __ARCH_X86_INTERRUPTS_HH__
30614184Sgabeblack@google.com