projects
/
soc.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
3143cf0
)
fix qemu trap test
author
Luke Kenneth Casson Leighton
<lkcl@lkcl.net>
Sun, 5 Jul 2020 10:34:16 +0000
(11:34 +0100)
committer
Luke Kenneth Casson Leighton
<lkcl@lkcl.net>
Sun, 5 Jul 2020 10:34:16 +0000
(11:34 +0100)
src/soc/decoder/isa/caller.py
patch
|
blob
|
history
src/soc/decoder/power_decoder2.py
patch
|
blob
|
history
src/soc/simulator/qemu.py
patch
|
blob
|
history
src/soc/simulator/test_sim.py
patch
|
blob
|
history
diff --git
a/src/soc/decoder/isa/caller.py
b/src/soc/decoder/isa/caller.py
index 273ffd17b9814047517559a0174c6c1c8bf9cb23..d25fa6282c069c227c1373607275e14b44ae7314 100644
(file)
--- 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,
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:
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]
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):
# 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)
# 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']
})
'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 = []
# 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):
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']
# 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):
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)))
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?
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
if not self.respect_pc:
self.fake_pc += 4
- print ("
NIA, C
IA", self.pc.CIA.value, self.pc.NIA.value)
+ print ("
execute one, CIA N
IA", 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
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])
else:
inputs.append(self.namespace[special])
+ # clear trap (trap) NIA
+ self.trap_nia = None
+
print(inputs)
results = info.func(self, *inputs)
print(results)
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:
# 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
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)
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)
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)
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 84e1c789897d52218f50cc6dcbf24a7dfa125b3f..812bf72e812f2491bb5c5adbc38eb9c1b700a512 100644
(file)
--- 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.
# 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
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]):
# 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
# 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
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 c265a77ffa2b16ec30487a04b86cd1fc3b26457b..b39ada05d07d1bb4879ec3f93bbdba9b400e1c79 100644
(file)
--- 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())
q.delete_breakpoint()
# run to completion
q.break_address(0x20000000 + program.size())
+ # or to trap
+ q.break_address(0x700)
q.gdb_continue()
return q
q.gdb_continue()
return q
diff --git
a/src/soc/simulator/test_sim.py
b/src/soc/simulator/test_sim.py
index de4193bc5f3bacd7311a984682e728c52484b6a4..a619ba1bd39c533bebfad9b6d7512db5a2be8b3c 100644
(file)
--- a/
src/soc/simulator/test_sim.py
+++ b/
src/soc/simulator/test_sim.py
@@
-209,7
+209,7
@@
class GeneralTestCases(FHDLTestCase):
class DecoderBase:
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
m = Module()
comb = m.d.comb
@@
-220,9
+220,13
@@
class DecoderBase:
pdecode = create_pdecode()
m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
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,
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)
sim = Simulator(m)
@@
-246,7
+250,8
@@
class DecoderBase:
def run_tst_program(self, prog, reglist, initial_mem=None):
import sys
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)
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("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)
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
for reg in regs:
qemu_val = qemu.get_register(reg)
sim_val = sim.gpr(reg).value