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