from openpower.decoder.selectable_int import (FieldSelectableInt, SelectableInt,
selectconcat)
from openpower.decoder.helpers import exts, gtu, ltu, undefined
-from openpower.decoder.isa.mem import Mem
+from openpower.decoder.isa.mem import Mem, MemException
from openpower.consts import MSRb # big-endian (PowerISA versions)
import math
def ld(self, address, width=8, swap=True, check_in_mem=False,
instr_fetch=False):
- print("RADIX: ld from addr 0x%x width %d" % (address, width))
-
- priv = ~(self.msr[MSRb.PR].value) # problem-state ==> privileged
if instr_fetch:
mode = 'EXECUTE'
else:
mode = 'LOAD'
- addr = SelectableInt(address, 64)
- pte = self._walk_tree(addr, mode, priv)
+ priv = ~(self.msr[MSRb.PR].value) # problem-state ==> privileged
+ virt = (self.msr[MSRb.DR].value) # DR -> virtual
+ print("RADIX: ld from addr 0x%x width %d mode %s "
+ "priv %d virt %d" % (address, width, mode, priv, virt))
- if type(pte)==str:
- print("error on load",pte)
- return 0
+ # virtual mode does a lookup to new address, otherwise use real addr
+ addr = SelectableInt(address, 64)
+ if virt:
+ addr = self._walk_tree(addr, mode, priv)
+ addr = addr.value
- # use pte to load from phys address
- data = self.mem.ld(pte.value, width, swap, check_in_mem)
+ # use address to load from phys address
+ data = self.mem.ld(addr, width, swap, check_in_mem)
self.last_ld_addr = self.mem.last_ld_addr
# XXX set SPRs on error
# TODO implement
def st(self, address, v, width=8, swap=True):
- print("RADIX: st to addr 0x%x width %d data %x" % (address, width, v))
priv = ~(self.msr[MSRb.PR].value) # problem-state ==> privileged
+ virt = (self.msr[MSRb.DR].value) # DR -> virtual
+ print("RADIX: st to addr 0x%x width %d data %x "
+ "priv %d virt %d " % (address, width, v, priv, virt))
mode = 'STORE'
+
+ # virtual mode does a lookup to new address, otherwise use real addr
addr = SelectableInt(address, 64)
- pte = self._walk_tree(addr, mode, priv)
+ if virt:
+ addr = self._walk_tree(addr, mode, priv)
+ addr = addr.value
- # use pte to store at phys address
- res = self.mem.st(pte.value, v, width, swap)
+ # use address to store at phys address
+ res = self.mem.st(addr, v, width, swap)
self.last_st_addr = self.mem.last_st_addr
# XXX set SPRs on error
# WIP
if mbits == 0:
- return "invalid"
+ exc = MemException("invalid")
+ exc.mode = mode
+ raise exc
# mask_size := mbits(4 downto 0);
mask_size = mbits[0:5]
print(" valid, leaf", valid, leaf)
if not valid:
- return "invalid" # TODO: return error
+ exc = MemException("invalid")
+ exc.mode = mode
+ raise exc
if leaf:
print ("is leaf, checking perms")
ok = self._check_perms(data, priv, mode)