/*
 * Copyright (c) 2012-2013 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2008 The Hewlett-Packard Development Company
 * All rights reserved.
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#include "arch/x86/regs/apic.hh"
#include "arch/x86/interrupts.hh"
#include "arch/x86/intmessage.hh"
#include "cpu/base.hh"
#include "debug/LocalApic.hh"
#include "dev/x86/i82094aa.hh"
#include "dev/x86/pc.hh"
#include "dev/x86/south_bridge.hh"
#include "mem/packet_access.hh"
#include "sim/system.hh"
#include "sim/full_system.hh"

int
divideFromConf(uint32_t conf)
{
    // This figures out what division we want from the division configuration
    // register in the local APIC. The encoding is a little odd but it can
    // be deciphered fairly easily.
    int shift = ((conf & 0x8) >> 1) | (conf & 0x3);
    shift = (shift + 1) % 8;
    return 1 << shift;
}

namespace X86ISA
{

ApicRegIndex
decodeAddr(Addr paddr)
{
    ApicRegIndex regNum;
    paddr &= ~mask(3);
    switch (paddr)
    {
      case 0x20:
        regNum = APIC_ID;
        break;
      case 0x30:
        regNum = APIC_VERSION;
        break;
      case 0x80:
        regNum = APIC_TASK_PRIORITY;
        break;
      case 0x90:
        regNum = APIC_ARBITRATION_PRIORITY;
        break;
      case 0xA0:
        regNum = APIC_PROCESSOR_PRIORITY;
        break;
      case 0xB0:
        regNum = APIC_EOI;
        break;
      case 0xD0:
        regNum = APIC_LOGICAL_DESTINATION;
        break;
      case 0xE0:
        regNum = APIC_DESTINATION_FORMAT;
        break;
      case 0xF0:
        regNum = APIC_SPURIOUS_INTERRUPT_VECTOR;
        break;
      case 0x100:
      case 0x108:
      case 0x110:
      case 0x118:
      case 0x120:
      case 0x128:
      case 0x130:
      case 0x138:
      case 0x140:
      case 0x148:
      case 0x150:
      case 0x158:
      case 0x160:
      case 0x168:
      case 0x170:
      case 0x178:
        regNum = APIC_IN_SERVICE((paddr - 0x100) / 0x8);
        break;
      case 0x180:
      case 0x188:
      case 0x190:
      case 0x198:
      case 0x1A0:
      case 0x1A8:
      case 0x1B0:
      case 0x1B8:
      case 0x1C0:
      case 0x1C8:
      case 0x1D0:
      case 0x1D8:
      case 0x1E0:
      case 0x1E8:
      case 0x1F0:
      case 0x1F8:
        regNum = APIC_TRIGGER_MODE((paddr - 0x180) / 0x8);
        break;
      case 0x200:
      case 0x208:
      case 0x210:
      case 0x218:
      case 0x220:
      case 0x228:
      case 0x230:
      case 0x238:
      case 0x240:
      case 0x248:
      case 0x250:
      case 0x258:
      case 0x260:
      case 0x268:
      case 0x270:
      case 0x278:
        regNum = APIC_INTERRUPT_REQUEST((paddr - 0x200) / 0x8);
        break;
      case 0x280:
        regNum = APIC_ERROR_STATUS;
        break;
      case 0x300:
        regNum = APIC_INTERRUPT_COMMAND_LOW;
        break;
      case 0x310:
        regNum = APIC_INTERRUPT_COMMAND_HIGH;
        break;
      case 0x320:
        regNum = APIC_LVT_TIMER;
        break;
      case 0x330:
        regNum = APIC_LVT_THERMAL_SENSOR;
        break;
      case 0x340:
        regNum = APIC_LVT_PERFORMANCE_MONITORING_COUNTERS;
        break;
      case 0x350:
        regNum = APIC_LVT_LINT0;
        break;
      case 0x360:
        regNum = APIC_LVT_LINT1;
        break;
      case 0x370:
        regNum = APIC_LVT_ERROR;
        break;
      case 0x380:
        regNum = APIC_INITIAL_COUNT;
        break;
      case 0x390:
        regNum = APIC_CURRENT_COUNT;
        break;
      case 0x3E0:
        regNum = APIC_DIVIDE_CONFIGURATION;
        break;
      default:
        // A reserved register field.
        panic("Accessed reserved register field %#x.\n", paddr);
        break;
    }
    return regNum;
}
}

Tick
X86ISA::Interrupts::read(PacketPtr pkt)
{
    Addr offset = pkt->getAddr() - pioAddr;
    //Make sure we're at least only accessing one register.
    if ((offset & ~mask(3)) != ((offset + pkt->getSize()) & ~mask(3)))
        panic("Accessed more than one register at a time in the APIC!\n");
    ApicRegIndex reg = decodeAddr(offset);
    uint32_t val = htog(readReg(reg));
    DPRINTF(LocalApic,
            "Reading Local APIC register %d at offset %#x as %#x.\n",
            reg, offset, val);
    pkt->setData(((uint8_t *)&val) + (offset & mask(3)));
    pkt->makeAtomicResponse();
    return pioDelay;
}

Tick
X86ISA::Interrupts::write(PacketPtr pkt)
{
    Addr offset = pkt->getAddr() - pioAddr;
    //Make sure we're at least only accessing one register.
    if ((offset & ~mask(3)) != ((offset + pkt->getSize()) & ~mask(3)))
        panic("Accessed more than one register at a time in the APIC!\n");
    ApicRegIndex reg = decodeAddr(offset);
    uint32_t val = regs[reg];
    pkt->writeData(((uint8_t *)&val) + (offset & mask(3)));
    DPRINTF(LocalApic,
            "Writing Local APIC register %d at offset %#x as %#x.\n",
            reg, offset, gtoh(val));
    setReg(reg, gtoh(val));
    pkt->makeAtomicResponse();
    return pioDelay;
}
void
X86ISA::Interrupts::requestInterrupt(uint8_t vector,
        uint8_t deliveryMode, bool level)
{
    /*
     * Fixed and lowest-priority delivery mode interrupts are handled
     * using the IRR/ISR registers, checking against the TPR, etc.
     * The SMI, NMI, ExtInt, INIT, etc interrupts go straight through.
     */
    if (deliveryMode == DeliveryMode::Fixed ||
            deliveryMode == DeliveryMode::LowestPriority) {
        DPRINTF(LocalApic, "Interrupt is an %s.\n",
                DeliveryMode::names[deliveryMode]);
        // Queue up the interrupt in the IRR.
        if (vector > IRRV)
            IRRV = vector;
        if (!getRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector)) {
            setRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector);
            if (level) {
                setRegArrayBit(APIC_TRIGGER_MODE_BASE, vector);
            } else {
                clearRegArrayBit(APIC_TRIGGER_MODE_BASE, vector);
            }
        }
    } else if (!DeliveryMode::isReserved(deliveryMode)) {
        DPRINTF(LocalApic, "Interrupt is an %s.\n",
                DeliveryMode::names[deliveryMode]);
        if (deliveryMode == DeliveryMode::SMI && !pendingSmi) {
            pendingUnmaskableInt = pendingSmi = true;
            smiVector = vector;
        } else if (deliveryMode == DeliveryMode::NMI && !pendingNmi) {
            pendingUnmaskableInt = pendingNmi = true;
            nmiVector = vector;
        } else if (deliveryMode == DeliveryMode::ExtInt && !pendingExtInt) {
            pendingExtInt = true;
            extIntVector = vector;
        } else if (deliveryMode == DeliveryMode::INIT && !pendingInit) {
            pendingUnmaskableInt = pendingInit = true;
            initVector = vector;
        } else if (deliveryMode == DeliveryMode::SIPI &&
                !pendingStartup && !startedUp) {
            pendingUnmaskableInt = pendingStartup = true;
            startupVector = vector;
        }
    }
    if (FullSystem)
        cpu->wakeup();
}


