| 1 | |
| 2 | class GetAttrError(Exception): |
| 3 | def __init__(self,name): |
| 4 | Exception.__init__(self) |
| 5 | self.name = name |
| 6 | def __str__(self): |
| 7 | return "The TLB has no getable field member '"+self.name+"'" |
| 8 | |
| 9 | class DelAttrError(Exception): |
| 10 | def __init__(self,name): |
| 11 | Exception.__init__(self) |
| 12 | self.name = name |
| 13 | def __str__(self): |
| 14 | return "TLB attributes such as "+name+" can not be deleted" |
| 15 | |
| 16 | class SetAttrError(Exception): |
| 17 | def __init__(self,name): |
| 18 | Exception.__init__(self) |
| 19 | self.name = name |
| 20 | def __str__(self): |
| 21 | return "The TLB has no setable field member '"+self.name+"'" |
| 22 | |
| 23 | |
| 24 | def __geterror_fun__(name,strand): |
| 25 | raise GetAttrError(name) |
| 26 | def __seterror_fun__(name,strand,value): |
| 27 | raise SetAttrError(name) |
| 28 | |
| 29 | def __geterror__(name): |
| 30 | return lambda strand: __geterror_fun__(name,strand) |
| 31 | def __seterror__(name): |
| 32 | return lambda strand,value: __seterror_fun__(name,strand,value) |
| 33 | |
| 34 | |
| 35 | class Tte: |
| 36 | PAGE_SIZE = ['8K','64K','512K','4M','32M','256M','2G','16G'] |
| 37 | |
| 38 | def __init__(self,tte_ref=None,**args): |
| 39 | if tte_ref == None: |
| 40 | self.valid = False |
| 41 | self.real = False |
| 42 | self.pid = 0 |
| 43 | self.ctx = 0 |
| 44 | self.size = 0 |
| 45 | self.tag = 0 |
| 46 | self.ie = False |
| 47 | self.nfo = False |
| 48 | self.x = False |
| 49 | self.p = False |
| 50 | self.w = False |
| 51 | self.e = False |
| 52 | self.cv = False |
| 53 | self.cp = False |
| 54 | self.lock = False |
| 55 | self.addr = 0 |
| 56 | # some N2 specific TTE fields |
| 57 | self.sw0 = 0 |
| 58 | self.sw1 = 0 |
| 59 | self.soft = 0 |
| 60 | # N1 specific TTE fields |
| 61 | self.diag7_3 = 0 |
| 62 | self.szh = 0 |
| 63 | self.szl = 0 |
| 64 | self.l = 0 |
| 65 | elif isinstance(tte_ref,TlbTte) or isinstance(tte_ref,Tte): |
| 66 | self.valid = tte_ref.valid |
| 67 | self.real = tte_ref.real |
| 68 | self.ctx = tte_ref.ctx |
| 69 | self.pid = tte_ref.pid |
| 70 | self.tag = tte_ref.tag |
| 71 | self.size = tte_ref.size |
| 72 | self.ie = tte_ref.ie |
| 73 | self.nfo = tte_ref.nfo |
| 74 | self.x = tte_ref.x |
| 75 | self.p = tte_ref.p |
| 76 | self.w = tte_ref.w |
| 77 | self.e = tte_ref.e |
| 78 | self.cv = tte_ref.cv |
| 79 | self.cp = tte_ref.cp |
| 80 | self.lock = tte_ref.lock |
| 81 | self.addr = tte_ref.addr |
| 82 | # N2 specific TTE fields |
| 83 | self.soft_flds = tte_ref.soft_flds |
| 84 | # N1 specific TTE fields |
| 85 | self.diag7_3 = tte_ref.diag7_3 |
| 86 | for arg in args: |
| 87 | if self.__dict__.has_key(arg): |
| 88 | setattr(self,arg,args[arg]) |
| 89 | else: |
| 90 | raise AttributeError(arg) |
| 91 | |
| 92 | def __str__(self): |
| 93 | """ |
| 94 | return a string of the most common looked at fields of the TTE |
| 95 | """ |
| 96 | if not self.valid: |
| 97 | return '-------' |
| 98 | elif self.real: |
| 99 | s = 'r' |
| 100 | ctx = '' |
| 101 | else: |
| 102 | s = 'v' |
| 103 | ctx = ' 0x%04x' % self.ctx |
| 104 | |
| 105 | s += self.p and 'p' or '-' |
| 106 | s += self.x and 'x' or '-' |
| 107 | s += self.w and 'w' or '-' |
| 108 | s += self.e and 'e' or '-' |
| 109 | s += self.nfo and 'n' or '-' |
| 110 | s += self.ie and 'i' or '-' |
| 111 | |
| 112 | tag = self.tag |
| 113 | if tag < 0: |
| 114 | tag = 0x10000000000000000 + tag |
| 115 | addr = self.addr |
| 116 | if addr < 0: |
| 117 | addr = 0x10000000000000000 + addr |
| 118 | |
| 119 | size = self.PAGE_SIZE[self.size] |
| 120 | s += '%4s 0x%016x 0x%016x 0x%02x' % (size,tag,addr,self.pid) |
| 121 | s += ctx |
| 122 | |
| 123 | return s |
| 124 | |
| 125 | |
| 126 | class TlbTte: |
| 127 | PAGE_SIZE = ['8K','64K','512K','4M','32M','256M','2G','16G'] |
| 128 | |
| 129 | __getfun__ = { 'xlate': __geterror__('xlate'), 'match': __geterror__('match') } |
| 130 | __setfun__ = {} |
| 131 | |
| 132 | for field in ['valid','real','pid','ctx','size','tag','ie','nfo', |
| 133 | 'x','p','w','e','cv','cp','lock','addr''soft_flds', |
| 134 | 'diag7_3','data','tag']: |
| 135 | __getfun__[field] = __geterror__(field) |
| 136 | __setfun__[field] = __seterror__(field) |
| 137 | |
| 138 | def __init__(self,tlb,index_fun,index_arg): |
| 139 | self.__dict__['__tlb__'] = tlb |
| 140 | self.__dict__['__fun__'] = index_fun |
| 141 | self.__dict__['__arg__'] = index_arg |
| 142 | |
| 143 | def __getattr__(self,name): |
| 144 | if TlbTte.__getfun__.has_key(name): |
| 145 | return TlbTte.__getfun__[name](self.__fun__(self.__arg__)) |
| 146 | else: |
| 147 | raise AttributeError |
| 148 | |
| 149 | def __setattr__(self,name,value): |
| 150 | if TlbTte.__setfun__.has_key(name): |
| 151 | tte = self.__fun__(self.__arg__) |
| 152 | TlbTte.__setfun__[name](tte,value) |
| 153 | if 'flush' in dir(self.__tlb__): |
| 154 | self.__tlb__.flush(tte) |
| 155 | else: |
| 156 | raise AttributeError |
| 157 | |
| 158 | def __repr__(self): |
| 159 | return '<TlbTte instance>' |
| 160 | |
| 161 | def __str__(self): |
| 162 | """ |
| 163 | return a string of the most common looked at fields of the TTE |
| 164 | """ |
| 165 | if not self.valid: |
| 166 | return '-------' |
| 167 | elif self.real: |
| 168 | s = 'r' |
| 169 | ctx = '' |
| 170 | else: |
| 171 | s = 'v' |
| 172 | ctx = ' 0x%04x' % self.ctx |
| 173 | |
| 174 | s += self.p and 'p' or '-' |
| 175 | s += self.x and 'x' or '-' |
| 176 | s += self.w and 'w' or '-' |
| 177 | s += self.e and 'e' or '-' |
| 178 | s += self.nfo and 'n' or '-' |
| 179 | s += self.ie and 'i' or '-' |
| 180 | |
| 181 | tag = self.tag |
| 182 | if tag < 0: |
| 183 | tag = 0x10000000000000000 + tag |
| 184 | addr = self.addr |
| 185 | if addr < 0: |
| 186 | addr = 0x10000000000000000 + addr |
| 187 | |
| 188 | size = self.PAGE_SIZE[self.size] |
| 189 | s += '%4s 0x%016x 0x%016x 0x%02x' % (size,tag,addr,self.pid) |
| 190 | s += ctx |
| 191 | |
| 192 | return s |
| 193 | |
| 194 | |
| 195 | class TlbIter: |
| 196 | def __init__(self,tlb): |
| 197 | self.tlb = tlb |
| 198 | self.idx = 0 |
| 199 | |
| 200 | def __iter__(self): |
| 201 | return self |
| 202 | |
| 203 | def next(self): |
| 204 | index = self.tlb.next_valid_index(self.idx) |
| 205 | if index >= 0: |
| 206 | self.idx = index + 1 |
| 207 | return index |
| 208 | raise StopIteration |
| 209 | |
| 210 | |
| 211 | class Tlb: |
| 212 | def __init__(self,tlb): |
| 213 | self.__dict__['__tlb__'] = tlb |
| 214 | self.__dict__['tte'] = {} |
| 215 | for i in range(0,self.size()): |
| 216 | self.tte[i] = TlbTte(tlb,self.index,i) |
| 217 | |
| 218 | def __len__(self): |
| 219 | n = 0 |
| 220 | i = self.next_valid_index(0) |
| 221 | while i >= 0: |
| 222 | n += 1 |
| 223 | i = self.next_valid_index(i+1) |
| 224 | return n |
| 225 | |
| 226 | def __iter__(self): |
| 227 | return TlbIter(self.__tlb__) |
| 228 | |
| 229 | def __repr__(self): |
| 230 | l = {} |
| 231 | i = self.__tlb__.next_valid_index(0) |
| 232 | while i >= 0: |
| 233 | l[i] = self.tte[i] |
| 234 | i = self.__tlb__.next_valid_index(i+1) |
| 235 | return str(l) |
| 236 | |
| 237 | def __str__(self): |
| 238 | s = '' |
| 239 | i = self.__tlb__.next_valid_index(0) |
| 240 | while i >= 0: |
| 241 | s += '0x%03x: %s\n' % (i,str(self.tte[i])) |
| 242 | i = self.__tlb__.next_valid_index(i+1) |
| 243 | return s |
| 244 | |
| 245 | def __getitem__(self,index): |
| 246 | return self.tte[index] |
| 247 | |
| 248 | def __setitem__(self,index,tte): |
| 249 | if isinstance(tte,Tte): |
| 250 | lhs = self.tte[index] |
| 251 | lhs.valid = tte.valid |
| 252 | lhs.real = tte.real |
| 253 | lhs.ctx = tte.ctx |
| 254 | lhs.pid = tte.pid |
| 255 | lhs.tag = tte.tag |
| 256 | lhs.size = tte.size |
| 257 | lhs.ie = tte.ie |
| 258 | lhs.nfo = tte.nfo |
| 259 | lhs.x = tte.x |
| 260 | lhs.p = tte.p |
| 261 | lhs.w = tte.w |
| 262 | lhs.e = tte.e |
| 263 | lhs.cv = tte.cv |
| 264 | lhs.cp = tte.cp |
| 265 | lhs.lock = tte.lock |
| 266 | lhs.addr = tte.addr |
| 267 | else: |
| 268 | raise TypeError |
| 269 | |
| 270 | # size() returns the fixed size of the TLB in number of TTEs. |
| 271 | |
| 272 | def size(self): |
| 273 | pass |
| 274 | |
| 275 | # index() returns the TTE currently at index i of the TLB. |
| 276 | |
| 277 | def index(self,i): |
| 278 | pass |
| 279 | |
| 280 | # insert() inserts the TTE in the TLB. |
| 281 | |
| 282 | def insert(self,tte): |
| 283 | pass |
| 284 | |
| 285 | # next_valid_index() returns the next valid TTE in the TLB |
| 286 | # starting from i. If none are found the -1 is returned. |
| 287 | |
| 288 | def next_valid_index(self,i): |
| 289 | if 0 <= i: |
| 290 | while i < index.size(): |
| 291 | if self.tte[i].valid: |
| 292 | return i |
| 293 | i += 1 |
| 294 | return -1 |
| 295 | |
| 296 | # return reference to the tte that got inserted |
| 297 | # tag_bits21_13 (0 .. 0x1ff) are the lower 9 bits of the tag |
| 298 | # real is 1 when the tsb needs to be a ra2 pa tte, 0 otherwise |
| 299 | def insert4v(self,pid,tag,data,tag_bits21_13,real): |
| 300 | pass |
| 301 | |
| 302 | def insert4u(self,pid,tag,data,va,real): |
| 303 | pass |
| 304 | |
| 305 | |
| 306 | |
| 307 | |
| 308 | |