/*
 * Copyright (c) 2021 Advanced Micro Devices, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. Neither the name of the copyright holder 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 HOLDER 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 __DEV_AMDGPU_AMDGPU_DEVICE_HH__
#define __DEV_AMDGPU_AMDGPU_DEVICE_HH__

#include <map>

#include "base/bitunion.hh"
#include "dev/amdgpu/amdgpu_defines.hh"
#include "dev/amdgpu/amdgpu_vm.hh"
#include "dev/amdgpu/memory_manager.hh"
#include "dev/amdgpu/mmio_reader.hh"
#include "dev/io_device.hh"
#include "dev/pci/device.hh"
#include "params/AMDGPUDevice.hh"

namespace gem5
{

class AMDGPUInterruptHandler;
class SDMAEngine;

/**
 * Device model for an AMD GPU. This models the interface between the PCI bus
 * and the various IP blocks behind it. It translates requests to the various
 * BARs and sends them to the appropriate IP block. BAR0 requests are VRAM
 * requests that go to device memory, BAR2 are doorbells which are decoded and
 * sent to the corresponding IP block. BAR5 is the MMIO interface which writes
 * data values to registers controlling the IP blocks.
 */
class AMDGPUDevice : public PciDevice
{
  private:
    /**
     * Convert a PCI packet into a response
     */
    void dispatchAccess(PacketPtr pkt, bool read);

    /**
     * Helper methods to handle specific BAR read/writes. Offset is the
     * address of the packet - base address of the BAR.
     *
     * read/writeFrame are used for BAR0 requests
     * read/writeDoorbell are used for BAR2 requests
     * read/writeMMIO are used for BAR5 requests
     */
    void readFrame(PacketPtr pkt, Addr offset);
    void readDoorbell(PacketPtr pkt, Addr offset);
    void readMMIO(PacketPtr pkt, Addr offset);

    void writeFrame(PacketPtr pkt, Addr offset);
    void writeDoorbell(PacketPtr pkt, Addr offset);
    void writeMMIO(PacketPtr pkt, Addr offset);

    /**
     * Structures to hold registers, doorbells, and some frame memory
     */
    using GPURegMap = std::unordered_map<uint32_t, uint64_t>;
    GPURegMap frame_regs;
    GPURegMap regs;
    std::unordered_map<uint32_t, QueueType> doorbells;

    /**
     * VGA ROM methods
     */
    AddrRange romRange;
    bool isROM(Addr addr) const { return romRange.contains(addr); }
    void readROM(PacketPtr pkt);

    std::array<uint8_t, ROM_SIZE> rom;

    /**
     * MMIO reader to populate device registers map.
     */
    AMDMMIOReader mmioReader;

    /**
     * Blocks of the GPU
     */
    AMDGPUMemoryManager *gpuMemMgr;
    AMDGPUInterruptHandler *deviceIH;
    AMDGPUVM gpuvm;
    SDMAEngine *sdma0;
    SDMAEngine *sdma1;
    std::unordered_map<uint32_t, SDMAEngine *> sdmaEngs;
    PM4PacketProcessor *pm4PktProc;
    GPUCommandProcessor *cp;

    /**
     * Initial checkpoint support variables.
     */
    bool checkpoint_before_mmios;
    int init_interrupt_count;

    // VMIDs data structures
    // map of pasids to vmids
    std::unordered_map<uint16_t, uint16_t> idMap;
    // map of doorbell offsets to vmids
    std::unordered_map<Addr, uint16_t> doorbellVMIDMap;
    // map of vmid to all queue ids using that vmid
    std::unordered_map<uint16_t, std::set<int>> usedVMIDs;
    // last vmid allocated by map_process PM4 packet
    uint16_t _lastVMID;

    /*
     * Backing store for GPU memory / framebuffer / VRAM
     */
    memory::PhysicalMemory deviceMem;

  public:
    AMDGPUDevice(const AMDGPUDeviceParams &p);

    /**
     * Methods inherited from PciDevice
     */
    void intrPost();

    Tick writeConfig(PacketPtr pkt) override;
    Tick readConfig(PacketPtr pkt) override;

    Tick read(PacketPtr pkt) override;
    Tick write(PacketPtr pkt) override;

    AddrRangeList getAddrRanges() const override;

    /**
     * Checkpoint support
     */
    void serialize(CheckpointOut &cp) const override;
    void unserialize(CheckpointIn &cp) override;

    /**
     * Get handles to GPU blocks.
     */
    AMDGPUInterruptHandler* getIH() { return deviceIH; }
    SDMAEngine* getSDMAById(int id);
    SDMAEngine* getSDMAEngine(Addr offset);
    AMDGPUVM &getVM() { return gpuvm; }
    AMDGPUMemoryManager* getMemMgr() { return gpuMemMgr; }
    GPUCommandProcessor* CP() { return cp; }

    /**
     * Set handles to GPU blocks.
     */
    void setDoorbellType(uint32_t offset, QueueType qt);
    void setSDMAEngine(Addr offset, SDMAEngine *eng);

    /**
     * Register value getter/setter. Used by other GPU blocks to change
     * values from incoming driver/user packets.
     */
    uint32_t getRegVal(uint32_t addr);
    void setRegVal(uint32_t addr, uint32_t value);

    /**
     * Methods related to translations and system/device memory.
     */
    RequestorID vramRequestorId() { return gpuMemMgr->getRequestorID(); }

    /* HW context stuff */
    uint16_t lastVMID() { return _lastVMID; }
    uint16_t allocateVMID(uint16_t pasid);
    void deallocateVmid(uint16_t vmid);
    void deallocatePasid(uint16_t pasid);
    void deallocateAllQueues();
    void mapDoorbellToVMID(Addr doorbell, uint16_t vmid);
    uint16_t getVMID(Addr doorbell) { return doorbellVMIDMap[doorbell]; }
    std::unordered_map<uint16_t, std::set<int>>& getUsedVMIDs();
    void insertQId(uint16_t vmid, int id);
};

} // namespace gem5

#endif // __DEV_AMDGPU_AMDGPU_DEVICE_HH__
