/*
 * 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.
 *
 * Authors: Andrew Schultz
 *          Ali Saidi
 *          Miguel Serrano
 */

#include <string>

#include "cpu/intr_control.hh"
#include "debug/IdeCtrl.hh"
#include "dev/ide_ctrl.hh"
#include "dev/ide_disk.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "params/IdeController.hh"
#include "sim/byteswap.hh"

// clang complains about std::set being overloaded with Packet::set if
// we open up the entire namespace std
using std::string;

// Bus master IDE registers
enum BMIRegOffset {
    BMICommand = 0x0,
    BMIStatus = 0x2,
    BMIDescTablePtr = 0x4
};

// PCI config space registers
enum ConfRegOffset {
    PrimaryTiming = 0x40,
    SecondaryTiming = 0x42,
    DeviceTiming = 0x44,
    UDMAControl = 0x48,
    UDMATiming = 0x4A,
    IDEConfig = 0x54
};

static const uint16_t timeRegWithDecodeEn = 0x8000;

IdeController::Channel::Channel(
        string newName, Addr _cmdSize, Addr _ctrlSize) :
    _name(newName),
    cmdAddr(0), cmdSize(_cmdSize), ctrlAddr(0), ctrlSize(_ctrlSize),
    master(NULL), slave(NULL), selected(NULL)
{
    memset(&bmiRegs, 0, sizeof(bmiRegs));
    bmiRegs.status.dmaCap0 = 1;
    bmiRegs.status.dmaCap1 = 1;
}

IdeController::Channel::~Channel()
{
}

IdeController::IdeController(Params *p)
    : PciDev(p), primary(name() + ".primary", BARSize[0], BARSize[1]),
    secondary(name() + ".secondary", BARSize[2], BARSize[3]),
    bmiAddr(0), bmiSize(BARSize[4]),
    primaryTiming(htole(timeRegWithDecodeEn)),
    secondaryTiming(htole(timeRegWithDecodeEn)),
    deviceTiming(0), udmaControl(0), udmaTiming(0), ideConfig(0),
    ioEnabled(false), bmEnabled(false),
    ioShift(p->io_shift), ctrlOffset(p->ctrl_offset)
{
    if (params()->disks.size() > 3)
        panic("IDE controllers support a maximum of 4 devices attached!\n");

    // Assign the disks to channels
    int numDisks = params()->disks.size();
    if (numDisks > 0)
        primary.master = params()->disks[0];
    if (numDisks > 1)
        primary.slave = params()->disks[1];
    if (numDisks > 2)
        secondary.master = params()->disks[2];
    if (numDisks > 3)
        secondary.slave = params()->disks[3];

    for (int i = 0; i < params()->disks.size(); i++) {
        params()->disks[i]->setController(this);
    }
    primary.select(false);
    secondary.select(false);

    if ((BARAddrs[0] & ~BAR_IO_MASK) && (!legacyIO[0] || ioShift)) {
        primary.cmdAddr = BARAddrs[0];  primary.cmdSize = BARSize[0];
        primary.ctrlAddr = BARAddrs[1]; primary.ctrlSize = BARAddrs[1];
    }
    if ((BARAddrs[2] & ~BAR_IO_MASK) && (!legacyIO[2] || ioShift)) {
        secondary.cmdAddr = BARAddrs[2];  secondary.cmdSize = BARSize[2];
        secondary.ctrlAddr = BARAddrs[3]; secondary.ctrlSize = BARAddrs[3];
    }

    ioEnabled = (config.command & htole(PCI_CMD_IOSE));
    bmEnabled = (config.command & htole(PCI_CMD_BME));
}

bool
IdeController::isDiskSelected(IdeDisk *diskPtr)
{
    return (primary.selected == diskPtr || secondary.selected == diskPtr);
}

void
IdeController::intrPost()
{
    primary.bmiRegs.status.intStatus = 1;
    PciDev::intrPost();
}

