/*
 * 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/i8042.hh"

#include "base/bitunion.hh"
#include "base/trace.hh"
#include "debug/I8042.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"

/**
 * Note: For details on the implementation see
 * https://wiki.osdev.org/%228042%22_PS/2_Controller
 */

// The 8042 has a whopping 32 bytes of internal RAM.
const uint8_t RamSize = 32;
const uint8_t NumOutputBits = 14;


X86ISA::I8042::I8042(const Params &p)
    : BasicPioDevice(p, 0), // pioSize arg is dummy value... not used
      latency(p.pio_latency),
      dataPort(p.data_port), commandPort(p.command_port),
      statusReg(0), commandByte(0), dataReg(0), lastCommand(NoCommand),
      mouse(p.mouse), keyboard(p.keyboard)
{
    fatal_if(!mouse, "The i8042 model requires a mouse instance");
    fatal_if(!keyboard, "The i8042 model requires a keyboard instance");

    statusReg.passedSelfTest = 1;
    statusReg.commandLast = 1;
    statusReg.keyboardUnlocked = 1;

    commandByte.convertScanCodes = 1;
    commandByte.passedSelfTest = 1;
    commandByte.keyboardFullInt = 1;

    for (int i = 0; i < p.port_keyboard_int_pin_connection_count; i++) {
        keyboardIntPin.push_back(new IntSourcePin<I8042>(
                    csprintf("%s.keyboard_int_pin[%d]", name(), i), i, this));
    }
    for (int i = 0; i < p.port_mouse_int_pin_connection_count; i++) {
        mouseIntPin.push_back(new IntSourcePin<I8042>(
                    csprintf("%s.mouse_int_pin[%d]", name(), i), i, this));
    }
}


AddrRangeList
X86ISA::I8042::getAddrRanges() const
{
    AddrRangeList ranges;
    // TODO: Are these really supposed to be a single byte and not 4?
    ranges.push_back(RangeSize(dataPort, 1));
    ranges.push_back(RangeSize(commandPort, 1));
    return ranges;
}

void
X86ISA::I8042::writeData(uint8_t newData, bool mouse)
{
    DPRINTF(I8042, "Set data %#02x.\n", newData);
    dataReg = newData;
    statusReg.outputFull = 1;
    statusReg.mouseOutputFull = (mouse ? 1 : 0);
    if (!mouse && commandByte.keyboardFullInt) {
        DPRINTF(I8042, "Sending keyboard interrupt.\n");
        for (auto *wire: keyboardIntPin) {
            wire->raise();
            //This is a hack
            wire->lower();
        }
    } else if (mouse && commandByte.mouseFullInt) {
        DPRINTF(I8042, "Sending mouse interrupt.\n");
        for (auto *wire: mouseIntPin) {
            wire->raise();
            //This is a hack
            wire->lower();
        }
    }
}

uint8_t
X86ISA::I8042::readDataOut()
{
    uint8_t data = dataReg;
    statusReg.outputFull = 0;
    statusReg.mouseOutputFull = 0;
    if (keyboard->hostDataAvailable()) {
        writeData(keyboard->hostRead(), false);
    } else if (mouse->hostDataAvailable()) {
        writeData(mouse->hostRead(), true);
    }
    return data;
}

Tick
X86ISA::I8042::read(PacketPtr pkt)
{
    assert(pkt->getSize() == 1);
    Addr addr = pkt->getAddr();
    if (addr == dataPort) {
        uint8_t data = readDataOut();
        //DPRINTF(I8042, "Read from data port got %#02x.\n", data);
        pkt->setLE<uint8_t>(data);
    } else if (addr == commandPort) {
        //DPRINTF(I8042, "Read status as %#02x.\n", (uint8_t)statusReg);
        pkt->setLE<uint8_t>((uint8_t)statusReg);
    } else {
        panic("Read from unrecognized port %#x.\n", addr);
    }
    pkt->makeAtomicResponse();
    return latency;
}