void
X86ISA::Interrupts::setCPU(BaseCPU * newCPU)
{
    assert(newCPU);
    if (cpu != NULL && cpu->cpuId() != newCPU->cpuId()) {
        panic("Local APICs can't be moved between CPUs"
                " with different IDs.\n");
    }
    cpu = newCPU;
    initialApicId = cpu->cpuId();
    regs[APIC_ID] = (initialApicId << 24);
    pioAddr = x86LocalAPICAddress(initialApicId, 0);
}


void
X86ISA::Interrupts::init()
{
    //
    // The local apic must register its address ranges on both its pio
    // port via the basicpiodevice(piodevice) init() function and its
    // int port that it inherited from IntDevice.  Note IntDevice is
    // not a SimObject itself.
    //
    BasicPioDevice::init();
    IntDevice::init();

    // the slave port has a range so inform the connected master
    intSlavePort.sendRangeChange();
}


Tick
X86ISA::Interrupts::recvMessage(PacketPtr pkt)
{
    Addr offset = pkt->getAddr() - x86InterruptAddress(initialApicId, 0);
    assert(pkt->cmd == MemCmd::MessageReq);
    switch(offset)
    {
      case 0:
        {
            TriggerIntMessage message = pkt->get<TriggerIntMessage>();
            DPRINTF(LocalApic,
                    "Got Trigger Interrupt message with vector %#x.\n",
                    message.vector);

            requestInterrupt(message.vector,
                    message.deliveryMode, message.trigger);
        }
        break;
      default:
        panic("Local apic got unknown interrupt message at offset %#x.\n",
                offset);
        break;
    }
    pkt->makeAtomicResponse();
    return pioDelay;
}


