arch-riscv: Fixing CMO instructions and allowing using CMO instructions in FS mode (#517)
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. --- 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. --- 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. --- arch-riscv: Add all supporting Z extensions to RISC-V isa string
This commit is contained in:
@@ -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
|
||||
@@ -109,4 +112,17 @@ class RiscvISA(BaseISA):
|
||||
if self.enable_rvv.value == True:
|
||||
isa_extensions.append("v")
|
||||
isa_string = "".join(isa_extensions)
|
||||
|
||||
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)
|
||||
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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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<bool>(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<bool>(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')
|
||||
}};
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user