From 3143cf091ddb638bcb3c1a27497b92f6dd847aa8 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 5 Jul 2020 00:52:35 +0100 Subject: [PATCH] cater for illegal instruction (generates a trap) --- src/soc/consts.py | 9 +++--- src/soc/decoder/decode2execute1.py | 2 +- src/soc/decoder/power_decoder2.py | 41 ++++++++++++++++------------ src/soc/fu/trap/main_stage.py | 5 +++- src/soc/fu/trap/trap_input_record.py | 2 +- 5 files changed, 34 insertions(+), 25 deletions(-) diff --git a/src/soc/consts.py b/src/soc/consts.py index 4fdc84db..f29ddcfb 100644 --- a/src/soc/consts.py +++ b/src/soc/consts.py @@ -21,8 +21,9 @@ class MSR: # (TODO: add more?) class PI: - FP = (63 - 43) # 1 if FP exception - PRIV = (63 - 45) # 1 if privileged interrupt - TRAP = (63 - 46) # 1 if exception is "trap" type - ADR = (63 - 47) # 0 if SRR0 = address of instruction causing exception + FP = (63 - 43) # 1 if FP exception + ILLEG = (63 - 44) # 1 if illegal instruction (not doing hypervisor) + PRIV = (63 - 45) # 1 if privileged interrupt + TRAP = (63 - 46) # 1 if exception is "trap" type + ADR = (63 - 47) # 0 if SRR0 = address of instruction causing exception diff --git a/src/soc/decoder/decode2execute1.py b/src/soc/decoder/decode2execute1.py index 966def93..f888c595 100644 --- a/src/soc/decoder/decode2execute1.py +++ b/src/soc/decoder/decode2execute1.py @@ -73,6 +73,6 @@ class Decode2ToExecute1Type(RecordObject): self.byte_reverse = Signal(reset_less=True) self.sign_extend = Signal(reset_less=True)# do we need this? self.update = Signal(reset_less=True) # LD/ST is "update" variant - self.traptype = Signal(4, reset_less=True) # see trap main_stage.py + self.traptype = Signal(5, reset_less=True) # see trap main_stage.py self.trapaddr = Signal(13, reset_less=True) diff --git a/src/soc/decoder/power_decoder2.py b/src/soc/decoder/power_decoder2.py index 09aacb0d..84e1c789 100644 --- a/src/soc/decoder/power_decoder2.py +++ b/src/soc/decoder/power_decoder2.py @@ -29,6 +29,7 @@ TT_FP = 1<<0 TT_PRIV = 1<<1 TT_TRAP = 1<<2 TT_ADDR = 1<<3 +TT_ILLEG = 1<<4 def decode_spr_num(spr): return Cat(spr[5:10], spr[0:5]) @@ -315,11 +316,6 @@ class DecodeOut(Elaboratable): comb += self.fast_out.data.eq(FastRegs.SRR0) # constant: SRR0 comb += self.fast_out.ok.eq(1) - # TRAP fast1 = SRR0 - with m.If(op.internal_op == InternalOp.OP_TRAP): - comb += self.fast_out.data.eq(FastRegs.SRR0) # constant: SRR0 - comb += self.fast_out.ok.eq(1) - return m @@ -359,11 +355,6 @@ class DecodeOut2(Elaboratable): comb += self.fast_out.data.eq(FastRegs.SRR1) # constant: SRR1 comb += self.fast_out.ok.eq(1) - # TRAP fast2 = SRR1 - with m.If(op.internal_op == InternalOp.OP_TRAP): - comb += self.fast_out.data.eq(FastRegs.SRR1) # constant: SRR1 - comb += self.fast_out.ok.eq(1) - return m @@ -634,18 +625,32 @@ class PowerDecode2(Elaboratable): with m.If(op.internal_op == InternalOp.OP_TRAP): comb += e.trapaddr.eq(0x70) # addr=0x700 (strip first nibble) + # illegal instruction must redirect to trap. this is done by + # *overwriting* the decoded instruction and starting again. + with m.If(op.internal_op == InternalOp.OP_ILLEGAL): + comb += e.eq(0) # reset eeeeeverything + # start again + comb += e.insn.eq(self.dec.opcode_in) + comb += e.insn_type.eq(InternalOp.OP_TRAP) + comb += e.fn_unit.eq(Function.TRAP) + comb += e.trapaddr.eq(0x70) # addr=0x700 (strip first nibble) + comb += e.traptype.eq(TT_ILLEG) # request illegal instruction + + # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs + with m.If(e.insn_type == InternalOp.OP_TRAP): + # TRAP write fast1 = SRR0 + comb += e.write_fast1.data.eq(FastRegs.SRR0) # constant: SRR0 + comb += e.write_fast1.ok.eq(1) + # TRAP write fast2 = SRR1 + comb += e.write_fast2.data.eq(FastRegs.SRR1) # constant: SRR1 + comb += e.write_fast2.ok.eq(1) + return m - # privileged instruction + # TODO: get msr, then can do privileged instruction with m.If(instr_is_priv(m, op.internal_op, e.insn) & msr[MSR_PR]): - # don't request registers RA/RT - comb += e.read_reg1.eq(0) - comb += e.read_reg2.eq(0) - comb += e.read_reg3.eq(0) - comb += e.write_reg.eq(0) - comb += e.write_ea.eq(0) # privileged instruction trap - comb += op.internal_op.eq(InternalOp.OP_TRAP) + comb += op.insn_type.eq(InternalOp.OP_TRAP) comb += e.traptype.eq(TT_PRIV) # request privileged instruction comb += e.trapaddr.eq(0x70) # addr=0x700 (strip first nibble) return m diff --git a/src/soc/fu/trap/main_stage.py b/src/soc/fu/trap/main_stage.py index 0737ced8..6a12eb2f 100644 --- a/src/soc/fu/trap/main_stage.py +++ b/src/soc/fu/trap/main_stage.py @@ -19,7 +19,8 @@ from soc.decoder.power_enums import InternalOp from soc.decoder.power_fields import DecodeFields from soc.decoder.power_fieldsn import SignalBitRange -from soc.decoder.power_decoder2 import (TT_FP, TT_PRIV, TT_TRAP, TT_ADDR) +from soc.decoder.power_decoder2 import (TT_FP, TT_PRIV, TT_TRAP, TT_ADDR, + TT_ILLEG) from soc.consts import MSR, PI @@ -159,6 +160,8 @@ class TrapMainStage(PipeModBase): 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_ILLEG): + comb += srr1_o.data[PI.ILLEG].eq(1) # move to MSR with m.Case(InternalOp.OP_MTMSRD): diff --git a/src/soc/fu/trap/trap_input_record.py b/src/soc/fu/trap/trap_input_record.py index d15dca7e..3624710a 100644 --- a/src/soc/fu/trap/trap_input_record.py +++ b/src/soc/fu/trap/trap_input_record.py @@ -15,7 +15,7 @@ class CompTrapOpSubset(Record): ('fn_unit', Function), ('insn', 32), ('is_32bit', 1), - ('traptype', 4), # see trap main_stage.py and PowerDecoder2 + ('traptype', 5), # see trap main_stage.py and PowerDecoder2 ('trapaddr', 13), ) -- 2.30.2