/*
 * 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.
 */

/** @file
 * Device model implementation for an IDE disk
 */

#include "dev/storage/ide_disk.hh"

#include <cerrno>
#include <cstring>
#include <deque>
#include <string>

#include "base/chunk_generator.hh"
#include "base/cprintf.hh" // csprintf
#include "base/trace.hh"
#include "debug/IdeDisk.hh"
#include "dev/storage/disk_image.hh"
#include "dev/storage/ide_ctrl.hh"
#include "sim/core.hh"
#include "sim/sim_object.hh"

IdeDisk::IdeDisk(const Params &p)
    : SimObject(p), ctrl(NULL), image(p.image), diskDelay(p.delay),
      ideDiskStats(this),
      dmaTransferEvent([this]{ doDmaTransfer(); }, name()),
      dmaReadCG(NULL),
      dmaReadWaitEvent([this]{ doDmaRead(); }, name()),
      dmaWriteCG(NULL),
      dmaWriteWaitEvent([this]{ doDmaWrite(); }, name()),
      dmaPrdReadEvent([this]{ dmaPrdReadDone(); }, name()),
      dmaReadEvent([this]{ dmaReadDone(); }, name()),
      dmaWriteEvent([this]{ dmaWriteDone(); }, name())
{
    // Reset the device state
    reset(p.driveID);

    // fill out the drive ID structure
    memset(&driveID, 0, sizeof(struct ataparams));

    // Calculate LBA and C/H/S values
    uint16_t cylinders;
    uint8_t heads;
    uint8_t sectors;

    uint32_t lba_size = image->size();
    if (lba_size >= 16383*16*63) {
        cylinders = 16383;
        heads = 16;
        sectors = 63;
    } else {
        if (lba_size >= 63)
            sectors = 63;
        else if (lba_size == 0)
            panic("Bad IDE image size: 0\n");
        else
            sectors = lba_size;

        if ((lba_size / sectors) >= 16)
            heads = 16;
        else
            heads = (lba_size / sectors);

        cylinders = lba_size / (heads * sectors);
    }

    // Setup the model name
    strncpy((char *)driveID.atap_model, "5MI EDD si k",
            sizeof(driveID.atap_model));
    // Set the maximum multisector transfer size
    driveID.atap_multi = MAX_MULTSECT;
    // IORDY supported, IORDY disabled, LBA enabled, DMA enabled
    driveID.atap_capabilities1 = 0x7;
    // UDMA support, EIDE support
    driveID.atap_extensions = 0x6;
    // Setup default C/H/S settings
    driveID.atap_cylinders = cylinders;
    driveID.atap_sectors = sectors;
    driveID.atap_heads = heads;
    // Setup the current multisector transfer size
    driveID.atap_curmulti = MAX_MULTSECT;
    driveID.atap_curmulti_valid = 0x1;
    // Number of sectors on disk
    driveID.atap_capacity = lba_size;
    // Multiword DMA mode 2 and below supported
    driveID.atap_dmamode_supp = 0x4;
    // Set PIO mode 4 and 3 supported
    driveID.atap_piomode_supp = 0x3;
    // Set DMA mode 4 and below supported
    driveID.atap_udmamode_supp = 0x1f;
    // Statically set hardware config word
    driveID.atap_hwreset_res = 0x4001;

    //arbitrary for now...
    driveID.atap_ata_major = WDC_VER_ATA7;
}

IdeDisk::~IdeDisk()
{
    // destroy the data buffer
    delete [] dataBuffer;
}

void
IdeDisk::reset(int id)
{
    // initialize the data buffer and shadow registers
    dataBuffer = new uint8_t[MAX_DMA_SIZE];

    memset(dataBuffer, 0, MAX_DMA_SIZE);
    memset(&cmdReg, 0, sizeof(CommandReg_t));
    memset(&curPrd.entry, 0, sizeof(PrdEntry_t));

    curPrdAddr = 0;
    curSector = 0;
    cmdBytes = 0;
    cmdBytesLeft = 0;
    drqBytesLeft = 0;
    dmaRead = false;
    intrPending = false;
    dmaAborted = false;

    // set the device state to idle
    dmaState = Dma_Idle;

    if (id == DEV0) {
        devState = Device_Idle_S;
        devID = DEV0;
    } else if (id == DEV1) {
        devState = Device_Idle_NS;
        devID = DEV1;
    } else {
        panic("Invalid device ID: %#x\n", id);
    }

    // set the device ready bit
    status = STATUS_DRDY_BIT;

    /* The error register must be set to 0x1 on start-up to
       indicate that no diagnostic error was detected */
    cmdReg.error = 0x1;
}

////
// Utility functions
////

bool
IdeDisk::isDEVSelect()
{
    return ctrl->isDiskSelected(this);
}