Tick
X86ISA::I8042::write(PacketPtr pkt)
{
    assert(pkt->getSize() == 1);
    Addr addr = pkt->getAddr();
    uint8_t data = pkt->getLE<uint8_t>();
    if (addr == dataPort) {
        statusReg.commandLast = 0;
        switch (lastCommand) {
          case NoCommand:
            keyboard->hostWrite(data);
            if (keyboard->hostDataAvailable())
                writeData(keyboard->hostRead(), false);
            break;
          case WriteToMouse:
            mouse->hostWrite(data);
            if (mouse->hostDataAvailable())
                writeData(mouse->hostRead(), true);
            break;
          case WriteCommandByte:
            commandByte = data;
            DPRINTF(I8042, "Got data %#02x for \"Write "
                    "command byte\" command.\n", data);
            statusReg.passedSelfTest = (uint8_t)commandByte.passedSelfTest;
            break;
          case WriteMouseOutputBuff:
            DPRINTF(I8042, "Got data %#02x for \"Write "
                    "mouse output buffer\" command.\n", data);
            writeData(data, true);
            break;
          case WriteKeyboardOutputBuff:
            DPRINTF(I8042, "Got data %#02x for \"Write "
                    "keyboad output buffer\" command.\n", data);
            writeData(data, false);
            break;
          case WriteOutputPort:
            DPRINTF(I8042, "Got data %#02x for \"Write "
                    "output port\" command.\n", data);
            panic_if(bits(data, 0) != 1, "Reset bit should be 1");
            // Safe to ignore otherwise
            break;
          default:
            panic("Data written for unrecognized "
                    "command %#02x\n", lastCommand);
        }
        lastCommand = NoCommand;
    } else if (addr == commandPort) {
        DPRINTF(I8042, "Got command %#02x.\n", data);
        statusReg.commandLast = 1;
        // These purposefully leave off the first byte of the controller RAM
        // so it can be handled specially.
        if (data > ReadControllerRamBase &&
                data < ReadControllerRamBase + RamSize) {
            panic("Attempted to use i8042 read controller RAM command to "
                    "get byte %d.\n", data - ReadControllerRamBase);
        } else if (data > WriteControllerRamBase &&
                data < WriteControllerRamBase + RamSize) {
            panic("Attempted to use i8042 read controller RAM command to "
                    "get byte %d.\n", data - ReadControllerRamBase);
        } else if (data >= PulseOutputBitBase &&
                data < PulseOutputBitBase + NumOutputBits) {
            panic("Attempted to use i8042 pulse output bit command to "
                    "to pulse bit %d.\n", data - PulseOutputBitBase);
        }
        switch (data) {
          case GetCommandByte:
            DPRINTF(I8042, "Getting command byte.\n");
            writeData(commandByte);
            break;
          case WriteCommandByte:
            DPRINTF(I8042, "Setting command byte.\n");
            lastCommand = WriteCommandByte;
            break;
          case CheckForPassword:
            panic("i8042 \"Check for password\" command not implemented.\n");
          case LoadPassword:
            panic("i8042 \"Load password\" command not implemented.\n");
          case CheckPassword:
            panic("i8042 \"Check password\" command not implemented.\n");
          case DisableMouse:
            DPRINTF(I8042, "Disabling mouse at controller.\n");
            commandByte.disableMouse = 1;
            break;
          case EnableMouse:
            DPRINTF(I8042, "Enabling mouse at controller.\n");
            commandByte.disableMouse = 0;
            break;
          case TestMouse:
            panic("i8042 \"Test mouse\" command not implemented.\n");
          case SelfTest:
            panic("i8042 \"Self test\" command not implemented.\n");
          case InterfaceTest:
            panic("i8042 \"Interface test\" command not implemented.\n");
          case DiagnosticDump:
            panic("i8042 \"Diagnostic dump\" command not implemented.\n");
          case DisableKeyboard:
            DPRINTF(I8042, "Disabling keyboard at controller.\n");
            commandByte.disableKeyboard = 1;
            break;
          case EnableKeyboard:
            DPRINTF(I8042, "Enabling keyboard at controller.\n");
            commandByte.disableKeyboard = 0;
            break;
          case ReadInputPort:
            panic("i8042 \"Read input port\" command not implemented.\n");
          case ContinuousPollLow:
            panic("i8042 \"Continuous poll low\" command not implemented.\n");
          case ContinuousPollHigh:
            panic("i8042 \"Continuous poll high\" command not implemented.\n");
          case ReadOutputPort:
            panic("i8042 \"Read output port\" command not implemented.\n");
          case WriteOutputPort:
            lastCommand = WriteOutputPort;
            break;
          case WriteKeyboardOutputBuff:
            lastCommand = WriteKeyboardOutputBuff;
            break;
          case WriteMouseOutputBuff:
            DPRINTF(I8042, "Got command to write to mouse output buffer.\n");
            lastCommand = WriteMouseOutputBuff;
            break;
          case WriteToMouse:
            DPRINTF(I8042, "Expecting mouse command.\n");
            lastCommand = WriteToMouse;
            break;
          case DisableA20:
            panic("i8042 \"Disable A20\" command not implemented.\n");
          case EnableA20:
            panic("i8042 \"Enable A20\" command not implemented.\n");
          case ReadTestInputs:
            panic("i8042 \"Read test inputs\" command not implemented.\n");
          case SystemReset:
            panic("i8042 \"System reset\" command not implemented.\n");
          default:
            warn("Write to unknown i8042 "
                    "(keyboard controller) command port.\n");
        }
    } else {
        panic("Write to unrecognized port %#x.\n", addr);
    }
    pkt->makeAtomicResponse();
    return latency;
}

void
X86ISA::I8042::serialize(CheckpointOut &cp) const
{
    SERIALIZE_SCALAR(dataPort);
    SERIALIZE_SCALAR(commandPort);
    SERIALIZE_SCALAR(statusReg);
    SERIALIZE_SCALAR(commandByte);
    SERIALIZE_SCALAR(dataReg);
    SERIALIZE_SCALAR(lastCommand);
}

void
X86ISA::I8042::unserialize(CheckpointIn &cp)
{
    UNSERIALIZE_SCALAR(dataPort);
    UNSERIALIZE_SCALAR(commandPort);
    UNSERIALIZE_SCALAR(statusReg);
    UNSERIALIZE_SCALAR(commandByte);
    UNSERIALIZE_SCALAR(dataReg);
    UNSERIALIZE_SCALAR(lastCommand);
}
