interrupts.hh revision 10112:1a2f64842044
12330SN/A/* 22330SN/A * Copyright (c) 2012 ARM Limited 32330SN/A * All rights reserved 42330SN/A * 52330SN/A * The license below extends only to copyright in the software and shall 62330SN/A * not be construed as granting a license to any other intellectual 72330SN/A * property including but not limited to intellectual property relating 82330SN/A * to a hardware implementation of the functionality of the software 92330SN/A * licensed hereunder. You may use the software subject to the license 102330SN/A * terms below provided that you ensure that this notice is replicated 112330SN/A * unmodified and in its entirety in all distributions of the software, 122330SN/A * modified or unmodified, in source code or in binary form. 132330SN/A * 142330SN/A * Copyright (c) 2007 The Hewlett-Packard Development Company 152330SN/A * All rights reserved. 162330SN/A * 172330SN/A * The license below extends only to copyright in the software and shall 182330SN/A * not be construed as granting a license to any other intellectual 192330SN/A * property including but not limited to intellectual property relating 202330SN/A * to a hardware implementation of the functionality of the software 212330SN/A * licensed hereunder. You may use the software subject to the license 222330SN/A * terms below provided that you ensure that this notice is replicated 232330SN/A * unmodified and in its entirety in all distributions of the software, 242330SN/A * modified or unmodified, in source code or in binary form. 252330SN/A * 262330SN/A * Redistribution and use in source and binary forms, with or without 272689Sktlim@umich.edu * modification, are permitted provided that the following conditions are 282689Sktlim@umich.edu * met: redistributions of source code must retain the above copyright 292330SN/A * notice, this list of conditions and the following disclaimer; 302292SN/A * redistributions in binary form must reproduce the above copyright 312292SN/A * notice, this list of conditions and the following disclaimer in the 322292SN/A * documentation and/or other materials provided with the distribution; 332292SN/A * neither the name of the copyright holders nor the names of its 342980Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 352362SN/A * this software without specific prior written permission. 362680Sktlim@umich.edu * 372292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 382678Sktlim@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 392683Sktlim@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 402683Sktlim@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 412678Sktlim@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 422678Sktlim@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 432292SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 442292SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 452292SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 462292SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 472330SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 482330SN/A * 492330SN/A * Authors: Gabe Black 502292SN/A * Andreas Hansson 512292SN/A */ 523402Sktlim@umich.edu 532862Sktlim@umich.edu#ifndef __ARCH_X86_INTERRUPTS_HH__ 543402Sktlim@umich.edu#define __ARCH_X86_INTERRUPTS_HH__ 552862Sktlim@umich.edu 562330SN/A#include "arch/x86/regs/apic.hh" 572330SN/A#include "arch/x86/faults.hh" 582330SN/A#include "arch/x86/intmessage.hh" 592330SN/A#include "base/bitfield.hh" 602330SN/A#include "cpu/thread_context.hh" 612330SN/A#include "dev/x86/intdev.hh" 622292SN/A#include "dev/io_device.hh" 632683Sktlim@umich.edu#include "params/X86LocalApic.hh" 642683Sktlim@umich.edu#include "sim/eventq.hh" 652292SN/A 663402Sktlim@umich.educlass ThreadContext; 672292SN/Aclass BaseCPU; 683402Sktlim@umich.edu 693402Sktlim@umich.eduint divideFromConf(uint32_t conf); 702292SN/A 712683Sktlim@umich.edunamespace X86ISA { 722862Sktlim@umich.edu 732862Sktlim@umich.eduApicRegIndex decodeAddr(Addr paddr); 742862Sktlim@umich.edu 752862Sktlim@umich.educlass Interrupts : public BasicPioDevice, IntDevice 762683Sktlim@umich.edu{ 772683Sktlim@umich.edu protected: 782683Sktlim@umich.edu // Storage for the APIC registers 792683Sktlim@umich.edu uint32_t regs[NUM_APIC_REGS]; 802683Sktlim@umich.edu 812683Sktlim@umich.edu BitUnion32(LVTEntry) 822683Sktlim@umich.edu Bitfield<7, 0> vector; 832683Sktlim@umich.edu Bitfield<10, 8> deliveryMode; 842683Sktlim@umich.edu Bitfield<12> status; 852683Sktlim@umich.edu Bitfield<13> polarity; 862683Sktlim@umich.edu Bitfield<14> remoteIRR; 872683Sktlim@umich.edu Bitfield<15> trigger; 882683Sktlim@umich.edu Bitfield<16> masked; 892683Sktlim@umich.edu Bitfield<17> periodic; 902683Sktlim@umich.edu EndBitUnion(LVTEntry) 912683Sktlim@umich.edu 922683Sktlim@umich.edu /* 932683Sktlim@umich.edu * Timing related stuff. 942683Sktlim@umich.edu */ 952683Sktlim@umich.edu class ApicTimerEvent : public Event 962683Sktlim@umich.edu { 972683Sktlim@umich.edu private: 982683Sktlim@umich.edu Interrupts *localApic; 992690Sktlim@umich.edu public: 1002690Sktlim@umich.edu ApicTimerEvent(Interrupts *_localApic) : 1012683Sktlim@umich.edu Event(), localApic(_localApic) 1022683Sktlim@umich.edu {} 1032690Sktlim@umich.edu 1042690Sktlim@umich.edu void process() 1052683Sktlim@umich.edu { 1062683Sktlim@umich.edu assert(localApic); 1072683Sktlim@umich.edu if (localApic->triggerTimerInterrupt()) { 1082683Sktlim@umich.edu localApic->setReg(APIC_INITIAL_COUNT, 1093402Sktlim@umich.edu localApic->readReg(APIC_INITIAL_COUNT)); 1102683Sktlim@umich.edu } 1112683Sktlim@umich.edu } 1122683Sktlim@umich.edu }; 1132683Sktlim@umich.edu 1142683Sktlim@umich.edu ApicTimerEvent apicTimerEvent; 1152678Sktlim@umich.edu 1162292SN/A /* 1172683Sktlim@umich.edu * A set of variables to keep track of interrupts that don't go through 1182683Sktlim@umich.edu * the IRR. 1192292SN/A */ 1202683Sktlim@umich.edu bool pendingSmi; 1212683Sktlim@umich.edu uint8_t smiVector; 1222683Sktlim@umich.edu bool pendingNmi; 1232683Sktlim@umich.edu uint8_t nmiVector; 1242683Sktlim@umich.edu bool pendingExtInt; 1252683Sktlim@umich.edu uint8_t extIntVector; 1262683Sktlim@umich.edu bool pendingInit; 1272683Sktlim@umich.edu uint8_t initVector; 1282683Sktlim@umich.edu bool pendingStartup; 1292683Sktlim@umich.edu uint8_t startupVector; 1302683Sktlim@umich.edu bool startedUp; 1312683Sktlim@umich.edu 1322683Sktlim@umich.edu // This is a quick check whether any of the above (except ExtInt) are set. 1332683Sktlim@umich.edu bool pendingUnmaskableInt; 1342683Sktlim@umich.edu 1352683Sktlim@umich.edu // A count of how many IPIs are in flight. 1362683Sktlim@umich.edu int pendingIPIs; 1372683Sktlim@umich.edu 1382683Sktlim@umich.edu /* 1392683Sktlim@umich.edu * IRR and ISR maintenance. 1402683Sktlim@umich.edu */ 1412683Sktlim@umich.edu uint8_t IRRV; 1422683Sktlim@umich.edu uint8_t ISRV; 1432683Sktlim@umich.edu 1442683Sktlim@umich.edu int 1452683Sktlim@umich.edu findRegArrayMSB(ApicRegIndex base) 1462683Sktlim@umich.edu { 1472683Sktlim@umich.edu int offset = 7; 1482683Sktlim@umich.edu do { 1492683Sktlim@umich.edu if (regs[base + offset] != 0) { 1502683Sktlim@umich.edu return offset * 32 + findMsbSet(regs[base + offset]); 1512683Sktlim@umich.edu } 1522683Sktlim@umich.edu } while (offset--); 1532683Sktlim@umich.edu return 0; 1542683Sktlim@umich.edu } 1552683Sktlim@umich.edu 1562683Sktlim@umich.edu void 1573402Sktlim@umich.edu updateIRRV() 1583402Sktlim@umich.edu { 1593402Sktlim@umich.edu IRRV = findRegArrayMSB(APIC_INTERRUPT_REQUEST_BASE); 1602683Sktlim@umich.edu } 1612683Sktlim@umich.edu 1622292SN/A void 1632292SN/A updateISRV() 1642292SN/A { 1652292SN/A ISRV = findRegArrayMSB(APIC_IN_SERVICE_BASE); 1662292SN/A } 1672690Sktlim@umich.edu 1682683Sktlim@umich.edu void 1692683Sktlim@umich.edu setRegArrayBit(ApicRegIndex base, uint8_t vector) 1702292SN/A { 1712683Sktlim@umich.edu regs[base + (vector / 32)] |= (1 << (vector % 32)); 1722683Sktlim@umich.edu } 1732292SN/A 1742292SN/A void 1752683Sktlim@umich.edu clearRegArrayBit(ApicRegIndex base, uint8_t vector) 1762292SN/A { 1772292SN/A regs[base + (vector / 32)] &= ~(1 << (vector % 32)); 1782292SN/A } 1792292SN/A 1802292SN/A bool 1812330SN/A getRegArrayBit(ApicRegIndex base, uint8_t vector) 1822683Sktlim@umich.edu { 1832683Sktlim@umich.edu return bits(regs[base + (vector / 32)], vector % 5); 1842683Sktlim@umich.edu } 1852683Sktlim@umich.edu 1862683Sktlim@umich.edu void requestInterrupt(uint8_t vector, uint8_t deliveryMode, bool level); 1872683Sktlim@umich.edu 1882683Sktlim@umich.edu BaseCPU *cpu; 1892683Sktlim@umich.edu 1902292SN/A int initialApicId; 1912678Sktlim@umich.edu 1922678Sktlim@umich.edu // Port for receiving interrupts 1932292SN/A IntSlavePort intSlavePort; 1942292SN/A 1952292SN/A public: 1962292SN/A 1972292SN/A int getInitialApicId() { return initialApicId; } 1982292SN/A 1992330SN/A /* 2002330SN/A * Params stuff. 2012330SN/A */ 2022683Sktlim@umich.edu typedef X86LocalApicParams Params; 2032683Sktlim@umich.edu 2042683Sktlim@umich.edu void setCPU(BaseCPU * newCPU); 2052683Sktlim@umich.edu 2062292SN/A const Params * 2073276Sgblack@eecs.umich.edu params() const 2083276Sgblack@eecs.umich.edu { 2093276Sgblack@eecs.umich.edu return dynamic_cast<const Params *>(_params); 2103276Sgblack@eecs.umich.edu } 2113276Sgblack@eecs.umich.edu 2123276Sgblack@eecs.umich.edu /* 2133276Sgblack@eecs.umich.edu * Initialize this object by registering it with the IO APIC. 2143276Sgblack@eecs.umich.edu */ 2153276Sgblack@eecs.umich.edu void init(); 2163276Sgblack@eecs.umich.edu 2172690Sktlim@umich.edu /* 2182292SN/A * Functions to interact with the interrupt port from IntDevice. 2192292SN/A */ 2202292SN/A Tick read(PacketPtr pkt); 2212292SN/A Tick write(PacketPtr pkt); 2222292SN/A Tick recvMessage(PacketPtr pkt); 2232292SN/A Tick recvResponse(PacketPtr pkt); 2242292SN/A 2252292SN/A bool 2262292SN/A triggerTimerInterrupt() 2272292SN/A { 2282292SN/A LVTEntry entry = regs[APIC_LVT_TIMER]; 2292292SN/A if (!entry.masked) 2302292SN/A requestInterrupt(entry.vector, entry.deliveryMode, entry.trigger); 2312292SN/A return entry.periodic; 2322292SN/A } 2332292SN/A 2342292SN/A AddrRangeList getIntAddrRange() const; 2352292SN/A 2362292SN/A BaseMasterPort &getMasterPort(const std::string &if_name, 2372292SN/A PortID idx = InvalidPortID) 2382292SN/A { 2392292SN/A if (if_name == "int_master") { 2402292SN/A return intMasterPort; 2412292SN/A } 2422292SN/A return BasicPioDevice::getMasterPort(if_name, idx); 243 } 244 245 BaseSlavePort &getSlavePort(const std::string &if_name, 246 PortID idx = InvalidPortID) 247 { 248 if (if_name == "int_slave") { 249 return intSlavePort; 250 } 251 return BasicPioDevice::getSlavePort(if_name, idx); 252 } 253 254 /* 255 * Functions to access and manipulate the APIC's registers. 256 */ 257 258 uint32_t readReg(ApicRegIndex miscReg); 259 void setReg(ApicRegIndex reg, uint32_t val); 260 void 261 setRegNoEffect(ApicRegIndex reg, uint32_t val) 262 { 263 regs[reg] = val; 264 } 265 266 /* 267 * Constructor. 268 */ 269 270 Interrupts(Params * p); 271 272 /* 273 * Functions for retrieving interrupts for the CPU to handle. 274 */ 275 276 bool checkInterrupts(ThreadContext *tc) const; 277 /** 278 * Check if there are pending interrupts without ignoring the 279 * interrupts disabled flag. 280 * 281 * @return true if there are interrupts pending. 282 */ 283 bool checkInterruptsRaw() const; 284 /** 285 * Check if there are pending unmaskable interrupts. 286 * 287 * @return true there are unmaskable interrupts pending. 288 */ 289 bool hasPendingUnmaskable() const { return pendingUnmaskableInt; } 290 Fault getInterrupt(ThreadContext *tc); 291 void updateIntrInfo(ThreadContext *tc); 292 293 /* 294 * Serialization. 295 */ 296 297 virtual void serialize(std::ostream &os); 298 virtual void unserialize(Checkpoint *cp, const std::string §ion); 299 300 /* 301 * Old functions needed for compatability but which will be phased out 302 * eventually. 303 */ 304 void 305 post(int int_num, int index) 306 { 307 panic("Interrupts::post unimplemented!\n"); 308 } 309 310 void 311 clear(int int_num, int index) 312 { 313 panic("Interrupts::clear unimplemented!\n"); 314 } 315 316 void 317 clearAll() 318 { 319 panic("Interrupts::clearAll unimplemented!\n"); 320 } 321}; 322 323} // namespace X86ISA 324 325#endif // __ARCH_X86_INTERRUPTS_HH__ 326