interrupts.cc (5651:7f0c8006c3d7) interrupts.cc (5654:340254de2031)
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 *

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

52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 *
55 * Authors: Gabe Black
56 */
57
58#include "arch/x86/apicregs.hh"
59#include "arch/x86/interrupts.hh"
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 *

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

52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 *
55 * Authors: Gabe Black
56 */
57
58#include "arch/x86/apicregs.hh"
59#include "arch/x86/interrupts.hh"
60#include "arch/x86/intmessage.hh"
60#include "cpu/base.hh"
61#include "cpu/base.hh"
62#include "mem/packet_access.hh"
61
62int
63divideFromConf(uint32_t conf)
64{
65 // This figures out what division we want from the division configuration
66 // register in the local APIC. The encoding is a little odd but it can
67 // be deciphered fairly easily.
68 int shift = ((conf & 0x8) >> 1) | (conf & 0x3);

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

237 reg, offset, gtoh(val));
238 setReg(reg, gtoh(val));
239 return latency;
240}
241
242Tick
243X86ISA::Interrupts::recvMessage(PacketPtr pkt)
244{
63
64int
65divideFromConf(uint32_t conf)
66{
67 // This figures out what division we want from the division configuration
68 // register in the local APIC. The encoding is a little odd but it can
69 // be deciphered fairly easily.
70 int shift = ((conf & 0x8) >> 1) | (conf & 0x3);

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

239 reg, offset, gtoh(val));
240 setReg(reg, gtoh(val));
241 return latency;
242}
243
244Tick
245X86ISA::Interrupts::recvMessage(PacketPtr pkt)
246{
245 Addr offset = pkt->getAddr() - x86InterruptAddress(0, 0);
247 uint8_t id = 0;
248 Addr offset = pkt->getAddr() - x86InterruptAddress(id, 0);
246 assert(pkt->cmd == MemCmd::MessageReq);
247 switch(offset)
248 {
249 case 0:
249 assert(pkt->cmd == MemCmd::MessageReq);
250 switch(offset)
251 {
252 case 0:
250 DPRINTF(LocalApic, "Got Trigger Interrupt message.\n");
253 {
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",
264 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 }
282 }
283 }
251 break;
252 default:
253 panic("Local apic got unknown interrupt message at offset %#x.\n",
254 offset);
255 break;
256 }
257 delete pkt->req;
258 delete pkt;

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

409 break;
410 default:
411 break;
412 }
413 regs[reg] = newVal;
414 return;
415}
416
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;
291 delete pkt;

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

442 break;
443 default:
444 break;
445 }
446 regs[reg] = newVal;
447 return;
448}
449
450bool
451X86ISA::Interrupts::check_interrupts(ThreadContext * tc) const
452{
453 RFLAGS rflags = tc->readMiscRegNoEffect(MISCREG_RFLAGS);
454 if (IRRV > ISRV && rflags.intf &&
455 bits(IRRV, 7, 4) > bits(regs[APIC_TASK_PRIORITY], 7, 4)) {
456 return true;
457 }
458 return false;
459}
460
461Fault
462X86ISA::Interrupts::getInterrupt(ThreadContext * tc)
463{
464 assert(check_interrupts(tc));
465 return new ExternalInterrupt(IRRV);
466}
467
468void
469X86ISA::Interrupts::updateIntrInfo(ThreadContext * tc)
470{
471 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();
478}
479
417X86ISA::Interrupts *
418X86LocalApicParams::create()
419{
420 return new X86ISA::Interrupts(this);
421}
480X86ISA::Interrupts *
481X86LocalApicParams::create()
482{
483 return new X86ISA::Interrupts(this);
484}