void
IdeController::setDmaComplete(IdeDisk *disk)
{
    Channel *channel;
    if (disk == primary.master || disk == primary.slave) {
        channel = &primary;
    } else if (disk == secondary.master || disk == secondary.slave) {
        channel = &secondary;
    } else {
        panic("Unable to find disk based on pointer %#x\n", disk);
    }

    channel->bmiRegs.command.startStop = 0;
    channel->bmiRegs.status.active = 0;
    channel->bmiRegs.status.intStatus = 1;
}

Tick
IdeController::readConfig(PacketPtr pkt)
{
    int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
    if (offset < PCI_DEVICE_SPECIFIC) {
        return PciDev::readConfig(pkt);
    }

    pkt->allocate();

    switch (pkt->getSize()) {
      case sizeof(uint8_t):
        switch (offset) {
          case DeviceTiming:
            pkt->set<uint8_t>(deviceTiming);
            break;
          case UDMAControl:
            pkt->set<uint8_t>(udmaControl);
            break;
          case PrimaryTiming + 1:
            pkt->set<uint8_t>(bits(htole(primaryTiming), 15, 8));
            break;
          case SecondaryTiming + 1:
            pkt->set<uint8_t>(bits(htole(secondaryTiming), 15, 8));
            break;
          case IDEConfig:
            pkt->set<uint8_t>(bits(htole(ideConfig), 7, 0));
            break;
          case IDEConfig + 1:
            pkt->set<uint8_t>(bits(htole(ideConfig), 15, 8));
            break;
          default:
            panic("Invalid PCI configuration read for size 1 at offset: %#x!\n",
                    offset);
        }
        DPRINTF(IdeCtrl, "PCI read offset: %#x size: 1 data: %#x\n", offset,
                (uint32_t)pkt->get<uint8_t>());
        break;
      case sizeof(uint16_t):
        switch (offset) {
          case PrimaryTiming:
            pkt->set<uint16_t>(primaryTiming);
            break;
          case SecondaryTiming:
            pkt->set<uint16_t>(secondaryTiming);
            break;
          case UDMATiming:
            pkt->set<uint16_t>(udmaTiming);
            break;
          case IDEConfig:
            pkt->set<uint16_t>(ideConfig);
            break;
          default:
            panic("Invalid PCI configuration read for size 2 offset: %#x!\n",
                    offset);
        }
        DPRINTF(IdeCtrl, "PCI read offset: %#x size: 2 data: %#x\n", offset,
                (uint32_t)pkt->get<uint16_t>());
        break;
      case sizeof(uint32_t):
        if (offset == IDEConfig)
            pkt->set<uint32_t>(ideConfig);
        else
            panic("No 32bit reads implemented for this device.");
        DPRINTF(IdeCtrl, "PCI read offset: %#x size: 4 data: %#x\n", offset,
                (uint32_t)pkt->get<uint32_t>());
        break;
      default:
        panic("invalid access size(?) for PCI configspace!\n");
    }
    pkt->makeAtomicResponse();
    return configDelay;
}


