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