Addr
IdeDisk::pciToDma(Addr pciAddr)
{
    if (ctrl)
        return ctrl->pciToDma(pciAddr);
    else
        panic("Access to unset controller!\n");
}

////
// Device registers read/write
////

void
IdeDisk::readCommand(const Addr offset, int size, uint8_t *data)
{
    if (offset == DATA_OFFSET) {
        if (size == sizeof(uint16_t)) {
            *(uint16_t *)data = cmdReg.data;
        } else if (size == sizeof(uint32_t)) {
            *(uint16_t *)data = cmdReg.data;
            updateState(ACT_DATA_READ_SHORT);
            *((uint16_t *)data + 1) = cmdReg.data;
        } else {
            panic("Data read of unsupported size %d.\n", size);
        }
        updateState(ACT_DATA_READ_SHORT);
        return;
    }
    assert(size == sizeof(uint8_t));
    switch (offset) {
      case ERROR_OFFSET:
        *data = cmdReg.error;
        break;
      case NSECTOR_OFFSET:
        *data = cmdReg.sec_count;
        break;
      case SECTOR_OFFSET:
        *data = cmdReg.sec_num;
        break;
      case LCYL_OFFSET:
        *data = cmdReg.cyl_low;
        break;
      case HCYL_OFFSET:
        *data = cmdReg.cyl_high;
        break;
      case DRIVE_OFFSET:
        *data = cmdReg.drive;
        break;
      case STATUS_OFFSET:
        *data = status;
        updateState(ACT_STAT_READ);
        break;
      default:
        panic("Invalid IDE command register offset: %#x\n", offset);
    }
    DPRINTF(IdeDisk, "Read to disk at offset: %#x data %#x\n", offset, *data);
}

void
IdeDisk::readControl(const Addr offset, int size, uint8_t *data)
{
    assert(size == sizeof(uint8_t));
    *data = status;
    if (offset != ALTSTAT_OFFSET)
        panic("Invalid IDE control register offset: %#x\n", offset);
    DPRINTF(IdeDisk, "Read to disk at offset: %#x data %#x\n", offset, *data);
}

void
IdeDisk::writeCommand(const Addr offset, int size, const uint8_t *data)
{
    if (offset == DATA_OFFSET) {
        if (size == sizeof(uint16_t)) {
            cmdReg.data = *(const uint16_t *)data;
        } else if (size == sizeof(uint32_t)) {
            cmdReg.data = *(const uint16_t *)data;
            updateState(ACT_DATA_WRITE_SHORT);
            cmdReg.data = *((const uint16_t *)data + 1);
        } else {
            panic("Data write of unsupported size %d.\n", size);
        }
        updateState(ACT_DATA_WRITE_SHORT);
        return;
    }

    assert(size == sizeof(uint8_t));
    switch (offset) {
      case FEATURES_OFFSET:
        break;
      case NSECTOR_OFFSET:
        cmdReg.sec_count = *data;
        break;
      case SECTOR_OFFSET:
        cmdReg.sec_num = *data;
        break;
      case LCYL_OFFSET:
        cmdReg.cyl_low = *data;
        break;
      case HCYL_OFFSET:
        cmdReg.cyl_high = *data;
        break;
      case DRIVE_OFFSET:
        cmdReg.drive = *data;
        updateState(ACT_SELECT_WRITE);
        break;
      case COMMAND_OFFSET:
        cmdReg.command = *data;
        updateState(ACT_CMD_WRITE);
        break;
      default:
        panic("Invalid IDE command register offset: %#x\n", offset);
    }
    DPRINTF(IdeDisk, "Write to disk at offset: %#x data %#x\n", offset,
            (uint32_t)*data);
}

void
IdeDisk::writeControl(const Addr offset, int size, const uint8_t *data)
{
    if (offset != CONTROL_OFFSET)
        panic("Invalid IDE control register offset: %#x\n", offset);

    if (*data & CONTROL_RST_BIT) {
        // force the device into the reset state
        devState = Device_Srst;
        updateState(ACT_SRST_SET);
    } else if (devState == Device_Srst && !(*data & CONTROL_RST_BIT)) {
        updateState(ACT_SRST_CLEAR);
    }

    nIENBit = *data & CONTROL_IEN_BIT;

    DPRINTF(IdeDisk, "Write to disk at offset: %#x data %#x\n", offset,
            (uint32_t)*data);
}

////
// Perform DMA transactions
////

