smmu_v3_caches.hh revision 14101
114039Sstacze01@arm.com/* 214039Sstacze01@arm.com * Copyright (c) 2014, 2018-2019 ARM Limited 314039Sstacze01@arm.com * All rights reserved 414039Sstacze01@arm.com * 514039Sstacze01@arm.com * The license below extends only to copyright in the software and shall 614039Sstacze01@arm.com * not be construed as granting a license to any other intellectual 714039Sstacze01@arm.com * property including but not limited to intellectual property relating 814039Sstacze01@arm.com * to a hardware implementation of the functionality of the software 914039Sstacze01@arm.com * licensed hereunder. You may use the software subject to the license 1014039Sstacze01@arm.com * terms below provided that you ensure that this notice is replicated 1114039Sstacze01@arm.com * unmodified and in its entirety in all distributions of the software, 1214039Sstacze01@arm.com * modified or unmodified, in source code or in binary form. 1314039Sstacze01@arm.com * 1414039Sstacze01@arm.com * Redistribution and use in source and binary forms, with or without 1514039Sstacze01@arm.com * modification, are permitted provided that the following conditions are 1614039Sstacze01@arm.com * met: redistributions of source code must retain the above copyright 1714039Sstacze01@arm.com * notice, this list of conditions and the following disclaimer; 1814039Sstacze01@arm.com * redistributions in binary form must reproduce the above copyright 1914039Sstacze01@arm.com * notice, this list of conditions and the following disclaimer in the 2014039Sstacze01@arm.com * documentation and/or other materials provided with the distribution; 2114039Sstacze01@arm.com * neither the name of the copyright holders nor the names of its 2214039Sstacze01@arm.com * contributors may be used to endorse or promote products derived from 2314039Sstacze01@arm.com * this software without specific prior written permission. 2414039Sstacze01@arm.com * 2514039Sstacze01@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2614039Sstacze01@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2714039Sstacze01@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2814039Sstacze01@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2914039Sstacze01@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3014039Sstacze01@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3114039Sstacze01@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3214039Sstacze01@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3314039Sstacze01@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3414039Sstacze01@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3514039Sstacze01@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3614039Sstacze01@arm.com * 3714039Sstacze01@arm.com * Authors: Stan Czerniawski 3814039Sstacze01@arm.com */ 3914039Sstacze01@arm.com 4014039Sstacze01@arm.com#ifndef __DEV_ARM_SMMU_V3_CACHES_HH__ 4114039Sstacze01@arm.com#define __DEV_ARM_SMMU_V3_CACHES_HH__ 4214039Sstacze01@arm.com 4314039Sstacze01@arm.com#include <stdint.h> 4414039Sstacze01@arm.com 4514039Sstacze01@arm.com#include <array> 4614039Sstacze01@arm.com#include <cstddef> 4714039Sstacze01@arm.com#include <string> 4814039Sstacze01@arm.com#include <vector> 4914039Sstacze01@arm.com 5014039Sstacze01@arm.com#include "base/random.hh" 5114039Sstacze01@arm.com#include "base/statistics.hh" 5214039Sstacze01@arm.com#include "base/types.hh" 5314039Sstacze01@arm.com 5414039Sstacze01@arm.com#define WALK_CACHE_LEVELS 4 5514039Sstacze01@arm.com 5614039Sstacze01@arm.comenum { 5714039Sstacze01@arm.com SMMU_CACHE_REPL_ROUND_ROBIN, 5814039Sstacze01@arm.com SMMU_CACHE_REPL_RANDOM, 5914039Sstacze01@arm.com SMMU_CACHE_REPL_LRU, 6014039Sstacze01@arm.com}; 6114039Sstacze01@arm.com 6214039Sstacze01@arm.comclass SMMUv3BaseCache 6314039Sstacze01@arm.com{ 6414039Sstacze01@arm.com protected: 6514039Sstacze01@arm.com int replacementPolicy; 6614039Sstacze01@arm.com size_t nextToReplace; 6714039Sstacze01@arm.com Random random; 6814039Sstacze01@arm.com uint32_t useStamp; 6914039Sstacze01@arm.com 7014039Sstacze01@arm.com Stats::Formula averageLookups; 7114039Sstacze01@arm.com Stats::Scalar totalLookups; 7214039Sstacze01@arm.com 7314039Sstacze01@arm.com Stats::Formula averageMisses; 7414039Sstacze01@arm.com Stats::Scalar totalMisses; 7514039Sstacze01@arm.com 7614039Sstacze01@arm.com Stats::Formula averageUpdates; 7714039Sstacze01@arm.com Stats::Scalar totalUpdates; 7814039Sstacze01@arm.com 7914039Sstacze01@arm.com Stats::Formula averageHitRate; 8014039Sstacze01@arm.com 8114039Sstacze01@arm.com Stats::Scalar insertions; 8214039Sstacze01@arm.com 8314039Sstacze01@arm.com static int decodePolicyName(const std::string &policy_name); 8414039Sstacze01@arm.com 8514039Sstacze01@arm.com public: 8614039Sstacze01@arm.com SMMUv3BaseCache(const std::string &policy_name, uint32_t seed); 8714039Sstacze01@arm.com virtual ~SMMUv3BaseCache() {} 8814039Sstacze01@arm.com 8914039Sstacze01@arm.com virtual void regStats(const std::string &name); 9014039Sstacze01@arm.com}; 9114039Sstacze01@arm.com 9214039Sstacze01@arm.comclass SMMUTLB : public SMMUv3BaseCache 9314039Sstacze01@arm.com{ 9414039Sstacze01@arm.com public: 9514039Sstacze01@arm.com enum AllocPolicy { 9614039Sstacze01@arm.com ALLOC_ANY_WAY, 9714039Sstacze01@arm.com ALLOC_ANY_BUT_LAST_WAY, 9814039Sstacze01@arm.com ALLOC_LAST_WAY, 9914039Sstacze01@arm.com }; 10014039Sstacze01@arm.com 10114039Sstacze01@arm.com struct Entry 10214039Sstacze01@arm.com { 10314039Sstacze01@arm.com bool valid; 10414039Sstacze01@arm.com bool prefetched; 10514039Sstacze01@arm.com mutable uint32_t lastUsed; 10614039Sstacze01@arm.com 10714039Sstacze01@arm.com // TAGS 10814039Sstacze01@arm.com uint32_t sid; 10914039Sstacze01@arm.com uint32_t ssid; 11014039Sstacze01@arm.com Addr va; 11114039Sstacze01@arm.com Addr vaMask; 11214039Sstacze01@arm.com 11314039Sstacze01@arm.com // EXTRA TAGS 11414039Sstacze01@arm.com uint16_t asid; 11514039Sstacze01@arm.com uint16_t vmid; 11614039Sstacze01@arm.com 11714039Sstacze01@arm.com // OUTPUTS 11814039Sstacze01@arm.com Addr pa; 11914039Sstacze01@arm.com uint8_t permissions; 12014039Sstacze01@arm.com }; 12114039Sstacze01@arm.com 12214039Sstacze01@arm.com SMMUTLB(unsigned numEntries, unsigned _associativity, 12314039Sstacze01@arm.com const std::string &policy); 12414039Sstacze01@arm.com SMMUTLB(const SMMUTLB& tlb) = delete; 12514039Sstacze01@arm.com virtual ~SMMUTLB() {} 12614039Sstacze01@arm.com 12714039Sstacze01@arm.com const Entry *lookup(uint32_t sid, uint32_t ssid, Addr va, 12814039Sstacze01@arm.com bool updStats=true); 12914039Sstacze01@arm.com const Entry *lookupAnyVA(uint32_t sid, uint32_t ssid, 13014039Sstacze01@arm.com bool updStats=true); 13114039Sstacze01@arm.com void store(const Entry &incoming, AllocPolicy alloc); 13214039Sstacze01@arm.com 13314039Sstacze01@arm.com void invalidateVA(Addr va, uint16_t asid, uint16_t vmid); 13414039Sstacze01@arm.com void invalidateVAA(Addr va, uint16_t vmid); 13514039Sstacze01@arm.com void invalidateASID(uint16_t asid, uint16_t vmid); 13614039Sstacze01@arm.com void invalidateVMID(uint16_t vmid); 13714039Sstacze01@arm.com void invalidateAll(); 13814039Sstacze01@arm.com 13914039Sstacze01@arm.com private: 14014039Sstacze01@arm.com typedef std::vector<Entry> Set; 14114039Sstacze01@arm.com std::vector<Set> sets; 14214039Sstacze01@arm.com 14314039Sstacze01@arm.com size_t associativity; 14414039Sstacze01@arm.com 14514039Sstacze01@arm.com size_t pickSetIdx(Addr va) const; 14614039Sstacze01@arm.com size_t pickEntryIdxToReplace(const Set &set, AllocPolicy alloc); 14714039Sstacze01@arm.com}; 14814039Sstacze01@arm.com 14914039Sstacze01@arm.comclass ARMArchTLB : public SMMUv3BaseCache 15014039Sstacze01@arm.com{ 15114039Sstacze01@arm.com public: 15214039Sstacze01@arm.com struct Entry 15314039Sstacze01@arm.com { 15414039Sstacze01@arm.com bool valid; 15514039Sstacze01@arm.com mutable uint32_t lastUsed; 15614039Sstacze01@arm.com 15714039Sstacze01@arm.com // TAGS 15814039Sstacze01@arm.com Addr va; 15914039Sstacze01@arm.com Addr vaMask; 16014039Sstacze01@arm.com uint16_t asid; 16114039Sstacze01@arm.com uint16_t vmid; 16214039Sstacze01@arm.com 16314039Sstacze01@arm.com // OUTPUTS 16414039Sstacze01@arm.com Addr pa; 16514039Sstacze01@arm.com uint8_t permissions; 16614039Sstacze01@arm.com }; 16714039Sstacze01@arm.com 16814039Sstacze01@arm.com ARMArchTLB(unsigned numEntries, unsigned _associativity, 16914039Sstacze01@arm.com const std::string &policy); 17014039Sstacze01@arm.com virtual ~ARMArchTLB() {} 17114039Sstacze01@arm.com 17214039Sstacze01@arm.com const Entry *lookup(Addr va, uint16_t asid, uint16_t vmid, 17314039Sstacze01@arm.com bool updStats=true); 17414039Sstacze01@arm.com 17514039Sstacze01@arm.com void store(const Entry &incoming); 17614039Sstacze01@arm.com 17714039Sstacze01@arm.com void invalidateVA(Addr va, uint16_t asid, uint16_t vmid); 17814039Sstacze01@arm.com void invalidateVAA(Addr va, uint16_t vmid); 17914039Sstacze01@arm.com void invalidateASID(uint16_t asid, uint16_t vmid); 18014039Sstacze01@arm.com void invalidateVMID(uint16_t vmid); 18114039Sstacze01@arm.com void invalidateAll(); 18214039Sstacze01@arm.com 18314039Sstacze01@arm.com private: 18414039Sstacze01@arm.com typedef std::vector<Entry> Set; 18514039Sstacze01@arm.com std::vector<Set> sets; 18614039Sstacze01@arm.com 18714039Sstacze01@arm.com size_t associativity; 18814039Sstacze01@arm.com 18914039Sstacze01@arm.com size_t pickSetIdx(Addr va, uint16_t asid, uint16_t vmid) const; 19014039Sstacze01@arm.com size_t pickEntryIdxToReplace(const Set &set); 19114039Sstacze01@arm.com}; 19214039Sstacze01@arm.com 19314039Sstacze01@arm.comclass IPACache : public SMMUv3BaseCache 19414039Sstacze01@arm.com{ 19514039Sstacze01@arm.com public: 19614039Sstacze01@arm.com struct Entry 19714039Sstacze01@arm.com { 19814039Sstacze01@arm.com bool valid; 19914039Sstacze01@arm.com mutable uint32_t lastUsed; 20014039Sstacze01@arm.com 20114039Sstacze01@arm.com // TAGS 20214039Sstacze01@arm.com Addr ipa; 20314039Sstacze01@arm.com Addr ipaMask; 20414039Sstacze01@arm.com uint16_t vmid; 20514039Sstacze01@arm.com 20614039Sstacze01@arm.com // OUTPUTS 20714039Sstacze01@arm.com Addr pa; 20814039Sstacze01@arm.com uint8_t permissions; 20914039Sstacze01@arm.com }; 21014039Sstacze01@arm.com 21114039Sstacze01@arm.com IPACache(unsigned numEntries, unsigned _associativity, 21214039Sstacze01@arm.com const std::string &policy); 21314039Sstacze01@arm.com virtual ~IPACache() {} 21414039Sstacze01@arm.com 21514039Sstacze01@arm.com const Entry *lookup(Addr ipa, uint16_t vmid, bool updStats=true); 21614039Sstacze01@arm.com void store(const Entry &incoming); 21714039Sstacze01@arm.com 21814039Sstacze01@arm.com void invalidateIPA(Addr ipa, uint16_t vmid); 21914039Sstacze01@arm.com void invalidateIPAA(Addr ipa); 22014039Sstacze01@arm.com void invalidateVMID(uint16_t vmid); 22114039Sstacze01@arm.com void invalidateAll(); 22214039Sstacze01@arm.com 22314039Sstacze01@arm.com private: 22414039Sstacze01@arm.com typedef std::vector<Entry> Set; 22514039Sstacze01@arm.com std::vector<Set> sets; 22614039Sstacze01@arm.com 22714039Sstacze01@arm.com size_t associativity; 22814039Sstacze01@arm.com 22914039Sstacze01@arm.com size_t pickSetIdx(Addr ipa, uint16_t vmid) const; 23014039Sstacze01@arm.com size_t pickEntryIdxToReplace(const Set &set); 23114039Sstacze01@arm.com}; 23214039Sstacze01@arm.com 23314039Sstacze01@arm.comclass ConfigCache : public SMMUv3BaseCache 23414039Sstacze01@arm.com{ 23514039Sstacze01@arm.com public: 23614039Sstacze01@arm.com struct Entry 23714039Sstacze01@arm.com { 23814039Sstacze01@arm.com bool valid; 23914039Sstacze01@arm.com mutable uint32_t lastUsed; 24014039Sstacze01@arm.com 24114039Sstacze01@arm.com // TAGS 24214039Sstacze01@arm.com uint32_t sid; 24314039Sstacze01@arm.com uint32_t ssid; 24414039Sstacze01@arm.com 24514039Sstacze01@arm.com // OUTPUTS 24614039Sstacze01@arm.com bool stage1_en; 24714039Sstacze01@arm.com bool stage2_en; 24814039Sstacze01@arm.com Addr ttb0; 24914039Sstacze01@arm.com Addr ttb1; 25014039Sstacze01@arm.com Addr httb; 25114039Sstacze01@arm.com uint16_t asid; 25214039Sstacze01@arm.com uint16_t vmid; 25314039Sstacze01@arm.com uint8_t stage1_tg; 25414039Sstacze01@arm.com uint8_t stage2_tg; 25514101Sgiacomo.travaglini@arm.com uint8_t t0sz; 25614101Sgiacomo.travaglini@arm.com uint8_t s2t0sz; 25714039Sstacze01@arm.com }; 25814039Sstacze01@arm.com 25914039Sstacze01@arm.com ConfigCache(unsigned numEntries, unsigned _associativity, 26014039Sstacze01@arm.com const std::string &policy); 26114039Sstacze01@arm.com virtual ~ConfigCache() {} 26214039Sstacze01@arm.com 26314039Sstacze01@arm.com const Entry *lookup(uint32_t sid, uint32_t ssid, bool updStats=true); 26414039Sstacze01@arm.com void store(const Entry &incoming); 26514039Sstacze01@arm.com 26614039Sstacze01@arm.com void invalidateSSID(uint32_t sid, uint32_t ssid); 26714039Sstacze01@arm.com void invalidateSID(uint32_t sid); 26814039Sstacze01@arm.com void invalidateAll(); 26914039Sstacze01@arm.com 27014039Sstacze01@arm.com private: 27114039Sstacze01@arm.com typedef std::vector<Entry> Set; 27214039Sstacze01@arm.com std::vector<Set> sets; 27314039Sstacze01@arm.com 27414039Sstacze01@arm.com size_t associativity; 27514039Sstacze01@arm.com 27614039Sstacze01@arm.com size_t pickSetIdx(uint32_t sid, uint32_t ssid) const; 27714039Sstacze01@arm.com size_t pickEntryIdxToReplace(const Set &set); 27814039Sstacze01@arm.com}; 27914039Sstacze01@arm.com 28014039Sstacze01@arm.comclass WalkCache : public SMMUv3BaseCache 28114039Sstacze01@arm.com{ 28214039Sstacze01@arm.com public: 28314039Sstacze01@arm.com struct Entry 28414039Sstacze01@arm.com { 28514039Sstacze01@arm.com bool valid; 28614039Sstacze01@arm.com mutable uint32_t lastUsed; 28714039Sstacze01@arm.com 28814039Sstacze01@arm.com // TAGS 28914039Sstacze01@arm.com Addr va; 29014039Sstacze01@arm.com Addr vaMask; 29114039Sstacze01@arm.com uint16_t asid; 29214039Sstacze01@arm.com uint16_t vmid; 29314039Sstacze01@arm.com unsigned stage; 29414039Sstacze01@arm.com unsigned level; 29514039Sstacze01@arm.com 29614039Sstacze01@arm.com // OUTPUTS 29714039Sstacze01@arm.com bool leaf; 29814039Sstacze01@arm.com Addr pa; 29914039Sstacze01@arm.com uint8_t permissions; 30014039Sstacze01@arm.com }; 30114039Sstacze01@arm.com 30214039Sstacze01@arm.com WalkCache(const std::array<unsigned, 2*WALK_CACHE_LEVELS> &_sizes, 30314039Sstacze01@arm.com unsigned _associativity, const std::string &policy); 30414039Sstacze01@arm.com virtual ~WalkCache() {} 30514039Sstacze01@arm.com 30614039Sstacze01@arm.com const Entry *lookup(Addr va, Addr vaMask, uint16_t asid, uint16_t vmid, 30714039Sstacze01@arm.com unsigned stage, unsigned level, bool updStats=true); 30814039Sstacze01@arm.com void store(const Entry &incoming); 30914039Sstacze01@arm.com 31014039Sstacze01@arm.com void invalidateVA(Addr va, uint16_t asid, uint16_t vmid); 31114039Sstacze01@arm.com void invalidateVAA(Addr va, uint16_t vmid); 31214039Sstacze01@arm.com void invalidateASID(uint16_t asid, uint16_t vmid); 31314039Sstacze01@arm.com void invalidateVMID(uint16_t vmid); 31414039Sstacze01@arm.com void invalidateAll(); 31514039Sstacze01@arm.com 31614039Sstacze01@arm.com void regStats(const std::string &name) override; 31714039Sstacze01@arm.com 31814039Sstacze01@arm.com protected: 31914039Sstacze01@arm.com unsigned int lookupsByStageLevel[2][WALK_CACHE_LEVELS]; 32014039Sstacze01@arm.com Stats::Formula averageLookupsByStageLevel[2][WALK_CACHE_LEVELS]; 32114039Sstacze01@arm.com Stats::Scalar totalLookupsByStageLevel[2][WALK_CACHE_LEVELS]; 32214039Sstacze01@arm.com 32314039Sstacze01@arm.com unsigned int missesByStageLevel[2][WALK_CACHE_LEVELS]; 32414039Sstacze01@arm.com Stats::Formula averageMissesByStageLevel[2][WALK_CACHE_LEVELS]; 32514039Sstacze01@arm.com Stats::Scalar totalMissesByStageLevel[2][WALK_CACHE_LEVELS]; 32614039Sstacze01@arm.com 32714039Sstacze01@arm.com unsigned int updatesByStageLevel[2][WALK_CACHE_LEVELS]; 32814039Sstacze01@arm.com Stats::Formula averageUpdatesByStageLevel[2][WALK_CACHE_LEVELS]; 32914039Sstacze01@arm.com Stats::Scalar totalUpdatesByStageLevel[2][WALK_CACHE_LEVELS]; 33014039Sstacze01@arm.com 33114039Sstacze01@arm.com Stats::Formula averageHitRateByStageLevel[2][WALK_CACHE_LEVELS]; 33214039Sstacze01@arm.com 33314039Sstacze01@arm.com Stats::Scalar insertionsByStageLevel[2][WALK_CACHE_LEVELS]; 33414039Sstacze01@arm.com 33514039Sstacze01@arm.com private: 33614039Sstacze01@arm.com typedef std::vector<Entry> Set; 33714039Sstacze01@arm.com std::vector<Set> sets; 33814039Sstacze01@arm.com 33914039Sstacze01@arm.com size_t associativity; 34014039Sstacze01@arm.com std::array<unsigned, 2*WALK_CACHE_LEVELS> sizes; 34114039Sstacze01@arm.com std::array<unsigned, 2*WALK_CACHE_LEVELS> offsets; 34214039Sstacze01@arm.com 34314039Sstacze01@arm.com size_t pickSetIdx(Addr va, Addr vaMask, 34414039Sstacze01@arm.com unsigned stage, unsigned level) const; 34514039Sstacze01@arm.com 34614039Sstacze01@arm.com size_t pickEntryIdxToReplace(const Set &set, 34714039Sstacze01@arm.com unsigned stage, unsigned level); 34814039Sstacze01@arm.com}; 34914039Sstacze01@arm.com 35014039Sstacze01@arm.com#endif /* __DEV_ARM_SMMU_V3_CACHES_HH__ */ 351