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}