void
IdeDisk::doDmaTransfer()
{
    if (dmaAborted) {
        DPRINTF(IdeDisk, "DMA Aborted before reading PRD entry\n");
        updateState(ACT_CMD_ERROR);
        return;
    }

    if (dmaState != Dma_Transfer || devState != Transfer_Data_Dma)
        panic("Inconsistent DMA transfer state: dmaState = %d devState = %d\n",
              dmaState, devState);

    if (ctrl->dmaPending() || ctrl->drainState() != DrainState::Running) {
        schedule(dmaTransferEvent, curTick() + DMA_BACKOFF_PERIOD);
        return;
    } else
        ctrl->dmaRead(curPrdAddr, sizeof(PrdEntry_t), &dmaPrdReadEvent,
                (uint8_t*)&curPrd.entry);
}

void
IdeDisk::dmaPrdReadDone()
{
    if (dmaAborted) {
        DPRINTF(IdeDisk, "DMA Aborted while reading PRD entry\n");
        updateState(ACT_CMD_ERROR);
        return;
    }

    DPRINTF(IdeDisk,
            "PRD: baseAddr:%#x (%#x) byteCount:%d (%d) eot:%#x sector:%d\n",
            curPrd.getBaseAddr(), pciToDma(curPrd.getBaseAddr()),
            curPrd.getByteCount(), (cmdBytesLeft/SectorSize),
            curPrd.getEOT(), curSector);

    // the prd pointer has already been translated, so just do an increment
    curPrdAddr = curPrdAddr + sizeof(PrdEntry_t);

    if (dmaRead)
        doDmaDataRead();
    else
        doDmaDataWrite();
}

void
IdeDisk::doDmaDataRead()
{
    /** @todo we need to figure out what the delay actually will be */
    Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize);

    DPRINTF(IdeDisk, "doDmaRead, diskDelay: %d totalDiskDelay: %d\n",
            diskDelay, totalDiskDelay);

    schedule(dmaReadWaitEvent, curTick() + totalDiskDelay);
}

IdeDisk::
IdeDiskStats::IdeDiskStats(Stats::Group *parent)
    : Stats::Group(parent, "IdeDisk"),
      ADD_STAT(dmaReadFullPages, UNIT_COUNT,
               "Number of full page size DMA reads (not PRD)."),
      ADD_STAT(dmaReadBytes, UNIT_BYTE,
               "Number of bytes transfered via DMA reads (not PRD)."),
      ADD_STAT(dmaReadTxs, UNIT_COUNT,
               "Number of DMA read transactions (not PRD)."),
      ADD_STAT(dmaWriteFullPages, UNIT_COUNT,
               "Number of full page size DMA writes."),
      ADD_STAT(dmaWriteBytes, UNIT_BYTE,
               "Number of bytes transfered via DMA writes."),
      ADD_STAT(dmaWriteTxs, UNIT_COUNT, "Number of DMA write transactions.")
{
}

void
IdeDisk::doDmaRead()
{
    if (dmaAborted) {
        DPRINTF(IdeDisk, "DMA Aborted in middle of Dma Read\n");
        if (dmaReadCG)
            delete dmaReadCG;
        dmaReadCG = NULL;
        updateState(ACT_CMD_ERROR);
        return;
    }

    if (!dmaReadCG) {
        // clear out the data buffer
        memset(dataBuffer, 0, MAX_DMA_SIZE);
        dmaReadCG = new ChunkGenerator(curPrd.getBaseAddr(),
                curPrd.getByteCount(), chunkBytes);

    }
    if (ctrl->dmaPending() || ctrl->drainState() != DrainState::Running) {
        schedule(dmaReadWaitEvent, curTick() + DMA_BACKOFF_PERIOD);
        return;
    } else if (!dmaReadCG->done()) {
        assert(dmaReadCG->complete() < MAX_DMA_SIZE);
        ctrl->dmaRead(pciToDma(dmaReadCG->addr()), dmaReadCG->size(),
                &dmaReadWaitEvent, dataBuffer + dmaReadCG->complete());
        ideDiskStats.dmaReadBytes += dmaReadCG->size();
        ideDiskStats.dmaReadTxs++;
        if (dmaReadCG->size() == chunkBytes)
            ideDiskStats.dmaReadFullPages++;
        dmaReadCG->next();
    } else {
        assert(dmaReadCG->done());
        delete dmaReadCG;
        dmaReadCG = NULL;
        dmaReadDone();
    }
}

void
IdeDisk::dmaReadDone()
{
    uint32_t bytesWritten = 0;

    // write the data to the disk image
    for (bytesWritten = 0; bytesWritten < curPrd.getByteCount();
         bytesWritten += SectorSize) {

        cmdBytesLeft -= SectorSize;
        writeDisk(curSector++, (uint8_t *)(dataBuffer + bytesWritten));
    }

    // check for the EOT
    if (curPrd.getEOT()) {
        assert(cmdBytesLeft == 0);
        dmaState = Dma_Idle;
        updateState(ACT_DMA_DONE);
    } else {
        doDmaTransfer();
    }
}

