interrupts.cc (5654:340254de2031) | interrupts.cc (5655:74f76480407f) |
---|---|
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 * --- 245 unchanged lines hidden (view full) --- 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))); | 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 * --- 245 unchanged lines hidden (view full) --- 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", | 262 263 /* 264 * Fixed and lowest-priority delivery mode interrupts are handled 265 * using the IRR/ISR registers, checking against the TPR, etc. 266 * The SMI, NMI, ExtInt, INIT, etc interrupts go straight through. 267 */ 268 if (message.deliveryMode == DeliveryMode::Fixed || 269 message.deliveryMode == DeliveryMode::LowestPriority) { 270 DPRINTF(LocalApic, "Interrupt is an %s.\n", |
264 DeliveryMode::names[message.deliveryMode]); | 271 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 } | 272 // Queue up the interrupt in the IRR. 273 if (vector > IRRV) 274 IRRV = vector; 275 if (!getRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector)) { 276 setRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector); 277 if (message.trigger) { 278 // Level triggered. 279 setRegArrayBit(APIC_TRIGGER_MODE_BASE, vector); 280 } else { 281 // Edge triggered. 282 clearRegArrayBit(APIC_TRIGGER_MODE_BASE, vector); 283 } 284 } |
282 } | 285 } else if (!DeliveryMode::isReserved(message.deliveryMode)) { 286 DPRINTF(LocalApic, "Interrupt is an %s.\n", 287 DeliveryMode::names[message.deliveryMode]); 288 if (message.deliveryMode == DeliveryMode::SMI && 289 !pendingSmi) { 290 pendingUnmaskableInt = pendingSmi = true; 291 smiMessage = message; 292 } else if (message.deliveryMode == DeliveryMode::NMI && 293 !pendingNmi) { 294 pendingUnmaskableInt = pendingNmi = true; 295 nmiMessage = message; 296 } else if (message.deliveryMode == DeliveryMode::ExtInt && 297 !pendingExtInt) { 298 pendingExtInt = true; 299 extIntMessage = message; 300 } else if (message.deliveryMode == DeliveryMode::INIT && 301 !pendingInit) { 302 pendingUnmaskableInt = pendingInit = true; 303 initMessage = message; 304 } 305 } |
283 } 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; --- 155 unchanged lines hidden (view full) --- 446 regs[reg] = newVal; 447 return; 448} 449 450bool 451X86ISA::Interrupts::check_interrupts(ThreadContext * tc) const 452{ 453 RFLAGS rflags = tc->readMiscRegNoEffect(MISCREG_RFLAGS); | 306 } 307 break; 308 default: 309 panic("Local apic got unknown interrupt message at offset %#x.\n", 310 offset); 311 break; 312 } 313 delete pkt->req; --- 155 unchanged lines hidden (view full) --- 469 regs[reg] = newVal; 470 return; 471} 472 473bool 474X86ISA::Interrupts::check_interrupts(ThreadContext * tc) const 475{ 476 RFLAGS rflags = tc->readMiscRegNoEffect(MISCREG_RFLAGS); |
454 if (IRRV > ISRV && rflags.intf && 455 bits(IRRV, 7, 4) > bits(regs[APIC_TASK_PRIORITY], 7, 4)) { | 477 if (pendingUnmaskableInt) |
456 return true; | 478 return true; |
479 if (rflags.intf) { 480 if (pendingExtInt) 481 return true; 482 if (IRRV > ISRV && bits(IRRV, 7, 4) > 483 bits(regs[APIC_TASK_PRIORITY], 7, 4)) 484 return true; |
|
457 } 458 return false; 459} 460 461Fault 462X86ISA::Interrupts::getInterrupt(ThreadContext * tc) 463{ 464 assert(check_interrupts(tc)); | 485 } 486 return false; 487} 488 489Fault 490X86ISA::Interrupts::getInterrupt(ThreadContext * tc) 491{ 492 assert(check_interrupts(tc)); |
465 return new ExternalInterrupt(IRRV); | 493 // These are all probably fairly uncommon, so we'll make them easier to 494 // check for. 495 if (pendingUnmaskableInt) { 496 if (pendingSmi) { 497 return new SystemManagementInterrupt(); 498 } else if (pendingNmi) { 499 return new NonMaskableInterrupt(nmiMessage.vector); 500 } else if (pendingInit) { 501 return new InitInterrupt(initMessage.vector); 502 } else { 503 panic("pendingUnmaskableInt set, but no unmaskable " 504 "ints were pending.\n"); 505 return NoFault; 506 } 507 } else if (pendingExtInt) { 508 return new ExternalInterrupt(extIntMessage.vector); 509 } else { 510 // The only thing left are fixed and lowest priority interrupts. 511 return new ExternalInterrupt(IRRV); 512 } |
466} 467 468void 469X86ISA::Interrupts::updateIntrInfo(ThreadContext * tc) 470{ 471 assert(check_interrupts(tc)); | 513} 514 515void 516X86ISA::Interrupts::updateIntrInfo(ThreadContext * tc) 517{ 518 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(); | 519 if (pendingUnmaskableInt) { 520 if (pendingSmi) { 521 pendingSmi = false; 522 } else if (pendingNmi) { 523 pendingNmi = false; 524 } else if (pendingInit) { 525 pendingInit = false; 526 } 527 if (!(pendingSmi || pendingNmi || pendingInit)) 528 pendingUnmaskableInt = false; 529 } else if (pendingExtInt) { 530 pendingExtInt = false; 531 } else { 532 // Mark the interrupt as "in service". 533 ISRV = IRRV; 534 setRegArrayBit(APIC_IN_SERVICE_BASE, ISRV); 535 // Clear it out of the IRR. 536 clearRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, IRRV); 537 updateIRRV(); 538 } |
478} 479 480X86ISA::Interrupts * 481X86LocalApicParams::create() 482{ 483 return new X86ISA::Interrupts(this); 484} | 539} 540 541X86ISA::Interrupts * 542X86LocalApicParams::create() 543{ 544 return new X86ISA::Interrupts(this); 545} |