/*
 * Copyright (c) 2008 The Regents of The University of Michigan
 * All rights reserved.
 *
 * 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.
 */

#include "dev/x86/i82094aa.hh"

#include <list>

#include "arch/x86/interrupts.hh"
#include "arch/x86/intmessage.hh"
#include "cpu/base.hh"
#include "debug/I82094AA.hh"
#include "dev/x86/i8259.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "sim/system.hh"

X86ISA::I82094AA::I82094AA(const Params &p)
    : BasicPioDevice(p, 20), extIntPic(p.external_int_pic),
      lowestPriorityOffset(0),
      intRequestPort(name() + ".int_request", this, this, p.int_latency)
{
    // This assumes there's only one I/O APIC in the system and since the apic
    // id is stored in a 8-bit field with 0xff meaning broadcast, the id must
    // be less than 0xff

    assert(p.apic_id < 0xff);
    initialApicId = id = p.apic_id;
    arbId = id;
    regSel = 0;
    RedirTableEntry entry = 0;
    entry.mask = 1;
    for (int i = 0; i < TableSize; i++) {
        redirTable[i] = entry;
        pinStates[i] = false;
    }

    for (int i = 0; i < p.port_inputs_connection_count; i++)
        inputs.push_back(new IntSinkPin<I82094AA>(
                    csprintf("%s.inputs[%d]", name(), i), i, this));
}

void
X86ISA::I82094AA::init()
{
    // The io apic must register its address range with its pio port via
    // the piodevice init() function.
    BasicPioDevice::init();

    // If the request port isn't connected, we can't send interrupts anywhere.
    panic_if(!intRequestPort.isConnected(),
            "Int port not connected to anything!");
}

Port &
X86ISA::I82094AA::getPort(const std::string &if_name, PortID idx)
{
    if (if_name == "int_requestor")
        return intRequestPort;
    if (if_name == "inputs")
        return *inputs.at(idx);
    else
        return BasicPioDevice::getPort(if_name, idx);
}

Tick
X86ISA::I82094AA::read(PacketPtr pkt)
{
    assert(pkt->getSize() == 4);
    Addr offset = pkt->getAddr() - pioAddr;
    switch(offset) {
      case 0:
        pkt->setLE<uint32_t>(regSel);
        break;
      case 16:
        pkt->setLE<uint32_t>(readReg(regSel));
        break;
      default:
        panic("Illegal read from I/O APIC.\n");
    }
    pkt->makeAtomicResponse();
    return pioDelay;
}

Tick
X86ISA::I82094AA::write(PacketPtr pkt)
{
    assert(pkt->getSize() == 4);
    Addr offset = pkt->getAddr() - pioAddr;
    switch(offset) {
      case 0:
        regSel = pkt->getLE<uint32_t>();
        break;
      case 16:
        writeReg(regSel, pkt->getLE<uint32_t>());
        break;
      default:
        panic("Illegal write to I/O APIC.\n");
    }
    pkt->makeAtomicResponse();
    return pioDelay;
}

void
X86ISA::I82094AA::writeReg(uint8_t offset, uint32_t value)
{
    if (offset == 0x0) {
        id = bits(value, 31, 24);
    } else if (offset == 0x1) {
        // The IOAPICVER register is read only.
    } else if (offset == 0x2) {
        arbId = bits(value, 31, 24);
    } else if (offset >= 0x10 && offset <= (0x10 + TableSize * 2)) {
        int index = (offset - 0x10) / 2;
        if (offset % 2) {
            redirTable[index].topDW = value;
            redirTable[index].topReserved = 0;
        } else {
            redirTable[index].bottomDW = value;
            redirTable[index].bottomReserved = 0;
        }
    } else {
        warn("Access to undefined I/O APIC register %#x.\n", offset);
    }
    DPRINTF(I82094AA,
            "Wrote %#x to I/O APIC register %#x .\n", value, offset);
}

uint32_t
X86ISA::I82094AA::readReg(uint8_t offset)
{
    uint32_t result = 0;
    if (offset == 0x0) {
        result = id << 24;
    } else if (offset == 0x1) {
        result = ((TableSize - 1) << 16) | APICVersion;
    } else if (offset == 0x2) {
        result = arbId << 24;
    } else if (offset >= 0x10 && offset <= (0x10 + TableSize * 2)) {
        int index = (offset - 0x10) / 2;
        if (offset % 2) {
            result = redirTable[index].topDW;
        } else {
            result = redirTable[index].bottomDW;
        }
    } else {
        warn("Access to undefined I/O APIC register %#x.\n", offset);
    }
    DPRINTF(I82094AA,
            "Read %#x from I/O APIC register %#x.\n", result, offset);
    return result;
}

