From 52dd8548b7fdc76631f30fa5bf7082c4934429f9 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Wed, 8 Dec 2021 16:09:28 +0000 Subject: [PATCH] add instr_fault to LoadStore1 FSM this includes stopping LoadStore1 from processing (accepting) incoming LDST operations via its PortInterface --- src/soc/experiment/test/test_loadstore1.py | 23 ++++++-------------- src/soc/fu/ldst/loadstore.py | 25 ++++++++++++++++------ 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/soc/experiment/test/test_loadstore1.py b/src/soc/experiment/test/test_loadstore1.py index c351d4e9..b2f9b480 100644 --- a/src/soc/experiment/test/test_loadstore1.py +++ b/src/soc/experiment/test/test_loadstore1.py @@ -183,29 +183,18 @@ def _test_loadstore1_ifetch(dut, mem): virt_addr = 0x10200 - yield mmu.l_in.iside.eq(1) - yield mmu.l_in.load.eq(1) - yield mmu.l_in.valid.eq(1) - yield mmu.l_in.priv.eq(1) - yield mmu.l_in.addr.eq(virt_addr) + yield ldst.priv_mode.eq(1) + yield ldst.instr_fault.eq(1) + yield ldst.maddr.eq(virt_addr) #ld_data, exctype, exc = yield from pi_ld(pi, virt_addr, 8, msr_pr=1) #yield ldst.iside.eq(0) yield while True: - l_done = yield (mmu.l_out.done) - l_err = yield (mmu.l_out.err) - l_badtree = yield (mmu.l_out.badtree) - l_permerr = yield (mmu.l_out.perm_error) - l_rc_err = yield (mmu.l_out.rc_error) - l_segerr = yield (mmu.l_out.segerr) - l_invalid = yield (mmu.l_out.invalid) - if (l_done or l_err or l_badtree or - l_permerr or l_rc_err or l_segerr or l_invalid): + done = yield (ldst.done) + if done: break yield - yield mmu.l_in.valid.eq(0) - print ("******** errs?", - l_err, l_badtree, l_permerr, l_rc_err, l_segerr, l_invalid) + yield ldst.instr_fault.eq(0) yield yield yield diff --git a/src/soc/fu/ldst/loadstore.py b/src/soc/fu/ldst/loadstore.py index a3bff180..52a4e995 100644 --- a/src/soc/fu/ldst/loadstore.py +++ b/src/soc/fu/ldst/loadstore.py @@ -77,8 +77,8 @@ class LoadStore1(PortInterfaceBase): self.d_in = self.dcache.d_out # out from dcache is in for LoadStore self.i_out = self.icache.i_in # in to icache is out for LoadStore self.i_in = self.icache.i_out # out from icache is in for LoadStore - self.m_out = LoadStore1ToMMUType() # out *to* MMU - self.m_in = MMUToLoadStore1Type() # in *from* MMU + self.m_out = LoadStore1ToMMUType("m_out") # out *to* MMU + self.m_in = MMUToLoadStore1Type("m_in") # in *from* MMU self.req = LDSTRequest(name="ldst_req") # TODO, convert dcache wb_in/wb_out to "standard" nmigen Wishbone bus @@ -98,6 +98,7 @@ class LoadStore1(PortInterfaceBase): self.tlbie = Signal() self.dcbz = Signal() self.addr = Signal(64) + self.maddr = Signal(64) self.store_data = Signal(64) self.load_data = Signal(64) self.load_data_delay = Signal(64) @@ -111,8 +112,7 @@ class LoadStore1(PortInterfaceBase): self.virt_mode = Signal() self.priv_mode = Signal() self.state = Signal(State) - self.iside = Signal() # request instruction-side load - self.instr_fault = Signal() + self.instr_fault = Signal() # indicator to request i-cache MMU lookup self.align_intr = Signal() self.busy = Signal() self.wait_dcache = Signal() @@ -131,6 +131,10 @@ class LoadStore1(PortInterfaceBase): self.dsisr = Signal(32) self.dar = Signal(64) + # when external_busy set, do not allow PortInterface to proceed + def external_busy(self, m): + return self.instr_fault + 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) @@ -199,7 +203,7 @@ class LoadStore1(PortInterfaceBase): exception = exc.happened mmureq = Signal() - # copy of address, but gets over-ridden for OP_FETCH_FAILED + # copy of address, but gets over-ridden for instr_fault maddr = Signal(64) m.d.comb += maddr.eq(self.addr) @@ -213,12 +217,17 @@ class LoadStore1(PortInterfaceBase): # fsm skeleton with m.Switch(self.state): with m.Case(State.IDLE): - with m.If(self.d_validblip & ~exc.happened): + with m.If((self.d_validblip | self.instr_fault) & + ~exc.happened): 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.If(self.instr_fault): + comb += mmureq.eq(1) + comb += maddr.eq(self.maddr) + sync += self.state.eq(State.MMU_LOOKUP) with m.Else(): sync += ldst_r.eq(0) @@ -270,6 +279,7 @@ class LoadStore1(PortInterfaceBase): sync += ldst_r.eq(0) with m.Else(): sync += self.state.eq(State.IDLE) + comb += self.done.eq(1) with m.If(m_in.err): # MMU RADIX exception thrown. XXX @@ -381,8 +391,9 @@ class LoadStore1(PortInterfaceBase): # Update outputs to MMU m.d.comb += m_out.valid.eq(mmureq) - m.d.comb += m_out.iside.eq(self.iside) + m.d.comb += m_out.iside.eq(self.instr_fault) m.d.comb += m_out.load.eq(ldst_r.load) + m.d.comb += m_out.priv.eq(self.priv_mode) # m_out.priv <= r.priv_mode; TODO m.d.comb += m_out.tlbie.eq(self.tlbie) # m_out.mtspr <= mmu_mtspr; # TODO -- 2.30.2