void
IdeDisk::doDmaDataWrite()
{
    /** @todo we need to figure out what the delay actually will be */
    Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize);
    uint32_t bytesRead = 0;

    DPRINTF(IdeDisk, "doDmaWrite, diskDelay: %d totalDiskDelay: %d\n",
            diskDelay, totalDiskDelay);

    memset(dataBuffer, 0, MAX_DMA_SIZE);
    assert(cmdBytesLeft <= MAX_DMA_SIZE);
    while (bytesRead < curPrd.getByteCount()) {
        readDisk(curSector++, (uint8_t *)(dataBuffer + bytesRead));
        bytesRead += SectorSize;
        cmdBytesLeft -= SectorSize;
    }
    DPRINTF(IdeDisk, "doDmaWrite, bytesRead: %d cmdBytesLeft: %d\n",
            bytesRead, cmdBytesLeft);

    schedule(dmaWriteWaitEvent, curTick() + totalDiskDelay);
}

void
IdeDisk::doDmaWrite()
{
    if (dmaAborted) {
        DPRINTF(IdeDisk, "DMA Aborted while doing DMA Write\n");
        if (dmaWriteCG)
            delete dmaWriteCG;
        dmaWriteCG = NULL;
        updateState(ACT_CMD_ERROR);
        return;
    }
    if (!dmaWriteCG) {
        // clear out the data buffer
        dmaWriteCG = new ChunkGenerator(curPrd.getBaseAddr(),
                curPrd.getByteCount(), chunkBytes);
    }
    if (ctrl->dmaPending() || ctrl->drainState() != DrainState::Running) {
        schedule(dmaWriteWaitEvent, curTick() + DMA_BACKOFF_PERIOD);
        DPRINTF(IdeDisk, "doDmaWrite: rescheduling\n");
        return;
    } else if (!dmaWriteCG->done()) {
        assert(dmaWriteCG->complete() < MAX_DMA_SIZE);
        ctrl->dmaWrite(pciToDma(dmaWriteCG->addr()), dmaWriteCG->size(),
                &dmaWriteWaitEvent, dataBuffer + dmaWriteCG->complete());
        DPRINTF(IdeDisk, "doDmaWrite: not done curPrd byte count %d, eot %#x\n",
                curPrd.getByteCount(), curPrd.getEOT());
        ideDiskStats.dmaWriteBytes += dmaWriteCG->size();
        ideDiskStats.dmaWriteTxs++;
        if (dmaWriteCG->size() == chunkBytes)
            ideDiskStats.dmaWriteFullPages++;
        dmaWriteCG->next();
    } else {
        DPRINTF(IdeDisk, "doDmaWrite: done curPrd byte count %d, eot %#x\n",
                curPrd.getByteCount(), curPrd.getEOT());
        assert(dmaWriteCG->done());
        delete dmaWriteCG;
        dmaWriteCG = NULL;
        dmaWriteDone();
    }
}

void
IdeDisk::dmaWriteDone()
{
    DPRINTF(IdeDisk, "doWriteDone: curPrd byte count %d, eot %#x cmd bytes left:%d\n",
                curPrd.getByteCount(), curPrd.getEOT(), cmdBytesLeft);
    // check for the EOT
    if (curPrd.getEOT()) {
        assert(cmdBytesLeft == 0);
        dmaState = Dma_Idle;
        updateState(ACT_DMA_DONE);
    } else {
        doDmaTransfer();
    }
}

////
// Disk utility routines
///

void
IdeDisk::readDisk(uint32_t sector, uint8_t *data)
{
    uint32_t bytesRead = image->read(data, sector);

    if (bytesRead != SectorSize)
        panic("Can't read from %s. Only %d of %d read. errno=%d\n",
              name(), bytesRead, SectorSize, errno);
}

void
IdeDisk::writeDisk(uint32_t sector, uint8_t *data)
{
    uint32_t bytesWritten = image->write(data, sector);

    if (bytesWritten != SectorSize)
        panic("Can't write to %s. Only %d of %d written. errno=%d\n",
              name(), bytesWritten, SectorSize, errno);
}

////
// Setup and handle commands
////

void
IdeDisk::startDma(const uint32_t &prdTableBase)
{
    if (dmaState != Dma_Start)
        panic("Inconsistent DMA state, should be in Dma_Start!\n");

    if (devState != Transfer_Data_Dma)
        panic("Inconsistent device state for DMA start!\n");

    // PRD base address is given by bits 31:2
    curPrdAddr = pciToDma((Addr)(prdTableBase & ~ULL(0x3)));

    dmaState = Dma_Transfer;

    // schedule dma transfer (doDmaTransfer)
    schedule(dmaTransferEvent, curTick() + 1);
}

