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

#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#include "base/types.hh"
#include "sim/eventq.hh"

namespace gem5
{

/*
 * --- AddressManager has 3 main tasks ---
 *    (1) generate DRF request sequences
 *    (2) maintain internal log table
 *    (3) validate return values against ones in the log table
 *
 * A location is an abstract index of a unique real address.
 *    It's used internally within the tester only.
 *    randAddressMap has the mapping between a location and its real address.
 *
 * A value is an integer that a location in real memory can store.
 *    for now, we assume a value is 4-byte
 *
 * The location range (randAddressMap) has two distinct parts:
 *    Atomic locations: in the 1st part of randAddressMap &
 *    Non-atomic locations (or just locations): in the 2nd part
 */

/*
 * --- DRF request sequence generation ---
 *    Each lane of an episode starts selecting its location by calling:
 *      (1) getAtomicLoc
 *      (2) getLoadLoc/getStoreLoc
 *      (3) finishLocSelection
 *
 *    Each lane of an episode completes its executing by calling:
 *      releaseLocation for all locations it selected
 */

/*
 * --- Internal structures ---
 *  There are multiple atomic structures, each of which corresponds
 *    to an atomic location.
 *
 *  Each atomic structure manages a distinct range of locations in locArray
 *  This array is partitioned into 3 parts that are used to select locations
 *  for LDs and STs. Here is the location selecting rule:
 *                  |    (1)    |    (2)    |    (3)    |
 *    - all locations in (1) cannot be picked for any LD and ST action
 *    - all locations in (2) can be picked for either LD or ST action
 *    - all locations in (3) can be picked for LD action only
 *
 *  We maintain the 3 parts by 2 indices firstMark and secondMark.
 *  As locations are moved between partitions, both indices are updated
 *  accordingly.
 *    [0 .. firstMark-1]                  part (1)
 *    [firstMark .. secondMark-1]      part (2)
 *    [secondMark .. arraySize-1]        part (3)
 *
 *  Each location has its context/property. locProps maintains
 *  contexts/properties of all locations. Context/property includes
 *      - current index of a location in locArray
 *      - the number of owners who are currently using the location
 *
 *  To guarantee DRF constraints, the following conditions must hold
 *    - all locations in (1) have exactly 1 owner
 *    - all locations in (2) have exactly 0 owner
 *    - all locations in (3) have at least 1 owner
 *    - A LD request can randomly pick any location in (2) & (3)
 *    - A ST request can randomly pick any location in (2)
 *
 *  loadStoreMap maintains all locations already selected for LDs/STs so far
 *
 *  When endLocSelection is called (i.e., we've picked all locations for an
 *  episode), we need to move each selected location to its right partition.
 *    if LD_bit == 1 && ST_bit == 0 (i.e., picked for LDs), then move the
 *          location to (3) -> future LDs can pick it.
 *    if LD_bit == 0 && ST_bit == 1, then move the location to (1) -> NO future
 *          action can pick it until this episode is done.
 *    if LD_bit == 1 && ST_bit == 1, then move the location to (1) -> NO future
 *          action can pick it until this episode is done.
 *    clear the loadStoreMap
 */

class AddressManager
{
  public:
    AddressManager(int n_atomic_locs, int numNormalLocsPerAtomic);
    ~AddressManager();

    typedef int32_t Value;
    typedef int32_t Location;

    // return the unique address mapped to a location
    Addr getAddress(Location loc);
    // return a unique atomic location & start picking locations
    Location getAtomicLoc();
    // return a random location for LD
    Location getLoadLoc(Location atomic_loc);
    // return a random location for ST
    Location getStoreLoc(Location atomic_loc);
    // finish picking locations
    void finishLocSelection(Location atomic_loc);
    // an episode is done, release location I've picked
    void releaseLocation(Location atomic_loc, Location loc);
    // update a log table entry with a given set of values
    void updateLogTable(Location loc, int threadId, int episodeId,
                        Value new_value, Tick curTick, int cuId = -1);
    // return the current value in the log table
    Value getLoggedValue(Location loc) const;
    // validate atomic response
    bool validateAtomicResp(Location loc, Value ret_val);

    std::string printLastWriter(Location loc) const;

    static const int INVALID_VALUE;
    static const int INVALID_LOCATION;

  private:
    class LastWriter
    {
      public:
        LastWriter()
            : threadId(-1), cuId(-1), episodeId(-1), value(0),
              writeTick(0)
        { }

        const std::string print() const
        {
            return "(TesterThread ID " + std::to_string(threadId) +
                   ", CU ID " + std::to_string(cuId) +
                   ", Episode ID " + std::to_string(episodeId) +
                   ", Value " + std::to_string(value) +
                   ", Tick " + std::to_string(writeTick) +
                   ")";
        }

        void update(int _thread, int _cu, int _episode, Value _value,
                    Tick _tick)
        {
            threadId = _thread;
            cuId = _cu;
            episodeId = _episode;
            value = _value;
            writeTick = _tick;
        }

        Value getLastStoredValue() const { return value; }

      private:
        int threadId;
        int cuId;
        int episodeId;
        Value value;
        Tick writeTick;
    };

    class AtomicStruct
    {
      public:
        AtomicStruct(Location atom_loc, Location loc_begin, Location loc_end);
        ~AtomicStruct();

        // functions picking locations for LD/ST/ATOMIC ops
        void startLocSelection();
        Location getLoadLoc();
        Location getStoreLoc();
        void endLocSelection();

        // an episode completed its actions
        // return locations to their correct positions
        void releaseLoc(Location loc);
        // is the value what we expect?
        bool isExpectedValue(Value val);

      private:
        Location atomicLoc;
        Location locationBase;

        // array storing all locations this structure is managing
        Location* locArray;
        int firstMark, secondMark;
        int arraySize;

        // a vector of location's properties
        typedef std::pair<int, int> LocProperty;
        typedef std::vector<LocProperty> LocPropTable;
        LocPropTable locProps;

        // a temporary map of location and its LD/ST selection
        typedef std::pair<bool, bool> LdStBits;
        typedef std::unordered_map<Location, LdStBits> LdStMap;
        LdStMap loadStoreMap;

        // number of atomic requests at this location so far
        int requestCount;
        // a set of expected values
        // when we request the first n atomic ops, we expect to receive n
        // return values from [0 .. n-1]
        typedef std::unordered_set<Value> ExpectedValueSet;
        ExpectedValueSet expectedValues;

        // swap two locations in locArray
        void swap(LocProperty& prop_1, LocProperty& prop_2);

        bool inFirstRegion(int idx) const
        {
            return (idx >= 0 && idx < firstMark);
        }
        bool inSecondRegion(int idx) const
        {
            return (idx >= firstMark && idx < secondMark);
        }
        bool inThirdRegion(int idx) const
        {
            return (idx >= secondMark && idx < arraySize);
        }
    };

    // number of atomic locations
    int numAtomicLocs;
    // number of normal/non-atomic locations per atomic structure
    int numLocsPerAtomic;
    // total number of non-atomic locations
    int numNormalLocs;

    // location - address mapping
    typedef std::vector<Addr> AddressMap;
    AddressMap randAddressMap;

    // a list of atomic structures
    typedef std::vector<AtomicStruct*> AtomicStructTable;
    AtomicStructTable atomicStructs;

    // internal log table
    typedef std::vector<LastWriter*> LogTable;
    LogTable logTable;
};

} // namespace gem5

#endif /* CPU_TESTERS_PROTOCOL_TESTER_ADDRESS_MANAGER_HH_ */
