/*
 * 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 for an IDE disk
 */

#ifndef __DEV_STORAGE_IDE_DISK_HH__
#define __DEV_STORAGE_IDE_DISK_HH__

#include "base/statistics.hh"
#include "dev/io_device.hh"
#include "dev/storage/disk_image.hh"
#include "dev/storage/ide_atareg.h"
#include "dev/storage/ide_ctrl.hh"
#include "dev/storage/ide_wdcreg.h"
#include "params/IdeDisk.hh"
#include "sim/eventq.hh"

namespace gem5
{

class ChunkGenerator;

#define DMA_BACKOFF_PERIOD      200

#define MAX_DMA_SIZE            0x20000  // 128K
#define MAX_SINGLE_DMA_SIZE     0x10000
#define MAX_MULTSECT            (128)

#define PRD_BASE_MASK  0xfffffffe
#define PRD_COUNT_MASK 0xfffe
#define PRD_EOT_MASK   0x8000

struct PrdEntry_t
{
    uint32_t baseAddr;
    uint16_t byteCount;
    uint16_t endOfTable;
};

class PrdTableEntry
{
  public:
    PrdEntry_t entry;

    uint32_t getBaseAddr()
    {
        return (entry.baseAddr & PRD_BASE_MASK);
    }

    uint32_t getByteCount()
    {
        return ((entry.byteCount == 0) ? MAX_SINGLE_DMA_SIZE :
                (entry.byteCount & PRD_COUNT_MASK));
    }

    uint16_t getEOT()
    {
        return (entry.endOfTable & PRD_EOT_MASK);
    }
};

#define DATA_OFFSET     (0)
#define ERROR_OFFSET    (1)
#define FEATURES_OFFSET (1)
#define NSECTOR_OFFSET  (2)
#define SECTOR_OFFSET   (3)
#define LCYL_OFFSET     (4)
#define HCYL_OFFSET     (5)
#define SELECT_OFFSET   (6)
#define DRIVE_OFFSET    (6)
#define STATUS_OFFSET   (7)
#define COMMAND_OFFSET  (7)

#define CONTROL_OFFSET  (2)
#define ALTSTAT_OFFSET  (2)

#define SELECT_DEV_BIT  0x10
#define CONTROL_RST_BIT 0x04
#define CONTROL_IEN_BIT 0x02
#define STATUS_BSY_BIT  0x80
#define STATUS_DRDY_BIT 0x40
#define STATUS_DRQ_BIT  0x08
#define STATUS_SEEK_BIT 0x10
#define STATUS_DF_BIT   0x20
#define DRIVE_LBA_BIT   0x40

#define DEV0 (0)
#define DEV1 (1)

struct CommandReg_t
{
    uint16_t data;
    uint8_t error;
    uint8_t sec_count;
    uint8_t sec_num;
    uint8_t cyl_low;
    uint8_t cyl_high;
    union
    {
        uint8_t drive;
        uint8_t head;
    };
    uint8_t command;
};

enum Events_t
{
    None = 0,
    Transfer,
    ReadWait,
    WriteWait,
    PrdRead,
    DmaRead,
    DmaWrite
};

enum DevAction_t
{
    ACT_NONE = 0,
    ACT_CMD_WRITE,
    ACT_CMD_COMPLETE,
    ACT_CMD_ERROR,
    ACT_SELECT_WRITE,
    ACT_STAT_READ,
    ACT_DATA_READY,
    ACT_DATA_READ_BYTE,
    ACT_DATA_READ_SHORT,
    ACT_DATA_WRITE_BYTE,
    ACT_DATA_WRITE_SHORT,
    ACT_DMA_READY,
    ACT_DMA_DONE,
    ACT_SRST_SET,
    ACT_SRST_CLEAR
};

enum DevState_t
{
    // Device idle
    Device_Idle_S = 0,
    Device_Idle_SI,
    Device_Idle_NS,

    // Software reset
    Device_Srst,

    // Non-data commands
    Command_Execution,

    // PIO data-in (data to host)
    Prepare_Data_In,
    Data_Ready_INTRQ_In,
    Transfer_Data_In,

    // PIO data-out (data from host)
    Prepare_Data_Out,
    Data_Ready_INTRQ_Out,
    Transfer_Data_Out,

    // DMA protocol
    Prepare_Data_Dma,
    Transfer_Data_Dma,
    Device_Dma_Abort
};

enum DmaState_t
{
    Dma_Idle = 0,
    Dma_Start,
    Dma_Transfer
};

class IdeController;

/**
 * IDE Disk device model
 */
class IdeDisk : public SimObject
{
  protected:
    /** The IDE controller for this disk. */
    IdeController *ctrl = nullptr;
    /** The channel this disk is connected to. */
    IdeController::Channel *channel = nullptr;
    /** The image that contains the data of this disk. */
    DiskImage *image;