Tick
X86ISA::Interrupts::recvResponse(PacketPtr pkt)
{
    assert(!pkt->isError());
    assert(pkt->cmd == MemCmd::MessageResp);
    if (--pendingIPIs == 0) {
        InterruptCommandRegLow low = regs[APIC_INTERRUPT_COMMAND_LOW];
        // Record that the ICR is now idle.
        low.deliveryStatus = 0;
        regs[APIC_INTERRUPT_COMMAND_LOW] = low;
    }
    DPRINTF(LocalApic, "ICR is now idle.\n");
    return 0;
}


AddrRangeList
X86ISA::Interrupts::getIntAddrRange() const
{
    AddrRangeList ranges;
    ranges.push_back(RangeEx(x86InterruptAddress(initialApicId, 0),
                             x86InterruptAddress(initialApicId, 0) +
                             PhysAddrAPICRangeSize));
    return ranges;
}


uint32_t
X86ISA::Interrupts::readReg(ApicRegIndex reg)
{
    if (reg >= APIC_TRIGGER_MODE(0) &&
            reg <= APIC_TRIGGER_MODE(15)) {
        panic("Local APIC Trigger Mode registers are unimplemented.\n");
    }
    switch (reg) {
      case APIC_ARBITRATION_PRIORITY:
        panic("Local APIC Arbitration Priority register unimplemented.\n");
        break;
      case APIC_PROCESSOR_PRIORITY:
        panic("Local APIC Processor Priority register unimplemented.\n");
        break;
      case APIC_ERROR_STATUS:
        regs[APIC_INTERNAL_STATE] &= ~ULL(0x1);
        break;
      case APIC_CURRENT_COUNT:
        {
            if (apicTimerEvent.scheduled()) {
                // Compute how many m5 ticks happen per count.
                uint64_t ticksPerCount = clockPeriod() *
                    divideFromConf(regs[APIC_DIVIDE_CONFIGURATION]);
                // Compute how many m5 ticks are left.
                uint64_t val = apicTimerEvent.when() - curTick();
                // Turn that into a count.
                val = (val + ticksPerCount - 1) / ticksPerCount;
                return val;
            } else {
                return 0;
            }
        }
      default:
        break;
    }
    return regs[reg];
}

