add instr_fault to LoadStore1 FSM
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 8 Dec 2021 16:09:28 +0000 (16:09 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 8 Dec 2021 16:09:35 +0000 (16:09 +0000)
this includes stopping LoadStore1 from processing (accepting)
incoming LDST operations via its PortInterface

src/soc/experiment/test/test_loadstore1.py
src/soc/fu/ldst/loadstore.py

index c351d4e9e44ddcdb560dcf09de0e2d66ea7fd364..b2f9b480f32772e04e46e12ef0ec08c7d587ae89 100644 (file)
@@ -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
index a3bff180f290a5b1b384b0027b3de952a24ce731..52a4e99507f0ba2b15c276e80ba3ec2669e03c2a 100644 (file)
@@ -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