from soc.decoder.selectable_int import (FieldSelectableInt, SelectableInt,
selectconcat)
from soc.decoder.helpers import exts, gtu, ltu, undefined
+from soc.decoder.isa.mem import Mem
import math
import sys
def __init__(self, mem, caller):
self.mem = mem
self.caller = caller
+ #TODO move to lookup
self.dsisr = self.caller.spr["DSISR"]
self.dar = self.caller.spr["DAR"]
self.pidr = self.caller.spr["PIDR"]
self.pgtbl3 = 0
self.pt3_valid = False
- def __call__(self,*args, **kwargs):
- print("TODO: implement RADIX.__call__()")
- print(args)
- print(kwargs)
- return None
+ def __call__(self, addr, sz):
+ val = self.ld(addr.value, sz, swap=False)
+ print("RADIX memread", addr, sz, val)
+ return SelectableInt(val, sz*8)
def ld(self, address, width=8, swap=True, check_in_mem=False):
print("RADIX: ld from addr 0x%x width %d" % (address, width))
// Authority
//
"""
+ # get sprs
+ print("_walk_tree")
+ pidr = self.caller.spr["PIDR"]
+ prtbl = self.caller.spr["PRTBL"]
+ print(pidr)
+ print(prtbl)
+
+ # TODO read root entry from process table first
+
# walk tree starts on prtbl
while True:
ret = self._next_level()
new_shift = shift + (31 - 12) - mbits
return new_shift
- def _check_perms(self):
+ def _check_perms(self, data, priv, iside, store):
"""check page permissions
+ // Leaf PDE |
+ // |------------------------------| |----------------|
+ // |V|L|sw|//|RPN|sw|R|C|/|ATT|EAA| | usefulBits |
+ // |------------------------------| |----------------|
+ // [0] = V = Valid Bit |
+ // [1] = L = Leaf Bit = 1 if leaf |
+ // PDE |
+ // [2] = Sw = Sw bit 0. |
+ // [7:51] = RPN = Real Page Number, V
+ // real_page = RPN << 12 -------------> Logical OR
+ // [52:54] = Sw Bits 1:3 |
+ // [55] = R = Reference |
+ // [56] = C = Change V
+ // [58:59] = Att = Physical Address
+ // 0b00 = Normal Memory
+ // 0b01 = SAO
+ // 0b10 = Non Idenmpotent
+ // 0b11 = Tolerant I/O
+ // [60:63] = Encoded Access
+ // Authority
+ //
-- test leaf bit
- if data(62) = '1' then
-- check permissions and RC bits
perm_ok := '0';
if r.priv = '1' or data(3) = '0' then
v.rc_error := perm_ok;
end if;
"""
+ # check permissions and RC bits
+ perm_ok = 0
+ if priv == 1 or data[60] == 0:
+ if iside == 0:
+ perm_ok = data[62] | (data[61] & (store == 0))
+ # no IAMR, so no KUEP support for now
+ # deny execute permission if cache inhibited
+ perm_ok = data[63] & ~data[58]
+ rc_ok = data[55] & (data[56] | (store == 0))
+ if perm_ok == 1 and rc_ok == 1:
+ return True
+ return "perm_err" if perm_ok == 0 else "rc_err"
def _get_prtable_addr(self, shift, prtbl, addr, pid):
"""
# very quick test of maskgen function (TODO, move to util later)
if __name__ == '__main__':
+ # set up dummy minimal ISACaller
+ spr = {'DSISR': SelectableInt(0, 64),
+ 'DAR': SelectableInt(0, 64),
+ 'PIDR': SelectableInt(0, 64),
+ 'PRTBL': SelectableInt(0, 64)
+ }
+ class ISACaller: pass
+ caller = ISACaller()
+ caller.spr = spr
+
shift = SelectableInt(5, 6)
mask = genmask(shift, 43)
print (" mask", bin(mask.value))
mem = Mem(row_bytes=8)
- mem = RADIX(mem, None)
+ mem = RADIX(mem, caller)
# -----------------------------------------------
# |/|RTS1|/| RPDB | RTS2 | RPDS |
# -----------------------------------------------