| 1 | # ========== Copyright Header Begin ========================================== |
| 2 | # |
| 3 | # OpenSPARC T2 Processor File: Pfe_Strand.py |
| 4 | # Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. |
| 5 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. |
| 6 | # |
| 7 | # The above named program is free software; you can redistribute it and/or |
| 8 | # modify it under the terms of the GNU General Public |
| 9 | # License version 2 as published by the Free Software Foundation. |
| 10 | # |
| 11 | # The above named program is distributed in the hope that it will be |
| 12 | # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 | # General Public License for more details. |
| 15 | # |
| 16 | # You should have received a copy of the GNU General Public |
| 17 | # License along with this work; if not, write to the Free Software |
| 18 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. |
| 19 | # |
| 20 | # ========== Copyright Header End ============================================ |
| 21 | |
| 22 | class GetAttrError(Exception): |
| 23 | def __init__(self,name): |
| 24 | Exception.__init__(self) |
| 25 | self.name = name |
| 26 | def __str__(self): |
| 27 | return "The strand has no getable state member '"+self.name+"'" |
| 28 | |
| 29 | class DelAttrError(Exception): |
| 30 | def __init__(self,name): |
| 31 | Exception.__init__(self) |
| 32 | self.name = name |
| 33 | def __str__(self): |
| 34 | return "Strand attributes such as "+self.name+" can not be deleted" |
| 35 | |
| 36 | class SetAttrError(Exception): |
| 37 | def __init__(self,name): |
| 38 | Exception.__init__(self) |
| 39 | self.name = name |
| 40 | def __str__(self): |
| 41 | return "The strand has no setable state member '"+name+"'" |
| 42 | |
| 43 | class TrapLevelZeroError(Exception): |
| 44 | def __init__(self): |
| 45 | Exception.__init__(self) |
| 46 | def __str__(self): |
| 47 | return "Trap state can not be accessed when tl=0" |
| 48 | |
| 49 | |
| 50 | def __geterror_fun__(name,strand): |
| 51 | raise GetAttrError(name) |
| 52 | def __seterror_fun__(name,strand,value): |
| 53 | raise SetAttrError(name) |
| 54 | |
| 55 | def __geterror__(name): |
| 56 | return lambda strand: __geterror_fun__(name,strand) |
| 57 | def __seterror__(name): |
| 58 | return lambda strand,value: __seterror_fun__(name,strand,value) |
| 59 | |
| 60 | |
| 61 | def __gettl_check__(strand): |
| 62 | tl = Strand.__getfun__['tl'](strand) |
| 63 | if tl == 0: |
| 64 | raise TrapLevelZeroError() |
| 65 | return tl |
| 66 | |
| 67 | def __gettt__(strand): return TrapStack.__getfun__['tt'](strand,__gettl_check__(strand)) |
| 68 | def __settt__(strand,value): TrapStack.__setfun__['tt'](strand,__gettl_check__(strand),value) |
| 69 | def __gettpc__(strand): return TrapStack.__getfun__['tpc'](strand,__gettl_check__(strand)) |
| 70 | def __settpc__(strand,value): TrapStack.__setfun__['tpc'](strand,__gettl_check__(strand),value) |
| 71 | def __gettnpc__(strand): return TrapStack.__getfun__['tnpc'](strand,__gettl_check__(strand)) |
| 72 | def __settnpc__(strand,value): TrapStack.__setfun__['tnpc'](strand,__gettl_check__(strand),value) |
| 73 | def __gettstate__(strand): return TrapStack.__getfun__['tstate'](strand,__gettl_check__(strand)) |
| 74 | def __settstate__(strand,value): TrapStack.__setfun__['tstate'](strand,__gettl_check__(strand),value) |
| 75 | def __gethtstate__(strand): return TrapStack.__getfun__['htstate'](strand,__gettl_check__(strand)) |
| 76 | def __sethtstate__(strand,value): TrapStack.__setfun__['htstate'](strand,__gettl_check__(strand),value) |
| 77 | |
| 78 | |
| 79 | class Strand: |
| 80 | __getfun__= { |
| 81 | 'tt': __gettt__, |
| 82 | 'tpc': __gettpc__, |
| 83 | 'tnpc': __gettnpc__, |
| 84 | 'tstate': __gettstate__, |
| 85 | 'htstate': __gethtstate__ |
| 86 | } |
| 87 | __setfun__ = { |
| 88 | 'tt': __settt__, |
| 89 | 'tpc': __settpc__, |
| 90 | 'tnpc': __settnpc__, |
| 91 | 'tstate': __settstate__, |
| 92 | 'htstate': __sethtstate__ |
| 93 | } |
| 94 | |
| 95 | for i in ['pc', 'npc', 'cwp', 'cansave', 'canrestore', 'otherwin', 'cleanwin', 'wstate', |
| 96 | 'y', 'asi', 'ccr', 'fsr', 'gsr', 'fprs', 'pil', 'softint', |
| 97 | 'tl', 'gl', 'pstate', 'hpstate', 'tba', 'htba', 'hver', 'hintp', |
| 98 | 'tick', 'stick', 'tick_cmpr', 'stick_cmpr', 'hstick_cmpr', 'rstv_addr' |
| 99 | 'max_tl', 'max_gl', 'max_ptl', 'max_pgl','max_wp','strand_id']: |
| 100 | __getfun__[i] = __geterror__(i) |
| 101 | __setfun__[i] = __seterror__(i) |
| 102 | |
| 103 | __irf__ = ['g%d' % i for i in range(0,8)]\ |
| 104 | + ['o%d' % i for i in range(0,8)]\ |
| 105 | + ['l%d' % i for i in range(0,8)]\ |
| 106 | + ['i%d' % i for i in range(0,8)] |
| 107 | __frf__ = ['f%d' % i for i in range(0,64)] |
| 108 | __drf__ = ['d%d' % i for i in range(0,64,2)] |
| 109 | __qrf__ = ['q%d' % i for i in range(0,64,4)] |
| 110 | __asr__ = ['asr%d' % i for i in range(0,32)] |
| 111 | __pr__ = ['pr%d' % i for i in range(0,32)] |
| 112 | __hpr__ = ['hpr%d' % i for i in range(0,32)] |
| 113 | __sim__ = ['sim%d' % i for i in range(0,32)] |
| 114 | |
| 115 | for i in __irf__: |
| 116 | __getfun__[i] = __geterror__(i) |
| 117 | __setfun__[i] = __seterror__(i) |
| 118 | for i in __frf__: |
| 119 | __getfun__[i] = __geterror__(i) |
| 120 | __setfun__[i] = __seterror__(i) |
| 121 | for i in __drf__: |
| 122 | __getfun__[i] = __geterror__(i) |
| 123 | __setfun__[i] = __seterror__(i) |
| 124 | for i in __qrf__: |
| 125 | __getfun__[i] = __geterror__(i) |
| 126 | __setfun__[i] = __seterror__(i) |
| 127 | for i in __asr__: |
| 128 | __getfun__[i] = __geterror__(i) |
| 129 | __setfun__[i] = __seterror__(i) |
| 130 | for i in __pr__: |
| 131 | __getfun__[i] = __geterror__(i) |
| 132 | __setfun__[i] = __seterror__(i) |
| 133 | for i in __hpr__: |
| 134 | __getfun__[i] = __geterror__(i) |
| 135 | __setfun__[i] = __seterror__(i) |
| 136 | for i in __sim__: |
| 137 | __getfun__[i] = __geterror__(i) |
| 138 | __setfun__[i] = __seterror__(i) |
| 139 | |
| 140 | del i |
| 141 | |
| 142 | def __init__(self,strand,ref): |
| 143 | self.__dict__['__strand__'] = strand |
| 144 | self.__dict__['ref'] = ref |
| 145 | self.__dict__['inst_tlb'] = {} |
| 146 | self.__dict__['data_tlb'] = {} |
| 147 | self.__dict__['brk'] = {} |
| 148 | self.__dict__['t'] = TrapStack(strand) |
| 149 | self.__dict__['g'] = GlobalStack(strand) |
| 150 | self.__dict__['w'] = WindowStack(strand) |
| 151 | self.__dict__['__listing__'] = 0 |
| 152 | self.__dict__['__verify__'] = False |
| 153 | self.__dict__['__ras__'] = False |
| 154 | |
| 155 | def __getattr__(self,name): |
| 156 | if Strand.__getfun__.has_key(name): |
| 157 | return Strand.__getfun__[name](self.__strand__) |
| 158 | raise GetAttrError(name) |
| 159 | |
| 160 | def __setattr__(self,name,data): |
| 161 | if Strand.__setfun__.has_key(name): |
| 162 | return Strand.__setfun__[name](self.__strand__,data) |
| 163 | #self.__dict__[name] = data |
| 164 | if self.__dict__.has_key(name): |
| 165 | self.__dict__[name] = data |
| 166 | return |
| 167 | #else: |
| 168 | # print 'Cant set. No strand attribute %s\n' % (name,) |
| 169 | |
| 170 | try: |
| 171 | getattr(self,name) |
| 172 | except GetAttrError: |
| 173 | return 'Cant set. No strand attribute %s\n' % (name,) |
| 174 | else: |
| 175 | self.__dict__[name] = data |
| 176 | |
| 177 | |
| 178 | def __delattr__(self,name): |
| 179 | if name == 'brk': |
| 180 | for i in self.brk: |
| 181 | del self.brk[i] |
| 182 | elif name == 'inst_tlb': |
| 183 | for i in self.inst_tbl: |
| 184 | del self.inst_tlb[i] |
| 185 | elif name == 'data_tlb': |
| 186 | for i in self.data_tbl: |
| 187 | del self.data_tlb[i] |
| 188 | elif name == '__strand__' or name == 't': |
| 189 | DelAttrError(name) |
| 190 | else: |
| 191 | del self.__dict__[name] |
| 192 | |
| 193 | def __repr__(self): |
| 194 | return "<Strand instance>" |
| 195 | |
| 196 | def __str__(self): |
| 197 | return "<Strand instance>" |
| 198 | |
| 199 | #------------------------------------------------------------------------ |
| 200 | # mode switching related interface |
| 201 | #------------------------------------------------------------------------ |
| 202 | |
| 203 | def lstmode(self,lstval = None): |
| 204 | """ |
| 205 | lstmode() switches the strand to listing mode based on the value of lstval |
| 206 | a value of 0 disables the list mode. |
| 207 | a value of 1 enables the list mode where the executed instruction along |
| 208 | with the sideeffects are displayed. |
| 209 | a value of 2 enables the list mode where only the executed instruction |
| 210 | is displayed. |
| 211 | w/o an argument the current listing mode is returned |
| 212 | """ |
| 213 | if lstval == None: |
| 214 | return self.__listing__ |
| 215 | elif type(lstval) != int: |
| 216 | raise TypeError |
| 217 | |
| 218 | self.__listing__ = lstval |
| 219 | |
| 220 | if lstval != 0: |
| 221 | self.step = self.__lststep__ |
| 222 | if lstval == 1: |
| 223 | if self.__dict__.has_key('__lstnames__'): |
| 224 | if self.tl == 0: |
| 225 | for r in self.__lstnames__: |
| 226 | if r in ['tt','tpc','tnpc','tstate','htstate']: |
| 227 | self.__lststate__[r] = None |
| 228 | else: |
| 229 | self.__lststate__[r] = getattr(self,r) |
| 230 | else: |
| 231 | for r in self.__lststate__: |
| 232 | self.__lststate__[r] = getattr(self,r) |
| 233 | else: |
| 234 | self.step = self.__runstep__ |
| 235 | |
| 236 | |
| 237 | def vrfmode(self,on): |
| 238 | """ |
| 239 | vrfmode() switches the strand to verification mode when on=True, e.g turn of optimisations for |
| 240 | run mode. This means that every load/store and instruction fetch goes through the |
| 241 | mmu. |
| 242 | """ |
| 243 | if on == None: |
| 244 | return self.__verify__ |
| 245 | elif type(on) != bool: |
| 246 | raise TypeError |
| 247 | |
| 248 | self.__verify__ = on |
| 249 | |
| 250 | |
| 251 | def rasmode(self,on): |
| 252 | """ |
| 253 | rasmode() switches the strand into ras mode when on=True, expects vrfmode to be on |
| 254 | """ |
| 255 | if on == None: |
| 256 | return self.__ras__ |
| 257 | elif type(on) != bool: |
| 258 | raise TypeError |
| 259 | |
| 260 | self.__ras__ = on |
| 261 | |
| 262 | #------------------------------------------------------------------------ |
| 263 | # translate addresses |
| 264 | #------------------------------------------------------------------------ |
| 265 | |
| 266 | def va2pa(self,va,ctx=None,pid=None): |
| 267 | pass |
| 268 | |
| 269 | def ra2pa(self,ra,pid=None): |
| 270 | pass |
| 271 | |
| 272 | #------------------------------------------------------------------------ |
| 273 | # CMP related interface |
| 274 | #------------------------------------------------------------------------ |
| 275 | |
| 276 | def available(self,on=None): |
| 277 | pass |
| 278 | |
| 279 | def enable(self,on=None): |
| 280 | pass |
| 281 | |
| 282 | def running(self,on=None): |
| 283 | pass |
| 284 | |
| 285 | def stepping(self,on=None): |
| 286 | pass |
| 287 | |
| 288 | #------------------------------------------------------------------------ |
| 289 | # step related interface |
| 290 | #------------------------------------------------------------------------ |
| 291 | |
| 292 | def step(self,n=None): |
| 293 | """ |
| 294 | step() steps the simulator n instructions forward |
| 295 | The method is switched between __runstep__ and __lststep__ by lstmode() |
| 296 | """ |
| 297 | pass |
| 298 | |
| 299 | def __runstep__(self,n=None): |
| 300 | """ |
| 301 | runstep() steps the simulator n instruction without echoing inpstr to output |
| 302 | """ |
| 303 | pass |
| 304 | |
| 305 | def __lststep__(self,n=None): |
| 306 | """ |
| 307 | lststep() steps the simulator n instruction and echo instr to output |
| 308 | """ |
| 309 | pass |
| 310 | |
| 311 | |
| 312 | |
| 313 | class TrapStackEntry: |
| 314 | def __init__(self,strand,tl): |
| 315 | self.__dict__['strand'] = strand |
| 316 | self.__dict__['tl'] = tl |
| 317 | |
| 318 | def __getattr__(self,name): |
| 319 | return TrapStack.__getfun__[name](self.strand,self.tl) |
| 320 | |
| 321 | def __setattr__(self,name,value): |
| 322 | return TrapStack.__setfun__[name](self.strand,self.tl,value) |
| 323 | |
| 324 | |
| 325 | class TrapStack: |
| 326 | MAXTL = 15 |
| 327 | |
| 328 | __getfun__ = {} |
| 329 | __setfun__ = {} |
| 330 | |
| 331 | for field in ['tt','tpc','tnpc','tstate','htstate']: |
| 332 | __getfun__[field] = __geterror__(field) |
| 333 | __setfun__[field] = __seterror__(field) |
| 334 | del field |
| 335 | |
| 336 | def __init__(self,strand): |
| 337 | self.trap_stack = {} |
| 338 | for tl in range(1,TrapStack.MAXTL): |
| 339 | self.trap_stack[tl] = TrapStackEntry(strand,tl) |
| 340 | |
| 341 | def __getitem__(self,index): |
| 342 | if index == 0: |
| 343 | raise TrapLevelZeroError() |
| 344 | return self.trap_stack[index] |
| 345 | |
| 346 | |
| 347 | class GlobalStackEntry: |
| 348 | def __init__(self,strand,gl): |
| 349 | self.__dict__['strand'] = strand |
| 350 | self.__dict__['gl'] = gl |
| 351 | |
| 352 | def __getattr__(self,name): |
| 353 | return GlobalStack.__getfun__[name](self.strand,self.gl) |
| 354 | |
| 355 | def __setattr__(self,name,value): |
| 356 | return GlobalStack.__setfun__[name](self.strand,self.gl,value) |
| 357 | |
| 358 | def __getitem__(self,index): |
| 359 | return GlobalStack.__getfun__[index](self.strand,self.gl) |
| 360 | |
| 361 | def setitem__(self,index,value): |
| 362 | return GlobalStack.__setfun__[index](self.strand,self.gl,value) |
| 363 | |
| 364 | class GlobalStack: |
| 365 | MAXGL=15 |
| 366 | |
| 367 | __getfun__ = {} |
| 368 | __setfun__ = {} |
| 369 | |
| 370 | for r in ['g%d' % i for i in range(0,8)]: |
| 371 | __getfun__[r] = __geterror__(r) |
| 372 | __setfun__[r] = __seterror__(r) |
| 373 | |
| 374 | def __init__(self,strand): |
| 375 | self.global_stack = {} |
| 376 | for gl in range(0,GlobalStack.MAXGL + 1): |
| 377 | self.global_stack[gl] = GlobalStackEntry(strand,gl) |
| 378 | |
| 379 | def __getitem__(self,index): |
| 380 | return self.global_stack[index] |
| 381 | |
| 382 | class WindowRegEntry: |
| 383 | def __init__(self,strand,win): |
| 384 | self.__dict__['strand'] = strand |
| 385 | self.__dict__['win'] = win |
| 386 | |
| 387 | def __getattr__(self,name): |
| 388 | return WindowStack.__getfun__[name](self.strand,self.win) |
| 389 | |
| 390 | def __setattr__(self,name,value): |
| 391 | return WindowStack.__setfun__[name](self.strand,self.win,value) |
| 392 | |
| 393 | def __getitem__(self,index): |
| 394 | return WindowStack.__getfun__[index](self.strand,self.win) |
| 395 | |
| 396 | def __setitem__(self,index,value): |
| 397 | return WindowStack.__setfun__[index](self.strand,self.win,value) |
| 398 | |
| 399 | |
| 400 | class WindowStack: |
| 401 | MAXWP = 32 |
| 402 | |
| 403 | __getfun__ = {} |
| 404 | __setfun__ = {} |
| 405 | |
| 406 | for r in Strand.__irf__[8:]: |
| 407 | __getfun__[r] = __geterror__(r) |
| 408 | __setfun__[r] = __seterror__(r) |
| 409 | |
| 410 | def __init__(self,strand): |
| 411 | self.window_stack = {} |
| 412 | for win in range(0,WindowStack.MAXWP): |
| 413 | self.window_stack[win] = WindowRegEntry(strand,win) |
| 414 | |
| 415 | def __getitem__(self,index): |
| 416 | return self.window_stack[index] |
| 417 | |
| 418 | |
| 419 | |
| 420 | |
| 421 | |
| 422 | |
| 423 | |
| 424 | |
| 425 | |
| 426 | |
| 427 | |
| 428 | |
| 429 | |
| 430 | |