interrupts.hh revision 10541
12914Ssaidi@eecs.umich.edu/* 22914Ssaidi@eecs.umich.edu * Copyright (c) 2012 ARM Limited 32914Ssaidi@eecs.umich.edu * All rights reserved 42914Ssaidi@eecs.umich.edu * 52914Ssaidi@eecs.umich.edu * The license below extends only to copyright in the software and shall 62914Ssaidi@eecs.umich.edu * not be construed as granting a license to any other intellectual 72914Ssaidi@eecs.umich.edu * property including but not limited to intellectual property relating 82914Ssaidi@eecs.umich.edu * to a hardware implementation of the functionality of the software 92914Ssaidi@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 102914Ssaidi@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 112914Ssaidi@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 122914Ssaidi@eecs.umich.edu * modified or unmodified, in source code or in binary form. 132914Ssaidi@eecs.umich.edu * 142914Ssaidi@eecs.umich.edu * Copyright (c) 2007 The Hewlett-Packard Development Company 152914Ssaidi@eecs.umich.edu * All rights reserved. 162914Ssaidi@eecs.umich.edu * 172914Ssaidi@eecs.umich.edu * The license below extends only to copyright in the software and shall 182914Ssaidi@eecs.umich.edu * not be construed as granting a license to any other intellectual 192914Ssaidi@eecs.umich.edu * property including but not limited to intellectual property relating 202914Ssaidi@eecs.umich.edu * to a hardware implementation of the functionality of the software 212914Ssaidi@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 222914Ssaidi@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 232914Ssaidi@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 242914Ssaidi@eecs.umich.edu * modified or unmodified, in source code or in binary form. 252914Ssaidi@eecs.umich.edu * 262914Ssaidi@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 272914Ssaidi@eecs.umich.edu * modification, are permitted provided that the following conditions are 282914Ssaidi@eecs.umich.edu * met: redistributions of source code must retain the above copyright 292914Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 302914Ssaidi@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 313091Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 323091Sstever@eecs.umich.edu * documentation and/or other materials provided with the distribution; 333091Sstever@eecs.umich.edu * neither the name of the copyright holders nor the names of its 342914Ssaidi@eecs.umich.edu * contributors may be used to endorse or promote products derived from 352914Ssaidi@eecs.umich.edu * this software without specific prior written permission. 363091Sstever@eecs.umich.edu * 373091Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 382914Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 392914Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 402914Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 412914Ssaidi@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 422914Ssaidi@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 432914Ssaidi@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 442914Ssaidi@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 453091Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 463091Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 473091Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 483091Sstever@eecs.umich.edu * 493091Sstever@eecs.umich.edu * Authors: Gabe Black 503091Sstever@eecs.umich.edu * Andreas Hansson 513091Sstever@eecs.umich.edu */ 523091Sstever@eecs.umich.edu 533091Sstever@eecs.umich.edu#ifndef __ARCH_X86_INTERRUPTS_HH__ 543091Sstever@eecs.umich.edu#define __ARCH_X86_INTERRUPTS_HH__ 553091Sstever@eecs.umich.edu 563091Sstever@eecs.umich.edu#include "arch/x86/regs/apic.hh" 573091Sstever@eecs.umich.edu#include "arch/x86/faults.hh" 582914Ssaidi@eecs.umich.edu#include "arch/x86/intmessage.hh" 592914Ssaidi@eecs.umich.edu#include "base/bitfield.hh" 602914Ssaidi@eecs.umich.edu#include "cpu/thread_context.hh" 614490Sstever@eecs.umich.edu#include "dev/x86/intdev.hh" 624490Sstever@eecs.umich.edu#include "dev/io_device.hh" 634490Sstever@eecs.umich.edu#include "params/X86LocalApic.hh" 644490Sstever@eecs.umich.edu#include "sim/eventq.hh" 654490Sstever@eecs.umich.edu 664490Sstever@eecs.umich.educlass ThreadContext; 674490Sstever@eecs.umich.educlass BaseCPU; 684490Sstever@eecs.umich.edu 694490Sstever@eecs.umich.eduint divideFromConf(uint32_t conf); 704490Sstever@eecs.umich.edu 714490Sstever@eecs.umich.edunamespace X86ISA { 724490Sstever@eecs.umich.edu 734490Sstever@eecs.umich.eduApicRegIndex decodeAddr(Addr paddr); 743090Sstever@eecs.umich.edu 753090Sstever@eecs.umich.educlass Interrupts : public BasicPioDevice, IntDevice 764490Sstever@eecs.umich.edu{ 774490Sstever@eecs.umich.edu protected: 784490Sstever@eecs.umich.edu // Storage for the APIC registers 794490Sstever@eecs.umich.edu uint32_t regs[NUM_APIC_REGS]; 804490Sstever@eecs.umich.edu 813091Sstever@eecs.umich.edu BitUnion32(LVTEntry) 822914Ssaidi@eecs.umich.edu Bitfield<7, 0> vector; 833090Sstever@eecs.umich.edu Bitfield<10, 8> deliveryMode; 843403Ssaidi@eecs.umich.edu Bitfield<12> status; 853403Ssaidi@eecs.umich.edu Bitfield<13> polarity; 863403Ssaidi@eecs.umich.edu Bitfield<14> remoteIRR; 873403Ssaidi@eecs.umich.edu Bitfield<15> trigger; 884490Sstever@eecs.umich.edu Bitfield<16> masked; 894490Sstever@eecs.umich.edu Bitfield<17> periodic; 902914Ssaidi@eecs.umich.edu EndBitUnion(LVTEntry) 914490Sstever@eecs.umich.edu 922914Ssaidi@eecs.umich.edu /* 932914Ssaidi@eecs.umich.edu * Timing related stuff. 942914Ssaidi@eecs.umich.edu */ 952914Ssaidi@eecs.umich.edu class ApicTimerEvent : public Event 962914Ssaidi@eecs.umich.edu { 974490Sstever@eecs.umich.edu private: 984490Sstever@eecs.umich.edu Interrupts *localApic; 994490Sstever@eecs.umich.edu public: 1004490Sstever@eecs.umich.edu ApicTimerEvent(Interrupts *_localApic) : 1013403Ssaidi@eecs.umich.edu Event(), localApic(_localApic) 1023403Ssaidi@eecs.umich.edu {} 1033403Ssaidi@eecs.umich.edu 1043403Ssaidi@eecs.umich.edu void process() 1053403Ssaidi@eecs.umich.edu { 1062914Ssaidi@eecs.umich.edu assert(localApic); 1072914Ssaidi@eecs.umich.edu if (localApic->triggerTimerInterrupt()) { 1082914Ssaidi@eecs.umich.edu localApic->setReg(APIC_INITIAL_COUNT, 1092914Ssaidi@eecs.umich.edu localApic->readReg(APIC_INITIAL_COUNT)); 1102914Ssaidi@eecs.umich.edu } 1113091Sstever@eecs.umich.edu } 1123349Sbinkertn@umich.edu }; 1133091Sstever@eecs.umich.edu 1143091Sstever@eecs.umich.edu ApicTimerEvent apicTimerEvent; 1153349Sbinkertn@umich.edu 1163091Sstever@eecs.umich.edu /* 1173091Sstever@eecs.umich.edu * A set of variables to keep track of interrupts that don't go through 1183091Sstever@eecs.umich.edu * the IRR. 1193091Sstever@eecs.umich.edu */ 1203091Sstever@eecs.umich.edu bool pendingSmi; 1213091Sstever@eecs.umich.edu uint8_t smiVector; 1223091Sstever@eecs.umich.edu bool pendingNmi; 1233091Sstever@eecs.umich.edu uint8_t nmiVector; 1242914Ssaidi@eecs.umich.edu bool pendingExtInt; 1252914Ssaidi@eecs.umich.edu uint8_t extIntVector; 1263401Sktlim@umich.edu bool pendingInit; 1274490Sstever@eecs.umich.edu uint8_t initVector; 1284490Sstever@eecs.umich.edu bool pendingStartup; 1294490Sstever@eecs.umich.edu uint8_t startupVector; 1302914Ssaidi@eecs.umich.edu bool startedUp; 1312914Ssaidi@eecs.umich.edu 1324490Sstever@eecs.umich.edu // This is a quick check whether any of the above (except ExtInt) are set. 1334490Sstever@eecs.umich.edu bool pendingUnmaskableInt; 1343091Sstever@eecs.umich.edu 1353091Sstever@eecs.umich.edu // A count of how many IPIs are in flight. 1363091Sstever@eecs.umich.edu int pendingIPIs; 1373091Sstever@eecs.umich.edu 1383091Sstever@eecs.umich.edu /* 1393091Sstever@eecs.umich.edu * IRR and ISR maintenance. 1403091Sstever@eecs.umich.edu */ 1413091Sstever@eecs.umich.edu uint8_t IRRV; 1423091Sstever@eecs.umich.edu uint8_t ISRV; 1433091Sstever@eecs.umich.edu 1443091Sstever@eecs.umich.edu int 1453091Sstever@eecs.umich.edu findRegArrayMSB(ApicRegIndex base) 1463091Sstever@eecs.umich.edu { 1473091Sstever@eecs.umich.edu int offset = 7; 1483091Sstever@eecs.umich.edu do { 1493091Sstever@eecs.umich.edu if (regs[base + offset] != 0) { 1502914Ssaidi@eecs.umich.edu return offset * 32 + findMsbSet(regs[base + offset]); 1512914Ssaidi@eecs.umich.edu } 1522914Ssaidi@eecs.umich.edu } while (offset--); 1532914Ssaidi@eecs.umich.edu return 0; 154 } 155 156 void 157 updateIRRV() 158 { 159 IRRV = findRegArrayMSB(APIC_INTERRUPT_REQUEST_BASE); 160 } 161 162 void 163 updateISRV() 164 { 165 ISRV = findRegArrayMSB(APIC_IN_SERVICE_BASE); 166 } 167 168 void 169 setRegArrayBit(ApicRegIndex base, uint8_t vector) 170 { 171 regs[base + (vector / 32)] |= (1 << (vector % 32)); 172 } 173 174 void 175 clearRegArrayBit(ApicRegIndex base, uint8_t vector) 176 { 177 regs[base + (vector / 32)] &= ~(1 << (vector % 32)); 178 } 179 180 bool 181 getRegArrayBit(ApicRegIndex base, uint8_t vector) 182 { 183 return bits(regs[base + (vector / 32)], vector % 32); 184 } 185 186 void requestInterrupt(uint8_t vector, uint8_t deliveryMode, bool level); 187 188 BaseCPU *cpu; 189 190 int initialApicId; 191 192 // Port for receiving interrupts 193 IntSlavePort intSlavePort; 194 195 public: 196 197 int getInitialApicId() { return initialApicId; } 198 199 /* 200 * Params stuff. 201 */ 202 typedef X86LocalApicParams Params; 203 204 void setCPU(BaseCPU * newCPU); 205 206 const Params * 207 params() const 208 { 209 return dynamic_cast<const Params *>(_params); 210 } 211 212 /* 213 * Initialize this object by registering it with the IO APIC. 214 */ 215 void init(); 216 217 /* 218 * Functions to interact with the interrupt port from IntDevice. 219 */ 220 Tick read(PacketPtr pkt); 221 Tick write(PacketPtr pkt); 222 Tick recvMessage(PacketPtr pkt); 223 Tick recvResponse(PacketPtr pkt); 224 225 bool 226 triggerTimerInterrupt() 227 { 228 LVTEntry entry = regs[APIC_LVT_TIMER]; 229 if (!entry.masked) 230 requestInterrupt(entry.vector, entry.deliveryMode, entry.trigger); 231 return entry.periodic; 232 } 233 234 AddrRangeList getIntAddrRange() const; 235 236 BaseMasterPort &getMasterPort(const std::string &if_name, 237 PortID idx = InvalidPortID) 238 { 239 if (if_name == "int_master") { 240 return intMasterPort; 241 } 242 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