Tick
IdeController::writeConfig(PacketPtr pkt)
{
    int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
    if (offset < PCI_DEVICE_SPECIFIC) {
        PciDev::writeConfig(pkt);
    } else {
        switch (pkt->getSize()) {
          case sizeof(uint8_t):
            switch (offset) {
              case DeviceTiming:
                deviceTiming = pkt->get<uint8_t>();
                break;
              case UDMAControl:
                udmaControl = pkt->get<uint8_t>();
                break;
              case IDEConfig:
                replaceBits(ideConfig, 7, 0, pkt->get<uint8_t>());
                break;
              case IDEConfig + 1:
                replaceBits(ideConfig, 15, 8, pkt->get<uint8_t>());
                break;
              default:
                panic("Invalid PCI configuration write "
                        "for size 1 offset: %#x!\n", offset);
            }
            DPRINTF(IdeCtrl, "PCI write offset: %#x size: 1 data: %#x\n",
                    offset, (uint32_t)pkt->get<uint8_t>());
            break;
          case sizeof(uint16_t):
            switch (offset) {
              case PrimaryTiming:
                primaryTiming = pkt->get<uint16_t>();
                break;
              case SecondaryTiming:
                secondaryTiming = pkt->get<uint16_t>();
                break;
              case UDMATiming:
                udmaTiming = pkt->get<uint16_t>();
                break;
              case IDEConfig:
                ideConfig = pkt->get<uint16_t>();
                break;
              default:
                panic("Invalid PCI configuration write "
                        "for size 2 offset: %#x!\n",
                        offset);
            }
            DPRINTF(IdeCtrl, "PCI write offset: %#x size: 2 data: %#x\n",
                    offset, (uint32_t)pkt->get<uint16_t>());
            break;
          case sizeof(uint32_t):
            if (offset == IDEConfig)
                ideConfig = pkt->get<uint32_t>();
            else
                panic("Write of unimplemented PCI config. register: %x\n", offset);
            break;
          default:
            panic("invalid access size(?) for PCI configspace!\n");
        }
        pkt->makeAtomicResponse();
    }

    /* Trap command register writes and enable IO/BM as appropriate as well as
     * BARs. */
    switch(offset) {
      case PCI0_BASE_ADDR0:
        if (BARAddrs[0] != 0)
            primary.cmdAddr = BARAddrs[0];
        break;

      case PCI0_BASE_ADDR1:
        if (BARAddrs[1] != 0)
            primary.ctrlAddr = BARAddrs[1];
        break;

      case PCI0_BASE_ADDR2:
        if (BARAddrs[2] != 0)
            secondary.cmdAddr = BARAddrs[2];
        break;

      case PCI0_BASE_ADDR3:
        if (BARAddrs[3] != 0)
            secondary.ctrlAddr = BARAddrs[3];
        break;

      case PCI0_BASE_ADDR4:
        if (BARAddrs[4] != 0)
            bmiAddr = BARAddrs[4];
        break;

      case PCI_COMMAND:
        DPRINTF(IdeCtrl, "Writing to PCI Command val: %#x\n", config.command);
        ioEnabled = (config.command & htole(PCI_CMD_IOSE));
        bmEnabled = (config.command & htole(PCI_CMD_BME));
        break;
    }
    return configDelay;
}

void
IdeController::Channel::accessCommand(Addr offset,
        int size, uint8_t *data, bool read)
{
    const Addr SelectOffset = 6;
    const uint8_t SelectDevBit = 0x10;

    if (!read && offset == SelectOffset)
        select(*data & SelectDevBit);

    if (selected == NULL) {
        assert(size == sizeof(uint8_t));
        *data = 0;
    } else if (read) {
        selected->readCommand(offset, size, data);
    } else {
        selected->writeCommand(offset, size, data);
    }
}

void
IdeController::Channel::accessControl(Addr offset,
        int size, uint8_t *data, bool read)
{
    if (selected == NULL) {
        assert(size == sizeof(uint8_t));
        *data = 0;
    } else if (read) {
        selected->readControl(offset, size, data);
    } else {
        selected->writeControl(offset, size, data);
    }
}

