/*
 * Copyright (c) 2012-2013, 2021 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) 2001-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.
 */

#ifndef __MEM_FLASH_MEM_HH__
#define __MEM_FLASH_MEM_HH__

#include "mem/abstract_mem.hh"
#include "params/CfiMemory.hh"

namespace gem5
{

/**
 * CfiMemory: This is modelling a flash memory adhering to the
 * Common Flash Interface (CFI):
 *
 * JEDEC JESD68.01
 * JEDEC JEP137B
 * Intel Application Note 646
 *
 * This is as of now a pure functional model of a flash controller:
 * no timing/power information has been encoded in it and it is therefore
 * not representive of a real device. Some voltage/timing values have
 * nevertheless been encoded in the CFI table.
 * This is just a requirement from the CFI specification: guest software
 * might query those entries, but they are not reflected in gem5 statistics.
 *
 * The model is meant to be used to allow execution of flash drivers
 * (e.g. UEFI firmware storing EFI variables in non volatile memory)
 */
class CfiMemory : public AbstractMemory
{
  private:
    enum class CfiCommand
    {
        NO_CMD = 0,
        LOCK_BLOCK = 0x1,
        ERASE_BLOCK_SETUP = 0x20,
        WORD_PROGRAM = 0x40,
        CLEAR_STATUS_REG = 0x50,
        LOCK_BLOCK_SETUP = 0x60,
        READ_STATUS_REG = 0x70,
        READ_DEVICE_ID = 0x90,
        READ_CFI_QUERY = 0x98,
        BUFFERED_PROGRAM_SETUP = 0xE8,
        BUFFERED_PROGRAM_CONFIRM = 0xD0,
        BLOCK_ERASE_CONFIRM = 0xD0,
        UNLOCK_BLOCK = 0xD0,
        READ_ARRAY = 0xFF,

        /** This is not a real command, but it is used by the internal
         * model only to represent the 2nd write cycle state for a buffered
         * program (when the buffer size is supplied) */
        BUFFER_SIZE_READ,
    };

    /** Possible in the status register */
    static const uint8_t STATUS_ERASE_ERROR = 0x30;
    static const uint8_t STATUS_LOCK_ERROR = 0x12;
    static const uint8_t STATUS_READY = 0x80;
    static const uint8_t STATUS_PROGRAM_LOCK_BIT = 0x10;

    /** Metadata about the erase blocks in flash */
    struct BlockData : public Serializable
    {
        BlockData(const CfiMemory &_parent, ssize_t number, ssize_t size)
          : Serializable(), locked(number, false), blockSize(size),
            parent(_parent)
        {}

        /**
         * Return true if the block pointed by the block_address
         * parameter is locked
         *
         * @params block_address address of the erase block in flash
         *         memory: first block starts ad address 0x0
         * @return true if block is locked
         */
        bool isLocked(Addr block_address) const;

        /**
         * Lock the block pointed by the block_address
         * parameter
         *
         * @params block_address address of the erase block in flash
         *         memory: first block starts ad address 0x0
         */
        void lock(Addr block_address);

        /**
         * Unlock the block pointed by the block_address
         * parameter
         *
         * @params block_address address of the erase block in flash
         *         memory: first block starts ad address 0x0
         */
        void unlock(Addr block_address);

        /** Erase a single block. The address of the block
         * is supplied by the packet address.
         *
         * @params pkt memory packet targeting the erase block
         */
        void erase(PacketPtr pkt);

        /** Number of erase blocks in flash memory */
        ssize_t number() const { return locked.size(); }

        /** Size in bytes of a single erase block */
        ssize_t size() const { return blockSize; }

      private: // Serializable
        void serialize(CheckpointOut &cp) const override;

        void unserialize(CheckpointIn &cp) override;

      private:
        uint32_t blockIdx(Addr block_address) const;

        // Per block flag. True if the block is locked
        std::vector<bool> locked;

        // Size of the block in bytes
        const ssize_t blockSize;

        const CfiMemory &parent;
    };

    /**
     * Word Buffer used by the BUFFERED PROGRAM command
     * to write (program) chunks of words to flash
     */
    struct ProgramBuffer : public Serializable
    {
      public:
        // program buffer max size = 32 words
        static const ssize_t MAX_BUFFER_SIZE = 32 * 4;

        ProgramBuffer(const CfiMemory &_parent)
          : Serializable(), parent(_parent)
        {}

        /**
         * Start buffering
         * @param buffer_size new size (in bytes) of the program buffer
         */
        void setup(ssize_t buffer_size);

        /**
         * Write data into the buffer. If the buffer is full, the
         * method will return true, meaning it's time to write
         * back the buffer into memory
         *
         * @params flash_address address in flash (relative to the start)
         * @params data_ptr pointer to the data
         * @params size number of bytes to be written to the buffer
         *
         * @return true if buffer needs to be written back to flash
         */
        bool write(Addr flash_address, void *data_ptr, ssize_t size);

