/*
 * Copyright (c) 2004-2005 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/i8259.hh"

#include "arch/x86/x86_traits.hh"
#include "base/bitfield.hh"
#include "base/trace.hh"
#include "debug/I8259.hh"
#include "dev/x86/i82094aa.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"

namespace gem5
{

X86ISA::I8259::I8259(const Params &p) : BasicPioDevice(p, 2),
      latency(p.pio_latency), mode(p.mode), slave(p.slave)
{
    for (int i = 0; i < p.port_output_connection_count; i++) {
        output.push_back(new IntSourcePin<I8259>(
                    csprintf("%s.output[%d]", name(), i), i, this));
    }

    int in_count = p.port_inputs_connection_count;
    panic_if(in_count > NumLines,
            "I8259 only supports 8 inputs, but there are %d.", in_count);
    for (int i = 0; i < in_count; i++) {
        inputs.push_back(new IntSinkPin<I8259>(
                    csprintf("%s.inputs[%d]", name(), i), i, this));
    }
}

AddrRangeList
X86ISA::I8259::getAddrRanges() const
{
    AddrRangeList ranges = BasicPioDevice::getAddrRanges();
    if (mode == enums::I8259Master || mode == enums::I8259Single) {
        // Listen for INTA messages.
        ranges.push_back(RangeSize(PhysAddrIntA, 1));
    }
    return ranges;
}

void
X86ISA::I8259::init()
{
    BasicPioDevice::init();

    for (auto *input: inputs)
        pinStates[input->getId()] = input->state();
}

Tick
X86ISA::I8259::read(PacketPtr pkt)
{
    assert(pkt->getSize() == 1);
    if (pkt->getAddr() == PhysAddrIntA) {
        assert(mode == enums::I8259Master || mode == enums::I8259Single);
        pkt->setLE<uint8_t>(getVector());
    }
    switch(pkt->getAddr() - pioAddr) {
      case 0x0:
        if (readIRR) {
            DPRINTF(I8259, "Reading IRR as %#x.\n", IRR);
            pkt->setLE(IRR);
        } else {
            DPRINTF(I8259, "Reading ISR as %#x.\n", ISR);
            pkt->setLE(ISR);
        }
        break;
      case 0x1:
        DPRINTF(I8259, "Reading IMR as %#x.\n", IMR);
        pkt->setLE(IMR);
        break;
    }
    pkt->makeAtomicResponse();
    return latency;
}

Tick
X86ISA::I8259::write(PacketPtr pkt)
{
    assert(pkt->getSize() == 1);
    uint8_t val = pkt->getLE<uint8_t>();
    switch (pkt->getAddr() - pioAddr) {
      case 0x0:
        if (bits(val, 4)) {
            DPRINTF(I8259, "Received initialization command word 1.\n");
            IMR = 0;
            edgeTriggered = bits(val, 3);
            DPRINTF(I8259, "%s triggered mode.\n",
                    edgeTriggered ? "Edge" : "Level");
            cascadeMode = !bits(val, 1);
            DPRINTF(I8259, "%s mode.\n",
                    cascadeMode ? "Cascade" : "Single");
            expectICW4 = bits(val, 0);
            if (!expectICW4) {
                autoEOI = false;
            }
            initControlWord = 1;
            DPRINTF(I8259, "Expecting %d more bytes.\n", expectICW4 ? 3 : 2);
        } else if (bits(val, 4, 3) == 0) {
            DPRINTF(I8259, "Received operation command word 2.\n");
            switch (bits(val, 7, 5)) {
              case 0x0:
                DPRINTF(I8259,
                        "Subcommand: Rotate in auto-EOI mode (clear).\n");
                break;
              case 0x1:
                {
                    int line = findMsbSet(ISR);
                    DPRINTF(I8259, "Subcommand: Nonspecific EOI on line %d.\n",
                            line);
                    handleEOI(line);
                }
                break;
              case 0x2:
                DPRINTF(I8259, "Subcommand: No operation.\n");
                break;
              case 0x3:
                {
                    int line = bits(val, 2, 0);
                    DPRINTF(I8259, "Subcommand: Specific EIO on line %d.\n",
                            line);
                    handleEOI(line);
                }
                break;
              case 0x4:
                DPRINTF(I8259, "Subcommand: Rotate in auto-EOI mode (set).\n");
                break;
              case 0x5:
                DPRINTF(I8259, "Subcommand: Rotate on nonspecific EOI.\n");
                break;
              case 0x6:
                DPRINTF(I8259, "Subcommand: Set priority command.\n");
                DPRINTF(I8259, "Lowest: IRQ%d   Highest IRQ%d.\n",
                        bits(val, 2, 0), (bits(val, 2, 0) + 1) % 8);
                break;
              case 0x7:
                DPRINTF(I8259, "Subcommand: Rotate on specific EOI.\n");
                DPRINTF(I8259, "Lowest: IRQ%d   Highest IRQ%d.\n",
                        bits(val, 2, 0), (bits(val, 2, 0) + 1) % 8);
                break;
            }
        } else if (bits(val, 4, 3) == 1) {
            DPRINTF(I8259, "Received operation command word 3.\n");
            if (bits(val, 7)) {
                DPRINTF(I8259, "%s special mask mode.\n",
                        bits(val, 6) ? "Set" : "Clear");
            }
            if (bits(val, 1)) {
                readIRR = bits(val, 0);
                DPRINTF(I8259, "Read %s.\n", readIRR ? "IRR" : "ISR");
            }
        }
        break;
      case 0x1:
        switch (initControlWord) {
          case 0x0:
            DPRINTF(I8259, "Received operation command word 1.\n");
            DPRINTF(I8259, "Wrote IMR value %#x.\n", val);
            IMR = val;
            break;
          case 0x1:
            DPRINTF(I8259, "Received initialization command word 2.\n");
            vectorOffset = val & ~mask(3);
            DPRINTF(I8259, "Responsible for vectors %#x-%#x.\n",
                    vectorOffset, vectorOffset | mask(3));
            if (cascadeMode) {
                initControlWord++;
            } else {
                cascadeBits = 0;
                initControlWord = 0;
            }
            break;
          case 0x2:
            DPRINTF(I8259, "Received initialization command word 3.\n");
            if (mode == enums::I8259Master) {
                DPRINTF(I8259, "Responders attached to "
                        "IRQs:%s%s%s%s%s%s%s%s\n",
                        bits(val, 0) ? " 0" : "",
                        bits(val, 1) ? " 1" : "",
                        bits(val, 2) ? " 2" : "",
                        bits(val, 3) ? " 3" : "",
                        bits(val, 4) ? " 4" : "",
                        bits(val, 5) ? " 5" : "",
                        bits(val, 6) ? " 6" : "",
                        bits(val, 7) ? " 7" : "");
                cascadeBits = val;
            } else {
                DPRINTF(I8259, "Responder ID is %d.\n", val & mask(3));
                cascadeBits = val & mask(3);
            }
            if (expectICW4)
                initControlWord++;
            else
                initControlWord = 0;
            break;
          case 0x3:
            DPRINTF(I8259, "Received initialization command word 4.\n");
            if (bits(val, 4)) {
                DPRINTF(I8259, "Special fully nested mode.\n");
            } else {
                DPRINTF(I8259, "Not special fully nested mode.\n");
            }
            if (bits(val, 3) == 0) {
                DPRINTF(I8259, "Nonbuffered.\n");
            } else if (bits(val, 2) == 0) {
                DPRINTF(I8259, "Buffered.\n");
            } else {
                DPRINTF(I8259, "Unrecognized buffer mode.\n");
            }
            autoEOI = bits(val, 1);
            DPRINTF(I8259, "%s End Of Interrupt.\n",
                    autoEOI ? "Automatic" : "Normal");

            DPRINTF(I8259, "%s mode.\n", bits(val, 0) ? "80x86" : "MCX-80/85");
            initControlWord = 0;
            break;
        }
        break;
    }
    pkt->makeAtomicResponse();
    return latency;
}

void
X86ISA::I8259::handleEOI(int line)
{
    ISR &= ~(1 << line);
    // There may be an interrupt that was waiting which can
    // now be sent.
    if (IRR)
        requestInterrupt(findMsbSet(IRR));
}

void
X86ISA::I8259::requestInterrupt(int line)
{
    if (bits(ISR, 7, line) == 0) {
        if (!output.empty()) {
            DPRINTF(I8259, "Propogating interrupt.\n");
            for (auto *wire: output) {
                wire->raise();
                //XXX This is a hack.
                wire->lower();
            }
        } else {
            warn("Received interrupt but didn't have "
                    "anyone to tell about it.\n");
        }
    }
}

void
X86ISA::I8259::signalInterrupt(int line)
{
    DPRINTF(I8259, "Interrupt requested for line %d.\n", line);
    if (line >= NumLines)
        fatal("Line number %d doesn't exist. The max is %d.\n",
                line, NumLines - 1);
    if (bits(IMR, line)) {
        DPRINTF(I8259, "Interrupt %d was masked.\n", line);
    } else {
        IRR |= 1 << line;
        requestInterrupt(line);
    }
}

void
X86ISA::I8259::raiseInterruptPin(int number)
{
    DPRINTF(I8259, "Interrupt signal raised for pin %d.\n", number);
    if (number >= NumLines)
        fatal("Line number %d doesn't exist. The max is %d.\n",
                number, NumLines - 1);
    if (!pinStates[number])
        signalInterrupt(number);
    pinStates[number] = true;
}

void
X86ISA::I8259::lowerInterruptPin(int number)
{
    DPRINTF(I8259, "Interrupt signal lowered for pin %d.\n", number);
    if (number >= NumLines)
        fatal("Line number %d doesn't exist. The max is %d.\n",
                number, NumLines - 1);
    pinStates[number] = false;
}

int
X86ISA::I8259::getVector()
{
    /*
     * This code only handles one responder. Since that's how the PC platform
     * always uses the 8259 PIC, there shouldn't be any need for more. If
     * there -is- a need for more for some reason, "responder" can become a
     * vector of responders.
     */
    int line = findMsbSet(IRR);
    IRR &= ~(1 << line);
    DPRINTF(I8259, "Interrupt %d was accepted.\n", line);
    if (autoEOI) {
        handleEOI(line);
    } else {
        ISR |= 1 << line;
    }
    if (slave && bits(cascadeBits, line)) {
        DPRINTF(I8259, "Interrupt was from responder who will "
                "provide the vector.\n");
        return slave->getVector();
    }
    return line | vectorOffset;
}

