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
 
         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
         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)
         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()
         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)
         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)
 
         # 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)
 
                         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
 
         # 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