void
X86ISA::I82094AA::signalInterrupt(int line)
{
    DPRINTF(I82094AA, "Received interrupt %d.\n", line);
    assert(line < TableSize);
    RedirTableEntry entry = redirTable[line];
    if (entry.mask) {
        DPRINTF(I82094AA, "Entry was masked.\n");
        return;
    } else {
        TriggerIntMessage message = 0;
        message.destination = entry.dest;
        if (entry.deliveryMode == DeliveryMode::ExtInt) {
            assert(extIntPic);
            message.vector = extIntPic->getVector();
        } else {
            message.vector = entry.vector;
        }
        message.deliveryMode = entry.deliveryMode;
        message.destMode = entry.destMode;
        message.level = entry.polarity;
        message.trigger = entry.trigger;
        std::list<int> apics;
        int numContexts = sys->threads.size();
        if (message.destMode == 0) {
            if (message.deliveryMode == DeliveryMode::LowestPriority) {
                panic("Lowest priority delivery mode from the "
                        "IO APIC aren't supported in physical "
                        "destination mode.\n");
            }
            if (message.destination == 0xFF) {
                for (int i = 0; i < numContexts; i++) {
                    apics.push_back(i);
                }
            } else {
                apics.push_back(message.destination);
            }
        } else {
            for (int i = 0; i < numContexts; i++) {
                BaseInterrupts *base_int = sys->threads[i]->
                    getCpuPtr()->getInterruptController(0);
                auto *localApic = dynamic_cast<Interrupts *>(base_int);
                if ((localApic->readReg(APIC_LOGICAL_DESTINATION) >> 24) &
                        message.destination) {
                    apics.push_back(localApic->getInitialApicId());
                }
            }
            if (message.deliveryMode == DeliveryMode::LowestPriority &&
                    apics.size()) {
                // The manual seems to suggest that the chipset just does
                // something reasonable for these instead of actually using
                // state from the local APIC. We'll just rotate an offset
                // through the set of APICs selected above.
                uint64_t modOffset = lowestPriorityOffset % apics.size();
                lowestPriorityOffset++;
                auto apicIt = apics.begin();
                while (modOffset--) {
                    apicIt++;
                    assert(apicIt != apics.end());
                }
                int selected = *apicIt;
                apics.clear();
                apics.push_back(selected);
            }
        }
        for (auto id: apics) {
            PacketPtr pkt = buildIntTriggerPacket(id, message);
            intRequestPort.sendMessage(pkt, sys->isTimingMode());
        }
    }
}

void
X86ISA::I82094AA::raiseInterruptPin(int number)
{
    assert(number < TableSize);
    if (!pinStates[number])
        signalInterrupt(number);
    pinStates[number] = true;
}

void
X86ISA::I82094AA::lowerInterruptPin(int number)
{
    assert(number < TableSize);
    pinStates[number] = false;
}

void
X86ISA::I82094AA::serialize(CheckpointOut &cp) const
{
    uint64_t* redirTableArray = (uint64_t*)redirTable;
    SERIALIZE_SCALAR(regSel);
    SERIALIZE_SCALAR(initialApicId);
    SERIALIZE_SCALAR(id);
    SERIALIZE_SCALAR(arbId);
    SERIALIZE_SCALAR(lowestPriorityOffset);
    SERIALIZE_ARRAY(redirTableArray, TableSize);
    SERIALIZE_ARRAY(pinStates, TableSize);
}

void
X86ISA::I82094AA::unserialize(CheckpointIn &cp)
{
    uint64_t redirTableArray[TableSize];
    UNSERIALIZE_SCALAR(regSel);
    UNSERIALIZE_SCALAR(initialApicId);
    UNSERIALIZE_SCALAR(id);
    UNSERIALIZE_SCALAR(arbId);
    UNSERIALIZE_SCALAR(lowestPriorityOffset);
    UNSERIALIZE_ARRAY(redirTableArray, TableSize);
    UNSERIALIZE_ARRAY(pinStates, TableSize);
    for (int i = 0; i < TableSize; i++) {
        redirTable[i] = (RedirTableEntry)redirTableArray[i];
    }
}
