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)
# generate trap-type program interrupt
self.trap(m, trapaddr<<4, cia_i)
with m.If(traptype == 0):
- # say trap occurred (see 3.0B Book III 7.5.9)
+ # say trap occurred (see 3.0B Book III 6.5.9 p1074-6)
comb += srr1_o.data[PI.TRAP].eq(1)
with m.If(traptype & TT.PRIV):
comb += srr1_o.data[PI.PRIV].eq(1)
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):
# don't understand but it's in the spec. again: bits 32-34
# are copied from srr1_i and need *restoring* to msr_i
- bits = range(63-31:63-29+1) # bits 29, 30, 31 (Power notation)
+ bits = slice(63-31,63-29+1) # bits 29, 30, 31 (Power notation)
with m.If((msr_i[bits] == Const(0b010, 3)) &
(srr1_i[bits] == Const(0b000, 3))):
comb += msr_o.data[bits].eq(msr_i[bits])
# 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