void
IdeDisk::abortDma()
{
    if (dmaState == Dma_Idle)
        panic("Inconsistent DMA state, should be Start or Transfer!");

    if (devState != Transfer_Data_Dma && devState != Prepare_Data_Dma)
        panic("Inconsistent device state, should be Transfer or Prepare!\n");

    updateState(ACT_CMD_ERROR);
}

void
IdeDisk::startCommand()
{
    DevAction_t action = ACT_NONE;
    uint32_t size = 0;
    dmaRead = false;

    // Decode commands
    switch (cmdReg.command) {
        // Supported non-data commands
      case WDSF_READ_NATIVE_MAX:
        size = (uint32_t)image->size() - 1;
        cmdReg.sec_num = (size & 0xff);
        cmdReg.cyl_low = ((size & 0xff00) >> 8);
        cmdReg.cyl_high = ((size & 0xff0000) >> 16);
        cmdReg.head = ((size & 0xf000000) >> 24);

        devState = Command_Execution;
        action = ACT_CMD_COMPLETE;
        break;

      case WDCC_RECAL:
      case WDCC_IDP:
      case WDCC_STANDBY_IMMED:
      case WDCC_FLUSHCACHE:
      case WDSF_VERIFY:
      case WDSF_SEEK:
      case SET_FEATURES:
      case WDCC_SETMULTI:
      case WDCC_IDLE:
        devState = Command_Execution;
        action = ACT_CMD_COMPLETE;
        break;

        // Supported PIO data-in commands
      case WDCC_IDENTIFY:
      case ATAPI_IDENTIFY_DEVICE:
        cmdBytes = cmdBytesLeft = sizeof(struct ataparams);
        devState = Prepare_Data_In;
        action = ACT_DATA_READY;
        break;

      case WDCC_READMULTI:
      case WDCC_READ:
        if (!(cmdReg.drive & DRIVE_LBA_BIT))
            panic("Attempt to perform CHS access, only supports LBA\n");

        if (cmdReg.sec_count == 0)
            cmdBytes = cmdBytesLeft = (256 * SectorSize);
        else
            cmdBytes = cmdBytesLeft = (cmdReg.sec_count * SectorSize);

        curSector = getLBABase();

        /** @todo make this a scheduled event to simulate disk delay */
        devState = Prepare_Data_In;
        action = ACT_DATA_READY;
        break;

        // Supported PIO data-out commands
      case WDCC_WRITEMULTI:
      case WDCC_WRITE:
        if (!(cmdReg.drive & DRIVE_LBA_BIT))
            panic("Attempt to perform CHS access, only supports LBA\n");

        if (cmdReg.sec_count == 0)
            cmdBytes = cmdBytesLeft = (256 * SectorSize);
        else
            cmdBytes = cmdBytesLeft = (cmdReg.sec_count * SectorSize);
        DPRINTF(IdeDisk, "Setting cmdBytesLeft to %d\n", cmdBytesLeft);
        curSector = getLBABase();

        devState = Prepare_Data_Out;
        action = ACT_DATA_READY;
        break;

        // Supported DMA commands
      case WDCC_WRITEDMA:
        dmaRead = true;  // a write to the disk is a DMA read from memory
        M5_FALLTHROUGH;
      case WDCC_READDMA:
        if (!(cmdReg.drive & DRIVE_LBA_BIT))
            panic("Attempt to perform CHS access, only supports LBA\n");

        if (cmdReg.sec_count == 0)
            cmdBytes = cmdBytesLeft = (256 * SectorSize);
        else
            cmdBytes = cmdBytesLeft = (cmdReg.sec_count * SectorSize);
        DPRINTF(IdeDisk, "Setting cmdBytesLeft to %d in readdma\n", cmdBytesLeft);

        curSector = getLBABase();

        devState = Prepare_Data_Dma;
        action = ACT_DMA_READY;
        break;

      default:
        panic("Unsupported ATA command: %#x\n", cmdReg.command);
    }

    if (action != ACT_NONE) {
        // set the BSY bit
        status |= STATUS_BSY_BIT;
        // clear the DRQ bit
        status &= ~STATUS_DRQ_BIT;
        // clear the DF bit
        status &= ~STATUS_DF_BIT;

        updateState(action);
    }
}

////
// Handle setting and clearing interrupts
////

void
IdeDisk::intrPost()
{
    DPRINTF(IdeDisk, "Posting Interrupt\n");
    if (intrPending)
        panic("Attempt to post an interrupt with one pending\n");

    intrPending = true;

    // talk to controller to set interrupt
    if (ctrl) {
        ctrl->intrPost();
    }
}

