"""
from copy import copy
-from soc.decoder.selectable_int import (FieldSelectableInt, SelectableInt,
+from openpower.decoder.selectable_int import (FieldSelectableInt, SelectableInt,
selectconcat)
-from soc.decoder.helpers import exts, gtu, ltu, undefined
+from openpower.decoder.helpers import exts, gtu, ltu, undefined
+from openpower.util import log
import math
import sys
return x
+class MemException(Exception):
+ pass
+
+def process_mem(initial_mem, row_bytes=8):
+ res = {}
+ # different types of memory data structures recognised (for convenience)
+ if isinstance(initial_mem, list):
+ initial_mem = (0, initial_mem)
+ if isinstance(initial_mem, tuple):
+ startaddr, mem = initial_mem
+ initial_mem = {}
+ for i, val in enumerate(mem):
+ initial_mem[startaddr + row_bytes*i] = (val, row_bytes)
+
+ for addr, val in initial_mem.items():
+ if isinstance(val, tuple):
+ (val, width) = val
+ else:
+ width = row_bytes # assume same width
+ #val = swap_order(val, width)
+ res[addr] = (val, width)
+
+ return res
+
class Mem:
self.mem = {}
self.bytes_per_word = row_bytes
self.word_log2 = math.ceil(math.log2(row_bytes))
- print("Sim-Mem", initial_mem, self.bytes_per_word, self.word_log2)
+ 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
- # different types of memory data structures recognised (for convenience)
- if isinstance(initial_mem, list):
- initial_mem = (0, initial_mem)
- if isinstance(initial_mem, tuple):
- startaddr, mem = initial_mem
- initial_mem = {}
- for i, val in enumerate(mem):
- initial_mem[startaddr + row_bytes*i] = (val, row_bytes)
-
- for addr, val in initial_mem.items():
- if isinstance(val, tuple):
- (val, width) = val
- else:
- width = row_bytes # assume same width
+ for addr, (val, width) in process_mem(initial_mem, row_bytes).items():
#val = swap_order(val, width)
self.st(addr, val, width, swap=False)
# BE/LE mode?
shifter = remainder * 8
mask = (1 << (wid * 8)) - 1
- print("width,rem,shift,mask", wid, remainder, hex(shifter), hex(mask))
+ log("width,rem,shift,mask", wid, remainder, hex(shifter), hex(mask))
return shifter, mask
# TODO: Implement ld/st of lesser width
def ld(self, address, width=8, swap=True, check_in_mem=False,
instr_fetch=False):
- print("ld from addr 0x{:x} width {:d}".format(address, width),
+ 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
- assert remainder & (width - 1) == 0, "Unaligned access unsupported!"
+ if remainder & (width - 1) != 0:
+ exc = MemException("unaligned", "Unaligned access Error")
+ exc.dar = ldaddr
+ raise exc
if address in self.mem:
val = self.mem[address]
elif check_in_mem:
return None
else:
val = 0
- print("mem @ 0x{:x} rem {:d} : 0x{:x}".format(address, remainder, val))
+ log("ld mem @ 0x%x rem %d : 0x%x" % (ldaddr, remainder, val))
if width != self.bytes_per_word:
shifter, mask = self._get_shifter_mask(width, remainder)
- print("masking", hex(val), hex(mask << shifter), shifter)
+ log("masking", hex(val), hex(mask << shifter), shifter)
val = val & (mask << shifter)
val >>= shifter
if swap:
val = swap_order(val, width)
- print("Read 0x{:x} from addr 0x{:x}".format(val, address))
+ log("Read 0x%x from addr 0x%x" % (val, ldaddr))
return val
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
- print("Writing 0x{:x} to ST 0x{:x} "
- "memaddr 0x{:x}/{:x}".format(v, staddr, addr, remainder, swap))
- assert remainder & (width - 1) == 0, "Unaligned access unsupported!"
+ log("Writing 0x%x to ST 0x%x memaddr 0x%x/%x swap %s" % \
+ (v, staddr, addr, remainder, str(swap)))
+ if remainder & (width - 1) != 0:
+ exc = MemException("unaligned", "Unaligned access Error")
+ exc.dar = staddr
+ raise exc
if swap:
v = swap_order(v, width)
if width != self.bytes_per_word:
self.mem[addr] = val
else:
self.mem[addr] = v
- print("mem @ 0x{:x}: 0x{:x}".format(addr, self.mem[addr]))
+ log("mem @ 0x%x: 0x%x" % (staddr, self.mem[addr]))
def __call__(self, addr, sz):
val = self.ld(addr.value, sz, swap=False)
- print("memread", addr, sz, val)
+ log("memread", addr, sz, val)
return SelectableInt(val, sz*8)
def memassign(self, addr, sz, val):
- print("memassign", addr, sz, val)
+ log("memassign", addr, sz, val)
self.st(addr.value, val.value, sz, swap=False)
-
+ def dump(self, printout=True):
+ keys = list(self.mem.keys())
+ keys.sort()
+ res = []
+ for k in keys:
+ res.append(((k*8), self.mem[k]))
+ if not printout:
+ continue
+ print ("%016x: %016x" % ((k*8) & 0xffffffffffffffff, self.mem[k]))
+ return res