void
X86ISA::I8259::serialize(CheckpointOut &cp) const
{
    SERIALIZE_ARRAY(pinStates, NumLines);
    SERIALIZE_ENUM(mode);
    SERIALIZE_SCALAR(IRR);
    SERIALIZE_SCALAR(ISR);
    SERIALIZE_SCALAR(IMR);
    SERIALIZE_SCALAR(vectorOffset);
    SERIALIZE_SCALAR(cascadeMode);
    SERIALIZE_SCALAR(cascadeBits);
    SERIALIZE_SCALAR(edgeTriggered);
    SERIALIZE_SCALAR(readIRR);
    SERIALIZE_SCALAR(expectICW4);
    SERIALIZE_SCALAR(initControlWord);
    SERIALIZE_SCALAR(autoEOI);
}

void
X86ISA::I8259::unserialize(CheckpointIn &cp)
{
    UNSERIALIZE_ARRAY(pinStates, NumLines);
    UNSERIALIZE_ENUM(mode);
    UNSERIALIZE_SCALAR(IRR);
    UNSERIALIZE_SCALAR(ISR);
    UNSERIALIZE_SCALAR(IMR);
    UNSERIALIZE_SCALAR(vectorOffset);
    UNSERIALIZE_SCALAR(cascadeMode);
    UNSERIALIZE_SCALAR(cascadeBits);
    UNSERIALIZE_SCALAR(edgeTriggered);
    UNSERIALIZE_SCALAR(readIRR);
    UNSERIALIZE_SCALAR(expectICW4);
    UNSERIALIZE_SCALAR(initControlWord);
    UNSERIALIZE_SCALAR(autoEOI);
}

} // namespace gem5