        bool writeback();

      private:
        void serialize(CheckpointOut &cp) const override;

        void unserialize(CheckpointIn &cp) override;

      private:
        // program buffer
        std::vector<uint8_t> buffer;

        // Number of bytes written in the buffer
        ssize_t bytesWritten = 0;

        // Pointing to the latest written word in the buffer
        Addr blockPointer = 0;

        const CfiMemory &parent;
    };

    /**
     * A deferred packet stores a packet along with its scheduled
     * transmission time
     */
    class DeferredPacket
    {

      public:

        const Tick tick;
        const PacketPtr pkt;

        DeferredPacket(PacketPtr _pkt, Tick _tick) : tick(_tick), pkt(_pkt)
        { }
    };

    class MemoryPort : public ResponsePort
    {
      private:
        CfiMemory& mem;

      public:
        MemoryPort(const std::string& _name, CfiMemory& _memory);

      protected:
        Tick recvAtomic(PacketPtr pkt) override;
        Tick recvAtomicBackdoor(
                PacketPtr pkt, MemBackdoorPtr &_backdoor) override;
        void recvFunctional(PacketPtr pkt) override;
        bool recvTimingReq(PacketPtr pkt) override;
        void recvRespRetry() override;
        AddrRangeList getAddrRanges() const override;
    };

    MemoryPort port;

    /**
     * Latency from that a request is accepted until the response is
     * ready to be sent.
     */
    const Tick latency;

    /**
     * Fudge factor added to the latency.
     */
    const Tick latency_var;

    /**
     * Internal (unbounded) storage to mimic the delay caused by the
     * actual memory access. Note that this is where the packet spends
     * the memory latency.
     */
    std::list<DeferredPacket> packetQueue;

    /**
     * Bandwidth in ticks per byte. The regulation affects the
     * acceptance rate of requests and the queueing takes place after
     * the regulation.
     */
    const double bandwidth;

    /**
     * Track the state of the memory as either idle or busy, no need
     * for an enum with only two states.
     */
    bool isBusy;

    /**
     * Remember if we have to retry an outstanding request that
     * arrived while we were busy.
     */
    bool retryReq;

    /**
     * Remember if we failed to send a response and are awaiting a
     * retry. This is only used as a check.
     */
    bool retryResp;

    /**
     * Release the memory after being busy and send a retry if a
     * request was rejected in the meanwhile.
     */
    void release();

    EventFunctionWrapper releaseEvent;

    /**
     * Dequeue a packet from our internal packet queue and move it to
     * the port where it will be sent as soon as possible.
     */
    void dequeue();

    EventFunctionWrapper dequeueEvent;

    /**
     * Detemine the latency.
     *
     * @return the latency seen by the current packet
     */
    Tick getLatency() const;

    /**
     * Upstream caches need this packet until true is returned, so
     * hold it for deletion until a subsequent call
     */
    std::unique_ptr<Packet> pendingDelete;

    const uint8_t numberOfChips;

    const uint16_t vendorID;
    const uint16_t deviceID;
    const uint16_t bankWidth;

    /** Previous command (issued in the previous write cycle) */
    CfiCommand readState;
    CfiCommand writeState;

    uint8_t statusRegister;

    BlockData blocks;

    ProgramBuffer programBuffer;

    uint8_t cfiQueryTable[49];

  public:
    CfiMemory(const CfiMemoryParams &p);

    DrainState drain() override;

    Port &getPort(const std::string &if_name,
                  PortID idx=InvalidPortID) override;
    void init() override;

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

  protected:
    Tick recvAtomic(PacketPtr pkt);
    Tick recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &_backdoor);
    void recvFunctional(PacketPtr pkt);
    bool recvTimingReq(PacketPtr pkt);
    void recvRespRetry();

    /** Make a read/write access to the CFI Memory */
    void cfiAccess(PacketPtr pkt);

    /** Write request to the CFI Memory */
    void write(PacketPtr pkt);

    /** Read request to the CFI Memory */
    void read(PacketPtr pkt);

    /**
     * Helper function to read the device identifier after the
     * read state machine is put in the CfiCommand::READ_DEVICE_ID
     * mode.
     *
     * @param flash_address: The flash address LSBits encode the
     *                       the information the software is trying
     *                       to read
     */
    uint64_t readDeviceID(Addr flash_address) const;

    /**
     * Service a new command issued to the flash device
     *
     * @param command: new command issued to the flash device
     */
    void handleCommand(CfiCommand command);

    /** Return the selected entry in the CFI table
     *
     * @param addr: offset in the CFI table
     */
    uint64_t cfiQuery(Addr addr);
};

} // namespace gem5

#endif
