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 §ion) 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