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:
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)
'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 = []
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):
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?
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
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:
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)
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)
# 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
# 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
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
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)
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)
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