"""
from functools import wraps
+from copy import copy
from soc.decoder.orderedset import OrderedSet
from soc.decoder.selectable_int import (FieldSelectableInt, SelectableInt,
selectconcat)
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)
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)
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):
# 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