/*
 * Copyright (c) 2013 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * 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 "dev/storage/ide_ctrl.hh"

#include <string>

#include "cpu/intr_control.hh"
#include "debug/IdeCtrl.hh"
#include "dev/storage/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)
{
    bmiRegs.reset();
    bmiRegs.status.dmaCap0 = 1;
    bmiRegs.status.dmaCap1 = 1;
}

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

IdeController::IdeController(Params *p)
    : PciDevice(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)
{

    // Assign the disks to channels
    for (int i = 0; i < params()->disks.size(); i++) {
        if (!params()->disks[i])
            continue;
        switch (i) {
          case 0:
            primary.master = params()->disks[0];
            break;
          case 1:
            primary.slave = params()->disks[1];
            break;
          case 2:
            secondary.master = params()->disks[2];
            break;
          case 3:
            secondary.slave = params()->disks[3];
            break;
          default:
            panic("IDE controllers support a maximum "
                  "of 4 devices attached!\n");
        }
        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 = BARSize[1];
    }
    if ((BARAddrs[2] & ~BAR_IO_MASK) && (!legacyIO[2] || ioShift)) {
        secondary.cmdAddr = BARAddrs[2];  secondary.cmdSize = BARSize[2];
        secondary.ctrlAddr = BARAddrs[3]; secondary.ctrlSize = BARSize[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;
    PciDevice::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 PciDevice::readConfig(pkt);
    }

    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 UDMAControl:
            pkt->set<uint16_t>(udmaControl);
            break;
          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):
        switch (offset) {
          case PrimaryTiming:
            pkt->set<uint32_t>(primaryTiming);
            break;
          case IDEConfig:
            pkt->set<uint32_t>(ideConfig);
            break;
          default:
            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) {
        PciDevice::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 UDMAControl:
                udmaControl = pkt->get<uint16_t>();
                break;
              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):
            switch (offset) {
              case PrimaryTiming:
                primaryTiming = pkt->get<uint32_t>();
                break;
              case IDEConfig:
                ideConfig = pkt->get<uint32_t>();
                break;
              default:
                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 == 1) && (newVal.intStatus == 1)) {
                    newVal.intStatus = 0; // clear the interrupt?
                } else {
                    // Assigning two bitunion fields to each other does not
                    // work as intended, so we need to use this temporary variable
                    // to get around the bug.
                    uint8_t tmp = oldVal.intStatus;
                    newVal.intStatus = tmp;
                }
                if ((oldVal.dmaError == 1) && (newVal.dmaError == 1)) {
                    newVal.dmaError = 0;
                } else {
                    uint8_t tmp = oldVal.dmaError;
                    newVal.dmaError = tmp;
                }

                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)
{
    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(CheckpointOut &cp) const
{
    // Serialize the PciDevice base class
    PciDevice::serialize(cp);

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

    // 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,
                                  CheckpointOut &cp) const
{
    paramOut(cp, base + ".cmdAddr", cmdAddr);
    paramOut(cp, base + ".cmdSize", cmdSize);
    paramOut(cp, base + ".ctrlAddr", ctrlAddr);
    paramOut(cp, base + ".ctrlSize", ctrlSize);
    uint8_t command = bmiRegs.command;
    paramOut(cp, base + ".bmiRegs.command", command);
    paramOut(cp, base + ".bmiRegs.reserved0", bmiRegs.reserved0);
    uint8_t status = bmiRegs.status;
    paramOut(cp, base + ".bmiRegs.status", status);
    paramOut(cp, base + ".bmiRegs.reserved1", bmiRegs.reserved1);
    paramOut(cp, base + ".bmiRegs.bmidtp", bmiRegs.bmidtp);
    paramOut(cp, base + ".selectBit", selectBit);
}

void
IdeController::unserialize(CheckpointIn &cp)
{
    // Unserialize the PciDevice base class
    PciDevice::unserialize(cp);

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

    // 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, CheckpointIn &cp)
{
    paramIn(cp, base + ".cmdAddr", cmdAddr);
    paramIn(cp, base + ".cmdSize", cmdSize);
    paramIn(cp, base + ".ctrlAddr", ctrlAddr);
    paramIn(cp, base + ".ctrlSize", ctrlSize);
    uint8_t command;
    paramIn(cp, base +".bmiRegs.command", command);
    bmiRegs.command = command;
    paramIn(cp, base + ".bmiRegs.reserved0", bmiRegs.reserved0);
    uint8_t status;
    paramIn(cp, base + ".bmiRegs.status", status);
    bmiRegs.status = status;
    paramIn(cp, base + ".bmiRegs.reserved1", bmiRegs.reserved1);
    paramIn(cp, base + ".bmiRegs.bmidtp", bmiRegs.bmidtp);
    paramIn(cp, base + ".selectBit", selectBit);
    select(selectBit);
}

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