void
X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val)
{
    uint32_t newVal = val;
    if (reg >= APIC_IN_SERVICE(0) &&
            reg <= APIC_IN_SERVICE(15)) {
        panic("Local APIC In-Service registers are unimplemented.\n");
    }
    if (reg >= APIC_TRIGGER_MODE(0) &&
            reg <= APIC_TRIGGER_MODE(15)) {
        panic("Local APIC Trigger Mode registers are unimplemented.\n");
    }
    if (reg >= APIC_INTERRUPT_REQUEST(0) &&
            reg <= APIC_INTERRUPT_REQUEST(15)) {
        panic("Local APIC Interrupt Request registers "
                "are unimplemented.\n");
    }
    switch (reg) {
      case APIC_ID:
        newVal = val & 0xFF;
        break;
      case APIC_VERSION:
        // The Local APIC Version register is read only.
        return;
      case APIC_TASK_PRIORITY:
        newVal = val & 0xFF;
        break;
      case APIC_ARBITRATION_PRIORITY:
        panic("Local APIC Arbitration Priority register unimplemented.\n");
        break;
      case APIC_PROCESSOR_PRIORITY:
        panic("Local APIC Processor Priority register unimplemented.\n");
        break;
      case APIC_EOI:
        // Remove the interrupt that just completed from the local apic state.
        clearRegArrayBit(APIC_IN_SERVICE_BASE, ISRV);
        updateISRV();
        return;
      case APIC_LOGICAL_DESTINATION:
        newVal = val & 0xFF000000;
        break;
      case APIC_DESTINATION_FORMAT:
        newVal = val | 0x0FFFFFFF;
        break;
      case APIC_SPURIOUS_INTERRUPT_VECTOR:
        regs[APIC_INTERNAL_STATE] &= ~ULL(1 << 1);
        regs[APIC_INTERNAL_STATE] |= val & (1 << 8);
        if (val & (1 << 9))
            warn("Focus processor checking not implemented.\n");
        break;
      case APIC_ERROR_STATUS:
        {
            if (regs[APIC_INTERNAL_STATE] & 0x1) {
                regs[APIC_INTERNAL_STATE] &= ~ULL(0x1);
                newVal = 0;
            } else {
                regs[APIC_INTERNAL_STATE] |= ULL(0x1);
                return;
            }

        }
        break;
      case APIC_INTERRUPT_COMMAND_LOW:
        {
            InterruptCommandRegLow low = regs[APIC_INTERRUPT_COMMAND_LOW];
            // Check if we're already sending an IPI.
            if (low.deliveryStatus) {
                newVal = low;
                break;
            }
            low = val;
            InterruptCommandRegHigh high = regs[APIC_INTERRUPT_COMMAND_HIGH];
            // Record that an IPI is being sent.
            low.deliveryStatus = 1;
            TriggerIntMessage message = 0;
            message.destination = high.destination;
            message.vector = low.vector;
            message.deliveryMode = low.deliveryMode;
            message.destMode = low.destMode;
            message.level = low.level;
            message.trigger = low.trigger;
            bool timing(sys->isTimingMode());
            // Be careful no updates of the delivery status bit get lost.
            regs[APIC_INTERRUPT_COMMAND_LOW] = low;
            ApicList apics;
            int numContexts = sys->numContexts();
            switch (low.destShorthand) {
              case 0:
                if (message.deliveryMode == DeliveryMode::LowestPriority) {
                    panic("Lowest priority delivery mode "
                            "IPIs aren't implemented.\n");
                }
                if (message.destMode == 1) {
                    int dest = message.destination;
                    hack_once("Assuming logical destinations are 1 << id.\n");
                    for (int i = 0; i < numContexts; i++) {
                        if (dest & 0x1)
                            apics.push_back(i);
                        dest = dest >> 1;
                    }
                } else {
                    if (message.destination == 0xFF) {
                        for (int i = 0; i < numContexts; i++) {
                            if (i == initialApicId) {
                                requestInterrupt(message.vector,
                                        message.deliveryMode, message.trigger);
                            } else {
                                apics.push_back(i);
                            }
                        }
                    } else {
                        if (message.destination == initialApicId) {
                            requestInterrupt(message.vector,
                                    message.deliveryMode, message.trigger);
                        } else {
                            apics.push_back(message.destination);
                        }
                    }
                }
                break;
              case 1:
                newVal = val;
                requestInterrupt(message.vector,
                        message.deliveryMode, message.trigger);
                break;
              case 2:
                requestInterrupt(message.vector,
                        message.deliveryMode, message.trigger);
                // Fall through
              case 3:
                {
                    for (int i = 0; i < numContexts; i++) {
                        if (i != initialApicId) {
                            apics.push_back(i);
                        }
                    }
                }
                break;
            }
            pendingIPIs += apics.size();
            intMasterPort.sendMessage(apics, message, timing);
            newVal = regs[APIC_INTERRUPT_COMMAND_LOW];
        }
        break;
      case APIC_LVT_TIMER:
      case APIC_LVT_THERMAL_SENSOR:
      case APIC_LVT_PERFORMANCE_MONITORING_COUNTERS:
      case APIC_LVT_LINT0:
      case APIC_LVT_LINT1:
      case APIC_LVT_ERROR:
        {
            uint64_t readOnlyMask = (1 << 12) | (1 << 14);
            newVal = (val & ~readOnlyMask) |
                     (regs[reg] & readOnlyMask);
        }
        break;
      case APIC_INITIAL_COUNT:
        {
            newVal = bits(val, 31, 0);
            // Compute how many timer ticks we're being programmed for.
            uint64_t newCount = newVal *
                (divideFromConf(regs[APIC_DIVIDE_CONFIGURATION]));
            // Schedule on the edge of the next tick plus the new count.
            Tick offset = curTick() % clockPeriod();
            if (offset) {
                reschedule(apicTimerEvent,
                           curTick() + (newCount + 1) *
                           clockPeriod() - offset, true);
            } else {
                if (newCount)
                    reschedule(apicTimerEvent,
                               curTick() + newCount *
                               clockPeriod(), true);
            }
        }
        break;
      case APIC_CURRENT_COUNT:
        //Local APIC Current Count register is read only.
        return;
      case APIC_DIVIDE_CONFIGURATION:
        newVal = val & 0xB;
        break;
      default:
        break;
    }
    regs[reg] = newVal;
    return;
}


