From d8443042357b41ffaf57f480ff2e1d5b8343c73c Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Tue, 21 Jul 2020 14:10:54 +0100 Subject: [PATCH] add msr exception bits setting function in hardware and do same thing in ISACaller trap --- src/soc/decoder/isa/caller.py | 19 ++++++++++++++++--- src/soc/fu/trap/main_stage.py | 27 +++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/soc/decoder/isa/caller.py b/src/soc/decoder/isa/caller.py index ad4318ec..5c8d6b6f 100644 --- a/src/soc/decoder/isa/caller.py +++ b/src/soc/decoder/isa/caller.py @@ -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) diff --git a/src/soc/fu/trap/main_stage.py b/src/soc/fu/trap/main_stage.py index 37ea4af2..dfd75bef 100644 --- a/src/soc/fu/trap/main_stage.py +++ b/src/soc/fu/trap/main_stage.py @@ -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 -- 2.30.2