/*
 * Copyright (c) 2018 Inria
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * 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;
 * neither the name of the copyright holders 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
 * OWNER 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.
 *
 * Authors: Daniel Carvalho
 */

/**
 * @file
 * Declaration of a sector tag store.
 */

#ifndef __MEM_CACHE_TAGS_SECTOR_TAGS_HH__
#define __MEM_CACHE_TAGS_SECTOR_TAGS_HH__

#include <string>
#include <vector>

#include "mem/cache/tags/base.hh"
#include "mem/cache/tags/sector_blk.hh"
#include "params/SectorTags.hh"

class BaseCache;
class BaseReplacementPolicy;
class ReplaceableEntry;

/**
 * A SectorTags cache tag store.
 * @sa  \ref gem5MemorySystem "gem5 Memory System"
 *
 * The SectorTags placement policy divides the cache into s sectors of w
 * consecutive sectors (ways). Each sector then consists of a number of
 * sequential cache lines that may or may not be present.
 */
class SectorTags : public BaseTags
{
  protected:
    /** The allocatable associativity of the cache (alloc mask). */
    unsigned allocAssoc;

    /** Whether tags and data are accessed sequentially. */
    const bool sequentialAccess;

    /** Replacement policy */
    BaseReplacementPolicy *replacementPolicy;

    /** Number of data blocks per sector. */
    const unsigned numBlocksPerSector;

    /** The number of sectors in the cache. */
    const unsigned numSectors;

    /** The cache blocks. */
    std::vector<SectorSubBlk> blks;
    /** The cache sector blocks. */
    std::vector<SectorBlk> secBlks;

    // Organization of an address:
    // Tag | Placement Location | Sector Offset # | Offset #
    /** The amount to shift the address to get the sector tag. */
    const int sectorShift;

    /** Mask out all bits that aren't part of the sector tag. */
    const unsigned sectorMask;

  public:
    /** Convenience typedef. */
     typedef SectorTagsParams Params;

    /**
     * Construct and initialize this tag store.
     */
    SectorTags(const Params *p);

    /**
     * Destructor.
     */
    virtual ~SectorTags() {};

    /**
     * Initialize blocks and set the parent cache back pointer.
     *
     * @param _cache Pointer to parent cache.
     */
    void init(BaseCache *_cache) override;

    /**
     * This function updates the tags when a block is invalidated but does
     * not invalidate the block itself. It also updates the replacement data.
     *
     * @param blk The block to invalidate.
     */
    void invalidate(CacheBlk *blk) override;

    /**
     * Access block and update replacement data. May not succeed, in which
     * case nullptr is returned. This has all the implications of a cache
     * access and should only be used as such. Returns the access latency
     * as a side effect.
     *
     * @param addr The address to find.
     * @param is_secure True if the target memory space is secure.
     * @param lat The access latency.
     * @return Pointer to the cache block if found.
     */
    CacheBlk* accessBlock(Addr addr, bool is_secure, Cycles &lat) override;

    /**
     * Insert the new block into the cache and update replacement data.
     *
     * @param addr Address of the block.
     * @param is_secure Whether the block is in secure space or not.
     * @param src_master_ID The source requestor ID.
     * @param task_ID The new task ID.
     * @param blk The block to update.
     */
    void insertBlock(const Addr addr, const bool is_secure,
                     const int src_master_ID, const uint32_t task_ID,
                     CacheBlk *blk) override;

    /**
     * Finds the given address in the cache, do not update replacement data.
     * i.e. This is a no-side-effect find of a block.
     *
     * @param addr The address to find.
     * @param is_secure True if the target memory space is secure.
     * @return Pointer to the cache block if found.
     */
    CacheBlk* findBlock(Addr addr, bool is_secure) const override;

    /**
     * Find replacement victim based on address.
     *
     * @param addr Address to find a victim for.
     * @param is_secure True if the target memory space is secure.
     * @param evict_blks Cache blocks to be evicted.
     * @return Cache block to be replaced.
     */
    CacheBlk* findVictim(Addr addr, const bool is_secure,
                         std::vector<CacheBlk*>& evict_blks) const override;

    /**
     * Calculate a block's offset in a sector from the address.
     *
     * @param addr The address to get the offset from.
     * @return Offset of the corresponding block within its sector.
     */
    int extractSectorOffset(Addr addr) const;

    /**
     * Regenerate the block address from the tag and location.
     *
     * @param block The block.
     * @return the block address.
     */
    Addr regenerateBlkAddr(const CacheBlk* blk) const override;

    /**
     * Visit each sub-block in the tags and apply a visitor.
     *
     * The visitor should be a std::function that takes a cache block.
     * reference as its parameter.
     *
     * @param visitor Visitor to call on each block.
     */
    void forEachBlk(std::function<void(CacheBlk &)> visitor) override;

    /**
     * Find if any of the sub-blocks satisfies a condition.
     *
     * The visitor should be a std::function that takes a cache block
     * reference as its parameter. The visitor will terminate the
     * traversal early if the condition is satisfied.
     *
     * @param visitor Visitor to call on each block.
     */
    bool anyBlk(std::function<bool(CacheBlk &)> visitor) override;
};

#endif //__MEM_CACHE_TAGS_SECTOR_TAGS_HH__
