113938Sodanrc@yahoo.com.br/*
213938Sodanrc@yahoo.com.br * Copyright (c) 2018 Inria
313938Sodanrc@yahoo.com.br * All rights reserved.
413938Sodanrc@yahoo.com.br *
513938Sodanrc@yahoo.com.br * Redistribution and use in source and binary forms, with or without
613938Sodanrc@yahoo.com.br * modification, are permitted provided that the following conditions are
713938Sodanrc@yahoo.com.br * met: redistributions of source code must retain the above copyright
813938Sodanrc@yahoo.com.br * notice, this list of conditions and the following disclaimer;
913938Sodanrc@yahoo.com.br * redistributions in binary form must reproduce the above copyright
1013938Sodanrc@yahoo.com.br * notice, this list of conditions and the following disclaimer in the
1113938Sodanrc@yahoo.com.br * documentation and/or other materials provided with the distribution;
1213938Sodanrc@yahoo.com.br * neither the name of the copyright holders nor the names of its
1313938Sodanrc@yahoo.com.br * contributors may be used to endorse or promote products derived from
1413938Sodanrc@yahoo.com.br * this software without specific prior written permission.
1513938Sodanrc@yahoo.com.br *
1613938Sodanrc@yahoo.com.br * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1713938Sodanrc@yahoo.com.br * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1813938Sodanrc@yahoo.com.br * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1913938Sodanrc@yahoo.com.br * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2013938Sodanrc@yahoo.com.br * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2113938Sodanrc@yahoo.com.br * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2213938Sodanrc@yahoo.com.br * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2313938Sodanrc@yahoo.com.br * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2413938Sodanrc@yahoo.com.br * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2513938Sodanrc@yahoo.com.br * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2613938Sodanrc@yahoo.com.br * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2713938Sodanrc@yahoo.com.br *
2813938Sodanrc@yahoo.com.br * Authors: Daniel Carvalho
2913938Sodanrc@yahoo.com.br */
3013938Sodanrc@yahoo.com.br
3113938Sodanrc@yahoo.com.br/**
3213938Sodanrc@yahoo.com.br * @file
3313938Sodanrc@yahoo.com.br * Definitions of a base set associative compressed superblocks tag store.
3413938Sodanrc@yahoo.com.br */
3513938Sodanrc@yahoo.com.br
3613938Sodanrc@yahoo.com.br#include "mem/cache/tags/compressed_tags.hh"
3713938Sodanrc@yahoo.com.br
3813946Sodanrc@yahoo.com.br#include "base/trace.hh"
3913946Sodanrc@yahoo.com.br#include "debug/CacheComp.hh"
4013938Sodanrc@yahoo.com.br#include "mem/cache/replacement_policies/base.hh"
4113946Sodanrc@yahoo.com.br#include "mem/cache/replacement_policies/replaceable_entry.hh"
4213938Sodanrc@yahoo.com.br#include "mem/cache/tags/indexing_policies/base.hh"
4313945Sodanrc@yahoo.com.br#include "mem/packet.hh"
4413938Sodanrc@yahoo.com.br#include "params/CompressedTags.hh"
4513938Sodanrc@yahoo.com.br
4613938Sodanrc@yahoo.com.brCompressedTags::CompressedTags(const Params *p)
4713938Sodanrc@yahoo.com.br    : SectorTags(p)
4813938Sodanrc@yahoo.com.br{
4913938Sodanrc@yahoo.com.br}
5013938Sodanrc@yahoo.com.br
5113938Sodanrc@yahoo.com.brvoid
5213938Sodanrc@yahoo.com.brCompressedTags::tagsInit()
5313938Sodanrc@yahoo.com.br{
5413938Sodanrc@yahoo.com.br    // Create blocks and superblocks
5513938Sodanrc@yahoo.com.br    blks = std::vector<CompressionBlk>(numBlocks);
5613938Sodanrc@yahoo.com.br    superBlks = std::vector<SuperBlk>(numSectors);
5713938Sodanrc@yahoo.com.br
5813938Sodanrc@yahoo.com.br    // Initialize all blocks
5913938Sodanrc@yahoo.com.br    unsigned blk_index = 0;          // index into blks array
6013938Sodanrc@yahoo.com.br    for (unsigned superblock_index = 0; superblock_index < numSectors;
6113938Sodanrc@yahoo.com.br         superblock_index++)
6213938Sodanrc@yahoo.com.br    {
6313938Sodanrc@yahoo.com.br        // Locate next cache superblock
6413938Sodanrc@yahoo.com.br        SuperBlk* superblock = &superBlks[superblock_index];
6513938Sodanrc@yahoo.com.br
6613947Sodanrc@yahoo.com.br        // Superblocks must be aware of the block size due to their co-
6713947Sodanrc@yahoo.com.br        // allocation conditions
6813947Sodanrc@yahoo.com.br        superblock->setBlkSize(blkSize);
6913947Sodanrc@yahoo.com.br
7013938Sodanrc@yahoo.com.br        // Associate a replacement data entry to the block
7113938Sodanrc@yahoo.com.br        superblock->replacementData = replacementPolicy->instantiateEntry();
7213938Sodanrc@yahoo.com.br
7313938Sodanrc@yahoo.com.br        // Initialize all blocks in this superblock
7413938Sodanrc@yahoo.com.br        superblock->blks.resize(numBlocksPerSector, nullptr);
7513938Sodanrc@yahoo.com.br        for (unsigned k = 0; k < numBlocksPerSector; ++k){
7613938Sodanrc@yahoo.com.br            // Select block within the set to be linked
7713938Sodanrc@yahoo.com.br            SectorSubBlk*& blk = superblock->blks[k];
7813938Sodanrc@yahoo.com.br
7913938Sodanrc@yahoo.com.br            // Locate next cache block
8013938Sodanrc@yahoo.com.br            blk = &blks[blk_index];
8113938Sodanrc@yahoo.com.br
8213938Sodanrc@yahoo.com.br            // Associate a data chunk to the block
8313938Sodanrc@yahoo.com.br            blk->data = &dataBlks[blkSize*blk_index];
8413938Sodanrc@yahoo.com.br
8513938Sodanrc@yahoo.com.br            // Associate superblock to this block
8613938Sodanrc@yahoo.com.br            blk->setSectorBlock(superblock);
8713938Sodanrc@yahoo.com.br
8813938Sodanrc@yahoo.com.br            // Associate the superblock replacement data to this block
8913938Sodanrc@yahoo.com.br            blk->replacementData = superblock->replacementData;
9013938Sodanrc@yahoo.com.br
9113938Sodanrc@yahoo.com.br            // Set its index and sector offset
9213938Sodanrc@yahoo.com.br            blk->setSectorOffset(k);
9313938Sodanrc@yahoo.com.br
9413938Sodanrc@yahoo.com.br            // Update block index
9513938Sodanrc@yahoo.com.br            ++blk_index;
9613938Sodanrc@yahoo.com.br        }
9714117Sodanrc@yahoo.com.br
9814117Sodanrc@yahoo.com.br        // Link block to indexing policy
9914117Sodanrc@yahoo.com.br        indexingPolicy->setEntry(superblock, superblock_index);
10013938Sodanrc@yahoo.com.br    }
10113938Sodanrc@yahoo.com.br}
10213938Sodanrc@yahoo.com.br
10313946Sodanrc@yahoo.com.brCacheBlk*
10413946Sodanrc@yahoo.com.brCompressedTags::findVictim(Addr addr, const bool is_secure,
10513946Sodanrc@yahoo.com.br                           const std::size_t compressed_size,
10613946Sodanrc@yahoo.com.br                           std::vector<CacheBlk*>& evict_blks) const
10713946Sodanrc@yahoo.com.br{
10813946Sodanrc@yahoo.com.br    // Get all possible locations of this superblock
10913946Sodanrc@yahoo.com.br    const std::vector<ReplaceableEntry*> superblock_entries =
11013946Sodanrc@yahoo.com.br        indexingPolicy->getPossibleEntries(addr);
11113946Sodanrc@yahoo.com.br
11213946Sodanrc@yahoo.com.br    // Check if the superblock this address belongs to has been allocated. If
11313946Sodanrc@yahoo.com.br    // so, try co-allocating
11413946Sodanrc@yahoo.com.br    Addr tag = extractTag(addr);
11513946Sodanrc@yahoo.com.br    SuperBlk* victim_superblock = nullptr;
11613946Sodanrc@yahoo.com.br    bool is_co_allocation = false;
11713946Sodanrc@yahoo.com.br    const uint64_t offset = extractSectorOffset(addr);
11813946Sodanrc@yahoo.com.br    for (const auto& entry : superblock_entries){
11913946Sodanrc@yahoo.com.br        SuperBlk* superblock = static_cast<SuperBlk*>(entry);
12013946Sodanrc@yahoo.com.br        if ((tag == superblock->getTag()) && superblock->isValid() &&
12113946Sodanrc@yahoo.com.br            (is_secure == superblock->isSecure()) &&
12213946Sodanrc@yahoo.com.br            !superblock->blks[offset]->isValid() &&
12313947Sodanrc@yahoo.com.br            superblock->isCompressed() &&
12413947Sodanrc@yahoo.com.br            superblock->canCoAllocate(compressed_size))
12513946Sodanrc@yahoo.com.br        {
12613946Sodanrc@yahoo.com.br            victim_superblock = superblock;
12713946Sodanrc@yahoo.com.br            is_co_allocation = true;
12813946Sodanrc@yahoo.com.br            break;
12913946Sodanrc@yahoo.com.br        }
13013946Sodanrc@yahoo.com.br    }
13113946Sodanrc@yahoo.com.br
13213946Sodanrc@yahoo.com.br    // If the superblock is not present or cannot be co-allocated a
13313946Sodanrc@yahoo.com.br    // superblock must be replaced
13413946Sodanrc@yahoo.com.br    if (victim_superblock == nullptr){
13513946Sodanrc@yahoo.com.br        // Choose replacement victim from replacement candidates
13613946Sodanrc@yahoo.com.br        victim_superblock = static_cast<SuperBlk*>(
13713946Sodanrc@yahoo.com.br            replacementPolicy->getVictim(superblock_entries));
13813946Sodanrc@yahoo.com.br
13913946Sodanrc@yahoo.com.br        // The whole superblock must be evicted to make room for the new one
14013946Sodanrc@yahoo.com.br        for (const auto& blk : victim_superblock->blks){
14113946Sodanrc@yahoo.com.br            evict_blks.push_back(blk);
14213946Sodanrc@yahoo.com.br        }
14313946Sodanrc@yahoo.com.br    }
14413946Sodanrc@yahoo.com.br
14513946Sodanrc@yahoo.com.br    // Get the location of the victim block within the superblock
14613946Sodanrc@yahoo.com.br    SectorSubBlk* victim = victim_superblock->blks[offset];
14713946Sodanrc@yahoo.com.br
14813946Sodanrc@yahoo.com.br    // It would be a hit if victim was valid in a co-allocation, and upgrades
14913946Sodanrc@yahoo.com.br    // do not call findVictim, so it cannot happen
15013946Sodanrc@yahoo.com.br    if (is_co_allocation){
15113946Sodanrc@yahoo.com.br        assert(!victim->isValid());
15213946Sodanrc@yahoo.com.br
15313946Sodanrc@yahoo.com.br        // Print all co-allocated blocks
15413946Sodanrc@yahoo.com.br        DPRINTF(CacheComp, "Co-Allocation: offset %d with blocks\n", offset);
15513946Sodanrc@yahoo.com.br        for (const auto& blk : victim_superblock->blks){
15613946Sodanrc@yahoo.com.br            if (blk->isValid()) {
15713946Sodanrc@yahoo.com.br                DPRINTFR(CacheComp, "\t[%s]\n", blk->print());
15813946Sodanrc@yahoo.com.br            }
15913946Sodanrc@yahoo.com.br        }
16013946Sodanrc@yahoo.com.br    }
16113946Sodanrc@yahoo.com.br
16213946Sodanrc@yahoo.com.br    return victim;
16313946Sodanrc@yahoo.com.br}
16413946Sodanrc@yahoo.com.br
16513938Sodanrc@yahoo.com.brvoid
16613945Sodanrc@yahoo.com.brCompressedTags::insertBlock(const PacketPtr pkt, CacheBlk *blk)
16713945Sodanrc@yahoo.com.br{
16813947Sodanrc@yahoo.com.br    // We check if block can co-allocate before inserting, because this check
16913947Sodanrc@yahoo.com.br    // assumes the block is still invalid
17013947Sodanrc@yahoo.com.br    CompressionBlk* compression_blk = static_cast<CompressionBlk*>(blk);
17113947Sodanrc@yahoo.com.br    const SuperBlk* superblock = static_cast<const SuperBlk*>(
17213947Sodanrc@yahoo.com.br        compression_blk->getSectorBlock());
17313947Sodanrc@yahoo.com.br    const bool is_co_allocatable = superblock->isCompressed() &&
17413947Sodanrc@yahoo.com.br        superblock->canCoAllocate(compression_blk->getSizeBits());
17513947Sodanrc@yahoo.com.br
17613945Sodanrc@yahoo.com.br    // Insert block
17713945Sodanrc@yahoo.com.br    SectorTags::insertBlock(pkt, blk);
17813945Sodanrc@yahoo.com.br
17913947Sodanrc@yahoo.com.br    // We always store compressed blocks when possible
18013947Sodanrc@yahoo.com.br    if (is_co_allocatable) {
18113947Sodanrc@yahoo.com.br        compression_blk->setCompressed();
18213947Sodanrc@yahoo.com.br    } else {
18313947Sodanrc@yahoo.com.br        compression_blk->setUncompressed();
18413947Sodanrc@yahoo.com.br    }
18513945Sodanrc@yahoo.com.br}
18613945Sodanrc@yahoo.com.br
18713945Sodanrc@yahoo.com.brvoid
18813938Sodanrc@yahoo.com.brCompressedTags::forEachBlk(std::function<void(CacheBlk &)> visitor)
18913938Sodanrc@yahoo.com.br{
19013938Sodanrc@yahoo.com.br    for (CompressionBlk& blk : blks) {
19113938Sodanrc@yahoo.com.br        visitor(blk);
19213938Sodanrc@yahoo.com.br    }
19313938Sodanrc@yahoo.com.br}
19413938Sodanrc@yahoo.com.br
19513938Sodanrc@yahoo.com.brbool
19613938Sodanrc@yahoo.com.brCompressedTags::anyBlk(std::function<bool(CacheBlk &)> visitor)
19713938Sodanrc@yahoo.com.br{
19813938Sodanrc@yahoo.com.br    for (CompressionBlk& blk : blks) {
19913938Sodanrc@yahoo.com.br        if (visitor(blk)) {
20013938Sodanrc@yahoo.com.br            return true;
20113938Sodanrc@yahoo.com.br        }
20213938Sodanrc@yahoo.com.br    }
20313938Sodanrc@yahoo.com.br    return false;
20413938Sodanrc@yahoo.com.br}
20513938Sodanrc@yahoo.com.br
20613938Sodanrc@yahoo.com.brCompressedTags *
20713938Sodanrc@yahoo.com.brCompressedTagsParams::create()
20813938Sodanrc@yahoo.com.br{
20913938Sodanrc@yahoo.com.br    return new CompressedTags(this);
21013938Sodanrc@yahoo.com.br}
211