From 954cfc94aac3ae76cc978f6524dc78fc8a742565 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 5 Jul 2020 11:34:16 +0100 Subject: [PATCH] fix qemu trap test --- src/soc/decoder/isa/caller.py | 34 ++++++++++++++++++++++++------- src/soc/decoder/power_decoder2.py | 8 +++++++- src/soc/simulator/qemu.py | 2 ++ src/soc/simulator/test_sim.py | 13 +++++++++--- 4 files changed, 46 insertions(+), 11 deletions(-) diff --git a/src/soc/decoder/isa/caller.py b/src/soc/decoder/isa/caller.py index 273ffd17..d25fa628 100644 --- a/src/soc/decoder/isa/caller.py +++ b/src/soc/decoder/isa/caller.py @@ -244,7 +244,8 @@ class ISACaller: def __init__(self, decoder2, regfile, initial_sprs=None, initial_cr=0, initial_mem=None, initial_msr=0, initial_insns=None, respect_pc=False, - disassembly=None): + disassembly=None, + initial_pc=0): self.respect_pc = respect_pc if initial_sprs is None: @@ -262,12 +263,15 @@ class ISACaller: if not respect_pc: if isinstance(initial_mem, tuple): self.fake_pc = initial_mem[0] + disasm_start = self.fake_pc + else: + disasm_start = initial_pc # disassembly: we need this for now (not given from the decoder) self.disassembly = {} if disassembly: for i, code in enumerate(disassembly): - self.disassembly[i*4 + self.fake_pc] = code + self.disassembly[i*4 + disasm_start] = code # set up registers, instruction memory, data memory, PC, SPRs, MSR self.gpr = GPR(decoder2, regfile) @@ -312,6 +316,8 @@ class ISACaller: 'SO': XER_bits['SO'] }) + # update pc to requested start point + self.set_pc(initial_pc) # field-selectable versions of Condition Register TODO check bitranges? self.crl = [] @@ -325,12 +331,12 @@ class ISACaller: self.dec2 = decoder2 def TRAP(self, trap_addr=0x700): - print ("TRAP: TODO") + 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.set_pc(trap_addr) + self.trap_nia = SelectableInt(trap_addr, 64) self.namespace['MSR'][63-PI.TRAP] = 1 # bit 45, "this is a trap" def memassign(self, ea, sz, val): @@ -460,7 +466,7 @@ class ISACaller: if ins is None: raise KeyError("no instruction at 0x%x" % pc) print("setup: 0x%x 0x%x %s" % (pc, ins & 0xffffffff, bin(ins))) - print ("NIA, CIA", self.pc.CIA.value, self.pc.NIA.value) + print ("CIA NIA", self.respect_pc, self.pc.CIA.value, self.pc.NIA.value) yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff) yield self.dec2.dec.bigendian.eq(0) # little / big? @@ -476,7 +482,7 @@ class ISACaller: if not self.respect_pc: self.fake_pc += 4 - print ("NIA, CIA", self.pc.CIA.value, self.pc.NIA.value) + print ("execute one, CIA NIA", self.pc.CIA.value, self.pc.NIA.value) def get_assembly_name(self): # TODO, asmregs is from the spec, e.g. add RT,RA,RB @@ -546,10 +552,20 @@ class ISACaller: else: inputs.append(self.namespace[special]) + # clear trap (trap) NIA + self.trap_nia = None + print(inputs) results = info.func(self, *inputs) print(results) + # "inject" decorator takes namespace from function locals: we need to + # overwrite NIA being overwritten (sigh) + if self.trap_nia is not None: + self.namespace['NIA'] = self.trap_nia + + print ("after func", self.namespace['CIA'], self.namespace['NIA']) + # detect if CA/CA32 already in outputs (sra*, basically) already_done = 0 if info.write_regs: @@ -610,7 +626,8 @@ class ISACaller: output = SelectableInt(output.value, 64) self.gpr[regnum] = output - # update program counter + print ("end of call", self.namespace['CIA'], self.namespace['NIA']) + # UPDATE program counter self.pc.update(self.namespace) @@ -638,6 +655,9 @@ def inject(): saved_values = func_globals.copy() # Shallow copy of dict. func_globals.update(context) result = func(*args, **kwargs) + print ("globals after", func_globals['CIA'], func_globals['NIA']) + print ("args[0]", args[0].namespace['CIA'], + args[0].namespace['NIA']) args[0].namespace = func_globals #exec (func.__code__, func_globals) diff --git a/src/soc/decoder/power_decoder2.py b/src/soc/decoder/power_decoder2.py index 84e1c789..812bf72e 100644 --- a/src/soc/decoder/power_decoder2.py +++ b/src/soc/decoder/power_decoder2.py @@ -627,6 +627,8 @@ class PowerDecode2(Elaboratable): # illegal instruction must redirect to trap. this is done by # *overwriting* the decoded instruction and starting again. + # (note: the same goes for interrupts and for privileged operations, + # just with different trapaddr and traptype) with m.If(op.internal_op == InternalOp.OP_ILLEGAL): comb += e.eq(0) # reset eeeeeverything # start again @@ -649,8 +651,12 @@ class PowerDecode2(Elaboratable): # TODO: get msr, then can do privileged instruction with m.If(instr_is_priv(m, op.internal_op, e.insn) & msr[MSR_PR]): + 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) # privileged instruction 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/simulator/qemu.py b/src/soc/simulator/qemu.py index c265a77f..b39ada05 100644 --- a/src/soc/simulator/qemu.py +++ b/src/soc/simulator/qemu.py @@ -112,6 +112,8 @@ def run_program(program, initial_mem=None): q.delete_breakpoint() # run to completion q.break_address(0x20000000 + program.size()) + # or to trap + q.break_address(0x700) q.gdb_continue() return q diff --git a/src/soc/simulator/test_sim.py b/src/soc/simulator/test_sim.py index de4193bc..a619ba1b 100644 --- a/src/soc/simulator/test_sim.py +++ b/src/soc/simulator/test_sim.py @@ -209,7 +209,7 @@ class GeneralTestCases(FHDLTestCase): class DecoderBase: - def run_tst(self, generator, initial_mem=None): + def run_tst(self, generator, initial_mem=None, initial_pc=0): m = Module() comb = m.d.comb @@ -220,9 +220,13 @@ class DecoderBase: pdecode = create_pdecode() m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode) + # place program at requested address + gen = (initial_pc, gen) + simulator = ISA(pdecode2, [0] * 32, {}, 0, initial_mem, 0, initial_insns=gen, respect_pc=True, - disassembly=insn_code) + disassembly=insn_code, + initial_pc=initial_pc) sim = Simulator(m) @@ -246,7 +250,8 @@ class DecoderBase: def run_tst_program(self, prog, reglist, initial_mem=None): import sys - simulator = self.run_tst(prog, initial_mem=initial_mem) + simulator = self.run_tst(prog, initial_mem=initial_mem, + initial_pc=0x20000000) prog.reset() with run_program(prog, initial_mem) as q: self.qemu_register_compare(simulator, q, reglist) @@ -280,10 +285,12 @@ class DecoderBase: print("qemu pc", hex(qpc)) print("qemu cr", hex(qcr)) print("qemu xer", bin(qxer)) + print("sim nia", hex(sim.pc.NIA.value)) print("sim pc", hex(sim.pc.CIA.value)) print("sim cr", hex(sim_cr)) print("sim xer", hex(sim_xer)) self.assertEqual(qcr, sim_cr) + self.assertEqual(qpc, sim_pc) for reg in regs: qemu_val = qemu.get_register(reg) sim_val = sim.gpr(reg).value -- 2.30.2