interrupts.hh revision 8746:42d3554b1c35
16313Sgblack@eecs.umich.edu/* 212529Sgiacomo.travaglini@arm.com * Copyright (c) 2007 The Hewlett-Packard Development Company 37093Sgblack@eecs.umich.edu * All rights reserved. 47093Sgblack@eecs.umich.edu * 57093Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 67093Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 77093Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 87093Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 97093Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 107093Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 117093Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 127093Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 137093Sgblack@eecs.umich.edu * 146313Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 156313Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 166313Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 176313Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 186313Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 196313Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 206313Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 216313Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 226313Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 236313Sgblack@eecs.umich.edu * this software without specific prior written permission. 246313Sgblack@eecs.umich.edu * 256313Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 266313Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 276313Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 286313Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 296313Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 306313Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 316313Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 326313Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 336313Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 346313Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 356313Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 366313Sgblack@eecs.umich.edu * 376313Sgblack@eecs.umich.edu * Authors: Gabe Black 386313Sgblack@eecs.umich.edu */ 396313Sgblack@eecs.umich.edu 406313Sgblack@eecs.umich.edu#ifndef __ARCH_X86_INTERRUPTS_HH__ 416313Sgblack@eecs.umich.edu#define __ARCH_X86_INTERRUPTS_HH__ 426313Sgblack@eecs.umich.edu 436313Sgblack@eecs.umich.edu#include "arch/x86/regs/apic.hh" 447404SAli.Saidi@ARM.com#include "arch/x86/faults.hh" 456313Sgblack@eecs.umich.edu#include "arch/x86/intmessage.hh" 4610461SAndreas.Sandberg@ARM.com#include "base/bitfield.hh" 4712479SCurtis.Dunham@arm.com#include "config/full_system.hh" 486333Sgblack@eecs.umich.edu#include "cpu/thread_context.hh" 4910037SARM gem5 Developers#include "dev/x86/intdev.hh" 507404SAli.Saidi@ARM.com#include "dev/io_device.hh" 516313Sgblack@eecs.umich.edu#include "params/X86LocalApic.hh" 5212109SRekai.GonzalezAlberquilla@arm.com#include "sim/eventq.hh" 538232Snate@binkert.org 5412109SRekai.GonzalezAlberquilla@arm.comclass ThreadContext; 559384SAndreas.Sandberg@arm.comclass BaseCPU; 5611165SRekai.GonzalezAlberquilla@arm.com 576313Sgblack@eecs.umich.edunamespace X86ISA { 589384SAndreas.Sandberg@arm.com 5910461SAndreas.Sandberg@ARM.comclass Interrupts : public BasicPioDevice, IntDev 606333Sgblack@eecs.umich.edu{ 616313Sgblack@eecs.umich.edu protected: 626313Sgblack@eecs.umich.edu // Storage for the APIC registers 636313Sgblack@eecs.umich.edu uint32_t regs[NUM_APIC_REGS]; 646313Sgblack@eecs.umich.edu 656313Sgblack@eecs.umich.edu BitUnion32(LVTEntry) 669384SAndreas.Sandberg@arm.com Bitfield<7, 0> vector; 676313Sgblack@eecs.umich.edu Bitfield<10, 8> deliveryMode; 686313Sgblack@eecs.umich.edu Bitfield<12> status; 6910037SARM gem5 Developers Bitfield<13> polarity; 7010037SARM gem5 Developers Bitfield<14> remoteIRR; 7110037SARM gem5 Developers Bitfield<15> trigger; 7211165SRekai.GonzalezAlberquilla@arm.com Bitfield<16> masked; 7311165SRekai.GonzalezAlberquilla@arm.com Bitfield<17> periodic; 7412109SRekai.GonzalezAlberquilla@arm.com EndBitUnion(LVTEntry) 7511165SRekai.GonzalezAlberquilla@arm.com 7610461SAndreas.Sandberg@ARM.com /* 7710461SAndreas.Sandberg@ARM.com * Timing related stuff. 7810461SAndreas.Sandberg@ARM.com */ 7910461SAndreas.Sandberg@ARM.com Tick latency; 8010461SAndreas.Sandberg@ARM.com Tick clock; 8110461SAndreas.Sandberg@ARM.com 8210844Sandreas.sandberg@arm.com class ApicTimerEvent : public Event 8310844Sandreas.sandberg@arm.com { 8410844Sandreas.sandberg@arm.com private: 8513531Sjairo.balart@metempsy.com Interrupts *localApic; 8613531Sjairo.balart@metempsy.com public: 8713531Sjairo.balart@metempsy.com ApicTimerEvent(Interrupts *_localApic) : 8810037SARM gem5 Developers Event(), localApic(_localApic) 8911771SCurtis.Dunham@arm.com {} 9010037SARM gem5 Developers 9110037SARM gem5 Developers void process() 9210037SARM gem5 Developers { 9313173Sgiacomo.travaglini@arm.com assert(localApic); 9410037SARM gem5 Developers if (localApic->triggerTimerInterrupt()) { 9513531Sjairo.balart@metempsy.com localApic->setReg(APIC_INITIAL_COUNT, 9613114Sgiacomo.travaglini@arm.com localApic->readReg(APIC_INITIAL_COUNT)); 9710037SARM gem5 Developers } 9812714Sgiacomo.travaglini@arm.com } 9912714Sgiacomo.travaglini@arm.com }; 10012714Sgiacomo.travaglini@arm.com 10112714Sgiacomo.travaglini@arm.com ApicTimerEvent apicTimerEvent; 10212714Sgiacomo.travaglini@arm.com 10312714Sgiacomo.travaglini@arm.com /* 10412478SCurtis.Dunham@arm.com * A set of variables to keep track of interrupts that don't go through 10510037SARM gem5 Developers * the IRR. 10612477SCurtis.Dunham@arm.com */ 10712477SCurtis.Dunham@arm.com bool pendingSmi; 10812478SCurtis.Dunham@arm.com uint8_t smiVector; 10912478SCurtis.Dunham@arm.com bool pendingNmi; 11012478SCurtis.Dunham@arm.com uint8_t nmiVector; 11112478SCurtis.Dunham@arm.com bool pendingExtInt; 11212478SCurtis.Dunham@arm.com uint8_t extIntVector; 11312478SCurtis.Dunham@arm.com bool pendingInit; 11412478SCurtis.Dunham@arm.com uint8_t initVector; 11512478SCurtis.Dunham@arm.com bool pendingStartup; 11612478SCurtis.Dunham@arm.com uint8_t startupVector; 11712478SCurtis.Dunham@arm.com bool startedUp; 11812478SCurtis.Dunham@arm.com 11912478SCurtis.Dunham@arm.com // This is a quick check whether any of the above (except ExtInt) are set. 12012478SCurtis.Dunham@arm.com bool pendingUnmaskableInt; 12112478SCurtis.Dunham@arm.com 12212478SCurtis.Dunham@arm.com // A count of how many IPIs are in flight. 12312478SCurtis.Dunham@arm.com int pendingIPIs; 12410037SARM gem5 Developers 12510037SARM gem5 Developers /* 12612477SCurtis.Dunham@arm.com * IRR and ISR maintenance. 12712479SCurtis.Dunham@arm.com */ 12812477SCurtis.Dunham@arm.com uint8_t IRRV; 12912477SCurtis.Dunham@arm.com uint8_t ISRV; 13012477SCurtis.Dunham@arm.com 13112479SCurtis.Dunham@arm.com int 13212477SCurtis.Dunham@arm.com findRegArrayMSB(ApicRegIndex base) 13312477SCurtis.Dunham@arm.com { 13412477SCurtis.Dunham@arm.com int offset = 7; 13512477SCurtis.Dunham@arm.com do { 13612477SCurtis.Dunham@arm.com if (regs[base + offset] != 0) { 13712477SCurtis.Dunham@arm.com return offset * 32 + findMsbSet(regs[base + offset]); 13812477SCurtis.Dunham@arm.com } 13912478SCurtis.Dunham@arm.com } while (offset--); 14012478SCurtis.Dunham@arm.com return 0; 14112478SCurtis.Dunham@arm.com } 14212478SCurtis.Dunham@arm.com 14312478SCurtis.Dunham@arm.com void 14412478SCurtis.Dunham@arm.com updateIRRV() 14512478SCurtis.Dunham@arm.com { 14612478SCurtis.Dunham@arm.com IRRV = findRegArrayMSB(APIC_INTERRUPT_REQUEST_BASE); 14712478SCurtis.Dunham@arm.com } 14812478SCurtis.Dunham@arm.com 14912478SCurtis.Dunham@arm.com void 15012478SCurtis.Dunham@arm.com updateISRV() 15112478SCurtis.Dunham@arm.com { 15212478SCurtis.Dunham@arm.com ISRV = findRegArrayMSB(APIC_IN_SERVICE_BASE); 15312478SCurtis.Dunham@arm.com } 15412478SCurtis.Dunham@arm.com 15512479SCurtis.Dunham@arm.com void 15612479SCurtis.Dunham@arm.com setRegArrayBit(ApicRegIndex base, uint8_t vector) 15712479SCurtis.Dunham@arm.com { 15812479SCurtis.Dunham@arm.com regs[base + (vector / 32)] |= (1 << (vector % 32)); 15912479SCurtis.Dunham@arm.com } 16012479SCurtis.Dunham@arm.com 16112479SCurtis.Dunham@arm.com void 16212479SCurtis.Dunham@arm.com clearRegArrayBit(ApicRegIndex base, uint8_t vector) 16312479SCurtis.Dunham@arm.com { 16412479SCurtis.Dunham@arm.com regs[base + (vector / 32)] &= ~(1 << (vector % 32)); 16512479SCurtis.Dunham@arm.com } 16612479SCurtis.Dunham@arm.com 16712479SCurtis.Dunham@arm.com bool 16812479SCurtis.Dunham@arm.com getRegArrayBit(ApicRegIndex base, uint8_t vector) 16912479SCurtis.Dunham@arm.com { 17012479SCurtis.Dunham@arm.com return bits(regs[base + (vector / 32)], vector % 5); 17112479SCurtis.Dunham@arm.com } 17212479SCurtis.Dunham@arm.com 17312479SCurtis.Dunham@arm.com void requestInterrupt(uint8_t vector, uint8_t deliveryMode, bool level); 17412479SCurtis.Dunham@arm.com 17512479SCurtis.Dunham@arm.com BaseCPU *cpu; 17612479SCurtis.Dunham@arm.com 17712479SCurtis.Dunham@arm.com int initialApicId; 17812479SCurtis.Dunham@arm.com 17912479SCurtis.Dunham@arm.com public: 18012479SCurtis.Dunham@arm.com 18112479SCurtis.Dunham@arm.com int getInitialApicId() { return initialApicId; } 18212479SCurtis.Dunham@arm.com 18312479SCurtis.Dunham@arm.com /* 18412479SCurtis.Dunham@arm.com * Params stuff. 18512479SCurtis.Dunham@arm.com */ 18612479SCurtis.Dunham@arm.com typedef X86LocalApicParams Params; 18712479SCurtis.Dunham@arm.com 18812479SCurtis.Dunham@arm.com void setCPU(BaseCPU * newCPU); 18912479SCurtis.Dunham@arm.com 19012479SCurtis.Dunham@arm.com void 19112479SCurtis.Dunham@arm.com setClock(Tick newClock) 19212479SCurtis.Dunham@arm.com { 19312479SCurtis.Dunham@arm.com clock = newClock; 19412479SCurtis.Dunham@arm.com } 19512479SCurtis.Dunham@arm.com 19612479SCurtis.Dunham@arm.com const Params * 19712479SCurtis.Dunham@arm.com params() const 19812479SCurtis.Dunham@arm.com { 19912479SCurtis.Dunham@arm.com return dynamic_cast<const Params *>(_params); 20012479SCurtis.Dunham@arm.com } 20112479SCurtis.Dunham@arm.com 20212479SCurtis.Dunham@arm.com /* 20312479SCurtis.Dunham@arm.com * Initialize this object by registering it with the IO APIC. 20412479SCurtis.Dunham@arm.com */ 20512479SCurtis.Dunham@arm.com void init(); 20612479SCurtis.Dunham@arm.com 20712479SCurtis.Dunham@arm.com /* 20812479SCurtis.Dunham@arm.com * Functions to interact with the interrupt port from IntDev. 20912479SCurtis.Dunham@arm.com */ 21012479SCurtis.Dunham@arm.com Tick read(PacketPtr pkt); 21112479SCurtis.Dunham@arm.com Tick write(PacketPtr pkt); 21212479SCurtis.Dunham@arm.com Tick recvMessage(PacketPtr pkt); 21312668Sgiacomo.travaglini@arm.com Tick recvResponse(PacketPtr pkt); 21412668Sgiacomo.travaglini@arm.com 21512668Sgiacomo.travaglini@arm.com bool 21612668Sgiacomo.travaglini@arm.com triggerTimerInterrupt() 21712668Sgiacomo.travaglini@arm.com { 21812479SCurtis.Dunham@arm.com LVTEntry entry = regs[APIC_LVT_TIMER]; 21912479SCurtis.Dunham@arm.com if (!entry.masked) 22012479SCurtis.Dunham@arm.com requestInterrupt(entry.vector, entry.deliveryMode, entry.trigger); 22112479SCurtis.Dunham@arm.com return entry.periodic; 22212479SCurtis.Dunham@arm.com } 22312479SCurtis.Dunham@arm.com 22412479SCurtis.Dunham@arm.com void addressRanges(AddrRangeList &range_list); 22512479SCurtis.Dunham@arm.com void getIntAddrRange(AddrRangeList &range_list); 22612479SCurtis.Dunham@arm.com 22712479SCurtis.Dunham@arm.com Port *getPort(const std::string &if_name, int idx = -1) 22812479SCurtis.Dunham@arm.com { 22912479SCurtis.Dunham@arm.com if (if_name == "int_port") 23012479SCurtis.Dunham@arm.com return intPort; 23112668Sgiacomo.travaglini@arm.com return BasicPioDevice::getPort(if_name, idx); 23212668Sgiacomo.travaglini@arm.com } 23312668Sgiacomo.travaglini@arm.com 23412668Sgiacomo.travaglini@arm.com /* 23512668Sgiacomo.travaglini@arm.com * Functions to access and manipulate the APIC's registers. 23613395Sgiacomo.travaglini@arm.com */ 23713395Sgiacomo.travaglini@arm.com 23813395Sgiacomo.travaglini@arm.com uint32_t readReg(ApicRegIndex miscReg); 23913395Sgiacomo.travaglini@arm.com void setReg(ApicRegIndex reg, uint32_t val); 24013395Sgiacomo.travaglini@arm.com void 24112479SCurtis.Dunham@arm.com setRegNoEffect(ApicRegIndex reg, uint32_t val) 24212479SCurtis.Dunham@arm.com { 24312479SCurtis.Dunham@arm.com regs[reg] = val; 24412479SCurtis.Dunham@arm.com } 24512479SCurtis.Dunham@arm.com 24612479SCurtis.Dunham@arm.com /* 24712479SCurtis.Dunham@arm.com * Constructor. 24812479SCurtis.Dunham@arm.com */ 24912479SCurtis.Dunham@arm.com 25012479SCurtis.Dunham@arm.com Interrupts(Params * p); 25112479SCurtis.Dunham@arm.com 25212479SCurtis.Dunham@arm.com /* 25312479SCurtis.Dunham@arm.com * Functions for retrieving interrupts for the CPU to handle. 25412479SCurtis.Dunham@arm.com */ 25512479SCurtis.Dunham@arm.com 25612479SCurtis.Dunham@arm.com bool checkInterrupts(ThreadContext *tc) const; 25712479SCurtis.Dunham@arm.com Fault getInterrupt(ThreadContext *tc); 25812479SCurtis.Dunham@arm.com void updateIntrInfo(ThreadContext *tc); 25912479SCurtis.Dunham@arm.com 26012479SCurtis.Dunham@arm.com /* 26112479SCurtis.Dunham@arm.com * Serialization. 26212479SCurtis.Dunham@arm.com */ 26312479SCurtis.Dunham@arm.com 26412479SCurtis.Dunham@arm.com virtual void serialize(std::ostream &os); 26512479SCurtis.Dunham@arm.com virtual void unserialize(Checkpoint *cp, const std::string §ion); 26612479SCurtis.Dunham@arm.com 26712479SCurtis.Dunham@arm.com /* 26812479SCurtis.Dunham@arm.com * Old functions needed for compatability but which will be phased out 26912479SCurtis.Dunham@arm.com * eventually. 27012479SCurtis.Dunham@arm.com */ 27112479SCurtis.Dunham@arm.com void 27212479SCurtis.Dunham@arm.com post(int int_num, int index) 27312479SCurtis.Dunham@arm.com { 27412479SCurtis.Dunham@arm.com panic("Interrupts::post unimplemented!\n"); 27512479SCurtis.Dunham@arm.com } 27612479SCurtis.Dunham@arm.com 27712479SCurtis.Dunham@arm.com void 27812479SCurtis.Dunham@arm.com clear(int int_num, int index) 27912479SCurtis.Dunham@arm.com { 28012479SCurtis.Dunham@arm.com panic("Interrupts::clear unimplemented!\n"); 28112479SCurtis.Dunham@arm.com } 28212479SCurtis.Dunham@arm.com 28312479SCurtis.Dunham@arm.com void 28412479SCurtis.Dunham@arm.com clearAll() 28512479SCurtis.Dunham@arm.com { 28612479SCurtis.Dunham@arm.com panic("Interrupts::clearAll unimplemented!\n"); 28712479SCurtis.Dunham@arm.com } 28812479SCurtis.Dunham@arm.com}; 28912479SCurtis.Dunham@arm.com 29012479SCurtis.Dunham@arm.com} // namespace X86ISA 29112479SCurtis.Dunham@arm.com 29212479SCurtis.Dunham@arm.com#endif // __ARCH_X86_INTERRUPTS_HH__ 29312479SCurtis.Dunham@arm.com