void
IdeController::Channel::accessBMI(Addr offset,
        int size, uint8_t *data, bool read)
{
    assert(offset + size <= sizeof(BMIRegs));
    if (read) {
        memcpy(data, (uint8_t *)&bmiRegs + offset, size);
    } else {
        switch (offset) {
          case BMICommand:
            {
                if (size != sizeof(uint8_t))
                    panic("Invalid BMIC write size: %x\n", size);

                BMICommandReg oldVal = bmiRegs.command;
                BMICommandReg newVal = *data;

                // if a DMA transfer is in progress, R/W control cannot change
                if (oldVal.startStop && oldVal.rw != newVal.rw)
                    oldVal.rw = newVal.rw;

                if (oldVal.startStop != newVal.startStop) {
                    if (selected == NULL)
                        panic("DMA start for disk which does not exist\n");

                    if (oldVal.startStop) {
                        DPRINTF(IdeCtrl, "Stopping DMA transfer\n");
                        bmiRegs.status.active = 0;

                        selected->abortDma();
                    } else {
                        DPRINTF(IdeCtrl, "Starting DMA transfer\n");
                        bmiRegs.status.active = 1;

                        selected->startDma(letoh(bmiRegs.bmidtp));
                    }
                }

                bmiRegs.command = newVal;
            }
            break;
          case BMIStatus:
            {
                if (size != sizeof(uint8_t))
                    panic("Invalid BMIS write size: %x\n", size);

                BMIStatusReg oldVal = bmiRegs.status;
                BMIStatusReg newVal = *data;

                // the BMIDEA bit is read only
                newVal.active = oldVal.active;

                // to reset (set 0) IDEINTS and IDEDMAE, write 1 to each
                if (oldVal.intStatus && newVal.intStatus)
                    newVal.intStatus = 0; // clear the interrupt?
                else
                    newVal.intStatus = oldVal.intStatus;
                if (oldVal.dmaError && newVal.dmaError)
                    newVal.dmaError = 0;
                else
                    newVal.dmaError = oldVal.dmaError;

                bmiRegs.status = newVal;
            }
            break;
          case BMIDescTablePtr:
            if (size != sizeof(uint32_t))
                panic("Invalid BMIDTP write size: %x\n", size);
            bmiRegs.bmidtp = htole(*(uint32_t *)data & ~0x3);
            break;
          default:
            if (size != sizeof(uint8_t) && size != sizeof(uint16_t) &&
                    size != sizeof(uint32_t))
                panic("IDE controller write of invalid write size: %x\n", size);
            memcpy((uint8_t *)&bmiRegs + offset, data, size);
        }
    }
}

void
IdeController::dispatchAccess(PacketPtr pkt, bool read)
{
    pkt->allocate();
    if (pkt->getSize() != 1 && pkt->getSize() != 2 && pkt->getSize() !=4)
         panic("Bad IDE read size: %d\n", pkt->getSize());

    if (!ioEnabled) {
        pkt->makeAtomicResponse();
        DPRINTF(IdeCtrl, "io not enabled\n");
        return;
    }

    Addr addr = pkt->getAddr();
    int size = pkt->getSize();
    uint8_t *dataPtr = pkt->getPtr<uint8_t>();

    if (addr >= primary.cmdAddr &&
            addr < (primary.cmdAddr + primary.cmdSize)) {
        addr -= primary.cmdAddr;
        // linux may have shifted the address by ioShift,
        // here we shift it back, similarly for ctrlOffset.
        addr >>= ioShift;
        primary.accessCommand(addr, size, dataPtr, read);
    } else if (addr >= primary.ctrlAddr &&
               addr < (primary.ctrlAddr + primary.ctrlSize)) {
        addr -= primary.ctrlAddr;
        addr += ctrlOffset;
        primary.accessControl(addr, size, dataPtr, read);
    } else if (addr >= secondary.cmdAddr &&
               addr < (secondary.cmdAddr + secondary.cmdSize)) {
        addr -= secondary.cmdAddr;
        secondary.accessCommand(addr, size, dataPtr, read);
    } else if (addr >= secondary.ctrlAddr &&
               addr < (secondary.ctrlAddr + secondary.ctrlSize)) {
        addr -= secondary.ctrlAddr;
        secondary.accessControl(addr, size, dataPtr, read);
    } else if (addr >= bmiAddr && addr < (bmiAddr + bmiSize)) {
        if (!read && !bmEnabled)
            return;
        addr -= bmiAddr;
        if (addr < sizeof(Channel::BMIRegs)) {
            primary.accessBMI(addr, size, dataPtr, read);
        } else {
            addr -= sizeof(Channel::BMIRegs);
            secondary.accessBMI(addr, size, dataPtr, read);
        }
    } else {
        panic("IDE controller access to invalid address: %#x\n", addr);
    }

#ifndef NDEBUG
    uint32_t data;
    if (pkt->getSize() == 1)
        data = pkt->get<uint8_t>();
    else if (pkt->getSize() == 2)
        data = pkt->get<uint16_t>();
    else
        data = pkt->get<uint32_t>();
    DPRINTF(IdeCtrl, "%s from offset: %#x size: %#x data: %#x\n",
            read ? "Read" : "Write", pkt->getAddr(), pkt->getSize(), data);
#endif

    pkt->makeAtomicResponse();
}

