From 2521ba066475ae0884d80ef0285efbd327767380 Mon Sep 17 00:00:00 2001 From: Hoa Nguyen Date: Mon, 30 Oct 2023 02:07:04 +0000 Subject: [PATCH 1/4] 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') }}; From f615ee4cd43fb968397b24946257eb12fd0f3395 Mon Sep 17 00:00:00 2001 From: Hoa Nguyen Date: Mon, 30 Oct 2023 02:18:29 +0000 Subject: [PATCH 2/4] arch-riscv: Fix generateDisassembly for Store with 1 source reg Currently, store instructions are assumed to have two source registers. However, since we are supporting the RISC-V CMO instructions, which are Store instructions in gem5 but they only have one source register. This change allows printing disassembly of Store instructions with one source register. Change-Id: I4dd7818c9ac8a89d5e10e77db72248942a25e938 Signed-off-by: Hoa Nguyen --- src/arch/riscv/insts/mem.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/arch/riscv/insts/mem.cc b/src/arch/riscv/insts/mem.cc index 5f58a68a57..8ebda7406d 100644 --- a/src/arch/riscv/insts/mem.cc +++ b/src/arch/riscv/insts/mem.cc @@ -55,8 +55,13 @@ std::string Store::generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const { std::stringstream ss; - ss << mnemonic << ' ' << registerName(srcRegIdx(1)) << ", " << - offset << '(' << registerName(srcRegIdx(0)) << ')'; + if (_numSrcRegs == 1) { + ss << mnemonic << ' ' << offset << '(' << registerName(srcRegIdx(0)) + << ")"; + } else { + ss << mnemonic << ' ' << registerName(srcRegIdx(1)) << ", " << + offset << '(' << registerName(srcRegIdx(0)) << ')'; + } return ss.str(); } From 7c6fcb38386cce2121e699e2eab75e01ea98d97d Mon Sep 17 00:00:00 2001 From: Hoa Nguyen Date: Mon, 30 Oct 2023 02:36:24 +0000 Subject: [PATCH 3/4] arch-riscv: Add all supporting Z extensions to RISC-V isa string Change-Id: I809744fc546bc5c0e27380f9b75bdf99f8520583 Signed-off-by: Hoa Nguyen --- src/arch/riscv/RiscvISA.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/arch/riscv/RiscvISA.py b/src/arch/riscv/RiscvISA.py index 62dcffb5d8..ca533bef0e 100644 --- a/src/arch/riscv/RiscvISA.py +++ b/src/arch/riscv/RiscvISA.py @@ -109,4 +109,15 @@ class RiscvISA(BaseISA): if self.enable_rvv.value == True: isa_extensions.append("v") isa_string = "".join(isa_extensions) + + isa_string += "_Zicbom" # Cache-block Management Instructions + isa_string += "_Zicboz" # Cache-block Zero Instruction + isa_string += "_Zicntr" # Performance Couter Spec + isa_string += "_Zicsr" # RMW CSR Instructions (Privileged Spec) + isa_string += "_Zifencei" # FENCE.I Instruction (Unprivileged Spec) + isa_string += "_Zihpm" # Performance Couter Spec + isa_string += "_Zba" # Address Generation + isa_string += "_Zbb" # Basic Bit Manipulation + isa_string += "_Zbs" # Single-bit Instructions + return isa_string From 68287604ee3364747c6ef54bef38a8fc08245896 Mon Sep 17 00:00:00 2001 From: Hoa Nguyen Date: Mon, 30 Oct 2023 02:41:26 +0000 Subject: [PATCH 4/4] arch-riscv: Make Zicbom/Zicboz extensions optional in FS mode Currently, we're enable Zicbom/Zicboz by default. Since those extensions might be buggy as they are not well-tested, making those entensions optional allows running simulation where the performance implication of the instructions do not matter. Effectively, by turning off the extensions, we simply remove those extensions from the device tree, so the OS would not use them. It doesn't prohibit the userspace application to use those instructions, however. Change-Id: Ib30e98c4c39f741dec5f7d31bd7b832391686840 Signed-off-by: Hoa Nguyen --- src/arch/riscv/RiscvISA.py | 9 +++++++-- src/python/gem5/components/boards/riscv_board.py | 12 ++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/arch/riscv/RiscvISA.py b/src/arch/riscv/RiscvISA.py index ca533bef0e..bce7f2497f 100644 --- a/src/arch/riscv/RiscvISA.py +++ b/src/arch/riscv/RiscvISA.py @@ -96,6 +96,9 @@ class RiscvISA(BaseISA): ELEN in Ch. 2 of RISC-V vector spec", ) + enable_Zicbom_fs = Param.Bool(True, "Enable Zicbom extension in FS mode") + enable_Zicboz_fs = Param.Bool(True, "Enable Zicboz extension in FS mode") + def get_isa_string(self): isa_extensions = [] # check for the base ISA type @@ -110,8 +113,10 @@ class RiscvISA(BaseISA): isa_extensions.append("v") isa_string = "".join(isa_extensions) - isa_string += "_Zicbom" # Cache-block Management Instructions - isa_string += "_Zicboz" # Cache-block Zero Instruction + if self.enable_Zicbom_fs.value: + isa_string += "_Zicbom" # Cache-block Management Instructions + if self.enable_Zicboz_fs.value: + isa_string += "_Zicboz" # Cache-block Zero Instruction isa_string += "_Zicntr" # Performance Couter Spec isa_string += "_Zicsr" # RMW CSR Instructions (Privileged Spec) isa_string += "_Zifencei" # FENCE.I Instruction (Unprivileged Spec) diff --git a/src/python/gem5/components/boards/riscv_board.py b/src/python/gem5/components/boards/riscv_board.py index 9b0d6454e1..5e5af815a4 100644 --- a/src/python/gem5/components/boards/riscv_board.py +++ b/src/python/gem5/components/boards/riscv_board.py @@ -279,6 +279,18 @@ class RiscvBoard(AbstractSystemBoard, KernelDiskWorkload): node.append(FdtPropertyStrings("device_type", "cpu")) node.append(FdtPropertyWords("reg", state.CPUAddrCells(i))) node.append(FdtPropertyStrings("mmu-type", "riscv,sv48")) + if core.core.isa[0].enable_Zicbom_fs.value: + node.append( + FdtPropertyWords( + "riscv,cbom-block-size", self.get_cache_line_size() + ) + ) + if core.core.isa[0].enable_Zicboz_fs.value: + node.append( + FdtPropertyWords( + "riscv,cboz-block-size", self.get_cache_line_size() + ) + ) node.append(FdtPropertyStrings("status", "okay")) node.append( FdtPropertyStrings(