  protected:
    /** The disk delay in microseconds. */
    int diskDelay;

  private:
    /** Drive identification structure for this disk */
    struct ataparams driveID;
    /** Data buffer for transfers */
    uint8_t *dataBuffer;
    /** Number of bytes in command data transfer */
    uint32_t cmdBytes;
    /** Number of bytes left in command data transfer */
    uint32_t cmdBytesLeft;
    /** Number of bytes left in DRQ block */
    uint32_t drqBytesLeft;
    /** Current sector in access */
    uint32_t curSector;
    /** Command block registers */
    CommandReg_t cmdReg;
    /** Status register */
    uint8_t status;
    /** Interrupt enable bit */
    bool nIENBit;
    /** Device state */
    DevState_t devState;
    /** Dma state */
    DmaState_t dmaState;
    /** Dma transaction is a read */
    bool dmaRead;
    /** Size of chunks to DMA. */
    Addr chunkBytes;
    /** PRD table base address */
    uint32_t curPrdAddr;
    /** PRD entry */
    PrdTableEntry curPrd;
    /** Device ID (device0=0/device1=1) */
    int devID;
    /** Interrupt pending */
    bool pendingInterrupt;
    /** DMA Aborted */
    bool dmaAborted;

    struct IdeDiskStats : public statistics::Group
    {
        IdeDiskStats(statistics::Group *parent);

        statistics::Scalar dmaReadFullPages;
        statistics::Scalar dmaReadBytes;
        statistics::Scalar dmaReadTxs;
        statistics::Scalar dmaWriteFullPages;
        statistics::Scalar dmaWriteBytes;
        statistics::Scalar dmaWriteTxs;
    } ideDiskStats;

  public:
    typedef IdeDiskParams Params;
    IdeDisk(const Params &p);

    /**
     * Delete the data buffer.
     */
    ~IdeDisk();

    /**
     * Reset the device state
     */
    void reset(int id);

    /**
     * Set the controller for this device
     * @param c The IDE controller
     */
    void
    setChannel(IdeController::Channel *_channel, Addr chunk_bytes)
    {
        panic_if(channel, "Cannot change the channel once set!");
        channel = _channel;
        ctrl = channel->controller();
        chunkBytes = chunk_bytes;
    }

    // Device register read/write
    void readCommand(const Addr offset, int size, uint8_t *data);
    void readControl(const Addr offset, int size, uint8_t *data);
    void writeCommand(const Addr offset, int size, const uint8_t *data);
    void writeControl(const Addr offset, int size, const uint8_t *data);

    // Start/abort functions
    void startDma(const uint32_t &prdTableBase);
    void abortDma();

  private:
    void startCommand();

    // Interrupt management
    void postInterrupt();
    void clearInterrupt();

    // DMA stuff
    void doDmaTransfer();
    EventFunctionWrapper dmaTransferEvent;

    void doDmaDataRead();

    void doDmaRead();
    ChunkGenerator *dmaReadCG = nullptr;
    EventFunctionWrapper dmaReadWaitEvent;

    void doDmaDataWrite();

    void doDmaWrite();
    ChunkGenerator *dmaWriteCG = nullptr;
    EventFunctionWrapper dmaWriteWaitEvent;

    void dmaPrdReadDone();
    EventFunctionWrapper dmaPrdReadEvent;

    void dmaReadDone();
    EventFunctionWrapper dmaReadEvent;

    void dmaWriteDone();
    EventFunctionWrapper dmaWriteEvent;

    // Disk image read/write
    void readDisk(uint32_t sector, uint8_t *data);
    void writeDisk(uint32_t sector, uint8_t *data);

    // State machine management
    void updateState(DevAction_t action);

    // Utility functions
    bool isBSYSet() { return (status & STATUS_BSY_BIT); }
    bool isIENSet() { return nIENBit; }
    bool isDEVSelect();

    void
    setComplete()
    {
        // clear out the status byte
        status = 0;
        // set the DRDY bit
        status |= STATUS_DRDY_BIT;
        // set the SEEK bit
        status |= STATUS_SEEK_BIT;
    }

    uint32_t
    getLBABase()
    {
        return ((cmdReg.head & 0xf) << 24) |
               (cmdReg.cyl_high << 16) |
               (cmdReg.cyl_low << 8) |
               (cmdReg.sec_num);
    }

    inline Addr pciToDma(Addr pciAddr);

    void serialize(CheckpointOut &cp) const override;
    void unserialize(CheckpointIn &cp) override;
};

} // namespace gem5

#endif // __DEV_STORAGE_IDE_DISK_HH__