void
IdeDisk::intrClear()
{
    DPRINTF(IdeDisk, "Clearing Interrupt\n");
    if (!intrPending)
        panic("Attempt to clear a non-pending interrupt\n");

    intrPending = false;

    // talk to controller to clear interrupt
    if (ctrl)
        ctrl->intrClear();
}

////
// Manage the device internal state machine
////

void
IdeDisk::updateState(DevAction_t action)
{
    switch (devState) {
      case Device_Srst:
        if (action == ACT_SRST_SET) {
            // set the BSY bit
            status |= STATUS_BSY_BIT;
        } else if (action == ACT_SRST_CLEAR) {
            // clear the BSY bit
            status &= ~STATUS_BSY_BIT;

            // reset the device state
            reset(devID);
        }
        break;

      case Device_Idle_S:
        if (action == ACT_SELECT_WRITE && !isDEVSelect()) {
            devState = Device_Idle_NS;
        } else if (action == ACT_CMD_WRITE) {
            startCommand();
        }

        break;

      case Device_Idle_SI:
        if (action == ACT_SELECT_WRITE && !isDEVSelect()) {
            devState = Device_Idle_NS;
            intrClear();
        } else if (action == ACT_STAT_READ || isIENSet()) {
            devState = Device_Idle_S;
            intrClear();
        } else if (action == ACT_CMD_WRITE) {
            intrClear();
            startCommand();
        }

        break;

      case Device_Idle_NS:
        if (action == ACT_SELECT_WRITE && isDEVSelect()) {
            if (!isIENSet() && intrPending) {
                devState = Device_Idle_SI;
                intrPost();
            }
            if (isIENSet() || !intrPending) {
                devState = Device_Idle_S;
            }
        }
        break;

      case Command_Execution:
        if (action == ACT_CMD_COMPLETE) {
            // clear the BSY bit
            setComplete();

            if (!isIENSet()) {
                devState = Device_Idle_SI;
                intrPost();
            } else {
                devState = Device_Idle_S;
            }
        }
        break;

      case Prepare_Data_In:
        if (action == ACT_CMD_ERROR) {
            // clear the BSY bit
            setComplete();

            if (!isIENSet()) {
                devState = Device_Idle_SI;
                intrPost();
            } else {
                devState = Device_Idle_S;
            }
        } else if (action == ACT_DATA_READY) {
            // clear the BSY bit
            status &= ~STATUS_BSY_BIT;
            // set the DRQ bit
            status |= STATUS_DRQ_BIT;

            // copy the data into the data buffer
            if (cmdReg.command == WDCC_IDENTIFY ||
                cmdReg.command == ATAPI_IDENTIFY_DEVICE) {
                // Reset the drqBytes for this block
                drqBytesLeft = sizeof(struct ataparams);

                memcpy((void *)dataBuffer, (void *)&driveID,
                       sizeof(struct ataparams));
            } else {
                // Reset the drqBytes for this block
                drqBytesLeft = SectorSize;

                readDisk(curSector++, dataBuffer);
            }

            // put the first two bytes into the data register
            memcpy((void *)&cmdReg.data, (void *)dataBuffer,
                   sizeof(uint16_t));

            if (!isIENSet()) {
                devState = Data_Ready_INTRQ_In;
                intrPost();
            } else {
                devState = Transfer_Data_In;
            }
        }
        break;

      case Data_Ready_INTRQ_In:
        if (action == ACT_STAT_READ) {
            devState = Transfer_Data_In;
            intrClear();
        }
        break;

      case Transfer_Data_In:
        if (action == ACT_DATA_READ_BYTE || action == ACT_DATA_READ_SHORT) {
            if (action == ACT_DATA_READ_BYTE) {
                panic("DEBUG: READING DATA ONE BYTE AT A TIME!\n");
            } else {
                drqBytesLeft -= 2;
                cmdBytesLeft -= 2;

                // copy next short into data registers
                if (drqBytesLeft)
                    memcpy((void *)&cmdReg.data,
                           (void *)&dataBuffer[SectorSize - drqBytesLeft],
                           sizeof(uint16_t));
            }

            if (drqBytesLeft == 0) {
                if (cmdBytesLeft == 0) {
                    // Clear the BSY bit
                    setComplete();
                    devState = Device_Idle_S;
                } else {
                    devState = Prepare_Data_In;
                    // set the BSY_BIT
                    status |= STATUS_BSY_BIT;
                    // clear the DRQ_BIT
                    status &= ~STATUS_DRQ_BIT;

                    /** @todo change this to a scheduled event to simulate
                        disk delay */
                    updateState(ACT_DATA_READY);
                }
            }
        }
        break;

      case Prepare_Data_Out:
        if (action == ACT_CMD_ERROR || cmdBytesLeft == 0) {
            // clear the BSY bit
            setComplete();

            if (!isIENSet()) {
                devState = Device_Idle_SI;
                intrPost();
            } else {
                devState = Device_Idle_S;
            }
        } else if (action == ACT_DATA_READY && cmdBytesLeft != 0) {
            // clear the BSY bit
            status &= ~STATUS_BSY_BIT;
            // set the DRQ bit
            status |= STATUS_DRQ_BIT;

            // clear the data buffer to get it ready for writes
            memset(dataBuffer, 0, MAX_DMA_SIZE);

            // reset the drqBytes for this block
            drqBytesLeft = SectorSize;

            if (cmdBytesLeft == cmdBytes || isIENSet()) {
                devState = Transfer_Data_Out;
            } else {
                devState = Data_Ready_INTRQ_Out;
                intrPost();
            }
        }
        break;

      case Data_Ready_INTRQ_Out:
        if (action == ACT_STAT_READ) {
            devState = Transfer_Data_Out;
            intrClear();
        }
        break;

      case Transfer_Data_Out:
        if (action == ACT_DATA_WRITE_BYTE ||
            action == ACT_DATA_WRITE_SHORT) {

            if (action == ACT_DATA_READ_BYTE) {
                panic("DEBUG: WRITING DATA ONE BYTE AT A TIME!\n");
            } else {
                // copy the latest short into the data buffer
                memcpy((void *)&dataBuffer[SectorSize - drqBytesLeft],
                       (void *)&cmdReg.data,
                       sizeof(uint16_t));

                drqBytesLeft -= 2;
                cmdBytesLeft -= 2;
            }

            if (drqBytesLeft == 0) {
                // copy the block to the disk
                writeDisk(curSector++, dataBuffer);

                // set the BSY bit
                status |= STATUS_BSY_BIT;
                // set the seek bit
                status |= STATUS_SEEK_BIT;
                // clear the DRQ bit
                status &= ~STATUS_DRQ_BIT;

                devState = Prepare_Data_Out;

                /** @todo change this to a scheduled event to simulate
                    disk delay */
                updateState(ACT_DATA_READY);
            }
        }
        break;

      case Prepare_Data_Dma:
        if (action == ACT_CMD_ERROR) {
            // clear the BSY bit
            setComplete();

            if (!isIENSet()) {
                devState = Device_Idle_SI;
                intrPost();
            } else {
                devState = Device_Idle_S;
            }
        } else if (action == ACT_DMA_READY) {
            // clear the BSY bit
            status &= ~STATUS_BSY_BIT;
            // set the DRQ bit
            status |= STATUS_DRQ_BIT;

            devState = Transfer_Data_Dma;

            if (dmaState != Dma_Idle)
                panic("Inconsistent DMA state, should be Dma_Idle\n");

            dmaState = Dma_Start;
            // wait for the write to the DMA start bit
        }
        break;

      case Transfer_Data_Dma:
        if (action == ACT_CMD_ERROR) {
            dmaAborted = true;
            devState = Device_Dma_Abort;
        } else if (action == ACT_DMA_DONE) {
            // clear the BSY bit
            setComplete();
            // set the seek bit
            status |= STATUS_SEEK_BIT;
            // clear the controller state for DMA transfer
            ctrl->setDmaComplete(this);

            if (!isIENSet()) {
                devState = Device_Idle_SI;
                intrPost();
            } else {
                devState = Device_Idle_S;
            }
        }
        break;

      case Device_Dma_Abort:
        if (action == ACT_CMD_ERROR) {
            setComplete();
            status |= STATUS_SEEK_BIT;
            ctrl->setDmaComplete(this);
            dmaAborted = false;
            dmaState = Dma_Idle;

            if (!isIENSet()) {
                devState = Device_Idle_SI;
                intrPost();
            } else {
                devState = Device_Idle_S;
            }
        } else {
            DPRINTF(IdeDisk, "Disk still busy aborting previous DMA command\n");
        }
        break;

      default:
        panic("Unknown IDE device state: %#x\n", devState);
    }
}

