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

/** @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"

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

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

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)

typedef struct CommandReg {
    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;
} CommandReg_t;

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

typedef enum DevAction {
    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
} DevAction_t;

typedef enum DevState {
    // 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
} DevState_t;

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

class IdeController;

/**
 * IDE Disk device model
 */
class IdeDisk : public SimObject
{
  protected:
    /** The IDE controller for this disk. */
    IdeController *ctrl;
    /** 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;
    /** PRD table base address */
    uint32_t curPrdAddr;
    /** PRD entry */
    PrdTableEntry curPrd;
    /** Device ID (master=0/slave=1) */
    int devID;
    /** Interrupt pending */
    bool intrPending;
    /** DMA Aborted */
    bool dmaAborted;

    Stats::Scalar dmaReadFullPages;
    Stats::Scalar dmaReadBytes;
    Stats::Scalar dmaReadTxs;
    Stats::Scalar dmaWriteFullPages;
    Stats::Scalar dmaWriteBytes;
    Stats::Scalar dmaWriteTxs;

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

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

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

    /**
     * Register Statistics
     */
    void regStats() override;

    /**
     * Set the controller for this device
     * @param c The IDE controller
     */
    void setController(IdeController *c) {
        if (ctrl) panic("Cannot change the controller once set!\n");
        ctrl = c;
    }

    // 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 intrPost();
    void intrClear();

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

    void doDmaDataRead();

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

    void doDmaDataWrite();

    void doDmaWrite();
    ChunkGenerator *dmaWriteCG;
    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  (Addr)(((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;
};


#endif // __DEV_STORAGE_IDE_DISK_HH__
