113553Sjavier.bueno@metempsy.com/**
213553Sjavier.bueno@metempsy.com * Copyright (c) 2018 Metempsy Technology Consulting
313553Sjavier.bueno@metempsy.com * All rights reserved.
413553Sjavier.bueno@metempsy.com *
513553Sjavier.bueno@metempsy.com * Redistribution and use in source and binary forms, with or without
613553Sjavier.bueno@metempsy.com * modification, are permitted provided that the following conditions are
713553Sjavier.bueno@metempsy.com * met: redistributions of source code must retain the above copyright
813553Sjavier.bueno@metempsy.com * notice, this list of conditions and the following disclaimer;
913553Sjavier.bueno@metempsy.com * redistributions in binary form must reproduce the above copyright
1013553Sjavier.bueno@metempsy.com * notice, this list of conditions and the following disclaimer in the
1113553Sjavier.bueno@metempsy.com * documentation and/or other materials provided with the distribution;
1213553Sjavier.bueno@metempsy.com * neither the name of the copyright holders nor the names of its
1313553Sjavier.bueno@metempsy.com * contributors may be used to endorse or promote products derived from
1413553Sjavier.bueno@metempsy.com * this software without specific prior written permission.
1513553Sjavier.bueno@metempsy.com *
1613553Sjavier.bueno@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1713553Sjavier.bueno@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1813553Sjavier.bueno@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1913553Sjavier.bueno@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2013553Sjavier.bueno@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2113553Sjavier.bueno@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2213553Sjavier.bueno@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2313553Sjavier.bueno@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2413553Sjavier.bueno@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2513553Sjavier.bueno@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2613553Sjavier.bueno@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2713553Sjavier.bueno@metempsy.com *
2813553Sjavier.bueno@metempsy.com * Authors: Javier Bueno
2913553Sjavier.bueno@metempsy.com */
3013553Sjavier.bueno@metempsy.com
3113553Sjavier.bueno@metempsy.com#ifndef __CACHE_PREFETCH_ASSOCIATIVE_SET_HH__
3213553Sjavier.bueno@metempsy.com#define __CACHE_PREFETCH_ASSOCIATIVE_SET_HH__
3313553Sjavier.bueno@metempsy.com
3413553Sjavier.bueno@metempsy.com#include "mem/cache/replacement_policies/base.hh"
3513553Sjavier.bueno@metempsy.com#include "mem/cache/replacement_policies/replaceable_entry.hh"
3613553Sjavier.bueno@metempsy.com#include "mem/cache/tags/indexing_policies/base.hh"
3713553Sjavier.bueno@metempsy.com
3813553Sjavier.bueno@metempsy.com/**
3913553Sjavier.bueno@metempsy.com * Entry used for set-associative tables, usable with replacement policies
4013553Sjavier.bueno@metempsy.com */
4113553Sjavier.bueno@metempsy.comclass TaggedEntry : public ReplaceableEntry {
4213553Sjavier.bueno@metempsy.com    /** Tag for the entry */
4313553Sjavier.bueno@metempsy.com    Addr tag;
4413553Sjavier.bueno@metempsy.com    /** Valid bit */
4513553Sjavier.bueno@metempsy.com    bool valid;
4613553Sjavier.bueno@metempsy.com    /** Whether this entry refers to a memory area in the secure space */
4713553Sjavier.bueno@metempsy.com    bool secure;
4813553Sjavier.bueno@metempsy.com  public:
4913553Sjavier.bueno@metempsy.com    TaggedEntry() : tag(0), valid(false), secure(false) {}
5013553Sjavier.bueno@metempsy.com    virtual ~TaggedEntry() {}
5113553Sjavier.bueno@metempsy.com
5213553Sjavier.bueno@metempsy.com    /**
5313553Sjavier.bueno@metempsy.com     * Consult the valid bit
5413553Sjavier.bueno@metempsy.com     * @return True if the entry is valid
5513553Sjavier.bueno@metempsy.com     */
5613553Sjavier.bueno@metempsy.com    bool isValid() const
5713553Sjavier.bueno@metempsy.com    {
5813553Sjavier.bueno@metempsy.com        return valid;
5913553Sjavier.bueno@metempsy.com    }
6013553Sjavier.bueno@metempsy.com
6113553Sjavier.bueno@metempsy.com    /**
6213553Sjavier.bueno@metempsy.com     * Sets the entry to valid
6313553Sjavier.bueno@metempsy.com     */
6413553Sjavier.bueno@metempsy.com    void setValid()
6513553Sjavier.bueno@metempsy.com    {
6613553Sjavier.bueno@metempsy.com        valid = true;
6713553Sjavier.bueno@metempsy.com    }
6813553Sjavier.bueno@metempsy.com
6913553Sjavier.bueno@metempsy.com    /**
7013553Sjavier.bueno@metempsy.com     * Sets the entry to invalid
7113553Sjavier.bueno@metempsy.com     */
7213553Sjavier.bueno@metempsy.com    void setInvalid() {
7313553Sjavier.bueno@metempsy.com        valid = false;
7413553Sjavier.bueno@metempsy.com    }
7513553Sjavier.bueno@metempsy.com
7613553Sjavier.bueno@metempsy.com    /**
7713553Sjavier.bueno@metempsy.com     * Obtain the entry tag
7813553Sjavier.bueno@metempsy.com     * @return the tag value
7913553Sjavier.bueno@metempsy.com     */
8013553Sjavier.bueno@metempsy.com    Addr getTag() const
8113553Sjavier.bueno@metempsy.com    {
8213553Sjavier.bueno@metempsy.com        return tag;
8313553Sjavier.bueno@metempsy.com    }
8413553Sjavier.bueno@metempsy.com
8513553Sjavier.bueno@metempsy.com    /**
8613553Sjavier.bueno@metempsy.com     * Sets the tag of the entry
8713553Sjavier.bueno@metempsy.com     * @param t the tag value
8813553Sjavier.bueno@metempsy.com     */
8913553Sjavier.bueno@metempsy.com    void setTag(Addr t)
9013553Sjavier.bueno@metempsy.com    {
9113553Sjavier.bueno@metempsy.com        tag = t;
9213553Sjavier.bueno@metempsy.com    }
9313553Sjavier.bueno@metempsy.com
9413553Sjavier.bueno@metempsy.com    /**
9513553Sjavier.bueno@metempsy.com     * Consult if this entry refers to a memory in the secure area
9613553Sjavier.bueno@metempsy.com     * @return True if this entry refers to secure memory area
9713553Sjavier.bueno@metempsy.com     */
9813553Sjavier.bueno@metempsy.com    bool isSecure() const
9913553Sjavier.bueno@metempsy.com    {
10013553Sjavier.bueno@metempsy.com        return secure;
10113553Sjavier.bueno@metempsy.com    }
10213553Sjavier.bueno@metempsy.com
10313553Sjavier.bueno@metempsy.com    /**
10413553Sjavier.bueno@metempsy.com     * Sets the secure value bit
10513553Sjavier.bueno@metempsy.com     * @param s secure bit value
10613553Sjavier.bueno@metempsy.com     */
10713553Sjavier.bueno@metempsy.com    void setSecure(bool s)
10813553Sjavier.bueno@metempsy.com    {
10913553Sjavier.bueno@metempsy.com        secure = s;
11013553Sjavier.bueno@metempsy.com    }
11113553Sjavier.bueno@metempsy.com
11213553Sjavier.bueno@metempsy.com    /**
11313553Sjavier.bueno@metempsy.com     * Resets the entry, this is called when an entry is evicted to allocate
11413553Sjavier.bueno@metempsy.com     * a new one. Types inheriting this class should provide its own
11513553Sjavier.bueno@metempsy.com     * implementation
11613553Sjavier.bueno@metempsy.com     */
11713553Sjavier.bueno@metempsy.com    virtual void reset () {
11813553Sjavier.bueno@metempsy.com    }
11913553Sjavier.bueno@metempsy.com};
12013553Sjavier.bueno@metempsy.com
12113553Sjavier.bueno@metempsy.com/**
12213553Sjavier.bueno@metempsy.com * Associative container based on the previosuly defined Entry type
12313553Sjavier.bueno@metempsy.com * Each element is indexed by a key of type Addr, an additional
12413553Sjavier.bueno@metempsy.com * bool value is used as an additional tag data of the entry.
12513553Sjavier.bueno@metempsy.com */
12613553Sjavier.bueno@metempsy.comtemplate<class Entry>
12713553Sjavier.bueno@metempsy.comclass AssociativeSet {
12813553Sjavier.bueno@metempsy.com    static_assert(std::is_base_of<TaggedEntry, Entry>::value,
12913553Sjavier.bueno@metempsy.com                  "Entry must derive from TaggedEntry");
13013553Sjavier.bueno@metempsy.com
13113553Sjavier.bueno@metempsy.com    /** Associativity of the container */
13213553Sjavier.bueno@metempsy.com    const int associativity;
13313553Sjavier.bueno@metempsy.com    /**
13413553Sjavier.bueno@metempsy.com     * Total number of entries, entries are organized in sets of the provided
13513553Sjavier.bueno@metempsy.com     * associativity. The number of associative sets is obtained by dividing
13613553Sjavier.bueno@metempsy.com     * numEntries by associativity.
13713553Sjavier.bueno@metempsy.com     */
13813553Sjavier.bueno@metempsy.com    const int numEntries;
13913553Sjavier.bueno@metempsy.com    /** Pointer to the indexing policy */
14013553Sjavier.bueno@metempsy.com    BaseIndexingPolicy* const indexingPolicy;
14113553Sjavier.bueno@metempsy.com    /** Pointer to the replacement policy */
14213553Sjavier.bueno@metempsy.com    BaseReplacementPolicy* const replacementPolicy;
14313553Sjavier.bueno@metempsy.com    /** Vector containing the entries of the container */
14413553Sjavier.bueno@metempsy.com    std::vector<Entry> entries;
14513553Sjavier.bueno@metempsy.com
14613553Sjavier.bueno@metempsy.com  public:
14713553Sjavier.bueno@metempsy.com    /**
14813553Sjavier.bueno@metempsy.com     * Public constructor
14913553Sjavier.bueno@metempsy.com     * @param assoc number of elements in each associative set
15013553Sjavier.bueno@metempsy.com     * @param num_entries total number of entries of the container, the number
15113553Sjavier.bueno@metempsy.com     *   of sets can be calculated dividing this balue by the 'assoc' value
15213553Sjavier.bueno@metempsy.com     * @param idx_policy indexing policy
15313553Sjavier.bueno@metempsy.com     * @param rpl_policy replacement policy
15413553Sjavier.bueno@metempsy.com     * @param initial value of the elements of the set
15513553Sjavier.bueno@metempsy.com     */
15613553Sjavier.bueno@metempsy.com    AssociativeSet(int assoc, int num_entries, BaseIndexingPolicy *idx_policy,
15713553Sjavier.bueno@metempsy.com                   BaseReplacementPolicy *rpl_policy, Entry const &init_value =
15813553Sjavier.bueno@metempsy.com                   Entry());
15913553Sjavier.bueno@metempsy.com
16013553Sjavier.bueno@metempsy.com    /**
16113553Sjavier.bueno@metempsy.com     * Find an entry within the set
16213553Sjavier.bueno@metempsy.com     * @param addr key element
16313553Sjavier.bueno@metempsy.com     * @param is_secure tag element
16413553Sjavier.bueno@metempsy.com     * @return returns a pointer to the wanted entry or nullptr if it does not
16513553Sjavier.bueno@metempsy.com     *  exist.
16613553Sjavier.bueno@metempsy.com     */
16713553Sjavier.bueno@metempsy.com    Entry* findEntry(Addr addr, bool is_secure) const;
16813553Sjavier.bueno@metempsy.com
16913553Sjavier.bueno@metempsy.com    /**
17013553Sjavier.bueno@metempsy.com     * Do an access to the entry, this is required to
17113553Sjavier.bueno@metempsy.com     * update the replacement information data.
17213553Sjavier.bueno@metempsy.com     * @param entry the accessed entry
17313553Sjavier.bueno@metempsy.com     */
17413553Sjavier.bueno@metempsy.com    void accessEntry(Entry *entry);
17513553Sjavier.bueno@metempsy.com
17613553Sjavier.bueno@metempsy.com    /**
17713553Sjavier.bueno@metempsy.com     * Find a victim to be replaced
17813553Sjavier.bueno@metempsy.com     * @param addr key to select the possible victim
17913553Sjavier.bueno@metempsy.com     * @result entry to be victimized
18013553Sjavier.bueno@metempsy.com     */
18113553Sjavier.bueno@metempsy.com    Entry* findVictim(Addr addr);
18213553Sjavier.bueno@metempsy.com
18313553Sjavier.bueno@metempsy.com    /**
18413553Sjavier.bueno@metempsy.com     * Find the set of entries that could be replaced given
18513553Sjavier.bueno@metempsy.com     * that we want to add a new entry with the provided key
18613553Sjavier.bueno@metempsy.com     * @param addr key to select the set of entries
18713553Sjavier.bueno@metempsy.com     * @result vector of candidates matching with the provided key
18813553Sjavier.bueno@metempsy.com     */
18913553Sjavier.bueno@metempsy.com    std::vector<Entry *> getPossibleEntries(const Addr addr) const;
19013553Sjavier.bueno@metempsy.com
19113553Sjavier.bueno@metempsy.com    /**
19213553Sjavier.bueno@metempsy.com     * Indicate that an entry has just been inserted
19313553Sjavier.bueno@metempsy.com     * @param addr key of the container
19413553Sjavier.bueno@metempsy.com     * @param is_secure tag component of the container
19513553Sjavier.bueno@metempsy.com     * @param entry pointer to the container entry to be inserted
19613553Sjavier.bueno@metempsy.com     */
19713553Sjavier.bueno@metempsy.com    void insertEntry(Addr addr, bool is_secure, Entry* entry);
19813707Sjavier.bueno@metempsy.com
19913707Sjavier.bueno@metempsy.com    /** Iterator types */
20013707Sjavier.bueno@metempsy.com    using const_iterator = typename std::vector<Entry>::const_iterator;
20113707Sjavier.bueno@metempsy.com    using iterator = typename std::vector<Entry>::iterator;
20213707Sjavier.bueno@metempsy.com
20313707Sjavier.bueno@metempsy.com    /**
20413707Sjavier.bueno@metempsy.com     * Returns an iterator to the first entry of the dictionary
20513707Sjavier.bueno@metempsy.com     * @result iterator to the first element
20613707Sjavier.bueno@metempsy.com     */
20713707Sjavier.bueno@metempsy.com    iterator begin()
20813707Sjavier.bueno@metempsy.com    {
20913707Sjavier.bueno@metempsy.com        return entries.begin();
21013707Sjavier.bueno@metempsy.com    }
21113707Sjavier.bueno@metempsy.com
21213707Sjavier.bueno@metempsy.com    /**
21313707Sjavier.bueno@metempsy.com     * Returns an iterator pointing to the end of the the dictionary
21413707Sjavier.bueno@metempsy.com     * (placeholder element, should not be accessed)
21513707Sjavier.bueno@metempsy.com     * @result iterator to the end element
21613707Sjavier.bueno@metempsy.com     */
21713707Sjavier.bueno@metempsy.com    iterator end()
21813707Sjavier.bueno@metempsy.com    {
21913707Sjavier.bueno@metempsy.com        return entries.end();
22013707Sjavier.bueno@metempsy.com    }
22113707Sjavier.bueno@metempsy.com
22213707Sjavier.bueno@metempsy.com    /**
22313707Sjavier.bueno@metempsy.com     * Returns an iterator to the first entry of the dictionary
22413707Sjavier.bueno@metempsy.com     * @result iterator to the first element
22513707Sjavier.bueno@metempsy.com     */
22613707Sjavier.bueno@metempsy.com    const_iterator begin() const
22713707Sjavier.bueno@metempsy.com    {
22813707Sjavier.bueno@metempsy.com        return entries.begin();
22913707Sjavier.bueno@metempsy.com    }
23013707Sjavier.bueno@metempsy.com
23113707Sjavier.bueno@metempsy.com    /**
23213707Sjavier.bueno@metempsy.com     * Returns an iterator pointing to the end of the the dictionary
23313707Sjavier.bueno@metempsy.com     * (placeholder element, should not be accessed)
23413707Sjavier.bueno@metempsy.com     * @result iterator to the end element
23513707Sjavier.bueno@metempsy.com     */
23613707Sjavier.bueno@metempsy.com    const_iterator end() const
23713707Sjavier.bueno@metempsy.com    {
23813707Sjavier.bueno@metempsy.com        return entries.end();
23913707Sjavier.bueno@metempsy.com    }
24013553Sjavier.bueno@metempsy.com};
24113553Sjavier.bueno@metempsy.com
24213553Sjavier.bueno@metempsy.com#endif//__CACHE_PREFETCH_ASSOCIATIVE_SET_HH__
243