void
IdeDisk::serialize(CheckpointOut &cp) const
{
    // Check all outstanding events to see if they are scheduled
    // these are all mutually exclusive
    Tick reschedule = 0;
    Events_t event = None;

    int eventCount = 0;

    if (dmaTransferEvent.scheduled()) {
        reschedule = dmaTransferEvent.when();
        event = Transfer;
        eventCount++;
    }
    if (dmaReadWaitEvent.scheduled()) {
        reschedule = dmaReadWaitEvent.when();
        event = ReadWait;
        eventCount++;
    }
    if (dmaWriteWaitEvent.scheduled()) {
        reschedule = dmaWriteWaitEvent.when();
        event = WriteWait;
        eventCount++;
    }
    if (dmaPrdReadEvent.scheduled()) {
        reschedule = dmaPrdReadEvent.when();
        event = PrdRead;
        eventCount++;
    }
    if (dmaReadEvent.scheduled()) {
        reschedule = dmaReadEvent.when();
        event = DmaRead;
        eventCount++;
    }
    if (dmaWriteEvent.scheduled()) {
        reschedule = dmaWriteEvent.when();
        event = DmaWrite;
        eventCount++;
    }

    assert(eventCount <= 1);

    SERIALIZE_SCALAR(reschedule);
    SERIALIZE_ENUM(event);

    // Serialize device registers
    SERIALIZE_SCALAR(cmdReg.data);
    SERIALIZE_SCALAR(cmdReg.sec_count);
    SERIALIZE_SCALAR(cmdReg.sec_num);
    SERIALIZE_SCALAR(cmdReg.cyl_low);
    SERIALIZE_SCALAR(cmdReg.cyl_high);
    SERIALIZE_SCALAR(cmdReg.drive);
    SERIALIZE_SCALAR(cmdReg.command);
    SERIALIZE_SCALAR(status);
    SERIALIZE_SCALAR(nIENBit);
    SERIALIZE_SCALAR(devID);

    // Serialize the PRD related information
    SERIALIZE_SCALAR(curPrd.entry.baseAddr);
    SERIALIZE_SCALAR(curPrd.entry.byteCount);
    SERIALIZE_SCALAR(curPrd.entry.endOfTable);
    SERIALIZE_SCALAR(curPrdAddr);

    /** @todo need to serialized chunk generator stuff!! */
    // Serialize current transfer related information
    SERIALIZE_SCALAR(cmdBytesLeft);
    SERIALIZE_SCALAR(cmdBytes);
    SERIALIZE_SCALAR(drqBytesLeft);
    SERIALIZE_SCALAR(curSector);
    SERIALIZE_SCALAR(dmaRead);
    SERIALIZE_SCALAR(intrPending);
    SERIALIZE_SCALAR(dmaAborted);
    SERIALIZE_ENUM(devState);
    SERIALIZE_ENUM(dmaState);
    SERIALIZE_ARRAY(dataBuffer, MAX_DMA_SIZE);
}