X86ISA::Interrupts::Interrupts(Params * p)
    : BasicPioDevice(p, PageBytes), IntDevice(this, p->int_latency),
      apicTimerEvent(this),
      pendingSmi(false), smiVector(0),
      pendingNmi(false), nmiVector(0),
      pendingExtInt(false), extIntVector(0),
      pendingInit(false), initVector(0),
      pendingStartup(false), startupVector(0),
      startedUp(false), pendingUnmaskableInt(false),
      pendingIPIs(0), cpu(NULL),
      intSlavePort(name() + ".int_slave", this, this)
{
    memset(regs, 0, sizeof(regs));
    //Set the local apic DFR to the flat model.
    regs[APIC_DESTINATION_FORMAT] = (uint32_t)(-1);
    ISRV = 0;
    IRRV = 0;
}


bool
X86ISA::Interrupts::checkInterrupts(ThreadContext *tc) const
{
    RFLAGS rflags = tc->readMiscRegNoEffect(MISCREG_RFLAGS);
    if (pendingUnmaskableInt) {
        DPRINTF(LocalApic, "Reported pending unmaskable interrupt.\n");
        return true;
    }
    if (rflags.intf) {
        if (pendingExtInt) {
            DPRINTF(LocalApic, "Reported pending external interrupt.\n");
            return true;
        }
        if (IRRV > ISRV && bits(IRRV, 7, 4) >
               bits(regs[APIC_TASK_PRIORITY], 7, 4)) {
            DPRINTF(LocalApic, "Reported pending regular interrupt.\n");
            return true;
        }
    }
    return false;
}

bool
X86ISA::Interrupts::checkInterruptsRaw() const
{
    return pendingUnmaskableInt || pendingExtInt ||
        (IRRV > ISRV && bits(IRRV, 7, 4) >
         bits(regs[APIC_TASK_PRIORITY], 7, 4));
}

Fault
X86ISA::Interrupts::getInterrupt(ThreadContext *tc)
{
    assert(checkInterrupts(tc));
    // These are all probably fairly uncommon, so we'll make them easier to
    // check for.
    if (pendingUnmaskableInt) {
        if (pendingSmi) {
            DPRINTF(LocalApic, "Generated SMI fault object.\n");
            return new SystemManagementInterrupt();
        } else if (pendingNmi) {
            DPRINTF(LocalApic, "Generated NMI fault object.\n");
            return new NonMaskableInterrupt(nmiVector);
        } else if (pendingInit) {
            DPRINTF(LocalApic, "Generated INIT fault object.\n");
            return new InitInterrupt(initVector);
        } else if (pendingStartup) {
            DPRINTF(LocalApic, "Generating SIPI fault object.\n");
            return new StartupInterrupt(startupVector);
        } else {
            panic("pendingUnmaskableInt set, but no unmaskable "
                    "ints were pending.\n");
            return NoFault;
        }
    } else if (pendingExtInt) {
        DPRINTF(LocalApic, "Generated external interrupt fault object.\n");
        return new ExternalInterrupt(extIntVector);
    } else {
        DPRINTF(LocalApic, "Generated regular interrupt fault object.\n");
        // The only thing left are fixed and lowest priority interrupts.
        return new ExternalInterrupt(IRRV);
    }
}

