1# 2# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3# 4# SPDX-License-Identifier: BSD-2-Clause 5# 6 7from __future__ import absolute_import, division, print_function, \ 8 unicode_literals 9 10from capdl.Object import Object, Frame, CNode, Endpoint, Notification, SchedControl 11 12 13class Cap(object): 14 """ 15 A capability to a kernel object. 16 """ 17 18 def __init__(self, referent, **kwargs): 19 assert isinstance(referent, Object) 20 self.referent = referent 21 self.read = False 22 self.write = False 23 self.grant = False 24 self.grantreply = False 25 self.guard = 0 26 self.guard_size = 0 27 self.badge = None 28 self.cached = True 29 self.ports = None 30 self.mapping_container = None 31 self.mapping_slot = None 32 self.mapping_deferred = False 33 for (k, v) in kwargs.items(): 34 if hasattr(self, k): 35 setattr(self, k, v) 36 37 def set_guard(self, guard): 38 assert isinstance(self.referent, CNode) 39 assert isinstance(guard, int) 40 assert guard % 2**18 == guard, 'guards can be a maximum of 18 bits' 41 self.guard = guard 42 43 def set_guard_size(self, guard_size): 44 assert isinstance(self.referent, CNode) 45 assert isinstance(guard_size, int) 46 self.guard_size = guard_size 47 48 def set_badge(self, badge): 49 # Only endpoint caps can be badged. 50 assert isinstance(self.referent, Endpoint) or \ 51 isinstance(self.referent, Notification) 52 assert badge % 2**28 == badge, 'badges can be a maximum of 28 bits' 53 self.badge = badge 54 55 def set_cached(self, cached): 56 assert isinstance(self.referent, Frame) 57 self.cached = cached 58 59 def set_mapping(self, container, slot): 60 """ 61 @brief For a frame cap in a cspace, ensure that this is the 62 cap used for a mapping into a mapping object specified by 63 container and slot. 64 65 @param self A frame cap that is inside a CNode. 66 @param container The mapping object the frame is mapped into. 67 @param slot The index of the mapping object 68 """ 69 assert isinstance(self.referent, Frame) 70 self.mapping_container = container 71 self.mapping_slot = slot 72 73 def set_mapping_deferred(self): 74 """ 75 @brief Indicate that this cap is a mapping cap, but the container 76 and slot values are to be set later. 77 """ 78 assert isinstance(self.referent, Frame) 79 self.mapping_deferred = True 80 81 def __repr__(self): 82 extra = [] 83 84 if isinstance(self.referent, SchedControl): 85 return "sched_control (core: %d)" % self.referent.core 86 87 if isinstance(self.referent, 88 (Frame, Endpoint, Notification)): 89 is_frame = isinstance(self.referent, Frame) 90 rights = [sym for sym, flag in 91 [('R', self.read), 92 ('W', self.write), 93 ('X', is_frame and self.grant), 94 ('G', not is_frame and self.grant), 95 ('P', self.grantreply)] 96 if flag] 97 extra.append(''.join(rights)) 98 99 if isinstance(self.referent, Frame) and not self.cached: 100 extra.append('uncached') 101 if isinstance(self.referent, Frame) and \ 102 self.mapping_container is not None: 103 extra.append('mapping: (%s, %d)' % (self.mapping_container.name, self.mapping_slot)) 104 if isinstance(self.referent, (Endpoint, Notification)) and \ 105 self.badge is not None: 106 extra.append('badge: %d' % self.badge) 107 if isinstance(self.referent, CNode): 108 extra.append('guard: %s' % self.guard) 109 extra.append('guard_size: %s' % self.guard_size) 110 111 extra = [x for x in extra if x != ''] 112 113 return '%s%s' % (self.referent.name, 114 (' (%s)' % ', '.join(extra)) if extra else '') 115