| 1 | # ========== Copyright Header Begin ========================================== |
| 2 | # |
| 3 | # OpenSPARC T2 Processor File: RegisterMap.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 | """map ni-simics register name to riesling counterpart |
| 22 | """ |
| 23 | |
| 24 | """ |
| 25 | A reg is an integer register name. It can have any of the following values: |
| 26 | %r0-%r31 |
| 27 | %g0-%g7 (global registers; same as %r0-%r7) |
| 28 | %o0-%o7 (out registers; same as %r8-%r15) |
| 29 | %l0-%l7 (local registers; same as %r16-%r23) |
| 30 | %i0-%i7 (in registers; same as %r24-%r31) |
| 31 | %fp (frame pointer; conventionally same as %i6) |
| 32 | %sp (stack pointer; conventionally same as %o6) |
| 33 | """ |
| 34 | |
| 35 | LEVEL_SYS = 0 |
| 36 | LEVEL_CPU = 1 |
| 37 | LEVEL_CORE = 2 |
| 38 | LEVEL_UCORE = 3 |
| 39 | LEVEL_STRAND = 4 |
| 40 | |
| 41 | class RegisterMap: |
| 42 | """ |
| 43 | """ |
| 44 | |
| 45 | def __init__ (self,arch): |
| 46 | """ |
| 47 | """ |
| 48 | # maintain a mapping between register names used by this |
| 49 | # front end, and the common lower level layer name. |
| 50 | |
| 51 | self.regMap = { } |
| 52 | self.regMapArch = {} |
| 53 | self.regMapAsi = {} |
| 54 | |
| 55 | self.__regMapN2__ = {} |
| 56 | |
| 57 | self.regMap['g0'] = ['g0',0] |
| 58 | self.regMap['g1'] = ['g1',1] |
| 59 | self.regMap['g2'] = ['g2',2] |
| 60 | self.regMap['g3'] = ['g3',3] |
| 61 | self.regMap['g4'] = ['g4',4] |
| 62 | self.regMap['g5'] = ['g5',5] |
| 63 | self.regMap['g6'] = ['g6',6] |
| 64 | self.regMap['g7'] = ['g7',7] |
| 65 | self.regMap['o0'] = ['o0',8] |
| 66 | self.regMap['o1'] = ['o1',9] |
| 67 | self.regMap['o2'] = ['o2',10] |
| 68 | self.regMap['o3'] = ['o3',11] |
| 69 | self.regMap['o4'] = ['o4',12] |
| 70 | self.regMap['o5'] = ['o5',13] |
| 71 | self.regMap['o6'] = ['o6',14] |
| 72 | self.regMap['o7'] = ['o7',15] |
| 73 | self.regMap['l0'] = ['l0',16] |
| 74 | self.regMap['l1'] = ['l1',17] |
| 75 | self.regMap['l2'] = ['l2',18] |
| 76 | self.regMap['l3'] = ['l3',19] |
| 77 | self.regMap['l4'] = ['l4',20] |
| 78 | self.regMap['l5'] = ['l5',21] |
| 79 | self.regMap['l6'] = ['l6',22] |
| 80 | self.regMap['l7'] = ['l7',23] |
| 81 | self.regMap['i0'] = ['i0',24] |
| 82 | self.regMap['i1'] = ['i1',25] |
| 83 | self.regMap['i2'] = ['i2',26] |
| 84 | self.regMap['i3'] = ['i3',27] |
| 85 | self.regMap['i4'] = ['i4',28] |
| 86 | self.regMap['i5'] = ['i5',29] |
| 87 | self.regMap['i6'] = ['i6',30] |
| 88 | self.regMap['i7'] = ['i7',31] |
| 89 | self.regMap['pc'] = ['pc',32] |
| 90 | self.regMap['npc'] = ['npc',33] |
| 91 | self.regMap['y'] = ['y',34] |
| 92 | self.regMap['ccr'] = ['ccr',35] |
| 93 | self.regMap['fprs'] = ['fprs',36] |
| 94 | self.regMap['fsr'] = ['fsr',37] |
| 95 | self.regMap['asi'] = ['asi',38] |
| 96 | self.regMap['tick'] = ['tick',39] |
| 97 | self.regMap['gsr'] = ['gsr',40] |
| 98 | self.regMap['tick_cmpr'] = ['tick_cmpr',41] |
| 99 | # in Ni/N2 stick is an alias of tick, but archState has separate |
| 100 | # variable for each. N2_InstrEmu has stick_ = tick_ so change to |
| 101 | # either one will actually change ONLY tick, stick remains 0 always. |
| 102 | #self.regMap['stick'] = (42,LEVEL_STRAND,) |
| 103 | self.regMap['stick'] = ['stick',42] |
| 104 | self.regMap['stick_cmpr'] = ['stick_cmpr',43] |
| 105 | self.regMap['pstate'] = ['pstate',44] |
| 106 | self.regMap['tl'] = ['tl',45] |
| 107 | self.regMap['pil'] = ['pil',46] |
| 108 | self.regMap['tpc1'] = ['t[1].tpc',47] |
| 109 | self.regMap['tpc2'] = ['t[2].tpc',48] |
| 110 | self.regMap['tpc3'] = ['t[3].tpc',49] |
| 111 | self.regMap['tpc4'] = ['t[4].tpc',50] |
| 112 | self.regMap['tpc5'] = ['t[5].tpc',51] |
| 113 | # self.regMap['tpc6'] = ['t[6].tpc',52] |
| 114 | self.regMap['tnpc1'] = ['t[1].tnpc',57] |
| 115 | self.regMap['tnpc2'] = ['t[2].tnpc',58] |
| 116 | self.regMap['tnpc3'] = ['t[3].tnpc',59] |
| 117 | self.regMap['tnpc4'] = ['t[4].tnpc',60] |
| 118 | self.regMap['tnpc5'] = ['t[5].tnpc',61] |
| 119 | self.regMap['tstate1'] = ['t[1].tstate',67] |
| 120 | self.regMap['tstate2'] = ['t[2].tstate',68] |
| 121 | self.regMap['tstate3'] = ['t[3].tstate',69] |
| 122 | self.regMap['tstate4'] = ['t[4].tstate',70] |
| 123 | self.regMap['tstate5'] = ['t[5].tstate',71] |
| 124 | self.regMap['tt1'] = ['t[1].tt',77] |
| 125 | self.regMap['tt2'] = ['t[2].tt',78] |
| 126 | self.regMap['tt3'] = ['t[3].tt',79] |
| 127 | self.regMap['tt4'] = ['t[4].tt',80] |
| 128 | self.regMap['tt5'] = ['t[5].tt',81] |
| 129 | # self.regMap['tt6'] = ['t[6].tt',82] |
| 130 | self.regMap['tba'] = ['tba',87] |
| 131 | self.regMap['ver'] = ['hver',88] |
| 132 | self.regMap['cwp'] = ['cwp',89] |
| 133 | self.regMap['cansave'] = ['cansave',90] |
| 134 | self.regMap['canrestore'] = ['canrestore',91] |
| 135 | self.regMap['otherwin'] = ['otherwin',92] |
| 136 | self.regMap['wstate'] = ['wstate',93] |
| 137 | self.regMap['cleanwin'] = ['cleanwin',94] |
| 138 | self.regMap['softint'] = ['softint',95] |
| 139 | self.regMap['gl'] = ['gl',107] |
| 140 | self.regMap['hpstate'] = ['hpstate',108] |
| 141 | self.regMap['htstate1'] = ['t[1].htstate',109] |
| 142 | self.regMap['htstate2'] = ['t[2].htstate',110] |
| 143 | self.regMap['htstate3'] = ['t[3].htstate',111] |
| 144 | self.regMap['htstate4'] = ['t[4].htstate',112] |
| 145 | self.regMap['htstate5'] = ['t[5].htstate',113] |
| 146 | self.regMap['htba'] = ['htba',119] |
| 147 | self.regMap['hintp'] = ['hintp',120] |
| 148 | self.regMap['hstick_cmpr'] = ['hstick_cmpr',121] |
| 149 | self.regMap['fp'] = ['i6',30] |
| 150 | self.regMap['sp'] = ['o6',14] |
| 151 | |
| 152 | # these seem to be N2 specific regs. |
| 153 | # support is absent in the back end. |
| 154 | self.__regMapN2__['ecache_error_enable'] = ['',96] |
| 155 | self.__regMapN2__['asynchronous_fault_status'] = ['',97] |
| 156 | self.__regMapN2__['asynchronous_fault_address'] = ['',99] |
| 157 | self.__regMapN2__['out_intr_data0'] = ['',99] |
| 158 | self.__regMapN2__['out_intr_data1'] = ['',100] |
| 159 | self.__regMapN2__['out_intr_data2'] = ['',101] |
| 160 | self.__regMapN2__['intr_dispatch_status'] = ['',102] |
| 161 | self.__regMapN2__['in_intr_data0'] = ['',103] |
| 162 | self.__regMapN2__['in_intr_data1'] = ['',104] |
| 163 | self.__regMapN2__['in_intr_data2'] = ['',105] |
| 164 | self.__regMapN2__['intr_receive'] = ['',106] |
| 165 | self.__regMapN2__['tpc6'] = ['t[6].tpc',52] |
| 166 | self.__regMapN2__['tnpc6'] = ['t[6].tnpc',62] |
| 167 | self.__regMapN2__['tstate6'] = ['t[6].tstate',72] |
| 168 | self.__regMapN2__['tt6'] = ['t[6].tt',82] |
| 169 | self.__regMapN2__['htstate6'] = ['t[6].htstate',114] |
| 170 | |
| 171 | |
| 172 | # asi related registers. All the cmp and mmu related registers |
| 173 | # start wil CMP_ & MMU_ respectively. Maintain the same convention |
| 174 | # if/when adding new registers. |
| 175 | # format dir[regname] = [asi,va] |
| 176 | self.__asiRegMapN2__ = {} |
| 177 | ##################################################### |
| 178 | N2_ASI_CMP = 0x41 |
| 179 | N2_ASI_CMP_CORE_ID = 0x63 |
| 180 | N2_ASI_CMP_CORE_INTR_ID = 0x63 |
| 181 | N2_ASI_SCRATCHPAD = 0x20 |
| 182 | N2_ASI_INTR_RECEIVE = 0x72 |
| 183 | N2_ASI_INTR_W = 0x73 |
| 184 | N2_ASI_INTR_R = 0x74 |
| 185 | |
| 186 | self.__asiRegMapN2__['CMP_core_available'] = [N2_ASI_CMP,0x0] |
| 187 | self.__asiRegMapN2__['CMP_core_enable_status'] = [N2_ASI_CMP,0x10] |
| 188 | self.__asiRegMapN2__['CMP_core_enable'] = [N2_ASI_CMP,0x20] |
| 189 | self.__asiRegMapN2__['CMP_xir_steering'] = [N2_ASI_CMP,0x30] |
| 190 | self.__asiRegMapN2__['CMP_tick_enable'] = [N2_ASI_CMP,0x38] |
| 191 | self.__asiRegMapN2__['CMP_running'] = [N2_ASI_CMP,0x50] |
| 192 | self.__asiRegMapN2__['CMP_running_status'] = [N2_ASI_CMP,0x58] |
| 193 | self.__asiRegMapN2__['CMP_core_id'] = [N2_ASI_CMP_CORE_ID,0x0] |
| 194 | self.__asiRegMapN2__['CMP_core_intr_id'] = [N2_ASI_CMP_CORE_INTR_ID,0x10] |
| 195 | self.__asiRegMapN2__['scratch-pad0'] = [N2_ASI_SCRATCHPAD,0x0] |
| 196 | self.__asiRegMapN2__['scratch-pad1'] = [N2_ASI_SCRATCHPAD,0x10] |
| 197 | self.__asiRegMapN2__['scratch-pad2'] = [N2_ASI_SCRATCHPAD,0x18] |
| 198 | self.__asiRegMapN2__['scratch-pad3'] = [N2_ASI_SCRATCHPAD,0x20] |
| 199 | self.__asiRegMapN2__['scratch-pad4'] = [N2_ASI_SCRATCHPAD,0x30] |
| 200 | self.__asiRegMapN2__['intr_recv_reg'] = [N2_ASI_INTR_RECEIVE,0x0] |
| 201 | self.__asiRegMapN2__['intr_incoming_reg'] = [N2_ASI_INTR_R,0x0] |
| 202 | self.__asiRegMapN2__['MMU_ID_PRIMARY_CTXT_REG_0'] = [0x21,0x8] |
| 203 | self.__asiRegMapN2__['MMU_D_SCNDRY_CTXT_REG_0'] = [0x21,0x10] |
| 204 | self.__asiRegMapN2__['MMU_ID_PRIMARY_CTXT_REG_1'] = [0x21,0x108] |
| 205 | self.__asiRegMapN2__['MMU_D_SCNDRY_CTXT_REG_1'] = [0x21,0x110] |
| 206 | self.__asiRegMapN2__['MMU_LSU_CONTROL'] = [0x45,0x0] |
| 207 | self.__asiRegMapN2__['MMU_ITSB_TAG_TARGET'] = [0x50,0x0] |
| 208 | self.__asiRegMapN2__['MMU_ISFSR'] = [0x50,0x18] |
| 209 | self.__asiRegMapN2__['MMU_ITLB_TAG_ACCESS'] = [0x50,0x30] |
| 210 | self.__asiRegMapN2__['MMU_IMMU_VA_WATCHPOINT'] = [0x50,0x38] |
| 211 | self.__asiRegMapN2__['MMU_MRA_ACCESS'] = [0x51,0x0] |
| 212 | self.__asiRegMapN2__['MMU_REAL_RANGE_0'] = [0x52,0x108] |
| 213 | self.__asiRegMapN2__['MMU_REAL_RANGE_1'] = [0x52,0x110] |
| 214 | self.__asiRegMapN2__['MMU_REAL_RANGE_2'] = [0x52,0x118] |
| 215 | self.__asiRegMapN2__['MMU_REAL_RANGE_3'] = [0x52,0x120] |
| 216 | self.__asiRegMapN2__['MMU_PHYSICAL_OFFSET_0'] = [0x52,0x208] |
| 217 | self.__asiRegMapN2__['MMU_PHYSICAL_OFFSET_1'] = [0x52,0x210] |
| 218 | self.__asiRegMapN2__['MMU_PHYSICAL_OFFSET_2'] = [0x52,0x218] |
| 219 | self.__asiRegMapN2__['MMU_PHYSICAL_OFFSET_3'] = [0x52,0x220] |
| 220 | self.__asiRegMapN2__['MMU_ZERO_CONTEXT_TSB_CONFIG_0'] = [0x54,0x10] |
| 221 | self.__asiRegMapN2__['MMU_ZERO_CONTEXT_TSB_CONFIG_1'] = [0x54,0x18] |
| 222 | self.__asiRegMapN2__['MMU_ZERO_CONTEXT_TSB_CONFIG_2'] = [0x54,0x20] |
| 223 | self.__asiRegMapN2__['MMU_ZERO_CONTEXT_TSB_CONFIG_3'] = [0x54,0x28] |
| 224 | self.__asiRegMapN2__['MMU_NONZERO_CONTEXT_TSB_CONFIG_0'] = [0x54,0x30] |
| 225 | self.__asiRegMapN2__['MMU_NONZERO_CONTEXT_TSB_CONFIG_1'] = [0x54,0x38] |
| 226 | self.__asiRegMapN2__['MMU_NONZERO_CONTEXT_TSB_CONFIG_2'] = [0x54,0x40] |
| 227 | self.__asiRegMapN2__['MMU_NONZERO_CONTEXT_TSB_CONFIG_3'] = [0x54,0x48] |
| 228 | self.__asiRegMapN2__['MMU_ITSB_PTR_0'] = [0x54,0x50] |
| 229 | self.__asiRegMapN2__['MMU_ITSB_PTR_1'] = [0x54,0x58] |
| 230 | self.__asiRegMapN2__['MMU_ITSB_PTR_2'] = [0x54,0x60] |
| 231 | self.__asiRegMapN2__['MMU_ITSB_PTR_3'] = [0x54,0x68] |
| 232 | self.__asiRegMapN2__['MMU_DTSB_PTR_0'] = [0x54,0x70] |
| 233 | self.__asiRegMapN2__['MMU_DTSB_PTR_1'] = [0x54,0x78] |
| 234 | self.__asiRegMapN2__['MMU_DTSB_PTR_2'] = [0x54,0x80] |
| 235 | self.__asiRegMapN2__['MMU_DTSB_PTR_3'] = [0x54,0x88] |
| 236 | self.__asiRegMapN2__['MMU_PENDING_TABLEWALK_CONTROL'] = [0x54,0x90] |
| 237 | self.__asiRegMapN2__['MMU_PENDING_TABLEWALK_STATUS'] = [0x54,0x98] |
| 238 | for i in range(0x0,0x200,0x8): |
| 239 | self.__asiRegMapN2__['MMU_ITLB_DATA_ACCESS_REG_%X' % (i,)] = [0x55,i] |
| 240 | for i in range(0x0,0x200,0x8): |
| 241 | self.__asiRegMapN2__['MMU_ITLB_TAG_READ_REG_%X' % (i,)] = [0x56,i] |
| 242 | self.__asiRegMapN2__['MMU_DTSB_TAG_TARGET'] = [0x58,0x0] |
| 243 | self.__asiRegMapN2__['MMU_DSFSR'] = [0x58,0x18] |
| 244 | self.__asiRegMapN2__['MMU_DSFAR'] = [0x58,0x20] |
| 245 | self.__asiRegMapN2__['MMU_DTLB_TAG_ACCESS'] = [0x58,0x30] |
| 246 | self.__asiRegMapN2__['MMU_DMMU_WATCHPOINT'] = [0x58,0x38] |
| 247 | self.__asiRegMapN2__['MMU_HWTW_CONFIG'] = [0x58,0x40] |
| 248 | self.__asiRegMapN2__['MMU_PARTITION_ID'] = [0x58,0x80] |
| 249 | for i in range(0x0,0x800,0x8): |
| 250 | self.__asiRegMapN2__['MMU_DTLB_DATA_ACCESS_REG_%X' % (i,)] = [0x5d,i] |
| 251 | for i in range(0x0,0x800,0x8): |
| 252 | self.__asiRegMapN2__['MMU_DTLB_TAG_READ_REG_%X' % (i,)] = [0x5e,i] |
| 253 | ##################################################### |
| 254 | |
| 255 | # assign to regMapArch and asiRegMap based upon the |
| 256 | # architecture being simulated |
| 257 | if arch == 'n2': |
| 258 | self.regMapArch = self.__regMapN2__ |
| 259 | self.asiRegMap = self.__asiRegMapN2__ |
| 260 | |
| 261 | |
| 262 | def key2id(self,key): |
| 263 | if self.regMap.has_key(key): |
| 264 | return self.regMap[key][1] |
| 265 | elif self.regMapArch.has_key(key): |
| 266 | return self.regMapArch[key][1] |
| 267 | else: |
| 268 | return -1 |
| 269 | |
| 270 | def id2key(self,id): |
| 271 | """ return the Back end name for register id |
| 272 | """ |
| 273 | for reg in self.regMap.keys(): |
| 274 | if self.regMap[reg][1] == id: |
| 275 | return self.regMap[reg][0] |
| 276 | |
| 277 | for reg in self.regMapArch.keys(): |
| 278 | if self.regMapArch[reg][1] == id: |
| 279 | return self.regMapArch[reg][0] |
| 280 | |
| 281 | return '' |
| 282 | |
| 283 | |
| 284 | def hasReg(self, name): |
| 285 | if self.regMap.has_key(name): |
| 286 | return True |
| 287 | elif self.regMapArch.has_key(name): |
| 288 | return True |
| 289 | else: |
| 290 | return False |
| 291 | |
| 292 | |
| 293 | def feName2beName(self,feName): |
| 294 | if self.regMap.has_key(feName): |
| 295 | return self.regMap[feName][0] |
| 296 | elif self.regMapArch.has_key(feName): |
| 297 | return self.regMapArch[feName][0] |
| 298 | else: |
| 299 | return '' |
| 300 | |