/*
 * 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 "base/trace.hh"
#include "cpu/intr_control.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"

using namespace std;

// 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()
{
    delete master;
    delete slave;
}

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)
{
    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);

    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):
        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):
            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:
        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;
        primary.accessCommand(addr, size, dataPtr, read);
    } else if (addr >= primary.ctrlAddr &&
               addr < (primary.ctrlAddr + primary.ctrlSize)) {
        addr -= primary.ctrlAddr;
        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);
    }

    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);

    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);
}
