Record, Memory,
Const)
from nmutil.iocontrol import RecordObject
-from nmutil.util import rising_edge
+from nmutil.util import rising_edge, Display
from enum import Enum, unique
from soc.experiment.dcache import DCache
# these are accessed by OP_MTSPR/OP_MFSPR, on behalf of LoadStore1.
# by contrast microwatt has the spr set/get done *in* loadstore1.vhdl
self.dsisr = Signal(64)
- self.dar = Signal(64)
+ #self.dar = Signal(64)
# state info for LD/ST
self.done = Signal()
#self.nia = Signal(64)
#self.srr1 = Signal(16)
- def set_wr_addr(self, m, addr, mask, misalign, msr_pr):
+ def set_wr_addr(self, m, addr, mask, misalign, msr_pr, is_dcbz):
m.d.comb += self.req.load.eq(0) # store operation
m.d.comb += self.req.byte_sel.eq(mask)
m.d.comb += self.req.addr.eq(addr)
m.d.comb += self.req.priv_mode.eq(~msr_pr) # not-problem ==> priv
m.d.comb += self.req.virt_mode.eq(msr_pr) # problem-state ==> virt
m.d.comb += self.req.align_intr.eq(misalign)
+ m.d.comb += self.req.dcbz.eq(is_dcbz)
+
+ # m.d.comb += Display("set_wr_addr %i dcbz %i",addr,is_dcbz)
+
# option to disable the cache entirely for write
if self.disable_cache:
m.d.comb += self.req.nc.eq(1)
# a request when MMU_LOOKUP completes.
m.d.comb += self.d_validblip.eq(rising_edge(m, self.d_valid))
ldst_r = LDSTRequest("ldst_r")
+
+ comb += Display("MMUTEST: LoadStore1 d_in.error=%i",d_in.error)
# fsm skeleton
with m.Switch(self.state):
comb += self.busy.eq(1)
sync += self.state.eq(State.ACK_WAIT)
sync += ldst_r.eq(self.req) # copy of LDSTRequest on "blip"
+# sync += Display("validblip self.req.virt_mode=%i",
+# self.req.virt_mode)
with m.Else():
sync += ldst_r.eq(0)
# waiting for completion
with m.Case(State.ACK_WAIT):
+ comb += Display("MMUTEST: ACK_WAIT")
comb += self.busy.eq(~exc.happened)
with m.If(d_in.error):
comb += exception.eq(1)
sync += self.state.eq(State.IDLE)
sync += ldst_r.eq(0)
+ sync += Display("cache error -> update dsisr")
sync += self.dsisr[63 - 38].eq(~self.load)
# XXX there is no architected bit for this
# (probably should be a machine check in fact)
# waiting here for the MMU TLB lookup to complete.
# either re-try the dcache lookup or throw MMU exception
with m.Case(State.MMU_LOOKUP):
+ comb += Display("MMUTEST: MMU_LOOKUP")
comb += self.busy.eq(1)
with m.If(m_in.done):
with m.If(~self.instr_fault):
with m.Else():
sync += Display("MMU_LOOKUP, exception %x", self.addr)
# instruction lookup fault: store address in DAR
- comb += exc.happened.eq(1)
- sync += self.dar.eq(self.addr)
+ comb += exc.happened.eq(1) # reason = MMU_LOOKUP
+ # mark dar as updated ?
+ sync += self.pi.dar_o.eq(self.addr)
with m.If(m_in.err):
# MMU RADIX exception thrown
comb += exception.eq(1)
+ sync += Display("MMU RADIX exception thrown")
sync += self.dsisr[63 - 33].eq(m_in.invalid)
sync += self.dsisr[63 - 36].eq(m_in.perm_error)
sync += self.dsisr[63 - 38].eq(self.load)
# alignment error: store address in DAR
with m.If(self.align_intr):
- comb += exc.happened.eq(1)
- sync += self.dar.eq(self.addr)
+ comb += exc.happened.eq(1) # reason = alignment
+ sync += Display("alignment error: store addr in DAR %x", self.addr)
+ sync += self.pi.dar_o.eq(self.addr)
+ # TODO report reason
# happened, alignment, instr_fault, invalid.
# note that all of these flow through - eventually to the TRAP
if hasattr(dbus, "stall"):
comb += dcache.wb_in.stall.eq(dbus.stall)
- # write out d data only when flag set
+ # update out d data when flag set
with m.If(self.d_w_valid):
m.d.sync += d_out.data.eq(self.store_data)
- with m.Else():
- m.d.sync += d_out.data.eq(0)
+ #with m.Else():
+ # m.d.sync += d_out.data.eq(0)
+ # unit test passes with that change
# this must move into the FSM, conditionally noticing that
# the "blip" comes from self.d_validblip.
m.d.comb += d_out.priv_mode.eq(self.req.priv_mode)
m.d.comb += d_out.virt_mode.eq(self.req.virt_mode)
m.d.comb += self.align_intr.eq(self.req.align_intr)
+ #m.d.comb += Display("validblip dcbz=%i addr=%x",
+ #self.req.dcbz,self.req.addr)
+ m.d.comb += d_out.dcbz.eq(self.req.dcbz)
with m.Else():
m.d.comb += d_out.load.eq(ldst_r.load)
m.d.comb += d_out.byte_sel.eq(ldst_r.byte_sel)
m.d.comb += d_out.priv_mode.eq(ldst_r.priv_mode)
m.d.comb += d_out.virt_mode.eq(ldst_r.virt_mode)
m.d.comb += self.align_intr.eq(ldst_r.align_intr)
+ #m.d.comb += Display("no_validblip dcbz=%i addr=%x",
+ #ldst_r.dcbz,ldst_r.addr)
+ m.d.comb += d_out.dcbz.eq(ldst_r.dcbz)
# XXX these should be possible to remove but for some reason
# cannot be... yet. TODO, investigate