interrupts.cc (5655:74f76480407f) interrupts.cc (5689:bd70811ff2ef)
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);
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)
477 if (pendingUnmaskableInt) {
478 DPRINTF(LocalApic, "Reported pending unmaskable interrupt.\n");
478 return true;
479 return true;
480 }
479 if (rflags.intf) {
481 if (rflags.intf) {
480 if (pendingExtInt)
482 if (pendingExtInt) {
483 DPRINTF(LocalApic, "Reported pending external interrupt.\n");
481 return true;
484 return true;
485 }
482 if (IRRV > ISRV && bits(IRRV, 7, 4) >
486 if (IRRV > ISRV && bits(IRRV, 7, 4) >
483 bits(regs[APIC_TASK_PRIORITY], 7, 4))
487 bits(regs[APIC_TASK_PRIORITY], 7, 4)) {
488 DPRINTF(LocalApic, "Reported pending regular interrupt.\n");
484 return true;
489 return true;
490 }
485 }
486 return false;
487}
488
489Fault
490X86ISA::Interrupts::getInterrupt(ThreadContext * tc)
491{
492 assert(check_interrupts(tc));
493 // These are all probably fairly uncommon, so we'll make them easier to
494 // check for.
495 if (pendingUnmaskableInt) {
496 if (pendingSmi) {
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");
497 return new SystemManagementInterrupt();
498 } else if (pendingNmi) {
504 return new SystemManagementInterrupt();
505 } else if (pendingNmi) {
506 DPRINTF(LocalApic, "Generated NMI fault object.\n");
499 return new NonMaskableInterrupt(nmiMessage.vector);
500 } else if (pendingInit) {
507 return new NonMaskableInterrupt(nmiMessage.vector);
508 } else if (pendingInit) {
509 DPRINTF(LocalApic, "Generated INIT fault object.\n");
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) {
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");
508 return new ExternalInterrupt(extIntMessage.vector);
509 } else {
518 return new ExternalInterrupt(extIntMessage.vector);
519 } else {
520 DPRINTF(LocalApic, "Generated regular interrupt fault object.\n");
510 // The only thing left are fixed and lowest priority interrupts.
511 return new ExternalInterrupt(IRRV);
512 }
513}
514
515void
516X86ISA::Interrupts::updateIntrInfo(ThreadContext * tc)
517{
518 assert(check_interrupts(tc));
519 if (pendingUnmaskableInt) {
520 if (pendingSmi) {
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");
521 pendingSmi = false;
522 } else if (pendingNmi) {
533 pendingSmi = false;
534 } else if (pendingNmi) {
535 DPRINTF(LocalApic, "NMI sent to core.\n");
523 pendingNmi = false;
524 } else if (pendingInit) {
536 pendingNmi = false;
537 } else if (pendingInit) {
538 DPRINTF(LocalApic, "Init sent to core.\n");
525 pendingInit = false;
526 }
527 if (!(pendingSmi || pendingNmi || pendingInit))
528 pendingUnmaskableInt = false;
529 } else if (pendingExtInt) {
530 pendingExtInt = false;
531 } else {
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);
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 }
539}
540
541X86ISA::Interrupts *
542X86LocalApicParams::create()
543{
544 return new X86ISA::Interrupts(this);
545}
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}