void
X86ISA::Interrupts::updateIntrInfo(ThreadContext *tc)
{
    assert(checkInterrupts(tc));
    if (pendingUnmaskableInt) {
        if (pendingSmi) {
            DPRINTF(LocalApic, "SMI sent to core.\n");
            pendingSmi = false;
        } else if (pendingNmi) {
            DPRINTF(LocalApic, "NMI sent to core.\n");
            pendingNmi = false;
        } else if (pendingInit) {
            DPRINTF(LocalApic, "Init sent to core.\n");
            pendingInit = false;
            startedUp = false;
        } else if (pendingStartup) {
            DPRINTF(LocalApic, "SIPI sent to core.\n");
            pendingStartup = false;
            startedUp = true;
        }
        if (!(pendingSmi || pendingNmi || pendingInit || pendingStartup))
            pendingUnmaskableInt = false;
    } else if (pendingExtInt) {
        pendingExtInt = false;
    } else {
        DPRINTF(LocalApic, "Interrupt %d sent to core.\n", IRRV);
        // Mark the interrupt as "in service".
        ISRV = IRRV;
        setRegArrayBit(APIC_IN_SERVICE_BASE, ISRV);
        // Clear it out of the IRR.
        clearRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, IRRV);
        updateIRRV();
    }
}

void
X86ISA::Interrupts::serialize(std::ostream &os)
{
    SERIALIZE_ARRAY(regs, NUM_APIC_REGS);
    SERIALIZE_SCALAR(pendingSmi);
    SERIALIZE_SCALAR(smiVector);
    SERIALIZE_SCALAR(pendingNmi);
    SERIALIZE_SCALAR(nmiVector);
    SERIALIZE_SCALAR(pendingExtInt);
    SERIALIZE_SCALAR(extIntVector);
    SERIALIZE_SCALAR(pendingInit);
    SERIALIZE_SCALAR(initVector);
    SERIALIZE_SCALAR(pendingStartup);
    SERIALIZE_SCALAR(startupVector);
    SERIALIZE_SCALAR(startedUp);
    SERIALIZE_SCALAR(pendingUnmaskableInt);
    SERIALIZE_SCALAR(pendingIPIs);
    SERIALIZE_SCALAR(IRRV);
    SERIALIZE_SCALAR(ISRV);
    bool apicTimerEventScheduled = apicTimerEvent.scheduled();
    SERIALIZE_SCALAR(apicTimerEventScheduled);
    Tick apicTimerEventTick = apicTimerEvent.when();
    SERIALIZE_SCALAR(apicTimerEventTick);
}

void
X86ISA::Interrupts::unserialize(Checkpoint *cp, const std::string &section)
{
    UNSERIALIZE_ARRAY(regs, NUM_APIC_REGS);
    UNSERIALIZE_SCALAR(pendingSmi);
    UNSERIALIZE_SCALAR(smiVector);
    UNSERIALIZE_SCALAR(pendingNmi);
    UNSERIALIZE_SCALAR(nmiVector);
    UNSERIALIZE_SCALAR(pendingExtInt);
    UNSERIALIZE_SCALAR(extIntVector);
    UNSERIALIZE_SCALAR(pendingInit);
    UNSERIALIZE_SCALAR(initVector);
    UNSERIALIZE_SCALAR(pendingStartup);
    UNSERIALIZE_SCALAR(startupVector);
    UNSERIALIZE_SCALAR(startedUp);
    UNSERIALIZE_SCALAR(pendingUnmaskableInt);
    UNSERIALIZE_SCALAR(pendingIPIs);
    UNSERIALIZE_SCALAR(IRRV);
    UNSERIALIZE_SCALAR(ISRV);
    bool apicTimerEventScheduled;
    UNSERIALIZE_SCALAR(apicTimerEventScheduled);
    if (apicTimerEventScheduled) {
        Tick apicTimerEventTick;
        UNSERIALIZE_SCALAR(apicTimerEventTick);
        if (apicTimerEvent.scheduled()) {
            reschedule(apicTimerEvent, apicTimerEventTick, true);
        } else {
            schedule(apicTimerEvent, apicTimerEventTick);
        }
    }
}

X86ISA::Interrupts *
X86LocalApicParams::create()
{
    return new X86ISA::Interrupts(this);
}
