Skip to content

Commit 02fc114

Browse files
committed
add sfence_vma key
1 parent 26c3a2f commit 02fc114

3 files changed

Lines changed: 29 additions & 3 deletions

File tree

coreblocks/func_blocks/fu/priv.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from enum import IntFlag, auto, unique
66
from typing import Sequence
7-
from coreblocks.arch.isa_consts import Funct12, Funct3, Funct7, Opcode, PrivilegeLevel, SatpMode
7+
from coreblocks.arch.isa_consts import Funct12, Funct3, Funct7, Opcode, PrivilegeLevel
88

99

1010
from transactron import *
@@ -27,6 +27,7 @@
2727
UnsafeInstructionResolvedKey,
2828
FlushICacheKey,
2929
WaitForInterruptResumeKey,
30+
SFenceVMAKey,
3031
)
3132
from coreblocks.func_blocks.interface.func_protocols import FuncUnit
3233

@@ -89,6 +90,8 @@ def elaborate(self, platform):
8990
instr_imm = Signal(self.gen_params.isa.xlen)
9091
instr_s1_val = Signal(self.gen_params.isa.xlen)
9192
instr_s2_val = Signal(self.gen_params.isa.xlen)
93+
instr_s1_x0 = Signal()
94+
instr_s2_x0 = Signal()
9295

9396
mret = self.dm.get_dependency(MretKey())
9497
sret = self.dm.get_optional_dependency(SretKey())
@@ -97,6 +100,7 @@ def elaborate(self, platform):
97100
csr = self.dm.get_dependency(CSRInstancesKey())
98101
priv_mode = csr.m_mode.priv_mode
99102
flush_icache = self.dm.get_dependency(FlushICacheKey())
103+
sfence_vma = self.dm.get_optional_dependency(SFenceVMAKey())
100104
resume_core = self.dm.get_dependency(UnsafeInstructionResolvedKey())
101105

102106
@def_method(m, self.issue_decoded, ready=~instr_valid)
@@ -108,6 +112,8 @@ def _(arg):
108112
instr_fn.eq(arg.decode_fn),
109113
instr_s1_val.eq(arg.s1_val),
110114
instr_s2_val.eq(arg.s2_val),
115+
instr_s1_x0.eq(arg.rp_s1_reg == 0),
116+
instr_s2_x0.eq(arg.rp_s2_reg == 0),
111117
instr_imm.eq(arg.imm),
112118
]
113119

@@ -150,8 +156,10 @@ def _(arg):
150156
with branch(info.side_fx & (instr_fn == PrivilegedFn.Fn.SRET) & ~illegal_sret):
151157
sret(m)
152158

153-
# TODO: implement proper SFENCE.VMA, for BARE only - NO-OP is ok
154-
assert self.gen_params.vmem_params.supported_schemes == {SatpMode.BARE}
159+
if self.gen_params.vmem_params.supported_schemes > {SatpMode.BARE}:
160+
assert sfence_vma is not None
161+
with branch(info.side_fx & (instr_fn == PrivilegedFn.Fn.SFENCEVMA) & ~illegal_sfencevma):
162+
sfence_vma[0](m, vaddr=instr_s1_val, asid=instr_s2_val, all_vaddrs=instr_s1_x0, all_asids=instr_s2_x0)
155163

156164
with branch(info.side_fx & (instr_fn == PrivilegedFn.Fn.FENCEI)):
157165
flush_icache(m)

coreblocks/interface/keys.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"CoreStateKey",
2828
"CSRListKey",
2929
"FlushICacheKey",
30+
"SFenceVMAKey",
3031
"RollbackKey",
3132
"InstructionTaggedCounterKey",
3233
]
@@ -117,6 +118,16 @@ class FlushICacheKey(SimpleKey[Method]):
117118
pass
118119

119120

121+
@dataclass(frozen=True)
122+
class SFenceVMAKey(UnifierKey, unifier=MethodProduct.create):
123+
"""
124+
Collects SFENCE.VMA handlers to invalidate translation caches.
125+
Expected layout is `AddressTranslationLayouts.sfence_vma`.
126+
"""
127+
128+
pass
129+
130+
120131
@dataclass(frozen=True)
121132
class RollbackKey(UnifierKey, unifier=MethodProduct.create):
122133
"""

coreblocks/interface/layouts.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,13 @@ def __init__(self, gen_params: GenParams):
181181
("access_fault", 1),
182182
)
183183

184+
self.sfence_vma = make_layout(
185+
fields.vaddr,
186+
("asid", gen_params.vmem_params.asidlen),
187+
("all_vaddrs", 1),
188+
("all_asids", 1),
189+
)
190+
184191

185192
class SchedulerLayouts:
186193
"""Layouts used in the scheduler."""

0 commit comments

Comments
 (0)