interrupts.hh revision 14293
112802Sandreas.sandberg@arm.com/* 212802Sandreas.sandberg@arm.com * Copyright (c) 2012 ARM Limited 312802Sandreas.sandberg@arm.com * All rights reserved 412802Sandreas.sandberg@arm.com * 512802Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall 612802Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual 712802Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating 812802Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software 912802Sandreas.sandberg@arm.com * licensed hereunder. You may use the software subject to the license 1012802Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated 1112802Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software, 1212802Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form. 1312802Sandreas.sandberg@arm.com * 1412802Sandreas.sandberg@arm.com * Copyright (c) 2007 The Hewlett-Packard Development Company 1512802Sandreas.sandberg@arm.com * All rights reserved. 1612802Sandreas.sandberg@arm.com * 1712802Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall 1812802Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual 1912802Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating 2012802Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software 2112802Sandreas.sandberg@arm.com * licensed hereunder. You may use the software subject to the license 2212802Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated 2312802Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software, 2412802Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form. 2512802Sandreas.sandberg@arm.com * 2612802Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without 2712802Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are 2812802Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 2912802Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 3012802Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 3112802Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 3212802Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 3312802Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its 3412802Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from 3512802Sandreas.sandberg@arm.com * this software without specific prior written permission. 3612802Sandreas.sandberg@arm.com * 3712802Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3812802Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3912802Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 4012802Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 4112802Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4212802Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 4312802Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 4412802Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 4512802Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 4612802Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 4712802Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4812802Sandreas.sandberg@arm.com * 4912802Sandreas.sandberg@arm.com * Authors: Gabe Black 5012802Sandreas.sandberg@arm.com * Andreas Hansson 5112802Sandreas.sandberg@arm.com */ 5212802Sandreas.sandberg@arm.com 5312802Sandreas.sandberg@arm.com#ifndef __ARCH_X86_INTERRUPTS_HH__ 5412802Sandreas.sandberg@arm.com#define __ARCH_X86_INTERRUPTS_HH__ 5512802Sandreas.sandberg@arm.com 5612802Sandreas.sandberg@arm.com#include "arch/x86/regs/apic.hh" 5712802Sandreas.sandberg@arm.com#include "arch/x86/faults.hh" 5812802Sandreas.sandberg@arm.com#include "arch/x86/intmessage.hh" 5912802Sandreas.sandberg@arm.com#include "base/bitfield.hh" 6012802Sandreas.sandberg@arm.com#include "cpu/thread_context.hh" 6112802Sandreas.sandberg@arm.com#include "dev/x86/intdev.hh" 6212802Sandreas.sandberg@arm.com#include "dev/io_device.hh" 6313784Sgabeblack@google.com#include "params/X86LocalApic.hh" 6413784Sgabeblack@google.com#include "sim/eventq.hh" 6512802Sandreas.sandberg@arm.com 6612802Sandreas.sandberg@arm.comclass ThreadContext; 6712802Sandreas.sandberg@arm.comclass BaseCPU; 6813784Sgabeblack@google.com 6912802Sandreas.sandberg@arm.comint divideFromConf(uint32_t conf); 7012802Sandreas.sandberg@arm.com 7113784Sgabeblack@google.comnamespace X86ISA { 7212802Sandreas.sandberg@arm.com 7312802Sandreas.sandberg@arm.comApicRegIndex decodeAddr(Addr paddr); 7412802Sandreas.sandberg@arm.com 7512802Sandreas.sandberg@arm.comclass Interrupts : public PioDevice, IntDevice 7612823Srmk35@cl.cam.ac.uk{ 7712802Sandreas.sandberg@arm.com protected: 7812823Srmk35@cl.cam.ac.uk // Storage for the APIC registers 7912823Srmk35@cl.cam.ac.uk uint32_t regs[NUM_APIC_REGS]; 8012802Sandreas.sandberg@arm.com 8112802Sandreas.sandberg@arm.com BitUnion32(LVTEntry) 8212802Sandreas.sandberg@arm.com Bitfield<7, 0> vector; 8312802Sandreas.sandberg@arm.com Bitfield<10, 8> deliveryMode; 8412802Sandreas.sandberg@arm.com Bitfield<12> status; 8512802Sandreas.sandberg@arm.com Bitfield<13> polarity; 8612802Sandreas.sandberg@arm.com Bitfield<14> remoteIRR; 8712802Sandreas.sandberg@arm.com Bitfield<15> trigger; 8812802Sandreas.sandberg@arm.com Bitfield<16> masked; 8912802Sandreas.sandberg@arm.com Bitfield<17> periodic; 9012802Sandreas.sandberg@arm.com EndBitUnion(LVTEntry) 9112802Sandreas.sandberg@arm.com 9212802Sandreas.sandberg@arm.com /* 9312802Sandreas.sandberg@arm.com * Timing related stuff. 9412802Sandreas.sandberg@arm.com */ 9512802Sandreas.sandberg@arm.com EventFunctionWrapper apicTimerEvent; 9612802Sandreas.sandberg@arm.com void processApicTimerEvent(); 9712802Sandreas.sandberg@arm.com 9812802Sandreas.sandberg@arm.com /* 9912802Sandreas.sandberg@arm.com * A set of variables to keep track of interrupts that don't go through 10012802Sandreas.sandberg@arm.com * the IRR. 10112802Sandreas.sandberg@arm.com */ 10212823Srmk35@cl.cam.ac.uk bool pendingSmi; 10312802Sandreas.sandberg@arm.com uint8_t smiVector; 10412802Sandreas.sandberg@arm.com bool pendingNmi; 10512802Sandreas.sandberg@arm.com uint8_t nmiVector; 10612802Sandreas.sandberg@arm.com bool pendingExtInt; 10712802Sandreas.sandberg@arm.com uint8_t extIntVector; 10812802Sandreas.sandberg@arm.com bool pendingInit; 10912802Sandreas.sandberg@arm.com uint8_t initVector; 11012802Sandreas.sandberg@arm.com bool pendingStartup; 11112802Sandreas.sandberg@arm.com uint8_t startupVector; 11212802Sandreas.sandberg@arm.com bool startedUp; 11312802Sandreas.sandberg@arm.com 11412802Sandreas.sandberg@arm.com // This is a quick check whether any of the above (except ExtInt) are set. 11512802Sandreas.sandberg@arm.com bool pendingUnmaskableInt; 11612802Sandreas.sandberg@arm.com 11712802Sandreas.sandberg@arm.com // A count of how many IPIs are in flight. 11812802Sandreas.sandberg@arm.com int pendingIPIs; 11912802Sandreas.sandberg@arm.com 12012802Sandreas.sandberg@arm.com /* 12112802Sandreas.sandberg@arm.com * IRR and ISR maintenance. 12212802Sandreas.sandberg@arm.com */ 12312802Sandreas.sandberg@arm.com uint8_t IRRV; 12412802Sandreas.sandberg@arm.com uint8_t ISRV; 12512802Sandreas.sandberg@arm.com 12612802Sandreas.sandberg@arm.com int 12712802Sandreas.sandberg@arm.com findRegArrayMSB(ApicRegIndex base) 12812802Sandreas.sandberg@arm.com { 12912802Sandreas.sandberg@arm.com int offset = 7; 13012802Sandreas.sandberg@arm.com do { 13112802Sandreas.sandberg@arm.com if (regs[base + offset] != 0) { 13212802Sandreas.sandberg@arm.com return offset * 32 + findMsbSet(regs[base + offset]); 13312802Sandreas.sandberg@arm.com } 13412802Sandreas.sandberg@arm.com } while (offset--); 13512802Sandreas.sandberg@arm.com return 0; 13612802Sandreas.sandberg@arm.com } 13712802Sandreas.sandberg@arm.com 13812802Sandreas.sandberg@arm.com void 13912802Sandreas.sandberg@arm.com updateIRRV() 14012802Sandreas.sandberg@arm.com { 14112802Sandreas.sandberg@arm.com IRRV = findRegArrayMSB(APIC_INTERRUPT_REQUEST_BASE); 14212802Sandreas.sandberg@arm.com } 14312802Sandreas.sandberg@arm.com 14412802Sandreas.sandberg@arm.com void 14512802Sandreas.sandberg@arm.com updateISRV() 14612802Sandreas.sandberg@arm.com { 14712802Sandreas.sandberg@arm.com ISRV = findRegArrayMSB(APIC_IN_SERVICE_BASE); 14812802Sandreas.sandberg@arm.com } 14912802Sandreas.sandberg@arm.com 15012802Sandreas.sandberg@arm.com void 15112823Srmk35@cl.cam.ac.uk setRegArrayBit(ApicRegIndex base, uint8_t vector) 15212802Sandreas.sandberg@arm.com { 15312802Sandreas.sandberg@arm.com regs[base + (vector / 32)] |= (1 << (vector % 32)); 15412802Sandreas.sandberg@arm.com } 15512802Sandreas.sandberg@arm.com 15612802Sandreas.sandberg@arm.com void 15712802Sandreas.sandberg@arm.com clearRegArrayBit(ApicRegIndex base, uint8_t vector) 15812802Sandreas.sandberg@arm.com { 15912802Sandreas.sandberg@arm.com regs[base + (vector / 32)] &= ~(1 << (vector % 32)); 16012802Sandreas.sandberg@arm.com } 16112802Sandreas.sandberg@arm.com 16212802Sandreas.sandberg@arm.com bool 16312802Sandreas.sandberg@arm.com getRegArrayBit(ApicRegIndex base, uint8_t vector) 16412802Sandreas.sandberg@arm.com { 16512802Sandreas.sandberg@arm.com return bits(regs[base + (vector / 32)], vector % 32); 16612802Sandreas.sandberg@arm.com } 16712802Sandreas.sandberg@arm.com 16812802Sandreas.sandberg@arm.com void requestInterrupt(uint8_t vector, uint8_t deliveryMode, bool level); 16912802Sandreas.sandberg@arm.com 17012802Sandreas.sandberg@arm.com BaseCPU *cpu; 17112802Sandreas.sandberg@arm.com 17212802Sandreas.sandberg@arm.com int initialApicId; 17312802Sandreas.sandberg@arm.com 17412802Sandreas.sandberg@arm.com // Port for receiving interrupts 17512802Sandreas.sandberg@arm.com IntSlavePort intSlavePort; 17612802Sandreas.sandberg@arm.com 17712802Sandreas.sandberg@arm.com Tick pioDelay; 17812802Sandreas.sandberg@arm.com Addr pioAddr = MaxAddr; 17912802Sandreas.sandberg@arm.com 18012802Sandreas.sandberg@arm.com public: 18112802Sandreas.sandberg@arm.com 18212802Sandreas.sandberg@arm.com int getInitialApicId() { return initialApicId; } 18312802Sandreas.sandberg@arm.com 18412802Sandreas.sandberg@arm.com /* 18512802Sandreas.sandberg@arm.com * Params stuff. 18612802Sandreas.sandberg@arm.com */ 18712802Sandreas.sandberg@arm.com typedef X86LocalApicParams Params; 18812802Sandreas.sandberg@arm.com 18912802Sandreas.sandberg@arm.com void setCPU(BaseCPU * newCPU); 19012802Sandreas.sandberg@arm.com 19112802Sandreas.sandberg@arm.com const Params * 19212802Sandreas.sandberg@arm.com params() const 19312802Sandreas.sandberg@arm.com { 19412802Sandreas.sandberg@arm.com return dynamic_cast<const Params *>(_params); 19512802Sandreas.sandberg@arm.com } 19612802Sandreas.sandberg@arm.com 19712802Sandreas.sandberg@arm.com /* 19812802Sandreas.sandberg@arm.com * Initialize this object by registering it with the IO APIC. 19912802Sandreas.sandberg@arm.com */ 20012802Sandreas.sandberg@arm.com void init() override; 20112802Sandreas.sandberg@arm.com 20212802Sandreas.sandberg@arm.com /* 20312802Sandreas.sandberg@arm.com * Functions to interact with the interrupt port from IntDevice. 20412802Sandreas.sandberg@arm.com */ 20512802Sandreas.sandberg@arm.com Tick read(PacketPtr pkt) override; 20612802Sandreas.sandberg@arm.com Tick write(PacketPtr pkt) override; 20712802Sandreas.sandberg@arm.com Tick recvMessage(PacketPtr pkt) override; 20812802Sandreas.sandberg@arm.com Tick recvResponse(PacketPtr pkt) override; 209 210 bool 211 triggerTimerInterrupt() 212 { 213 LVTEntry entry = regs[APIC_LVT_TIMER]; 214 if (!entry.masked) 215 requestInterrupt(entry.vector, entry.deliveryMode, entry.trigger); 216 return entry.periodic; 217 } 218 219 AddrRangeList getAddrRanges() const override; 220 AddrRangeList getIntAddrRange() const override; 221 222 Port &getPort(const std::string &if_name, 223 PortID idx=InvalidPortID) override 224 { 225 if (if_name == "int_master") { 226 return intMasterPort; 227 } else if (if_name == "int_slave") { 228 return intSlavePort; 229 } 230 return PioDevice::getPort(if_name, idx); 231 } 232 233 /* 234 * Functions to access and manipulate the APIC's registers. 235 */ 236 237 uint32_t readReg(ApicRegIndex miscReg); 238 void setReg(ApicRegIndex reg, uint32_t val); 239 void 240 setRegNoEffect(ApicRegIndex reg, uint32_t val) 241 { 242 regs[reg] = val; 243 } 244 245 /* 246 * Constructor. 247 */ 248 249 Interrupts(Params * p); 250 251 /* 252 * Functions for retrieving interrupts for the CPU to handle. 253 */ 254 255 bool checkInterrupts(ThreadContext *tc) const; 256 /** 257 * Check if there are pending interrupts without ignoring the 258 * interrupts disabled flag. 259 * 260 * @return true if there are interrupts pending. 261 */ 262 bool checkInterruptsRaw() const; 263 /** 264 * Check if there are pending unmaskable interrupts. 265 * 266 * @return true there are unmaskable interrupts pending. 267 */ 268 bool hasPendingUnmaskable() const { return pendingUnmaskableInt; } 269 Fault getInterrupt(ThreadContext *tc); 270 void updateIntrInfo(ThreadContext *tc); 271 272 /* 273 * Serialization. 274 */ 275 void serialize(CheckpointOut &cp) const override; 276 void unserialize(CheckpointIn &cp) override; 277 278 /* 279 * Old functions needed for compatability but which will be phased out 280 * eventually. 281 */ 282 void 283 post(int int_num, int index) 284 { 285 panic("Interrupts::post unimplemented!\n"); 286 } 287 288 void 289 clear(int int_num, int index) 290 { 291 panic("Interrupts::clear unimplemented!\n"); 292 } 293 294 void 295 clearAll() 296 { 297 panic("Interrupts::clearAll unimplemented!\n"); 298 } 299}; 300 301} // namespace X86ISA 302 303#endif // __ARCH_X86_INTERRUPTS_HH__ 304