/*
 * 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 "base/bitfield.hh"
#include "debug/I8259.hh"
#include "dev/x86/i82094aa.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"

X86ISA::I8259::I8259(Params * p)
    : BasicPioDevice(p, 2),
      latency(p->pio_latency),
      mode(p->mode), slave(p->slave),
      IRR(0), ISR(0), IMR(0),
      readIRR(true), initControlWord(0), autoEOI(false)
{
    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));
    }

    for (bool &state: pinStates)
        state = false;
}

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);
    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, "Slaves 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, "Slave 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 slave. 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, "slave" can become a
     * vector of slaves.
     */
    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 slave 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);
}

X86ISA::I8259 *
I8259Params::create()
{
    return new X86ISA::I8259(this);
}
