interrupts.cc (5651:7f0c8006c3d7) | interrupts.cc (5654:340254de2031) |
---|---|
1/* 2 * Copyright (c) 2008 The Hewlett-Packard Development Company 3 * All rights reserved. 4 * 5 * Redistribution and use of this software in source and binary forms, 6 * with or without modification, are permitted provided that the 7 * following conditions are met: 8 * --- 43 unchanged lines hidden (view full) --- 52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 54 * 55 * Authors: Gabe Black 56 */ 57 58#include "arch/x86/apicregs.hh" 59#include "arch/x86/interrupts.hh" | 1/* 2 * Copyright (c) 2008 The Hewlett-Packard Development Company 3 * All rights reserved. 4 * 5 * Redistribution and use of this software in source and binary forms, 6 * with or without modification, are permitted provided that the 7 * following conditions are met: 8 * --- 43 unchanged lines hidden (view full) --- 52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 54 * 55 * Authors: Gabe Black 56 */ 57 58#include "arch/x86/apicregs.hh" 59#include "arch/x86/interrupts.hh" |
60#include "arch/x86/intmessage.hh" |
|
60#include "cpu/base.hh" | 61#include "cpu/base.hh" |
62#include "mem/packet_access.hh" |
|
61 62int 63divideFromConf(uint32_t conf) 64{ 65 // This figures out what division we want from the division configuration 66 // register in the local APIC. The encoding is a little odd but it can 67 // be deciphered fairly easily. 68 int shift = ((conf & 0x8) >> 1) | (conf & 0x3); --- 168 unchanged lines hidden (view full) --- 237 reg, offset, gtoh(val)); 238 setReg(reg, gtoh(val)); 239 return latency; 240} 241 242Tick 243X86ISA::Interrupts::recvMessage(PacketPtr pkt) 244{ | 63 64int 65divideFromConf(uint32_t conf) 66{ 67 // This figures out what division we want from the division configuration 68 // register in the local APIC. The encoding is a little odd but it can 69 // be deciphered fairly easily. 70 int shift = ((conf & 0x8) >> 1) | (conf & 0x3); --- 168 unchanged lines hidden (view full) --- 239 reg, offset, gtoh(val)); 240 setReg(reg, gtoh(val)); 241 return latency; 242} 243 244Tick 245X86ISA::Interrupts::recvMessage(PacketPtr pkt) 246{ |
245 Addr offset = pkt->getAddr() - x86InterruptAddress(0, 0); | 247 uint8_t id = 0; 248 Addr offset = pkt->getAddr() - x86InterruptAddress(id, 0); |
246 assert(pkt->cmd == MemCmd::MessageReq); 247 switch(offset) 248 { 249 case 0: | 249 assert(pkt->cmd == MemCmd::MessageReq); 250 switch(offset) 251 { 252 case 0: |
250 DPRINTF(LocalApic, "Got Trigger Interrupt message.\n"); | 253 { 254 TriggerIntMessage message = pkt->get<TriggerIntMessage>(); 255 uint8_t vector = message.vector; 256 DPRINTF(LocalApic, 257 "Got Trigger Interrupt message with vector %#x.\n", 258 vector); 259 // Make sure we're really supposed to get this. 260 assert((message.destMode == 0 && message.destination == id) || 261 (bits((int)message.destination, id))); 262 if (DeliveryMode::isUnmaskable(message.deliveryMode)) { 263 DPRINTF(LocalApic, "Interrupt is an %s and unmaskable.\n", 264 DeliveryMode::names[message.deliveryMode]); 265 panic("Unmaskable interrupts aren't implemented.\n"); 266 } else if (DeliveryMode::isMaskable(message.deliveryMode)) { 267 DPRINTF(LocalApic, "Interrupt is an %s and maskable.\n", 268 DeliveryMode::names[message.deliveryMode]); 269 // Queue up the interrupt in the IRR. 270 if (vector > IRRV) 271 IRRV = vector; 272 if (!getRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector)) { 273 setRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector); 274 if (message.trigger) { 275 // Level triggered. 276 setRegArrayBit(APIC_TRIGGER_MODE_BASE, vector); 277 } else { 278 // Edge triggered. 279 clearRegArrayBit(APIC_TRIGGER_MODE_BASE, vector); 280 } 281 } 282 } 283 } |
251 break; 252 default: 253 panic("Local apic got unknown interrupt message at offset %#x.\n", 254 offset); 255 break; 256 } 257 delete pkt->req; 258 delete pkt; --- 150 unchanged lines hidden (view full) --- 409 break; 410 default: 411 break; 412 } 413 regs[reg] = newVal; 414 return; 415} 416 | 284 break; 285 default: 286 panic("Local apic got unknown interrupt message at offset %#x.\n", 287 offset); 288 break; 289 } 290 delete pkt->req; 291 delete pkt; --- 150 unchanged lines hidden (view full) --- 442 break; 443 default: 444 break; 445 } 446 regs[reg] = newVal; 447 return; 448} 449 |
450bool 451X86ISA::Interrupts::check_interrupts(ThreadContext * tc) const 452{ 453 RFLAGS rflags = tc->readMiscRegNoEffect(MISCREG_RFLAGS); 454 if (IRRV > ISRV && rflags.intf && 455 bits(IRRV, 7, 4) > bits(regs[APIC_TASK_PRIORITY], 7, 4)) { 456 return true; 457 } 458 return false; 459} 460 461Fault 462X86ISA::Interrupts::getInterrupt(ThreadContext * tc) 463{ 464 assert(check_interrupts(tc)); 465 return new ExternalInterrupt(IRRV); 466} 467 468void 469X86ISA::Interrupts::updateIntrInfo(ThreadContext * tc) 470{ 471 assert(check_interrupts(tc)); 472 // Mark the interrupt as "in service". 473 ISRV = IRRV; 474 setRegArrayBit(APIC_IN_SERVICE_BASE, ISRV); 475 // Clear it out of the IRR. 476 clearRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, IRRV); 477 updateIRRV(); 478} 479 |
|
417X86ISA::Interrupts * 418X86LocalApicParams::create() 419{ 420 return new X86ISA::Interrupts(this); 421} | 480X86ISA::Interrupts * 481X86LocalApicParams::create() 482{ 483 return new X86ISA::Interrupts(this); 484} |