From 32cd87d73afd7e1f6e68bab5d1efdbe85764e122 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Tue, 11 May 2021 11:59:45 +0100 Subject: [PATCH] pass through MSR.PR through PortInterface, into LoadStore1 --- src/soc/experiment/pi2ls.py | 4 ++-- src/soc/experiment/pimem.py | 14 ++++++++------ src/soc/experiment/test/test_l0_cache_buffer2.py | 4 ++-- src/soc/experiment/test/test_mmu_dcache_pi.py | 11 ++++++----- src/soc/fu/ldst/loadstore.py | 8 ++++++-- 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/soc/experiment/pi2ls.py b/src/soc/experiment/pi2ls.py index 19278be1..2392620b 100644 --- a/src/soc/experiment/pi2ls.py +++ b/src/soc/experiment/pi2ls.py @@ -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) diff --git a/src/soc/experiment/pimem.py b/src/soc/experiment/pimem.py index 6bc70fe0..3d6dc8c7 100644 --- a/src/soc/experiment/pimem.py +++ b/src/soc/experiment/pimem.py @@ -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) diff --git a/src/soc/experiment/test/test_l0_cache_buffer2.py b/src/soc/experiment/test/test_l0_cache_buffer2.py index e9044549..ec435e65 100644 --- a/src/soc/experiment/test/test_l0_cache_buffer2.py +++ b/src/soc/experiment/test/test_l0_cache_buffer2.py @@ -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): diff --git a/src/soc/experiment/test/test_mmu_dcache_pi.py b/src/soc/experiment/test/test_mmu_dcache_pi.py index 0dc182b2..7f95f7d6 100644 --- a/src/soc/experiment/test/test_mmu_dcache_pi.py +++ b/src/soc/experiment/test/test_mmu_dcache_pi.py @@ -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): diff --git a/src/soc/fu/ldst/loadstore.py b/src/soc/fu/ldst/loadstore.py index b2713639..c7732a11 100644 --- a/src/soc/fu/ldst/loadstore.py +++ b/src/soc/fu/ldst/loadstore.py @@ -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)): -- 2.30.2