interrupts.cc (5690:0fee2dde61d7) interrupts.cc (5691:28d6ff8b94e2)
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 *

--- 226 unchanged lines hidden (view full) ---

235 uint32_t val = regs[reg];
236 pkt->writeData(((uint8_t *)&val) + (offset & mask(3)));
237 DPRINTF(LocalApic,
238 "Writing Local APIC register %d at offset %#x as %#x.\n",
239 reg, offset, gtoh(val));
240 setReg(reg, gtoh(val));
241 return latency;
242}
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 *

--- 226 unchanged lines hidden (view full) ---

235 uint32_t val = regs[reg];
236 pkt->writeData(((uint8_t *)&val) + (offset & mask(3)));
237 DPRINTF(LocalApic,
238 "Writing Local APIC register %d at offset %#x as %#x.\n",
239 reg, offset, gtoh(val));
240 setReg(reg, gtoh(val));
241 return latency;
242}
243void
244X86ISA::Interrupts::requestInterrupt(uint8_t vector,
245 uint8_t deliveryMode, bool level)
246{
247 /*
248 * Fixed and lowest-priority delivery mode interrupts are handled
249 * using the IRR/ISR registers, checking against the TPR, etc.
250 * The SMI, NMI, ExtInt, INIT, etc interrupts go straight through.
251 */
252 if (deliveryMode == DeliveryMode::Fixed ||
253 deliveryMode == DeliveryMode::LowestPriority) {
254 DPRINTF(LocalApic, "Interrupt is an %s.\n",
255 DeliveryMode::names[deliveryMode]);
256 // Queue up the interrupt in the IRR.
257 if (vector > IRRV)
258 IRRV = vector;
259 if (!getRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector)) {
260 setRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector);
261 if (level) {
262 setRegArrayBit(APIC_TRIGGER_MODE_BASE, vector);
263 } else {
264 clearRegArrayBit(APIC_TRIGGER_MODE_BASE, vector);
265 }
266 }
267 } else if (!DeliveryMode::isReserved(deliveryMode)) {
268 DPRINTF(LocalApic, "Interrupt is an %s.\n",
269 DeliveryMode::names[deliveryMode]);
270 if (deliveryMode == DeliveryMode::SMI && !pendingSmi) {
271 pendingUnmaskableInt = pendingSmi = true;
272 smiVector = vector;
273 } else if (deliveryMode == DeliveryMode::NMI && !pendingNmi) {
274 pendingUnmaskableInt = pendingNmi = true;
275 nmiVector = vector;
276 } else if (deliveryMode == DeliveryMode::ExtInt && !pendingExtInt) {
277 pendingExtInt = true;
278 extIntVector = vector;
279 } else if (deliveryMode == DeliveryMode::INIT && !pendingInit) {
280 pendingUnmaskableInt = pendingInit = true;
281 initVector = vector;
282 }
283 }
284}
243
244Tick
245X86ISA::Interrupts::recvMessage(PacketPtr pkt)
246{
247 uint8_t id = 0;
248 Addr offset = pkt->getAddr() - x86InterruptAddress(id, 0);
249 assert(pkt->cmd == MemCmd::MessageReq);
250 switch(offset)

--- 4 unchanged lines hidden (view full) ---

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
285
286Tick
287X86ISA::Interrupts::recvMessage(PacketPtr pkt)
288{
289 uint8_t id = 0;
290 Addr offset = pkt->getAddr() - x86InterruptAddress(id, 0);
291 assert(pkt->cmd == MemCmd::MessageReq);
292 switch(offset)

--- 4 unchanged lines hidden (view full) ---

297 uint8_t vector = message.vector;
298 DPRINTF(LocalApic,
299 "Got Trigger Interrupt message with vector %#x.\n",
300 vector);
301 // Make sure we're really supposed to get this.
302 assert((message.destMode == 0 && message.destination == id) ||
303 (bits((int)message.destination, id)));
304
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",
271 DeliveryMode::names[message.deliveryMode]);
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 }
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 }
305 requestInterrupt(message.vector,
306 message.deliveryMode, message.trigger);
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;

--- 184 unchanged lines hidden (view full) ---

498 // These are all probably fairly uncommon, so we'll make them easier to
499 // check for.
500 if (pendingUnmaskableInt) {
501 if (pendingSmi) {
502 DPRINTF(LocalApic, "Generated SMI fault object.\n");
503 return new SystemManagementInterrupt();
504 } else if (pendingNmi) {
505 DPRINTF(LocalApic, "Generated NMI fault object.\n");
307 }
308 break;
309 default:
310 panic("Local apic got unknown interrupt message at offset %#x.\n",
311 offset);
312 break;
313 }
314 delete pkt->req;

--- 184 unchanged lines hidden (view full) ---

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");
506 return new NonMaskableInterrupt(nmiMessage.vector);
507 return new NonMaskableInterrupt(nmiVector);
507 } else if (pendingInit) {
508 DPRINTF(LocalApic, "Generated INIT fault object.\n");
508 } else if (pendingInit) {
509 DPRINTF(LocalApic, "Generated INIT fault object.\n");
509 return new InitInterrupt(initMessage.vector);
510 return new InitInterrupt(initVector);
510 } else {
511 panic("pendingUnmaskableInt set, but no unmaskable "
512 "ints were pending.\n");
513 return NoFault;
514 }
515 } else if (pendingExtInt) {
516 DPRINTF(LocalApic, "Generated external interrupt fault object.\n");
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");
517 return new ExternalInterrupt(extIntMessage.vector);
518 return new ExternalInterrupt(extIntVector);
518 } else {
519 DPRINTF(LocalApic, "Generated regular interrupt fault object.\n");
520 // The only thing left are fixed and lowest priority interrupts.
521 return new ExternalInterrupt(IRRV);
522 }
523}
524
525void

--- 34 unchanged lines hidden ---
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

--- 34 unchanged lines hidden ---