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 * --- 460 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); |
477 if (pendingUnmaskableInt) { 478 DPRINTF(LocalApic, "Reported pending unmaskable interrupt.\n"); |
479 return true; |
480 } |
481 if (rflags.intf) { |
482 if (pendingExtInt) { 483 DPRINTF(LocalApic, "Reported pending external interrupt.\n"); |
484 return true; |
485 } |
486 if (IRRV > ISRV && bits(IRRV, 7, 4) > |
487 bits(regs[APIC_TASK_PRIORITY], 7, 4)) { 488 DPRINTF(LocalApic, "Reported pending regular interrupt.\n"); |
489 return true; |
490 } |
491 } 492 return false; 493} 494 495Fault 496X86ISA::Interrupts::getInterrupt(ThreadContext * tc) 497{ 498 assert(check_interrupts(tc)); 499 // These are all probably fairly uncommon, so we'll make them easier to 500 // check for. 501 if (pendingUnmaskableInt) { 502 if (pendingSmi) { |
503 DPRINTF(LocalApic, "Generated SMI fault object.\n"); |
504 return new SystemManagementInterrupt(); 505 } else if (pendingNmi) { |
506 DPRINTF(LocalApic, "Generated NMI fault object.\n"); |
507 return new NonMaskableInterrupt(nmiMessage.vector); 508 } else if (pendingInit) { |
509 DPRINTF(LocalApic, "Generated INIT fault object.\n"); |
510 return new InitInterrupt(initMessage.vector); 511 } else { 512 panic("pendingUnmaskableInt set, but no unmaskable " 513 "ints were pending.\n"); 514 return NoFault; 515 } 516 } else if (pendingExtInt) { |
517 DPRINTF(LocalApic, "Generated external interrupt fault object.\n"); |
518 return new ExternalInterrupt(extIntMessage.vector); 519 } else { |
520 DPRINTF(LocalApic, "Generated regular interrupt fault object.\n"); |
521 // The only thing left are fixed and lowest priority interrupts. 522 return new ExternalInterrupt(IRRV); 523 } 524} 525 526void 527X86ISA::Interrupts::updateIntrInfo(ThreadContext * tc) 528{ 529 assert(check_interrupts(tc)); 530 if (pendingUnmaskableInt) { 531 if (pendingSmi) { |
532 DPRINTF(LocalApic, "SMI sent to core.\n"); |
533 pendingSmi = false; 534 } else if (pendingNmi) { |
535 DPRINTF(LocalApic, "NMI sent to core.\n"); |
536 pendingNmi = false; 537 } else if (pendingInit) { |
538 DPRINTF(LocalApic, "Init sent to core.\n"); |
539 pendingInit = false; 540 } 541 if (!(pendingSmi || pendingNmi || pendingInit)) 542 pendingUnmaskableInt = false; 543 } else if (pendingExtInt) { 544 pendingExtInt = false; 545 } else { |
546 DPRINTF(LocalApic, "Interrupt %d sent to core.\n", IRRV); |
547 // Mark the interrupt as "in service". 548 ISRV = IRRV; 549 setRegArrayBit(APIC_IN_SERVICE_BASE, ISRV); 550 // Clear it out of the IRR. 551 clearRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, IRRV); 552 updateIRRV(); 553 } 554} 555 556X86ISA::Interrupts * 557X86LocalApicParams::create() 558{ 559 return new X86ISA::Interrupts(this); 560} |