00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00087 #define DO_HW_MFPR if((function & 0xc0) == 0x40) \
00088 { \
00089 state.r[REG_1] = ((u64) state.asn << 39) | ((u64) state.astrr << 9) | \
00090 ((u64) state.aster << 5) | (state.fpen ? U64(0x1) << 2 : 0) | \
00091 (state.ppcen ? U64(0x1) << 1 : 0); \
00092 } \
00093 else \
00094 { \
00095 switch(function) \
00096 { \
00097 case 0x05: \
00098 state.r[REG_1] = state.pmpc; \
00099 break; \
00100 \
00101 case 0x06: \
00102 state.r[REG_1] = state.exc_addr; \
00103 break; \
00104 \
00105 case 0x07: \
00106 state.r[REG_1] = va_form(state.exc_addr, true); \
00107 break; \
00108 \
00109 case 0x08: \
00110 case 0x09: \
00111 case 0x0a: \
00112 case 0x0b: \
00113 state.r[REG_1] = (((u64) state.eien) << 33) | (((u64) state.slen) << 32) | \
00114 (((u64) state.cren) << 31) | (((u64) state.pcen) << 29) | \
00115 (((u64) state.sien) << 13) | (((u64) state.asten) << 13) | \
00116 (((u64) state.cm) << 3); \
00117 break; \
00118 \
00119 case 0x0c: \
00120 state.r[REG_1] = ((u64) state.sir) << 13; \
00121 break; \
00122 \
00123 case 0x0d: \
00124 state.r[REG_1] = (((u64) (state.eir & state.eien)) << 33) | \
00125 (((u64) (state.slr & state.slen)) << 32) | \
00126 (((u64) (state.crr & state.cren)) << 31) | \
00127 (((u64) (state.pcr & state.pcen)) << 29) | \
00128 (((u64) (state.sir & state.sien)) << 13) | \
00129 ( \
00130 ( \
00131 (u64) \
00132 (((U64(0x1) << (state.cm + 1)) - 1) & state.aster & state.astrr & (state.asten * 0x3)) \
00133 ) << 3 \
00134 ) | \
00135 ( \
00136 ( \
00137 (u64) \
00138 (((U64(0x1) << (state.cm + 1)) - 1) & state.aster & state.astrr & (state.asten * 0xc)) \
00139 ) << 7 \
00140 ); \
00141 break; \
00142 \
00143 case 0x0f: \
00144 state.r[REG_1] = state.exc_sum; \
00145 break; \
00146 \
00147 case 0x10: \
00148 state.r[REG_1] = state.pal_base; \
00149 break; \
00150 \
00151 case 0x11: \
00152 state.r[REG_1] = state.i_ctl_other | \
00153 (((u64) CPU_CHIP_ID) << 24) | \
00154 (u64) state.i_ctl_vptb | \
00155 (((u64) state.i_ctl_va_mode) << 15) | \
00156 (state.hwe ? U64(0x1) << 12 : 0) | \
00157 (state.sde ? U64(0x1) << 7 : 0) | \
00158 (((u64) state.i_ctl_spe) << 3); \
00159 break; \
00160 \
00161 case 0x14: \
00162 state.r[REG_1] = state.pctr_ctl; \
00163 break; \
00164 \
00165 case 0x16: \
00166 state.r[REG_1] = state.i_stat; \
00167 break; \
00168 \
00169 case 0x27: \
00170 state.r[REG_1] = state.mm_stat; \
00171 break; \
00172 \
00173 case 0x2a: \
00174 state.r[REG_1] = state.dc_stat; \
00175 break; \
00176 \
00177 case 0x2b: \
00178 state.r[REG_1] = 0; \
00179 break; \
00180 \
00181 case 0xc0: \
00182 state.r[REG_1] = (((u64) state.cc_offset) << 32) | (state.cc & U64(0xffffffff)); \
00183 break; \
00184 \
00185 case 0xc2: \
00186 state.r[REG_1] = state.fault_va; \
00187 break; \
00188 \
00189 case 0xc3: \
00190 state.r[REG_1] = va_form(state.fault_va, false); \
00191 break; \
00192 \
00193 default: \
00194 UNKNOWN2; \
00195 } \
00196 }
00197
00198 #define DO_HW_MTPR if((function & 0xc0) == 0x40) \
00199 { \
00200 if(function & 1) \
00201 state.asn = (int) (state.r[REG_2] >> 39) & 0xff; \
00202 if(function & 2) \
00203 { \
00204 state.aster = (int) (state.r[REG_2] >> 5) & 0xf; \
00205 state.check_int = true; \
00206 } \
00207 if(function & 4) \
00208 { \
00209 state.astrr = (int) (state.r[REG_2] >> 9) & 0xf; \
00210 state.check_int = true; \
00211 } \
00212 if(function & 8) \
00213 state.ppcen = (int) (state.r[REG_2] >> 1) & 1; \
00214 if(function & 16) \
00215 state.fpen = (int) (state.r[REG_2] >> 2) & 1; \
00216 } \
00217 else \
00218 { \
00219 switch(function) \
00220 { \
00221 case 0x00: \
00222 state.last_tb_virt = state.r[REG_2]; \
00223 break; \
00224 \
00225 case 0x01: \
00226 add_tb_i(state.last_tb_virt, state.r[REG_2]); \
00227 break; \
00228 \
00229 case 0x02: \
00230 tbiap(ACCESS_EXEC); \
00231 break; \
00232 \
00233 case 0x03: \
00234 tbia(ACCESS_EXEC); \
00235 break; \
00236 \
00237 case 0x04: \
00238 tbis(state.r[REG_2], ACCESS_EXEC); \
00239 break; \
00240 \
00241 case 0x09: \
00242 state.cm = (int) (state.r[REG_2] >> 3) & 3; \
00243 state.check_int = true; \
00244 break; \
00245 \
00246 case 0x0b: \
00247 state.cm = (int) (state.r[REG_2] >> 3) & 3; \
00248 state.check_int = true; \
00249 \
00250 case 0x0a: \
00251 state.asten = (int) (state.r[REG_2] >> 13) & 1; \
00252 state.sien = (int) (state.r[REG_2] >> 13) & 0xfffe; \
00253 state.pcen = (int) (state.r[REG_2] >> 29) & 3; \
00254 state.cren = (int) (state.r[REG_2] >> 31) & 1; \
00255 state.slen = (int) (state.r[REG_2] >> 32) & 1; \
00256 state.eien = (int) (state.r[REG_2] >> 33) & 0x3f; \
00257 state.check_int = true; \
00258 break; \
00259 \
00260 case 0x0c: \
00261 state.sir = (int) (state.r[REG_2] >> 13) & 0xfffe; \
00262 state.check_int = true; \
00263 break; \
00264 \
00265 case 0x0e: \
00266 state.pcr &= ~((state.r[REG_2] >> 29) & U64(0x3)); \
00267 state.crr &= ~((state.r[REG_2] >> 31) & U64(0x1)); \
00268 state.slr &= ~((state.r[REG_2] >> 32) & U64(0x1)); \
00269 break; \
00270 \
00271 case 0x10: \
00272 set_PAL_BASE(state.r[REG_2] & U64(0x00000fffffff8000)); \
00273 break; \
00274 \
00275 case 0x11: \
00276 state.i_ctl_other = state.r[REG_2] & U64(0x00000000007e2f67); \
00277 state.i_ctl_vptb = sext_u64_48(state.r[REG_2] & U64(0x0000ffffc0000000)); \
00278 state.i_ctl_spe = (int) (state.r[REG_2] >> 3) & 3; \
00279 state.sde = (state.r[REG_2] >> 7) & 1; \
00280 state.hwe = (state.r[REG_2] >> 12) & 1; \
00281 state.i_ctl_va_mode = (int) (state.r[REG_2] >> 15) & 3; \
00282 break; \
00283 \
00284 case 0x12: \
00285 flush_icache_asm(); \
00286 break; \
00287 \
00288 case 0x13: \
00289 flush_icache(); \
00290 break; \
00291 \
00292 case 0x14: \
00293 state.pctr_ctl = state.r[REG_2] & U64(0xffffffffffffffdf); \
00294 break; \
00295 \
00296 case 0x15: \
00297 case 0x17: \
00298 case 0x27: \
00299 case 0x2b: \
00300 case 0x2c: \
00301 case 0x2d: \
00302 break; \
00303 \
00304 case 0x16: \
00305 state.i_stat &= ~state.r[REG_2]; \
00306 break; \
00307 \
00308 case 0x20: \
00309 state.last_tb_virt = state.r[REG_2]; \
00310 break; \
00311 \
00312 case 0x21: \
00313 add_tb_d(state.last_tb_virt, state.r[REG_2]); \
00314 break; \
00315 \
00316 case 0x24: \
00317 tbis(state.r[REG_2], ACCESS_READ); \
00318 break; \
00319 \
00320 case 0x25: \
00321 state.asn0 = (int) (state.r[REG_2] >> 56); \
00322 break; \
00323 \
00324 case 0x26: \
00325 state.alt_cm = (int) (state.r[REG_2] & 3); \
00326 break; \
00327 \
00328 case 0x28: \
00329 state.smc = (int) (state.r[REG_2] >> 4) & 3; \
00330 state.m_ctl_spe = (int) (state.r[REG_2] >> 1) & 7; \
00331 break; \
00332 \
00333 case 0x29: \
00334 state.dc_ctl = state.r[REG_2]; \
00335 break; \
00336 \
00337 case 0x2a: \
00338 state.dc_stat &= ~state.r[REG_2]; \
00339 break; \
00340 \
00341 case 0xa0: \
00342 state.last_tb_virt = state.r[REG_2]; \
00343 break; \
00344 \
00345 case 0xa1: \
00346 add_tb_d(state.last_tb_virt, state.r[REG_2]); \
00347 break; \
00348 \
00349 case 0xa2: \
00350 tbiap(ACCESS_READ); \
00351 break; \
00352 \
00353 case 0xa3: \
00354 tbia(ACCESS_READ); \
00355 break; \
00356 \
00357 case 0xa4: \
00358 tbis(state.r[REG_2], ACCESS_READ); \
00359 break; \
00360 \
00361 case 0xa5: \
00362 state.asn1 = (int) (state.r[REG_2] >> 56); \
00363 break; \
00364 \
00365 case 0xc0: \
00366 state.cc_offset = (u32) (state.r[REG_2] >> 32); \
00367 break; \
00368 \
00369 case 0xc1: \
00370 state.cc_ena = (state.r[REG_2] >> 32) & 1; \
00371 state.cc = (u32) (state.r[REG_2] & U64(0xfffffff0)); \
00372 break; \
00373 \
00374 case 0xc4: \
00375 state.va_ctl_vptb = sext_u64_48(state.r[REG_2] & U64(0x0000ffffc0000000)); \
00376 state.va_ctl_va_mode = (int) (state.r[REG_2] >> 1) & 3; \
00377 break; \
00378 \
00379 default: \
00380 UNKNOWN2; \
00381 } \
00382 }
00383
00384 #define DO_HW_RET set_pc(state.r[REG_2])
00385 #define DO_HW_LDL switch(function) \
00386 { \
00387 case 0: \
00388 phys_address = state.r[REG_2] + DISP_12; \
00389 state.r[REG_1] = READ_PHYS_NT(32); \
00390 break; \
00391 \
00392 case 2: \
00393 phys_address = state.r[REG_2] + DISP_12; \
00394 cSystem->cpu_lock(state.iProcNum, phys_address); \
00395 state.r[REG_1] = READ_PHYS_NT(32); \
00396 break; \
00397 \
00398 case 4: \
00399 DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | NO_CHECK | VPTE); \
00400 state.r[REG_1] = READ_PHYS_NT(32); \
00401 break; \
00402 \
00403 case 8: \
00404 DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | NO_CHECK); \
00405 state.r[REG_1] = READ_PHYS_NT(32); \
00406 break; \
00407 \
00408 case 10: \
00409 DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ); \
00410 state.r[REG_1] = READ_PHYS_NT(32); \
00411 break; \
00412 \
00413 case 12: \
00414 DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | NO_CHECK | ALT); \
00415 state.r[REG_1] = READ_PHYS_NT(32); \
00416 break; \
00417 \
00418 case 14: \
00419 DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | ALT); \
00420 state.r[REG_1] = READ_PHYS_NT(32); \
00421 break; \
00422 \
00423 default: \
00424 UNKNOWN2; \
00425 }
00426
00427 #define DO_HW_LDQ switch(function) \
00428 { \
00429 case 1: \
00430 phys_address = state.r[REG_2] + DISP_12; \
00431 state.r[REG_1] = READ_PHYS_NT(64); \
00432 break; \
00433 \
00434 case 3: \
00435 phys_address = state.r[REG_2] + DISP_12; \
00436 cSystem->cpu_lock(state.iProcNum, phys_address); \
00437 state.r[REG_1] = READ_PHYS_NT(64); \
00438 break; \
00439 \
00440 case 5: \
00441 DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | NO_CHECK | VPTE); \
00442 state.r[REG_1] = READ_PHYS_NT(64); \
00443 break; \
00444 \
00445 case 9: \
00446 DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | NO_CHECK); \
00447 state.r[REG_1] = READ_PHYS_NT(64); \
00448 break; \
00449 \
00450 case 11: \
00451 DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ); \
00452 state.r[REG_1] = READ_PHYS_NT(64); \
00453 break; \
00454 \
00455 case 13: \
00456 DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | NO_CHECK | ALT); \
00457 state.r[REG_1] = READ_PHYS_NT(64); \
00458 break; \
00459 \
00460 case 15: \
00461 DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | ALT); \
00462 state.r[REG_1] = READ_PHYS_NT(64); \
00463 break; \
00464 \
00465 default: \
00466 UNKNOWN2; \
00467 }
00468
00469 #define DO_HW_STL switch(function) \
00470 { \
00471 case 0: \
00472 phys_address = state.r[REG_2] + DISP_12; \
00473 WRITE_PHYS_NT(state.r[REG_1], 32); \
00474 break; \
00475 \
00476 case 2: \
00477 if(cSystem->cpu_unlock(state.iProcNum)) \
00478 { \
00479 phys_address = state.r[REG_2] + DISP_12; \
00480 WRITE_PHYS_NT(state.r[REG_1], 32); \
00481 state.r[REG_1] = 1; \
00482 } \
00483 else \
00484 state.r[REG_1] = 0; \
00485 break; \
00486 \
00487 case 4: \
00488 DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | NO_CHECK); \
00489 WRITE_PHYS_NT(state.r[REG_1], 32); \
00490 break; \
00491 \
00492 case 12: \
00493 DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | NO_CHECK | ALT); \
00494 WRITE_PHYS_NT(state.r[REG_1], 32); \
00495 break; \
00496 \
00497 default: \
00498 UNKNOWN2; \
00499 }
00500
00501 #define DO_HW_STQ switch(function) \
00502 { \
00503 case 1: \
00504 phys_address = state.r[REG_2] + DISP_12; \
00505 WRITE_PHYS_NT(state.r[REG_1], 64); \
00506 break; \
00507 \
00508 case 3: \
00509 if(cSystem->cpu_unlock(state.iProcNum)) \
00510 { \
00511 phys_address = state.r[REG_2] + DISP_12; \
00512 WRITE_PHYS_NT(state.r[REG_1], 64); \
00513 state.r[REG_1] = 1; \
00514 } \
00515 else \
00516 state.r[REG_1] = 0; \
00517 break; \
00518 \
00519 case 5: \
00520 DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | NO_CHECK); \
00521 WRITE_PHYS_NT(state.r[REG_1], 64); \
00522 break; \
00523 \
00524 case 13: \
00525 DATA_PHYS_NT(state.r[REG_2] + DISP_12, ACCESS_READ | NO_CHECK | ALT); \
00526 WRITE_PHYS_NT(state.r[REG_1], 64); \
00527 break; \
00528 \
00529 default: \
00530 UNKNOWN2; \
00531 }