From c83321b843e39cf03256b704ef77eafbdcb57a76 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Tue, 16 Jul 2024 15:59:50 +0100 Subject: [PATCH] arch-arm: Define a SetAssociative indexing policy for the TLB Change-Id: I8149ddc4ecf7ac3b8b7e8e1cf7eb4932fd99c34a Signed-off-by: Giacomo Travaglini Reviewed-by: Andreas Sandberg --- src/arch/arm/ArmTLB.py | 22 ++++- src/arch/arm/SConscript | 197 +++++++++++++++++++++----------------- src/arch/arm/pagetable.cc | 9 ++ src/arch/arm/pagetable.hh | 75 +++++++++++---- 4 files changed, 194 insertions(+), 109 deletions(-) diff --git a/src/arch/arm/ArmTLB.py b/src/arch/arm/ArmTLB.py index c868a322f1..b8a0850924 100644 --- a/src/arch/arm/ArmTLB.py +++ b/src/arch/arm/ArmTLB.py @@ -1,6 +1,6 @@ # -*- mode:python -*- -# Copyright (c) 2009, 2013, 2015, 2021 Arm Limited +# Copyright (c) 2009, 2013, 2015, 2021, 2024 Arm Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -45,6 +45,26 @@ class ArmLookupLevel(Enum): vals = ["L0", "L1", "L2", "L3"] +class TLBIndexingPolicy(SimObject): + type = "TLBIndexingPolicy" + abstract = True + cxx_class = "gem5::IndexingPolicyTemplate" + cxx_header = "arch/arm/pagetable.hh" + cxx_template_params = ["class Types"] + + # Get the size from the parent (cache) + num_entries = Param.Int(Parent.size, "number of TLB entries") + + # Get the associativity + assoc = Param.Int(Parent.assoc, "associativity") + + +class TLBSetAssociative(TLBIndexingPolicy): + type = "TLBSetAssociative" + cxx_class = "gem5::ArmISA::TLBSetAssociative" + cxx_header = "arch/arm/pagetable.hh" + + class ArmTLB(BaseTLB): type = "ArmTLB" cxx_class = "gem5::ArmISA::TLB" diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript index 948cefb4e4..b555c6f12c 100644 --- a/src/arch/arm/SConscript +++ b/src/arch/arm/SConscript @@ -38,104 +38,127 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -Import('*') +Import("*") -Source('insts/fplib.cc') +Source("insts/fplib.cc") -if env['CONF']['USE_ARM_ISA']: - env.TagImplies('arm isa', 'gem5 lib') +if env["CONF"]["USE_ARM_ISA"]: + env.TagImplies("arm isa", "gem5 lib") # The GTest function does not have a 'tags' parameter. We therefore apply this # guard to ensure this test is only built when ARM is compiled. # # Note: This will need reconfigured for multi-isa. E.g., if this is # incorporated: https://gem5-review.googlesource.com/c/public/gem5/+/52491 -if env['CONF']['USE_ARM_ISA']: - GTest('aapcs64.test', 'aapcs64.test.cc', - '../../base/debug.cc', - '../../cpu/reg_class.cc', - '../../sim/bufval.cc', '../../sim/cur_tick.cc', - 'regs/int.cc') - GTest('matrix.test', 'matrix.test.cc') -Source('decoder.cc', tags='arm isa') -Source('faults.cc', tags='arm isa') -Source('htm.cc', tags='arm isa') -Source('insts/branch.cc', tags='arm isa') -Source('insts/branch64.cc', tags='arm isa') -Source('insts/data64.cc', tags='arm isa') -Source('insts/macromem.cc', tags='arm isa') -Source('insts/mem.cc', tags='arm isa') -Source('insts/mem64.cc', tags='arm isa') -Source('insts/misc.cc', tags='arm isa') -Source('insts/misc64.cc', tags='arm isa') -Source('insts/pred_inst.cc', tags='arm isa') -Source('insts/pseudo.cc', tags='arm isa') -Source('insts/sme.cc', tags='arm isa') -Source('insts/static_inst.cc', tags='arm isa') -Source('insts/sve.cc', tags='arm isa') -Source('insts/sve_mem.cc', tags='arm isa') -Source('insts/vfp.cc', tags='arm isa') -Source('insts/crypto.cc', tags='arm isa') -Source('insts/tme64.cc', tags='arm isa') -if env['CONF']['PROTOCOL'] == 'MESI_Three_Level_HTM': - Source('insts/tme64ruby.cc', tags='arm isa') +if env["CONF"]["USE_ARM_ISA"]: + GTest( + "aapcs64.test", + "aapcs64.test.cc", + "../../base/debug.cc", + "../../cpu/reg_class.cc", + "../../sim/bufval.cc", + "../../sim/cur_tick.cc", + "regs/int.cc", + ) + GTest("matrix.test", "matrix.test.cc") +Source("decoder.cc", tags="arm isa") +Source("faults.cc", tags="arm isa") +Source("htm.cc", tags="arm isa") +Source("insts/branch.cc", tags="arm isa") +Source("insts/branch64.cc", tags="arm isa") +Source("insts/data64.cc", tags="arm isa") +Source("insts/macromem.cc", tags="arm isa") +Source("insts/mem.cc", tags="arm isa") +Source("insts/mem64.cc", tags="arm isa") +Source("insts/misc.cc", tags="arm isa") +Source("insts/misc64.cc", tags="arm isa") +Source("insts/pred_inst.cc", tags="arm isa") +Source("insts/pseudo.cc", tags="arm isa") +Source("insts/sme.cc", tags="arm isa") +Source("insts/static_inst.cc", tags="arm isa") +Source("insts/sve.cc", tags="arm isa") +Source("insts/sve_mem.cc", tags="arm isa") +Source("insts/vfp.cc", tags="arm isa") +Source("insts/crypto.cc", tags="arm isa") +Source("insts/tme64.cc", tags="arm isa") +if env["CONF"]["PROTOCOL"] == "MESI_Three_Level_HTM": + Source("insts/tme64ruby.cc", tags="arm isa") else: - Source('insts/tme64classic.cc', tags='arm isa') -Source('interrupts.cc', tags='arm isa') -Source('isa.cc', tags='arm isa') -Source('isa_device.cc', tags='arm isa') -Source('linux/process.cc', tags='arm isa') -Source('linux/se_workload.cc', tags='arm isa') -Source('linux/fs_workload.cc', tags='arm isa') -Source('freebsd/fs_workload.cc', tags='arm isa') -Source('freebsd/se_workload.cc', tags='arm isa') -Source('fs_workload.cc', tags='arm isa') -Source('regs/int.cc', tags='arm isa') -Source('regs/misc.cc', tags='arm isa') -Source('mmu.cc', tags='arm isa') -Source('mpam.cc', tags='arm isa') -Source('nativetrace.cc', tags='arm isa') -Source('pagetable.cc', tags='arm isa') -Source('pauth_helpers.cc', tags='arm isa') -Source('pmu.cc', tags='arm isa') -Source('process.cc', tags='arm isa') -Source('qarma.cc', tags='arm isa') -Source('remote_gdb.cc', tags='arm isa') -Source('reg_abi.cc', tags='arm isa') -Source('semihosting.cc', tags='arm isa') -Source('system.cc', tags='arm isa') -Source('table_walker.cc', tags='arm isa') -Source('self_debug.cc', tags='arm isa') -Source('stage2_lookup.cc', tags='arm isa') -Source('tlb.cc', tags='arm isa') -Source('tlbi_op.cc', tags='arm isa') -Source('utility.cc', tags='arm isa') + Source("insts/tme64classic.cc", tags="arm isa") +Source("interrupts.cc", tags="arm isa") +Source("isa.cc", tags="arm isa") +Source("isa_device.cc", tags="arm isa") +Source("linux/process.cc", tags="arm isa") +Source("linux/se_workload.cc", tags="arm isa") +Source("linux/fs_workload.cc", tags="arm isa") +Source("freebsd/fs_workload.cc", tags="arm isa") +Source("freebsd/se_workload.cc", tags="arm isa") +Source("fs_workload.cc", tags="arm isa") +Source("regs/int.cc", tags="arm isa") +Source("regs/misc.cc", tags="arm isa") +Source("mmu.cc", tags="arm isa") +Source("mpam.cc", tags="arm isa") +Source("nativetrace.cc", tags="arm isa") +Source("pagetable.cc", tags="arm isa") +Source("pauth_helpers.cc", tags="arm isa") +Source("pmu.cc", tags="arm isa") +Source("process.cc", tags="arm isa") +Source("qarma.cc", tags="arm isa") +Source("remote_gdb.cc", tags="arm isa") +Source("reg_abi.cc", tags="arm isa") +Source("semihosting.cc", tags="arm isa") +Source("system.cc", tags="arm isa") +Source("table_walker.cc", tags="arm isa") +Source("self_debug.cc", tags="arm isa") +Source("stage2_lookup.cc", tags="arm isa") +Source("tlb.cc", tags="arm isa") +Source("tlbi_op.cc", tags="arm isa") +Source("utility.cc", tags="arm isa") -SimObject('ArmDecoder.py', sim_objects=['ArmDecoder'], tags='arm isa') -SimObject('ArmFsWorkload.py', sim_objects=[ - 'ArmFsWorkload', 'ArmFsLinux', 'ArmFsFreebsd'], - enums=['ArmMachineType'], tags='arm isa') -SimObject('ArmInterrupts.py', sim_objects=['ArmInterrupts'], tags='arm isa') -SimObject('ArmISA.py', sim_objects=['ArmISA'], enums=['DecoderFlavor'], - tags='arm isa') -SimObject('ArmMMU.py', sim_objects=['ArmTableWalker', 'ArmMMU'], - tags='arm isa') -SimObject('ArmNativeTrace.py', sim_objects=['ArmNativeTrace'], tags='arm isa') -SimObject('ArmSemihosting.py', sim_objects=['ArmSemihosting'], tags='arm isa') -SimObject('ArmSeWorkload.py', sim_objects=[ - 'ArmSEWorkload', 'ArmEmuLinux', 'ArmEmuFreebsd'], tags='arm isa') -SimObject('ArmSystem.py', sim_objects=['ArmSystem', 'ArmRelease'], - enums=['ArmExtension'], tags='arm isa') -SimObject('ArmTLB.py', sim_objects=['ArmTLB'], enums=['ArmLookupLevel'], - tags='arm isa') -SimObject('ArmPMU.py', sim_objects=['ArmPMU'], tags='arm isa') +SimObject("ArmDecoder.py", sim_objects=["ArmDecoder"], tags="arm isa") +SimObject( + "ArmFsWorkload.py", + sim_objects=["ArmFsWorkload", "ArmFsLinux", "ArmFsFreebsd"], + enums=["ArmMachineType"], + tags="arm isa", +) +SimObject("ArmInterrupts.py", sim_objects=["ArmInterrupts"], tags="arm isa") +SimObject( + "ArmISA.py", + sim_objects=["ArmISA"], + enums=["DecoderFlavor"], + tags="arm isa", +) +SimObject( + "ArmMMU.py", sim_objects=["ArmTableWalker", "ArmMMU"], tags="arm isa" +) +SimObject("ArmNativeTrace.py", sim_objects=["ArmNativeTrace"], tags="arm isa") +SimObject("ArmSemihosting.py", sim_objects=["ArmSemihosting"], tags="arm isa") +SimObject( + "ArmSeWorkload.py", + sim_objects=["ArmSEWorkload", "ArmEmuLinux", "ArmEmuFreebsd"], + tags="arm isa", +) +SimObject( + "ArmSystem.py", + sim_objects=["ArmSystem", "ArmRelease"], + enums=["ArmExtension"], + tags="arm isa", +) +SimObject( + "ArmTLB.py", + sim_objects=["ArmTLB", "TLBIndexingPolicy", "TLBSetAssociative"], + enums=["ArmLookupLevel"], + tags="arm isa", +) +SimObject("ArmPMU.py", sim_objects=["ArmPMU"], tags="arm isa") -SimObject('ArmCPU.py', sim_objects=[], tags='arm isa') +SimObject("ArmCPU.py", sim_objects=[], tags="arm isa") -DebugFlag('Arm', tags='arm isa') -DebugFlag('ArmTme', 'Transactional Memory Extension', tags='arm isa') -DebugFlag('MPAM', 'MPAM debug flag', tags='arm isa') -DebugFlag('PMUVerbose', "Performance Monitor", tags='arm isa') +DebugFlag("Arm", tags="arm isa") +DebugFlag("ArmTme", "Transactional Memory Extension", tags="arm isa") +DebugFlag("MPAM", "MPAM debug flag", tags="arm isa") +DebugFlag("PMUVerbose", "Performance Monitor", tags="arm isa") # Add files generated by the ISA description. -ISADesc('isa/main.isa', decoder_splits=3, exec_splits=6, tags='arm isa') +ISADesc("isa/main.isa", decoder_splits=3, exec_splits=6, tags="arm isa") diff --git a/src/arch/arm/pagetable.cc b/src/arch/arm/pagetable.cc index e93e00e844..ce95a4c8aa 100644 --- a/src/arch/arm/pagetable.cc +++ b/src/arch/arm/pagetable.cc @@ -489,5 +489,14 @@ getPageTableOps(GrainSize trans_granule) } } +TLBTypes::KeyType::KeyType(const TlbEntry &entry) + : va(entry.vpn << entry.N), pageSize(entry.N), size(0), + asn(entry.asid), ignoreAsn(false), + vmid(entry.vmid), ss(entry.ss), + functional(false), + targetRegime(entry.regime), + mode(BaseMMU::Read) +{} + } // namespace ArmISA } // namespace gem5 diff --git a/src/arch/arm/pagetable.hh b/src/arch/arm/pagetable.hh index b38d28df91..5e0571fd84 100644 --- a/src/arch/arm/pagetable.hh +++ b/src/arch/arm/pagetable.hh @@ -50,6 +50,9 @@ #include "enums/TypeTLB.hh" #include "enums/ArmLookupLevel.hh" #include "mem/cache/replacement_policies/replaceable_entry.hh" +#include "mem/cache/tags/indexing_policies/base.hh" +#include "params/TLBIndexingPolicy.hh" +#include "params/TLBSetAssociative.hh" #include "sim/serialize.hh" namespace gem5 @@ -162,30 +165,15 @@ struct V8PageTableOps64k : public PageTableOps LookupLevel lastLevel() const override; }; -// ITB/DTB table entry -struct TlbEntry : public ReplaceableEntry, Serializable +struct TlbEntry; + +class TLBTypes { public: - typedef enums::ArmLookupLevel LookupLevel; - - enum class MemoryType : std::uint8_t + struct KeyType { - StronglyOrdered, - Device, - Normal - }; - - struct Lookup - { - Lookup() = default; - explicit Lookup(const TlbEntry &entry) - : va(entry.vpn << entry.N), pageSize(entry.N), size(0), - asn(entry.asid), ignoreAsn(false), - vmid(entry.vmid), ss(entry.ss), - functional(false), - targetRegime(entry.regime), - mode(BaseMMU::Read) - {} + KeyType() = default; + explicit KeyType(const TlbEntry &entry); // virtual address Addr va = 0; @@ -213,6 +201,48 @@ struct TlbEntry : public ReplaceableEntry, Serializable BaseMMU::Mode mode = BaseMMU::Read; }; + using Params = TLBIndexingPolicyParams; +}; +using TLBIndexingPolicy = IndexingPolicyTemplate; + +class TLBSetAssociative : public TLBIndexingPolicy +{ + public: + PARAMS(TLBSetAssociative); + TLBSetAssociative(const Params &p) + : TLBIndexingPolicy(p, p.num_entries, 0) + {} + + std::vector + getPossibleEntries(const KeyType &key) const override + { + Addr set_number = (key.va >> key.pageSize) & setMask; + return sets[set_number]; + } + + Addr + regenerateAddr(const KeyType &key, + const ReplaceableEntry *entry) const override + { + panic("Unimplemented\n"); + } +}; + +// ITB/DTB table entry +struct TlbEntry : public ReplaceableEntry, Serializable +{ + public: + using LookupLevel = enums::ArmLookupLevel; + using Lookup = TLBTypes::KeyType; + using IndexingPolicy = TLBIndexingPolicy; + + enum class MemoryType : std::uint8_t + { + StronglyOrdered, + Device, + Normal + }; + // Matching variables Addr pfn; Addr size; // Size of this entry, == Type of TLB Rec @@ -545,6 +575,9 @@ struct TlbEntry : public ReplaceableEntry, Serializable const PageTableOps *getPageTableOps(GrainSize trans_granule); } // namespace ArmISA + +template class IndexingPolicyTemplate; + } // namespace gem5 #endif // __ARCH_ARM_PAGETABLE_H__