From 2521ba066475ae0884d80ef0285efbd327767380 Mon Sep 17 00:00:00 2001 From: Hoa Nguyen Date: Mon, 30 Oct 2023 02:07:04 +0000 Subject: [PATCH] arch-riscv: Fix implementation of CMO extension instructions This change introduces a template for store instruction's mem access. The new template is called CacheBlockBasedStore. The reasons for not reusing the current Store's mem access template are as follows, - The CMO extension instructions operate on cache block size granularity, while regular load/store instructions operate on data of size 64 bits or fewer. - The writeMemAtomicLE/writeMemTimingLE interfaces do not allow passing nullptr as data. However, CPUs in gem5 rely on (data == NULL) to detect CACHE_BLOCK_ZERO instructions. Setting `Mem = 0;` to `uint64_t Mem;` does not solve the problem as the reference is allocated and thus, it's always true that `&Mem != NULL`. This change uses the writeMemAtomic/writeMemTiming interfaces instead. - Per CMO v1.0.1, the instructions in the spec do not generate address misaligned faults. - The CMO extension instructions do not use IMM. Change-Id: I323615639a4ba882fe40a55ed32c7632e0251421 Signed-off-by: Hoa Nguyen --- src/arch/riscv/isa/formats/mem.isa | 69 ++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/src/arch/riscv/isa/formats/mem.isa b/src/arch/riscv/isa/formats/mem.isa index 7cec113ba1..53de4af8b4 100644 --- a/src/arch/riscv/isa/formats/mem.isa +++ b/src/arch/riscv/isa/formats/mem.isa @@ -228,6 +228,69 @@ def template StoreCompleteAcc {{ } }}; +def template CacheBlockBasedStoreExecute {{ + Fault + %(class_name)s::execute(ExecContext *xc, + trace::InstRecord *traceData) const + { + Addr EA; + + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + Addr cacheBlockSize = xc->tcBase()->getCpuPtr()->cacheLineSize(); + uint64_t numOffsetBits = floorLog2(cacheBlockSize); + EA = (EA >> numOffsetBits) << numOffsetBits; + + { + Fault fault = + writeMemAtomic(xc, nullptr, EA, cacheBlockSize, memAccessFlags, + nullptr, std::vector(cacheBlockSize, true)); + if (fault != NoFault) + return fault; + } + + return NoFault; + } +}}; + +def template CacheBlockBasedStoreInitiateAcc {{ + Fault + %(class_name)s::initiateAcc(ExecContext *xc, + trace::InstRecord *traceData) const + { + Addr EA; + + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + Addr cacheBlockSize = xc->tcBase()->getCpuPtr()->cacheLineSize(); + uint64_t numOffsetBits = floorLog2(cacheBlockSize); + EA = (EA >> numOffsetBits) << numOffsetBits; + + { + Fault fault = + writeMemTiming(xc, nullptr, EA, cacheBlockSize, memAccessFlags, + nullptr, std::vector(cacheBlockSize, true)); + if (fault != NoFault) + return fault; + } + + return NoFault; + } +}}; + +def template CacheBlockBasedStoreCompleteAcc {{ + Fault + %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc, + trace::InstRecord *traceData) const + { + return NoFault; + } +}}; + def format Load(memacc_code, ea_code = {{EA = rvZext(Rs1 + offset);}}, offset_code={{offset = sext<12>(IMM12);}}, mem_flags=[], inst_flags=[]) {{ @@ -244,9 +307,9 @@ def format Store(memacc_code, ea_code={{EA = rvZext(Rs1 + offset);}}, inst_flags, 'Store', exec_template_base='Store') }}; -def format CBMOp(memacc_code, ea_code={{EA = rvZext(Rs1 + offset);}}, - offset_code={{offset = 0;}}, mem_flags=[], inst_flags=[]) {{ +def format CBMOp(memacc_code, ea_code={{EA = rvZext(Rs1);}}, + offset_code={{;}}, mem_flags=[], inst_flags=[]) {{ (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name, offset_code, ea_code, memacc_code, mem_flags, - inst_flags, 'Store', exec_template_base='Store') + inst_flags, 'Store', exec_template_base='CacheBlockBasedStore') }};