add msr exception bits setting function in hardware
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 21 Jul 2020 13:10:54 +0000 (14:10 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 21 Jul 2020 13:10:54 +0000 (14:10 +0100)
and do same thing in ISACaller trap

src/soc/decoder/isa/caller.py
src/soc/fu/trap/main_stage.py

index ad4318ecbe24b5c4f528153e419d8a225614f1c7..5c8d6b6f06a12d0dadf43d9d5db114209f984e7e 100644 (file)
@@ -10,6 +10,7 @@ related bugs:
 """
 
 from functools import wraps
+from copy import copy
 from soc.decoder.orderedset import OrderedSet
 from soc.decoder.selectable_int import (FieldSelectableInt, SelectableInt,
                                         selectconcat)
@@ -343,10 +344,22 @@ class ISACaller:
         print ("TRAP:", hex(trap_addr))
         # store CIA(+4?) in SRR0, set NIA to 0x700
         # store MSR in SRR1, set MSR to um errr something, have to check spec
-        self.spr['SRR0'] = self.pc.CIA
-        self.spr['SRR1'] = self.namespace['MSR']
+        self.spr['SRR0'].value = self.pc.CIA.value
+        self.spr['SRR1'].value = self.namespace['MSR'].value
         self.trap_nia = SelectableInt(trap_addr, 64)
-        self.namespace['MSR'][63-trap_bit] = 1
+        self.spr['SRR1'][63-trap_bit] = 1 # change *copy* of MSR in SRR1
+
+        # set exception bits.  TODO: this should, based on the address
+        # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
+        # bits appropriately.  however it turns out that *for now* in all
+        # cases (all trap_addrs) the exact same thing is needed.
+        self.namespace['MSR'][63-MSR.SF] = 1
+        self.namespace['MSR'][63-MSR.EE] = 0
+        self.namespace['MSR'][63-MSR.PR] = 0
+        self.namespace['MSR'][63-MSR.IR] = 0
+        self.namespace['MSR'][63-MSR.DR] = 0
+        self.namespace['MSR'][63-MSR.RI] = 0
+        self.namespace['MSR'][63-MSR.LE] = 1
 
     def memassign(self, ea, sz, val):
         self.mem.memassign(ea, sz, val)
index 37ea4af293def050f0d290f30e419fa464e24196..dfd75befd9952e8ff76379cdc6445cf0ea3de81d 100644 (file)
@@ -76,6 +76,26 @@ class TrapMainStage(PipeModBase):
         comb += msr_copy(srr1_o.data, msr_i) # old MSR
         comb += srr1_o.ok.eq(1)
 
+    def msr_exception(self, m, trap_addr):
+        """msr_exception - sets bits in MSR specific to an exception.
+        the full list of what needs to be done is given in V3.0B
+        Book III Section 6.5 p1063 however it turns out that for the
+        majority of cases (microwatt showing the way, here), all these
+        bits are all set by all (implemented) interrupt types.  this
+        may change in the future, hence the (unused) trap_addr argument
+        """
+        comb  = m.d.comb
+        msr_i, msr_o = self.i.msr, self.o.msr
+        comb += msr_o.data.eq(msr_i) # copy msr, first, then modify
+        comb += msr_o.data[MSR.SF].eq(1)
+        comb += msr_o.data[MSR.EE].eq(0)
+        comb += msr_o.data[MSR.PR].eq(0)
+        comb += msr_o.data[MSR.IR].eq(0)
+        comb += msr_o.data[MSR.DR].eq(0)
+        comb += msr_o.data[MSR.RI].eq(0)
+        comb += msr_o.data[MSR.LE].eq(1)
+        comb += msr_o.ok.eq(1)
+
     def ispec(self):
         return TrapInputData(self.pspec)
 
@@ -160,6 +180,10 @@ class TrapMainStage(PipeModBase):
                         comb += srr1_o.data[PI.ADR].eq(1)
                     with m.If(traptype & TT.ILLEG):
                         comb += srr1_o.data[PI.ILLEG].eq(1)
+                    comb += srr1_o.ok.eq(1)
+
+                    # when SRR1 is written to, update MSR bits
+                    self.msr_exception(m, trapaddr)
 
             # move to MSR
             with m.Case(MicrOp.OP_MTMSRD, MicrOp.OP_MTMSR):
@@ -227,6 +251,9 @@ class TrapMainStage(PipeModBase):
                 # jump to the trap address, return at cia+4
                 self.trap(m, 0xc00, cia_i+4)
 
+                # and update several MSR bits
+                self.msr_exception(m, 0xc00)
+
             # TODO (later)
             #with m.Case(MicrOp.OP_ADDPCIS):
             #    pass