add misaligned mmu.bin test 5 notes: currently LoadStore1 does not
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 28 Dec 2021 02:30:11 +0000 (02:30 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 28 Dec 2021 02:30:11 +0000 (02:30 +0000)
support misaligned LD/ST therefore a 0x600 exception is raised
where actually a page-table lookup over the boundary (into a second
PTE which does not exist) should result in a 0x300 (DAR) fault.

also took the opportunity to set align_intr when no-cache is requested
on dcbz

src/soc/experiment/mmu.py
src/soc/fu/ldst/loadstore.py

index a245ddbd7d1af973ee09d6560279759affb04ee8..4850269028ccaa1e68a3c2280f70b0b0d7d16bae 100644 (file)
@@ -722,6 +722,16 @@ def dcache_get(dut):
              0x12010: 0x0a00010000000000, # page table
     }
 
+    # microwatt mmu.bin test 5.
+    # PRTBL must be set to 0x12000, PID to 1
+    mem = {
+             0x0: 0x000000, # to get mtspr prtbl working
+             0x13cf8: 0x86b10000000000c0, # leaf node
+             0x13d00: 0x0000000000000000, # invalid leaf node
+             0x10008: 0x0930010000000080, # directory node
+             0x12010: 0x0a00010000000000, # page table
+    }
+
     while not stop:
         while True: # wait for dc_valid
             if stop:
@@ -819,7 +829,13 @@ def mmu_sim(dut):
 
     #addr = 0x10000  # original test
     #addr = 0x124108  # microwatt mmu.bin test 2
-    addr = 0x10b0d8  # microwatt mmu.bin test 4
+    #addr = 0x10b0d8  # microwatt mmu.bin test 4
+    # these are a misalignment test. one load results in two actual
+    # lookups, one of which has a valid page table entry, the other
+    # does not.  we currently do not support misaligned in Loadstore1
+    # therefore these tests fail with an align_intr (0x600) at 0x39fffd
+    addr = 0x39fffd # microwatt mmu.bin test 5
+    addr = 0x3a0000 # microwatt mmu.bin test 5
 
     # MMU PTE request
     yield dut.l_in.load.eq(1)
index 6d081eec2f2e8c20ed556b07d7b6ee3fd2ddcb5a..1ecac0add15494d57aed59bfaeb837387c9bfc15 100644 (file)
@@ -143,21 +143,26 @@ class LoadStore1(PortInterfaceBase):
         m.d.comb += self.req.priv_mode.eq(~msr.pr) # not-problem  ==> priv
         m.d.comb += self.req.virt_mode.eq(msr.dr) # DR ==> virt
         m.d.comb += self.req.mode_32bit.eq(~msr.sf) # not-sixty-four ==> 32bit
-        m.d.comb += self.req.align_intr.eq(misalign)
         m.d.comb += self.req.dcbz.eq(is_dcbz)
+        # XXX TODO sort out misalignment, mmu test5 fails
+        m.d.comb += self.req.align_intr.eq(misalign)
 
         # 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)
+
+        # dcbz cannot do no-cache
+        with m.If(is_dcbz & self.req.nc):
+            m.d.comb += self.req.align_intr.eq(1)
+
         return None
 
     def set_rd_addr(self, m, addr, mask, misalign, msr):
         m.d.comb += self.d_valid.eq(1)
         m.d.comb += self.req.load.eq(1) # load operation
         m.d.comb += self.req.byte_sel.eq(mask)
-        m.d.comb += self.req.align_intr.eq(misalign)
         m.d.comb += self.req.raddr.eq(addr)
         m.d.comb += self.req.priv_mode.eq(~msr.pr) # not-problem  ==> priv
         m.d.comb += self.req.virt_mode.eq(msr.dr) # DR ==> virt
@@ -169,6 +174,8 @@ class LoadStore1(PortInterfaceBase):
         # option to disable the cache entirely for read
         if self.disable_cache:
             m.d.comb += self.req.nc.eq(1)
+        # XXX TODO sort out misalignment, mmu test5 fails
+        m.d.comb += self.req.align_intr.eq(misalign)
         return None #FIXME return value
 
     def set_wr_data(self, m, data, wen):