/*
 * Copyright (c) 2016-2017 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_HSA_HW_SCHEDULER_HH__
#define __DEV_HSA_HW_SCHEDULER_HH__

#include <cstdint>
#include <map>

#include "base/types.hh"
#include "dev/hsa/hsa_packet_processor.hh"
#include "enums/GfxVersion.hh"
#include "sim/eventq.hh"

// We allocate one PIO page for doorbells and each
// address is 8 bytes
#define MAX_ACTIVE_QUEUES (PAGE_SIZE/8)

namespace gem5
{

class HWScheduler
{
  public:
    HWScheduler(HSAPacketProcessor* hsa_pp, Tick wakeup_delay)
               : hsaPP(hsa_pp), nextALId(0), nextRLId(0),
                 wakeupDelay(wakeup_delay), schedWakeupEvent(this)
    {}
    void write(Addr db_addr, uint64_t doorbell_reg);
    void registerNewQueue(uint64_t hostReadIndexPointer,
                          uint64_t basePointer,
                          uint64_t queue_id,
                          uint32_t size, int doorbellSize,
                          GfxVersion gfxVersion,
                          Addr offset = 0, uint64_t rd_idx = 0);
    void unregisterQueue(uint64_t queue_id, int doorbellSize);
    void wakeup();
    void schedWakeup();
    class SchedulerWakeupEvent : public Event
    {
      private:
        HWScheduler *hwSchdlr;
      public:
        SchedulerWakeupEvent(HWScheduler *hw_schdlr) : hwSchdlr(hw_schdlr) {}
        virtual void process();
        virtual const char *description() const;
    };
    bool isRLQIdle(uint32_t rl_idx);
    bool findNextActiveALQ();
    bool findNextIdleRLQ();
    bool unmapQFromRQ();
    bool contextSwitchQ();
    bool findEmptyHWQ();
    bool mapQIfSlotAvlbl(uint32_t al_idx, AQLRingBuffer* aql_buf,
                         HSAQueueDescriptor* q_desc);
    void addQCntxt(uint32_t al_idx, AQLRingBuffer* aql_buf,
                   HSAQueueDescriptor* q_desc);
    void removeQCntxt();
    void scheduleAndWakeupMappedQ();
    void updateRRVars(uint32_t al_idx, uint32_t rl_idx);

  private:
    // Active list keeps track of all queues created
    std::map<uint32_t, QCntxt> activeList;
    //TODO: Modify this to support multi-process in the future.
    // doorbell map, maps doorbell offsets to queue ID
    std::map<Addr, uint32_t> dbMap;
    // Reverse of doorbell map, maps queue ID to doorbell offset
    std::map<uint64_t, Addr> qidMap;
    // regdListMap keeps track of the mapping of queues to
    // registered list. regdListMap is indexed with active
    // list index (which is same as queue ID)
    std::map<uint32_t, uint32_t> regdListMap;
    HSAPacketProcessor* hsaPP;

    // Scheduling information.
    // For now, this is simple round robin but
    // this will be changed to a sophisticated logic
    // in the future. So, in the future, we will
    // move these variables into a scheduler class
    uint32_t nextALId;
    uint32_t nextRLId;
    const Tick wakeupDelay;
    SchedulerWakeupEvent schedWakeupEvent;
};

} // namespace gem5

#endif // __DEV_HSA_HW_SCHEDULER_HH__