void
IdeDisk::unserialize(CheckpointIn &cp)
{
    // Reschedule events that were outstanding
    // these are all mutually exclusive
    Tick reschedule = 0;
    Events_t event = None;

    UNSERIALIZE_SCALAR(reschedule);
    UNSERIALIZE_ENUM(event);

    switch (event) {
      case None : break;
      case Transfer : schedule(dmaTransferEvent, reschedule); break;
      case ReadWait : schedule(dmaReadWaitEvent, reschedule); break;
      case WriteWait : schedule(dmaWriteWaitEvent, reschedule); break;
      case PrdRead : schedule(dmaPrdReadEvent, reschedule); break;
      case DmaRead : schedule(dmaReadEvent, reschedule); break;
      case DmaWrite : schedule(dmaWriteEvent, reschedule); break;
    }

    // Unserialize device registers
    UNSERIALIZE_SCALAR(cmdReg.data);
    UNSERIALIZE_SCALAR(cmdReg.sec_count);
    UNSERIALIZE_SCALAR(cmdReg.sec_num);
    UNSERIALIZE_SCALAR(cmdReg.cyl_low);
    UNSERIALIZE_SCALAR(cmdReg.cyl_high);
    UNSERIALIZE_SCALAR(cmdReg.drive);
    UNSERIALIZE_SCALAR(cmdReg.command);
    UNSERIALIZE_SCALAR(status);
    UNSERIALIZE_SCALAR(nIENBit);
    UNSERIALIZE_SCALAR(devID);

    // Unserialize the PRD related information
    UNSERIALIZE_SCALAR(curPrd.entry.baseAddr);
    UNSERIALIZE_SCALAR(curPrd.entry.byteCount);
    UNSERIALIZE_SCALAR(curPrd.entry.endOfTable);
    UNSERIALIZE_SCALAR(curPrdAddr);

    /** @todo need to serialized chunk generator stuff!! */
    // Unserialize current transfer related information
    UNSERIALIZE_SCALAR(cmdBytes);
    UNSERIALIZE_SCALAR(cmdBytesLeft);
    UNSERIALIZE_SCALAR(drqBytesLeft);
    UNSERIALIZE_SCALAR(curSector);
    UNSERIALIZE_SCALAR(dmaRead);
    UNSERIALIZE_SCALAR(intrPending);
    UNSERIALIZE_SCALAR(dmaAborted);
    UNSERIALIZE_ENUM(devState);
    UNSERIALIZE_ENUM(dmaState);
    UNSERIALIZE_ARRAY(dataBuffer, MAX_DMA_SIZE);
}
