for i, code in enumerate(disassembly):
self.disassembly[i*4 + disasm_start] = code
- # set up registers, instruction memory, data memory, PC, SPRs, MSR
+ # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
self.svp64rm = SVP64RM()
if initial_svstate is None:
initial_svstate = 0
if isinstance(initial_svstate, int):
initial_svstate = SVP64State(initial_svstate)
+ # SVSTATE, MSR and PC
self.svstate = initial_svstate
+ self.msr = SelectableInt(initial_msr, 64) # underlying reg
+ self.pc = PC()
+ # GPR FPR SPR registers
self.gpr = GPR(decoder2, self, self.svstate, regfile)
self.fpr = GPR(decoder2, self, self.svstate, fpregfile)
self.spr = SPR(decoder2, initial_sprs) # initialise SPRs before MMU
+ # "raw" memory
self.mem = Mem(row_bytes=8, initial_mem=initial_mem)
self.imem = Mem(row_bytes=4, initial_mem=initial_insns)
# MMU mode, redirect underlying Mem through RADIX
- self.msr = SelectableInt(initial_msr, 64) # underlying reg
if mmu:
self.mem = RADIX(self.mem, self)
if icachemmu:
self.imem = RADIX(self.imem, self)
- self.pc = PC()
# TODO, needed here:
# FPR (same as GPR except for FP nums)
def call(self, name):
"""call(opcode) - the primary execution point for instructions
"""
+ self.last_st_addr = None # reset the last known store address
+ self.last_ld_addr = None # etc.
+
name = name.strip() # remove spaces if not already done so
if self.halted:
log("halted - not executing", name)
# clear trap (trap) NIA
self.trap_nia = None
- # execute actual instruction here
+ # execute actual instruction here (finally)
log("inputs", inputs)
results = info.func(self, *inputs)
log("results", results)
log("after func", self.namespace['CIA'], self.namespace['NIA'])
+ # check if op was a LD/ST so that debugging can check the
+ # address
+ if int_op in [MicrOp.OP_STORE.value,
+ ]:
+ self.last_st_addr = self.mem.last_st_addr
+ if int_op in [MicrOp.OP_LOAD.value,
+ ]:
+ self.last_st_addr = self.mem.last_st_addr
+ log ("op", int_op, MicrOp.OP_STORE.value, MicrOp.OP_LOAD.value,
+ self.last_st_addr, self.last_ld_addr)
+
# detect if CA/CA32 already in outputs (sra*, basically)
already_done = 0
if info.write_regs:
self.mem = {}
self.bytes_per_word = row_bytes
self.word_log2 = math.ceil(math.log2(row_bytes))
+ self.last_ld_addr = None
+ self.last_st_addr = None
log("Sim-Mem", initial_mem, self.bytes_per_word, self.word_log2)
if not initial_mem:
return
instr_fetch=False):
log("ld from addr 0x%x width %d" % (address, width),
swap, check_in_mem, instr_fetch)
+ self.last_ld_addr = address # record last load
ldaddr = address
remainder = address & (self.bytes_per_word - 1)
address = address >> self.word_log2
def st(self, addr, v, width=8, swap=True):
staddr = addr
+ self.last_st_addr = addr # record last store
remainder = addr & (self.bytes_per_word - 1)
addr = addr >> self.word_log2
log("Writing 0x%x to ST 0x%x memaddr 0x%x/%x swap %s" % \
if not _pc or simulator.halted:
qemu.set_endian(False)
qemu_register_compare(simulator, qemu, range(32), range(32))
+ # check last store address
+ if simulator.last_st_addr is not None:
+ addr = simulator.last_st_addr & ~0x7 # align
+ sim_data = simulator.mem.ld(addr, 8, swap=False)
+ qdata = qemu.get_mem(addr, 8)[0]
+ log ("last st", simulator.last_st_addr, sim_data, qdata)
+ if sim_data !=qdata :
+ log("expect mem %x, %x got %x" % (addr, qdata, sim_data))
if _pc is None:
break
return 0
# use pte to load from phys address
- return self.mem.ld(pte.value, width, swap, check_in_mem)
+ data = self.mem.ld(pte.value, width, swap, check_in_mem)
+ self.last_ld_addr = self.mem.last_ld_addr
# XXX set SPRs on error
+ return data
# TODO implement
def st(self, address, v, width=8, swap=True):
pte = self._walk_tree(addr, mode, priv)
# use pte to store at phys address
- return self.mem.st(pte.value, v, width, swap)
+ res = self.mem.st(pte.value, v, width, swap)
+ self.last_st_addr = self.mem.last_st_addr
# XXX set SPRs on error
+ return res
def memassign(self, addr, sz, val):
print("memassign", addr, sz, val)
def find_uint128(val):
- print (val[1:])
+ #print (val[1:])
assert val[1:].startswith('uint128 =')
val = val.split("=")[1]
val = val.split(',')[0].strip()
sim: kernel.bin
echo -n -e \\0060\\0000\\0061\\0000 > test.bin
echo -n -e \\0060\\0000\\0061\\0000 >> test.bin
- pypowersim --load test.bin:0 -g gpr.list -i kernel.bin
+ pypowersim -q --load test.bin:0 -g gpr.list -i kernel.bin
clean:
rm *.o *.elf *.bin