Tick
IdeController::read(PacketPtr pkt)
{
    dispatchAccess(pkt, true);
    return pioDelay;
}

Tick
IdeController::write(PacketPtr pkt)
{
    dispatchAccess(pkt, false);
    return pioDelay;
}

void
IdeController::serialize(std::ostream &os)
{
    // Serialize the PciDev base class
    PciDev::serialize(os);

    // Serialize channels
    primary.serialize("primary", os);
    secondary.serialize("secondary", os);

    // Serialize config registers
    SERIALIZE_SCALAR(primaryTiming);
    SERIALIZE_SCALAR(secondaryTiming);
    SERIALIZE_SCALAR(deviceTiming);
    SERIALIZE_SCALAR(udmaControl);
    SERIALIZE_SCALAR(udmaTiming);
    SERIALIZE_SCALAR(ideConfig);

    // Serialize internal state
    SERIALIZE_SCALAR(ioEnabled);
    SERIALIZE_SCALAR(bmEnabled);
    SERIALIZE_SCALAR(bmiAddr);
    SERIALIZE_SCALAR(bmiSize);
}

void
IdeController::Channel::serialize(const std::string &base, std::ostream &os)
{
    paramOut(os, base + ".cmdAddr", cmdAddr);
    paramOut(os, base + ".cmdSize", cmdSize);
    paramOut(os, base + ".ctrlAddr", ctrlAddr);
    paramOut(os, base + ".ctrlSize", ctrlSize);
    uint8_t command = bmiRegs.command;
    paramOut(os, base + ".bmiRegs.command", command);
    paramOut(os, base + ".bmiRegs.reserved0", bmiRegs.reserved0);
    uint8_t status = bmiRegs.status;
    paramOut(os, base + ".bmiRegs.status", status);
    paramOut(os, base + ".bmiRegs.reserved1", bmiRegs.reserved1);
    paramOut(os, base + ".bmiRegs.bmidtp", bmiRegs.bmidtp);
    paramOut(os, base + ".selectBit", selectBit);
}

void
IdeController::unserialize(Checkpoint *cp, const std::string &section)
{
    // Unserialize the PciDev base class
    PciDev::unserialize(cp, section);

    // Unserialize channels
    primary.unserialize("primary", cp, section);
    secondary.unserialize("secondary", cp, section);

    // Unserialize config registers
    UNSERIALIZE_SCALAR(primaryTiming);
    UNSERIALIZE_SCALAR(secondaryTiming);
    UNSERIALIZE_SCALAR(deviceTiming);
    UNSERIALIZE_SCALAR(udmaControl);
    UNSERIALIZE_SCALAR(udmaTiming);
    UNSERIALIZE_SCALAR(ideConfig);

    // Unserialize internal state
    UNSERIALIZE_SCALAR(ioEnabled);
    UNSERIALIZE_SCALAR(bmEnabled);
    UNSERIALIZE_SCALAR(bmiAddr);
    UNSERIALIZE_SCALAR(bmiSize);
}

void
IdeController::Channel::unserialize(const std::string &base, Checkpoint *cp,
    const std::string &section)
{
    paramIn(cp, section, base + ".cmdAddr", cmdAddr);
    paramIn(cp, section, base + ".cmdSize", cmdSize);
    paramIn(cp, section, base + ".ctrlAddr", ctrlAddr);
    paramIn(cp, section, base + ".ctrlSize", ctrlSize);
    uint8_t command;
    paramIn(cp, section, base +".bmiRegs.command", command);
    bmiRegs.command = command;
    paramIn(cp, section, base + ".bmiRegs.reserved0", bmiRegs.reserved0);
    uint8_t status;
    paramIn(cp, section, base + ".bmiRegs.status", status);
    bmiRegs.status = status;
    paramIn(cp, section, base + ".bmiRegs.reserved1", bmiRegs.reserved1);
    paramIn(cp, section, base + ".bmiRegs.bmidtp", bmiRegs.bmidtp);
    paramIn(cp, section, base + ".selectBit", selectBit);
    select(selectBit);
}

IdeController *
IdeControllerParams::create()
{
    return new IdeController(this);
}
