/*
 * Copyright (c) 2016-2017 Advanced Micro Devices, Inc.
 * All rights reserved.
 *
 * For use for simulation and test purposes only
 *
 * 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 "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);
    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__
