super().__init__(pspec, "main")
self.fields = DecodeFields(SignalBitRange, [self.i.ctx.op.insn])
self.fields.create_specs()
+ self.kaivb = Signal(64) # KAIVB SPR
+ self.state_reset = Signal() # raise high to reset KAIVB cache
def trap(self, m, trap_addr, return_addr):
"""trap. sets new PC, stores MSR and old PC in SRR1 and SRR0
msr_i = op.msr
svstate_i = op.svstate
- srr1_i = self.i.srr1
+ exc = LDSTException("trapexc")
+ comb += exc.eq(op.ldst_exc)
+ srr1_i = exc.srr1 # new SRR1 bits come from exception
nia_o = self.o.nia
svsrr0_o, srr0_o, srr1_o = self.o.svsrr0, self.o.srr0, self.o.srr1
- # trap address
+ # trap address, including KAIVB override
comb += nia_o.data.eq(trap_addr)
+ comb += nia_o.data[13:].eq(self.kaivb[13:])
comb += nia_o.ok.eq(1)
# addr to begin from on return
# to copy microwatt behaviour. see writeback.vhdl
# IMPORTANT: PowerDecoder2 needed to actually read SRR1 for
# it to have the contents *of* SRR1 to copy over!
- comb += srr1_o.data.eq(srr1_i) # preserve 0-5 and 11-14
- comb += msr_copy(srr1_o.data, msr_i, False) # old MSR
+ comb += msr_copy(srr1_o.data, msr_i, False) # old MSR
+ comb += srr1_o.data[16:22].eq(srr1_i[0:6]) # IR,DR,PMM,RI,LE
+ comb += srr1_o.data[27:31].eq(srr1_i[11:15]) # MR,FP,ME,FE0
comb += srr1_o.ok.eq(1)
# take a copy of the current SVSTATE into SVSRR0
def elaborate(self, platform):
m = Module()
- comb = m.d.comb
+ comb, sync = m.d.comb, m.d.sync
op = self.i.ctx.op
# convenience variables
srr0_o, srr1_o, svsrr0_o = self.o.srr0, self.o.srr1, self.o.svsrr0
traptype, trapaddr = op.traptype, op.trapaddr
+ # hard reset of KAIVB
+ with m.If(self.state_reset):
+ sync += self.kaivb.eq(0)
+
# take copy of D-Form TO field
i_fields = self.fields.FormD
to = Signal(i_fields.TO[0:-1].shape())
# TODO: some #defines for the bits n stuff.
with m.Switch(op.insn_type):
+ ##############
+ # KAIVB https://bugs.libre-soc.org/show_bug.cgi?id=859
+
+ with m.Case(MicrOp.OP_MTSPR):
+ sync += self.kaivb.eq(a_i)
+
+ with m.Case(MicrOp.OP_MFSPR):
+ comb += o.data.eq(self.kaivb)
+ comb += o.ok.eq(1)
+
###############
# TDI/TWI/TD/TW. v3.0B p90-91
comb += srr1_o.data[PI.FP].eq(1)
with m.If(traptype & TT.ADDR):
comb += srr1_o.data[PI.ADR].eq(1)
- with m.If(traptype & TT.MEMEXC & (trapaddr == 0x400)):
+ with m.If((traptype & TT.MEMEXC).bool() &
+ (trapaddr == 0x400)):
# Instruction Storage Interrupt (ISI - 0x400)
# v3.0C Book III Chap 7.5.5 p1085
# decode exception bits, store in SRR1
# L => bit 16 in LSB0, bit 15 in MSB0 order
L = self.fields.FormX.L1[0:1] # X-Form field L1
# start with copy of msr
- comb += msr_o.eq(msr_i)
+ comb += msr_o.data.eq(msr_i)
with m.If(L):
# just update RI..EE
comb += msr_o.data[MSR.RI].eq(a_i[MSR.RI])
if False: # XXX no - not doing hypervisor yet
with m.If(~self.i.ctx.op.insn[9]): # XXX BAD HACK! (hrfid)
with m.If(field(msr_i, 3)): # HV
- comb += field(msr_o, 51).eq(field(srr1_i, 51)) # ME
+ comb += field(msr_o.data, 51).eq(field(srr1_i, 51)) # ME
with m.Else():
- comb += field(msr_o, 51).eq(field(msr_i, 51)) # ME
+ comb += field(msr_o.data, 51).eq(field(msr_i, 51)) # ME
else:
# same as microwatt: treat MSR.ME rfid same as hrfid
- comb += field(msr_o, 51).eq(field(srr1_i, 51)) # ME
+ comb += field(msr_o.data, 51).eq(field(srr1_i, 51)) # ME
# check problem state: if set, not permitted to set EE,IR,DR
msr_check_pr(m, srr1_i, msr_o.data)