/*
 * 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);
    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 doorbells to active list entry
    std::map<Addr, uint32_t> dbMap;
    // 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__
