comment cleanup, record last LD/ST address in simulator
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 1 Jun 2021 11:55:39 +0000 (12:55 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 1 Jun 2021 11:55:39 +0000 (12:55 +0100)
for checking with a snapshop on memory operations

src/openpower/decoder/isa/caller.py
src/openpower/decoder/isa/mem.py
src/openpower/decoder/isa/pypowersim.py
src/openpower/decoder/isa/radixmmu.py
src/openpower/simulator/qemu.py
src/test/basic_pypowersim/Makefile

index d3a6fa3891f1a822ea6f7669a44b8f2f91cdfd47..427ad4ff457b55c1fdb2865fe7f9e876c65b60bf 100644 (file)
@@ -559,25 +559,28 @@ class ISACaller:
             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)
@@ -982,6 +985,9 @@ class ISACaller:
     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)
@@ -1208,7 +1214,7 @@ class ISACaller:
         # 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)
@@ -1220,6 +1226,17 @@ class ISACaller:
 
         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:
index 36d6e8444c4b10cb72e3eb6e1463e0a38b19158a..adaa84b44a3b9019cda5f5dfa4d2b23b68aa3698 100644 (file)
@@ -38,6 +38,8 @@ class Mem:
         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
@@ -74,6 +76,7 @@ class Mem:
                  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
@@ -101,6 +104,7 @@ class Mem:
 
     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" % \
index 040fb64dfa38fe03a481036aaa8ef599be9232ed..690f3eca567b3d41ea6b5d3d011c7399cec82ef5 100644 (file)
@@ -224,6 +224,14 @@ def run_tst(args, generator, qemu,
             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
 
index 04fb775daa2da2eb39e9f52f1303f783e007049c..c647777f325c137e95ce534b331dff2262e22267 100644 (file)
@@ -308,9 +308,11 @@ class RADIX:
             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):
@@ -322,9 +324,11 @@ class RADIX:
         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)
index 32ed1f269bb1412c23dc72cc9869c3686517932b..4fbaecb1d5ef27269944ef8b85af115821b5b6d7 100644 (file)
@@ -21,7 +21,7 @@ def swap_order(x, nbytes):
 
 
 def find_uint128(val):
-    print (val[1:])
+    #print (val[1:])
     assert val[1:].startswith('uint128 =')
     val = val.split("=")[1]
     val = val.split(',')[0].strip()
index b9ef925ef47470838c2745add445a71284a4f8d2..bcce302cd7fc67df80700dd4061be68bedbf5c73 100644 (file)
@@ -8,7 +8,7 @@ all: sim
 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