|
|
1.1 ! root 1: #ifndef UAE_CPUMMU030_H ! 2: #define UAE_CPUMMU030_H ! 3: ! 4: #include "mmu_common.h" ! 5: ! 6: extern uae_u64 srp_030, crp_030; ! 7: extern uae_u32 tt0_030, tt1_030, tc_030; ! 8: extern uae_u16 mmusr_030; ! 9: ! 10: #define MAX_MMU030_ACCESS 10 ! 11: extern uae_u32 mm030_stageb_address; ! 12: extern int mmu030_idx; ! 13: extern bool mmu030_retry; ! 14: extern int mmu030_opcode, mmu030_opcode_stageb; ! 15: extern int mmu030_fake_prefetch; ! 16: extern uaecptr mmu030_fake_prefetch_addr; ! 17: extern uae_u16 mmu030_state[3]; ! 18: extern uae_u32 mmu030_data_buffer; ! 19: extern uae_u32 mmu030_disp_store[2]; ! 20: extern uae_u32 mmu030_fmovem_store[2]; ! 21: ! 22: #define MMU030_STATEFLAG1_FMOVEM 0x2000 ! 23: #define MMU030_STATEFLAG1_MOVEM1 0x4000 ! 24: #define MMU030_STATEFLAG1_MOVEM2 0x8000 ! 25: #define MMU030_STATEFLAG1_DISP0 0x0001 ! 26: #define MMU030_STATEFLAG1_DISP1 0x0002 ! 27: ! 28: struct mmu030_access ! 29: { ! 30: bool done; ! 31: uae_u32 val; ! 32: }; ! 33: extern struct mmu030_access mmu030_ad[MAX_MMU030_ACCESS]; ! 34: ! 35: uae_u32 REGPARAM3 get_disp_ea_020_mmu030 (uae_u32 base, int idx) REGPARAM; ! 36: void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc); ! 37: ! 38: bool mmu_op30_pmove (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra); ! 39: bool mmu_op30_ptest (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra); ! 40: bool mmu_op30_pload (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra); ! 41: bool mmu_op30_pflush (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra); ! 42: ! 43: uae_u32 mmu_op30_helper_get_fc(uae_u16 next); ! 44: ! 45: void mmu030_ptest_atc_search(uaecptr logical_addr, uae_u32 fc, bool write); ! 46: uae_u32 mmu030_ptest_table_search(uaecptr extra, uae_u32 fc, bool write, int level); ! 47: uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int level); ! 48: ! 49: ! 50: typedef struct { ! 51: uae_u32 addr_base; ! 52: uae_u32 addr_mask; ! 53: uae_u32 fc_base; ! 54: uae_u32 fc_mask; ! 55: } TT_info; ! 56: ! 57: TT_info mmu030_decode_tt(uae_u32 TT); ! 58: bool mmu030_decode_tc(uae_u32 TC); ! 59: bool mmu030_decode_rp(uae_u64 RP); ! 60: ! 61: int mmu030_logical_is_in_atc(uaecptr addr, uae_u32 fc, bool write); ! 62: void mmu030_atc_handle_history_bit(int entry_num); ! 63: ! 64: void mmu030_put_long_atc(uaecptr addr, uae_u32 val, int l, uae_u32 fc); ! 65: void mmu030_put_word_atc(uaecptr addr, uae_u16 val, int l, uae_u32 fc); ! 66: void mmu030_put_byte_atc(uaecptr addr, uae_u8 val, int l, uae_u32 fc); ! 67: uae_u32 mmu030_get_long_atc(uaecptr addr, int l, uae_u32 fc); ! 68: uae_u16 mmu030_get_word_atc(uaecptr addr, int l, uae_u32 fc); ! 69: uae_u8 mmu030_get_byte_atc(uaecptr addr, int l, uae_u32 fc); ! 70: ! 71: void mmu030_put_atc_generic(uaecptr addr, uae_u32 val, int l, uae_u32 fc, int size, int flags); ! 72: uae_u32 mmu030_get_atc_generic(uaecptr addr, int l, uae_u32 fc, int size, int flags, bool checkwrite); ! 73: ! 74: void mmu030_flush_atc_fc(uae_u32 fc_base, uae_u32 fc_mask); ! 75: void mmu030_flush_atc_page(uaecptr logical_addr); ! 76: void mmu030_flush_atc_page_fc(uaecptr logical_addr, uae_u32 fc_base, uae_u32 fc_mask); ! 77: void mmu030_flush_atc_all(void); ! 78: void mmu030_reset(int hardreset); ! 79: void mmu030_set_funcs(void); ! 80: uaecptr mmu030_translate(uaecptr addr, bool super, bool data, bool write); ! 81: ! 82: int mmu030_match_ttr(uaecptr addr, uae_u32 fc, bool write); ! 83: int mmu030_match_ttr_access(uaecptr addr, uae_u32 fc, bool write); ! 84: int mmu030_match_lrmw_ttr_access(uaecptr addr, uae_u32 fc); ! 85: int mmu030_do_match_ttr(uae_u32 tt, TT_info masks, uaecptr addr, uae_u32 fc, bool write); ! 86: int mmu030_do_match_lrmw_ttr(uae_u32 tt, TT_info masks, uaecptr addr, uae_u32 fc); ! 87: ! 88: void mmu030_put_long(uaecptr addr, uae_u32 val, uae_u32 fc); ! 89: void mmu030_put_word(uaecptr addr, uae_u16 val, uae_u32 fc); ! 90: void mmu030_put_byte(uaecptr addr, uae_u8 val, uae_u32 fc); ! 91: uae_u32 mmu030_get_long(uaecptr addr, uae_u32 fc); ! 92: uae_u16 mmu030_get_word(uaecptr addr, uae_u32 fc); ! 93: uae_u8 mmu030_get_byte(uaecptr addr, uae_u32 fc); ! 94: uae_u32 mmu030_get_ilong(uaecptr addr, uae_u32 fc); ! 95: uae_u16 mmu030_get_iword(uaecptr addr, uae_u32 fc); ! 96: ! 97: uae_u32 uae_mmu030_get_lrmw(uaecptr addr, int size); ! 98: void uae_mmu030_put_lrmw(uaecptr addr, uae_u32 val, int size); ! 99: ! 100: void mmu030_put_generic(uaecptr addr, uae_u32 val, uae_u32 fc, int size, int accesssize, int flags); ! 101: uae_u32 mmu030_get_generic(uaecptr addr, uae_u32 fc, int size, int accesssize, int flags); ! 102: ! 103: extern uae_u16 REGPARAM3 mmu030_get_word_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM; ! 104: extern uae_u32 REGPARAM3 mmu030_get_long_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM; ! 105: extern uae_u32 REGPARAM3 mmu030_get_ilong_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM; ! 106: extern uae_u16 REGPARAM3 mmu030_get_lrmw_word_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM; ! 107: extern uae_u32 REGPARAM3 mmu030_get_lrmw_long_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM; ! 108: extern void REGPARAM3 mmu030_put_word_unaligned(uaecptr addr, uae_u16 val, uae_u32 fc, int flags) REGPARAM; ! 109: extern void REGPARAM3 mmu030_put_long_unaligned(uaecptr addr, uae_u32 val, uae_u32 fc, int flags) REGPARAM; ! 110: ! 111: static ALWAYS_INLINE uae_u32 uae_mmu030_get_ilong(uaecptr addr) ! 112: { ! 113: uae_u32 fc = (regs.s ? 4 : 0) | 2; ! 114: ! 115: if (unlikely(is_unaligned(addr, 4))) ! 116: return mmu030_get_ilong_unaligned(addr, fc, 0); ! 117: return mmu030_get_ilong(addr, fc); ! 118: } ! 119: static ALWAYS_INLINE uae_u16 uae_mmu030_get_iword(uaecptr addr) ! 120: { ! 121: uae_u32 fc = (regs.s ? 4 : 0) | 2; ! 122: return mmu030_get_iword(addr, fc); ! 123: } ! 124: static ALWAYS_INLINE uae_u16 uae_mmu030_get_ibyte(uaecptr addr) ! 125: { ! 126: uae_u32 fc = (regs.s ? 4 : 0) | 2; ! 127: ! 128: return mmu030_get_byte(addr, fc); ! 129: } ! 130: static ALWAYS_INLINE uae_u32 uae_mmu030_get_long(uaecptr addr) ! 131: { ! 132: uae_u32 fc = (regs.s ? 4 : 0) | 1; ! 133: ! 134: if (unlikely(is_unaligned(addr, 4))) ! 135: return mmu030_get_long_unaligned(addr, fc, 0); ! 136: return mmu030_get_long(addr, fc); ! 137: } ! 138: static ALWAYS_INLINE uae_u16 uae_mmu030_get_word(uaecptr addr) ! 139: { ! 140: uae_u32 fc = (regs.s ? 4 : 0) | 1; ! 141: ! 142: if (unlikely(is_unaligned(addr, 2))) ! 143: return mmu030_get_word_unaligned(addr, fc, 0); ! 144: return mmu030_get_word(addr, fc); ! 145: } ! 146: static ALWAYS_INLINE uae_u8 uae_mmu030_get_byte(uaecptr addr) ! 147: { ! 148: uae_u32 fc = (regs.s ? 4 : 0) | 1; ! 149: ! 150: return mmu030_get_byte(addr, fc); ! 151: } ! 152: static ALWAYS_INLINE void uae_mmu030_put_long(uaecptr addr, uae_u32 val) ! 153: { ! 154: uae_u32 fc = (regs.s ? 4 : 0) | 1; ! 155: ! 156: if (unlikely(is_unaligned(addr, 4))) ! 157: mmu030_put_long_unaligned(addr, val, fc, 0); ! 158: else ! 159: mmu030_put_long(addr, val, fc); ! 160: } ! 161: static ALWAYS_INLINE void uae_mmu030_put_word(uaecptr addr, uae_u16 val) ! 162: { ! 163: uae_u32 fc = (regs.s ? 4 : 0) | 1; ! 164: ! 165: if (unlikely(is_unaligned(addr, 2))) ! 166: mmu030_put_word_unaligned(addr, val, fc, 0); ! 167: else ! 168: mmu030_put_word(addr, val, fc); ! 169: } ! 170: static ALWAYS_INLINE void uae_mmu030_put_byte(uaecptr addr, uae_u8 val) ! 171: { ! 172: uae_u32 fc = (regs.s ? 4 : 0) | 1; ! 173: ! 174: mmu030_put_byte(addr, val, fc); ! 175: } ! 176: ! 177: static ALWAYS_INLINE uae_u32 sfc030_get_long(uaecptr addr) ! 178: { ! 179: uae_u32 fc = regs.sfc; ! 180: #if MMUDEBUG > 2 ! 181: write_log(_T("sfc030_get_long: FC = %i\n"),fc); ! 182: #endif ! 183: if (unlikely(is_unaligned(addr, 4))) ! 184: return mmu030_get_long_unaligned(addr, fc, 0); ! 185: return mmu030_get_long(addr, fc); ! 186: } ! 187: ! 188: static ALWAYS_INLINE uae_u16 sfc030_get_word(uaecptr addr) ! 189: { ! 190: uae_u32 fc = regs.sfc; ! 191: #if MMUDEBUG > 2 ! 192: write_log(_T("sfc030_get_word: FC = %i\n"),fc); ! 193: #endif ! 194: if (unlikely(is_unaligned(addr, 2))) ! 195: return mmu030_get_word_unaligned(addr, fc, 0); ! 196: return mmu030_get_word(addr, fc); ! 197: } ! 198: ! 199: static ALWAYS_INLINE uae_u8 sfc030_get_byte(uaecptr addr) ! 200: { ! 201: uae_u32 fc = regs.sfc; ! 202: #if MMUDEBUG > 2 ! 203: write_log(_T("sfc030_get_byte: FC = %i\n"),fc); ! 204: #endif ! 205: return mmu030_get_byte(addr, fc); ! 206: } ! 207: ! 208: static ALWAYS_INLINE void dfc030_put_long(uaecptr addr, uae_u32 val) ! 209: { ! 210: uae_u32 fc = regs.dfc; ! 211: #if MMUDEBUG > 2 ! 212: write_log(_T("dfc030_put_long: %08X = %08X FC = %i\n"), addr, val, fc); ! 213: #endif ! 214: if (unlikely(is_unaligned(addr, 4))) ! 215: mmu030_put_long_unaligned(addr, val, fc, 0); ! 216: else ! 217: mmu030_put_long(addr, val, fc); ! 218: } ! 219: ! 220: static ALWAYS_INLINE void dfc030_put_word(uaecptr addr, uae_u16 val) ! 221: { ! 222: uae_u32 fc = regs.dfc; ! 223: #if MMUDEBUG > 2 ! 224: write_log(_T("dfc030_put_word: %08X = %04X FC = %i\n"), addr, val, fc); ! 225: #endif ! 226: if (unlikely(is_unaligned(addr, 2))) ! 227: mmu030_put_word_unaligned(addr, val, fc, 0); ! 228: else ! 229: mmu030_put_word(addr, val, fc); ! 230: } ! 231: ! 232: static ALWAYS_INLINE void dfc030_put_byte(uaecptr addr, uae_u8 val) ! 233: { ! 234: uae_u32 fc = regs.dfc; ! 235: #if MMUDEBUG > 2 ! 236: write_log(_T("dfc030_put_byte: %08X = %02X FC = %i\n"), addr, val, fc); ! 237: #endif ! 238: mmu030_put_byte(addr, val, fc); ! 239: } ! 240: ! 241: #define ACCESS_CHECK_PUT \ ! 242: if (!mmu030_ad[mmu030_idx].done) { \ ! 243: mmu030_ad[mmu030_idx].val = v; \ ! 244: } else if (mmu030_ad[mmu030_idx].done) { \ ! 245: mmu030_idx++; \ ! 246: return; \ ! 247: } ! 248: ! 249: #define ACCESS_CHECK_GET \ ! 250: if (mmu030_ad[mmu030_idx].done) { \ ! 251: v = mmu030_ad[mmu030_idx].val; \ ! 252: mmu030_idx++; \ ! 253: return v; \ ! 254: } ! 255: ! 256: #define ACCESS_CHECK_GET_PC(pc) \ ! 257: if (mmu030_ad[mmu030_idx].done) { \ ! 258: v = mmu030_ad[mmu030_idx].val; \ ! 259: mmu030_idx++; \ ! 260: m68k_incpci (pc); \ ! 261: return v; \ ! 262: } ! 263: ! 264: #define ACCESS_EXIT_PUT \ ! 265: mmu030_ad[mmu030_idx].done = true; \ ! 266: mmu030_idx++; \ ! 267: mmu030_ad[mmu030_idx].done = false; ! 268: ! 269: #define ACCESS_EXIT_GET \ ! 270: mmu030_ad[mmu030_idx].val = v; \ ! 271: mmu030_ad[mmu030_idx].done = true; \ ! 272: mmu030_idx++; \ ! 273: mmu030_ad[mmu030_idx].done = false; ! 274: ! 275: STATIC_INLINE void put_byte_mmu030_state (uaecptr addr, uae_u32 v) ! 276: { ! 277: ACCESS_CHECK_PUT ! 278: uae_mmu030_put_byte (addr, v); ! 279: ACCESS_EXIT_PUT ! 280: } ! 281: STATIC_INLINE void put_lrmw_byte_mmu030_state (uaecptr addr, uae_u32 v) ! 282: { ! 283: ACCESS_CHECK_PUT ! 284: uae_mmu030_put_lrmw (addr, v, sz_byte); ! 285: ACCESS_EXIT_PUT ! 286: } ! 287: STATIC_INLINE void put_word_mmu030_state (uaecptr addr, uae_u32 v) ! 288: { ! 289: ACCESS_CHECK_PUT ! 290: uae_mmu030_put_word (addr, v); ! 291: ACCESS_EXIT_PUT ! 292: } ! 293: STATIC_INLINE void put_lrmw_word_mmu030_state (uaecptr addr, uae_u32 v) ! 294: { ! 295: ACCESS_CHECK_PUT ! 296: uae_mmu030_put_lrmw (addr, v, sz_word); ! 297: ACCESS_EXIT_PUT ! 298: } ! 299: STATIC_INLINE void put_long_mmu030_state (uaecptr addr, uae_u32 v) ! 300: { ! 301: ACCESS_CHECK_PUT ! 302: uae_mmu030_put_long (addr, v); ! 303: ACCESS_EXIT_PUT ! 304: } ! 305: STATIC_INLINE void put_lrmw_long_mmu030_state (uaecptr addr, uae_u32 v) ! 306: { ! 307: ACCESS_CHECK_PUT ! 308: uae_mmu030_put_lrmw (addr, v, sz_long); ! 309: ACCESS_EXIT_PUT ! 310: } ! 311: ! 312: STATIC_INLINE uae_u32 get_byte_mmu030_state (uaecptr addr) ! 313: { ! 314: uae_u32 v; ! 315: ACCESS_CHECK_GET ! 316: v = uae_mmu030_get_byte (addr); ! 317: ACCESS_EXIT_GET ! 318: return v; ! 319: } ! 320: STATIC_INLINE uae_u32 get_lrmw_byte_mmu030_state (uaecptr addr) ! 321: { ! 322: uae_u32 v; ! 323: ACCESS_CHECK_GET ! 324: v = uae_mmu030_get_lrmw (addr, sz_byte); ! 325: ACCESS_EXIT_GET ! 326: return v; ! 327: } ! 328: ! 329: STATIC_INLINE uae_u32 get_word_mmu030_state (uaecptr addr) ! 330: { ! 331: uae_u32 v; ! 332: ACCESS_CHECK_GET ! 333: v = uae_mmu030_get_word (addr); ! 334: ACCESS_EXIT_GET ! 335: return v; ! 336: } ! 337: STATIC_INLINE uae_u32 get_lrmw_word_mmu030_state (uaecptr addr) ! 338: { ! 339: uae_u32 v; ! 340: ACCESS_CHECK_GET ! 341: v = uae_mmu030_get_lrmw (addr, sz_word); ! 342: ACCESS_EXIT_GET ! 343: return v; ! 344: } ! 345: STATIC_INLINE uae_u32 get_long_mmu030_state (uaecptr addr) ! 346: { ! 347: uae_u32 v; ! 348: ACCESS_CHECK_GET ! 349: v = uae_mmu030_get_long (addr); ! 350: ACCESS_EXIT_GET ! 351: return v; ! 352: } ! 353: STATIC_INLINE uae_u32 get_lrmw_long_mmu030_state (uaecptr addr) ! 354: { ! 355: uae_u32 v; ! 356: ACCESS_CHECK_GET ! 357: v = uae_mmu030_get_lrmw (addr, sz_long); ! 358: ACCESS_EXIT_GET ! 359: return v; ! 360: } ! 361: ! 362: STATIC_INLINE uae_u32 get_ibyte_mmu030_state (int o) ! 363: { ! 364: uae_u32 v; ! 365: uae_u32 addr = m68k_getpci () + o; ! 366: ACCESS_CHECK_GET ! 367: v = uae_mmu030_get_iword (addr); ! 368: ACCESS_EXIT_GET ! 369: return v; ! 370: } ! 371: STATIC_INLINE uae_u32 get_iword_mmu030_state (int o) ! 372: { ! 373: uae_u32 v; ! 374: uae_u32 addr = m68k_getpci () + o; ! 375: ACCESS_CHECK_GET ! 376: v = uae_mmu030_get_iword (addr); ! 377: ACCESS_EXIT_GET ! 378: return v; ! 379: } ! 380: STATIC_INLINE uae_u32 get_ilong_mmu030_state (int o) ! 381: { ! 382: uae_u32 v; ! 383: uae_u32 addr = m68k_getpci () + o; ! 384: ACCESS_CHECK_GET ! 385: v = uae_mmu030_get_ilong (addr); ! 386: ACCESS_EXIT_GET ! 387: return v; ! 388: } ! 389: STATIC_INLINE uae_u32 next_iword_mmu030_state (void) ! 390: { ! 391: uae_u32 v; ! 392: uae_u32 addr = m68k_getpci (); ! 393: ACCESS_CHECK_GET_PC(2); ! 394: v = uae_mmu030_get_iword (addr); ! 395: m68k_incpci (2); ! 396: ACCESS_EXIT_GET ! 397: return v; ! 398: } ! 399: STATIC_INLINE uae_u32 next_ilong_mmu030_state (void) ! 400: { ! 401: uae_u32 v; ! 402: uae_u32 addr = m68k_getpci (); ! 403: ACCESS_CHECK_GET_PC(4); ! 404: v = uae_mmu030_get_ilong (addr); ! 405: m68k_incpci (4); ! 406: ACCESS_EXIT_GET ! 407: return v; ! 408: } ! 409: ! 410: STATIC_INLINE uae_u32 get_byte_mmu030 (uaecptr addr) ! 411: { ! 412: return uae_mmu030_get_byte (addr); ! 413: } ! 414: STATIC_INLINE uae_u32 get_word_mmu030 (uaecptr addr) ! 415: { ! 416: return uae_mmu030_get_word (addr); ! 417: } ! 418: STATIC_INLINE uae_u32 get_long_mmu030 (uaecptr addr) ! 419: { ! 420: return uae_mmu030_get_long (addr); ! 421: } ! 422: STATIC_INLINE void put_byte_mmu030 (uaecptr addr, uae_u32 v) ! 423: { ! 424: uae_mmu030_put_byte (addr, v); ! 425: } ! 426: ! 427: STATIC_INLINE void put_word_mmu030 (uaecptr addr, uae_u32 v) ! 428: { ! 429: uae_mmu030_put_word (addr, v); ! 430: } ! 431: STATIC_INLINE void put_long_mmu030 (uaecptr addr, uae_u32 v) ! 432: { ! 433: uae_mmu030_put_long (addr, v); ! 434: } ! 435: ! 436: STATIC_INLINE uae_u32 get_ibyte_mmu030 (int o) ! 437: { ! 438: uae_u32 pc = m68k_getpci () + o; ! 439: return uae_mmu030_get_iword (pc); ! 440: } ! 441: STATIC_INLINE uae_u32 get_iword_mmu030 (int o) ! 442: { ! 443: uae_u32 pc = m68k_getpci () + o; ! 444: return uae_mmu030_get_iword (pc); ! 445: } ! 446: STATIC_INLINE uae_u32 get_ilong_mmu030 (int o) ! 447: { ! 448: uae_u32 pc = m68k_getpci () + o; ! 449: return uae_mmu030_get_ilong (pc); ! 450: } ! 451: STATIC_INLINE uae_u32 next_iword_mmu030 (void) ! 452: { ! 453: uae_u32 v; ! 454: uae_u32 pc = m68k_getpci (); ! 455: v = uae_mmu030_get_iword (pc); ! 456: m68k_incpci (2); ! 457: return v; ! 458: } ! 459: STATIC_INLINE uae_u32 next_ilong_mmu030 (void) ! 460: { ! 461: uae_u32 v; ! 462: uae_u32 pc = m68k_getpci (); ! 463: v = uae_mmu030_get_ilong (pc); ! 464: m68k_incpci (4); ! 465: return v; ! 466: } ! 467: ! 468: extern void m68k_do_rts_mmu030 (void); ! 469: extern void m68k_do_rte_mmu030 (uaecptr a7); ! 470: extern void flush_mmu030 (uaecptr, int); ! 471: extern void m68k_do_bsr_mmu030 (uaecptr oldpc, uae_s32 offset); ! 472: ! 473: #endif /* UAE_CPUMMU030_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.