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:
Bobby R. Bruce
2023-11-13 03:38:49 -08:00
committed by GitHub
4 changed files with 101 additions and 5 deletions

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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')
}};

View File

@@ -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(