pass through MSR.PR through PortInterface, into LoadStore1
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 11 May 2021 10:59:45 +0000 (11:59 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 11 May 2021 10:59:45 +0000 (11:59 +0100)
src/soc/experiment/pi2ls.py
src/soc/experiment/pimem.py
src/soc/experiment/test/test_l0_cache_buffer2.py
src/soc/experiment/test/test_mmu_dcache_pi.py
src/soc/fu/ldst/loadstore.py

index 19278be1da8226df33bc792dbf5abd958e4598d5..2392620bc5c67bc7dea7fb17ad249bc7afbb60cf 100644 (file)
@@ -46,12 +46,12 @@ class Pi2LSUI(PortInterfaceBase):
         self.lsui_busy = Signal()
         self.valid_l = SRLatch(False, name="valid")
 
-    def set_wr_addr(self, m, addr, mask, misalign):
+    def set_wr_addr(self, m, addr, mask, misalign, msr_pr):
         m.d.comb += self.valid_l.s.eq(1)
         m.d.comb += self.lsui.x_mask_i.eq(mask)
         m.d.comb += self.lsui.x_addr_i.eq(addr)
 
-    def set_rd_addr(self, m, addr, mask, misalign):
+    def set_rd_addr(self, m, addr, mask, misalign, msr_pr):
         m.d.comb += self.valid_l.s.eq(1)
         m.d.comb += self.lsui.x_mask_i.eq(mask)
         m.d.comb += self.lsui.x_addr_i.eq(addr)
index 6bc70fe0c4230576d1ce117c94d8c84ff840f19e..3d6dc8c79bcb69fbc4427767ba1a250a9a10a18f 100644 (file)
@@ -172,8 +172,8 @@ class PortInterfaceBase(Elaboratable):
     def connect_port(self, inport):
         return self.pi.connect_port(inport)
 
-    def set_wr_addr(self, m, addr, mask, misalign): pass
-    def set_rd_addr(self, m, addr, mask, misalign): pass
+    def set_wr_addr(self, m, addr, mask, misalign, msr_pr): pass
+    def set_rd_addr(self, m, addr, mask, misalign, msr_pr): pass
     def set_wr_data(self, m, data, wen): pass
     def get_rd_data(self, m): pass
 
@@ -211,6 +211,7 @@ class PortInterfaceBase(Elaboratable):
         pi = self.pi
         comb += lds.eq(pi.is_ld_i)  # ld-req signals
         comb += sts.eq(pi.is_st_i)  # st-req signals
+        pr = pi.msr_pr # MSR problem state: PR=1 ==> virt, PR==0 ==> priv
 
         # detect busy "edge"
         busy_delay = Signal()
@@ -224,6 +225,7 @@ class PortInterfaceBase(Elaboratable):
         misalign = Signal()
         comb += misalign.eq(lenexp.lexp_o[8:].bool())
 
+
         # activate mode: only on "edge"
         comb += ld_active.s.eq(rising_edge(m, lds))  # activate LD mode
         comb += st_active.s.eq(rising_edge(m, sts))  # activate ST mode
@@ -240,7 +242,7 @@ class PortInterfaceBase(Elaboratable):
             comb += lenexp.len_i.eq(pi.data_len)
             comb += lenexp.addr_i.eq(lsbaddr)
             with m.If(pi.addr.ok & adrok_l.qn):
-                self.set_rd_addr(m, pi.addr.data, lenexp.lexp_o, misalign)
+                self.set_rd_addr(m, pi.addr.data, lenexp.lexp_o, misalign, pr)
                 comb += pi.addr_ok_o.eq(1)  # acknowledge addr ok
                 sync += adrok_l.s.eq(1)       # and pull "ack" latch
 
@@ -252,7 +254,7 @@ class PortInterfaceBase(Elaboratable):
             comb += lenexp.len_i.eq(pi.data_len)
             comb += lenexp.addr_i.eq(lsbaddr)
             with m.If(pi.addr.ok):
-                self.set_wr_addr(m, pi.addr.data, lenexp.lexp_o, misalign)
+                self.set_wr_addr(m, pi.addr.data, lenexp.lexp_o, misalign, pr)
                 with m.If(adrok_l.qn):
                     comb += pi.addr_ok_o.eq(1)  # acknowledge addr ok
                     sync += adrok_l.s.eq(1)       # and pull "ack" latch
@@ -339,11 +341,11 @@ class TestMemoryPortInterface(PortInterfaceBase):
         # hard-code memory addressing width to 6 bits
         self.mem = TestMemory(regwid, 5, granularity=regwid//8, init=False)
 
-    def set_wr_addr(self, m, addr, mask, misalign):
+    def set_wr_addr(self, m, addr, mask, misalign, msr_pr):
         lsbaddr, msbaddr = self.splitaddr(addr)
         m.d.comb += self.mem.wrport.addr.eq(msbaddr)
 
-    def set_rd_addr(self, m, addr, mask, misalign):
+    def set_rd_addr(self, m, addr, mask, misalign, msr_pr):
         lsbaddr, msbaddr = self.splitaddr(addr)
         m.d.comb += self.mem.rdport.addr.eq(msbaddr)
 
index e90445496ed670585e19036d6b40e9719b9d595e..ec435e65296dc6ddfa32a6b10706ebb3d7c4acb2 100644 (file)
@@ -25,10 +25,10 @@ class TestCachedMemoryPortInterface(PortInterfaceBase):
         super().__init__(regwid, addrwid)
         self.ldst = LDSTSplitter(32, 48, 4)
 
-    def set_wr_addr(self, m, addr, mask, misalign):
+    def set_wr_addr(self, m, addr, mask, misalign, msr_pr):
         m.d.comb += self.ldst.addr_i.eq(addr)
 
-    def set_rd_addr(self, m, addr, mask, misalign):
+    def set_rd_addr(self, m, addr, mask, misalign, msr_pr):
         m.d.comb += self.ldst.addr_i.eq(addr)
 
     def set_wr_data(self, m, data, wen):
index 0dc182b290bb890757718337853dfe84464bcac9..7f95f7d6a1d1d242dbee26dc833d50440675a0ed 100644 (file)
@@ -43,29 +43,30 @@ from nmigen.compat.sim import run_simulation, Settle
 # will take at least one week (10.10.2020)
 # many unconnected signals
 
+
 class TestMicrowattMemoryPortInterface(PortInterfaceBase):
     """TestMicrowattMemoryPortInterface
 
     This is a Test Class for MMU and DCache conforming to PortInterface
     """
 
-    def __init__(self, mmu, dcache, regwid=64, addrwid=4,):
+    def __init__(self, mmu, dcache, regwid=64, addrwid=4):
         super().__init__(regwid, addrwid)
         self.mmu = mmu
         self.dcache = dcache
 
-    def set_wr_addr(self, m, addr, mask, misalign):
+    def set_wr_addr(self, m, addr, mask, misalign, msr_pr):
         m.d.comb += self.dcache.d_in.addr.eq(addr)
         m.d.comb += self.mmu.l_in.addr.eq(addr)
         m.d.comb += self.mmu.l_in.load.eq(0)
-        m.d.comb += self.mmu.l_in.priv.eq(1)
+        m.d.comb += self.mmu.l_in.priv.eq(1) # TODO put msr_pr here
         m.d.comb += self.mmu.l_in.valid.eq(1)
 
-    def set_rd_addr(self, m, addr, mask, misalign):
+    def set_rd_addr(self, m, addr, mask, misalign, msr_pr):
         m.d.comb += self.dcache.d_in.addr.eq(addr)
         m.d.comb += self.mmu.l_in.addr.eq(addr)
         m.d.comb += self.mmu.l_in.load.eq(1)
-        m.d.comb += self.mmu.l_in.priv.eq(1)
+        m.d.comb += self.mmu.l_in.priv.eq(1) # TODO put msr_pr here
         m.d.comb += self.mmu.l_in.valid.eq(1)
 
     def set_wr_data(self, m, data, wen):
index b2713639e1a15f841c869a7c629d6e72c40197fa..c7732a111a5be0d103b01633e24f4b3185850e56 100644 (file)
@@ -103,19 +103,21 @@ class LoadStore1(PortInterfaceBase):
         #self.nia           = Signal(64)
         #self.srr1          = Signal(16)
 
-    def set_wr_addr(self, m, addr, mask, misalign):
+    def set_wr_addr(self, m, addr, mask, misalign, msr_pr):
         m.d.comb += self.load.eq(0) # store operation
 
         m.d.comb += self.d_out.load.eq(0)
         m.d.comb += self.byte_sel.eq(mask)
         m.d.comb += self.addr.eq(addr)
+        m.d.comb += self.priv_mode.eq(~msr_pr) # not-problem  ==> priv
+        m.d.comb += self.virt_mode.eq(msr_pr) # problem-state ==> virt
         m.d.comb += self.align_intr.eq(misalign)
         # option to disable the cache entirely for write
         if self.disable_cache:
             m.d.comb += self.nc.eq(1)
         return None
 
-    def set_rd_addr(self, m, addr, mask, misalign):
+    def set_rd_addr(self, m, addr, mask, misalign, msr_pr):
         m.d.comb += self.d_valid.eq(1)
         m.d.comb += self.d_out.valid.eq(self.d_validblip)
         m.d.comb += self.load.eq(1) # load operation
@@ -123,6 +125,8 @@ class LoadStore1(PortInterfaceBase):
         m.d.comb += self.byte_sel.eq(mask)
         m.d.comb += self.align_intr.eq(misalign)
         m.d.comb += self.addr.eq(addr)
+        m.d.comb += self.priv_mode.eq(~msr_pr) # not-problem  ==> priv
+        m.d.comb += self.virt_mode.eq(msr_pr) # problem-state ==> virt
         # BAD HACK! disable cacheing on LD when address is 0xCxxx_xxxx
         # this is for peripherals. same thing done in Microwatt loadstore1.vhdl
         with m.If(addr[28:] == Const(0xc, 4)):