2 m68kmmu.h - PMMU implementation for 68851/68030/68040
6 Copyright Nicola Salmoria and the MAME Team.
7 Visit http://mamedev.org for licensing and usage restrictions.
10 // MMU status register bit definitions
14 struct m68ki_cpu_core;
16 #define MMULOG(A) printf A
21 #define logerror printf
26 // MMU SR register fields
27 #define M68K_MMU_SR_BUS_ERROR 0x8000
28 #define M68K_MMU_SR_SUPERVISOR_ONLY 0x2000
29 #define M68K_MMU_SR_WRITE_PROTECT 0x0800
30 #define M68K_MMU_SR_INVALID 0x0400
31 #define M68K_MMU_SR_MODIFIED 0x0200
32 #define M68K_MMU_SR_TRANSPARENT 0x0040
34 // MMU translation table descriptor field definitions
35 #define M68K_MMU_DF_DT 0x00000003
36 #define M68K_MMU_DF_DT_INVALID 0x00000000
37 #define M68K_MMU_DF_DT_PAGE 0x00000001
38 #define M68K_MMU_DF_DT_TABLE_4BYTE 0x00000002
39 #define M68K_MMU_DF_DT_TABLE_8BYTE 0x00000003
40 #define M68K_MMU_DF_WP 0x00000004
41 #define M68K_MMU_DF_USED 0x00000008
42 #define M68K_MMU_DF_MODIFIED 0x00000010
43 #define M68K_MMU_DF_CI 0x00000040
44 #define M68K_MMU_DF_SUPERVISOR 0x00000100
45 #define M68K_MMU_DF_ADDR_MASK 0xfffffff0
46 #define M68K_MMU_DF_IND_ADDR_MASK 0xfffffffc
49 #define M68K_MMU_ATC_BUSERROR 0x08000000
50 #define M68K_MMU_ATC_CACHE_IN 0x04000000
51 #define M68K_MMU_ATC_WRITE_PR 0x02000000
52 #define M68K_MMU_ATC_MODIFIED 0x01000000
53 #define M68K_MMU_ATC_MASK 0x00ffffff
54 #define M68K_MMU_ATC_SHIFT 8
55 #define M68K_MMU_ATC_VALID 0x08000000
57 // MMU Translation Control register
58 #define M68K_MMU_TC_SRE 0x02000000
59 #define M68K_MMU_TC_FCL 0x01000000
62 #define M68K_MMU_TT_ENABLE 0x8000
64 #define m_side_effects_disabled 0
66 /* decodes the effective address */
67 uint32 DECODE_EA_32(m68ki_cpu_core *state, int ea)
69 int mode = (ea >> 3) & 0x7;
80 uint32 ea = EA_AY_PI_32();
85 uint32 ea = EA_AY_DI_32();
88 case 6: // (An) + (Xn) + d8
90 uint32 ea = EA_AY_IX_32();
99 uint32 ea = OPER_I_16(state);
104 uint32 d1 = OPER_I_16(state);
105 uint32 d2 = OPER_I_16(state);
106 uint32 ea = (d1 << 16) | d2;
111 uint32 ea = EA_PCDI_32();
114 default: fatalerror("m68k: DECODE_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
118 default: fatalerror("m68k: DECODE_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
123 void pmmu_set_buserror(m68ki_cpu_core *state, uint32 addr_in)
125 if (!m_side_effects_disabled && ++state->mmu_tmp_buserror_occurred == 1)
127 state->mmu_tmp_buserror_address = addr_in;
128 state->mmu_tmp_buserror_rw = state->mmu_tmp_rw;
129 state->mmu_tmp_buserror_fc = state->mmu_tmp_fc;
130 state->mmu_tmp_buserror_sz = state->mmu_tmp_sz;
135 // pmmu_atc_add: adds this address to the ATC
136 void pmmu_atc_add(m68ki_cpu_core *state, uint32 logical, uint32 physical, int fc, int rw)
138 // get page size (i.e. # of bits to ignore); is 10 for Apollo
139 int ps = (state->mmu_tc >> 20) & 0xf;
140 uint32 atc_tag = M68K_MMU_ATC_VALID | ((fc & 7) << 24) | ((logical >> ps) << (ps - 8));
141 uint32 atc_data = (physical >> ps) << (ps - 8);
143 if (state->mmu_tmp_sr & (M68K_MMU_SR_BUS_ERROR|M68K_MMU_SR_INVALID|M68K_MMU_SR_SUPERVISOR_ONLY))
145 atc_data |= M68K_MMU_ATC_BUSERROR;
148 if (state->mmu_tmp_sr & M68K_MMU_SR_WRITE_PROTECT)
150 atc_data |= M68K_MMU_ATC_WRITE_PR;
153 if (!rw && !(state->mmu_tmp_sr & M68K_MMU_SR_WRITE_PROTECT))
155 atc_data |= M68K_MMU_ATC_MODIFIED;
158 // first see if this is already in the cache
159 for (int i = 0; i < MMU_ATC_ENTRIES; i++)
161 // if tag bits and function code match, don't add
162 if (state->mmu_atc_tag[i] == atc_tag)
164 MMULOG(("%s: hit, old %08x new %08x\n", __func__, state->mmu_atc_data[i], atc_data));
165 state->mmu_atc_data[i] = atc_data;
170 // find an open entry
172 for (int i = 0; i < MMU_ATC_ENTRIES; i++)
174 if (!(state->mmu_atc_tag[i] & M68K_MMU_ATC_VALID))
181 // did we find an entry? steal one by round-robin then
184 found = state->mmu_atc_rr++;
186 if (state->mmu_atc_rr >= MMU_ATC_ENTRIES)
188 state->mmu_atc_rr = 0;
193 MMULOG(("ATC[%2d] add: log %08x -> phys %08x (fc=%d) data=%08x\n",
194 found, (logical >> ps) << ps, (physical >> ps) << ps, fc, atc_data));
195 state->mmu_atc_tag[found] = atc_tag;
196 state->mmu_atc_data[found] = atc_data;
199 // pmmu_atc_flush: flush entire ATC
200 // 7fff0003 001ffd10 80f05750 is what should load
201 void pmmu_atc_flush(m68ki_cpu_core *state)
203 MMULOG(("ATC flush: pc=%08x\n", state->ppc));
204 // std::fill(std::begin(state->mmu_atc_tag), std::end(state->mmu_atc_tag), 0);
205 for(int i=0;i<MMU_ATC_ENTRIES;i++)
206 state->mmu_atc_tag[i]=0;
207 state->mmu_atc_rr = 0;
210 int fc_from_modes(m68ki_cpu_core *state, uint16 modes);
212 void pmmu_atc_flush_fc_ea(m68ki_cpu_core *state, uint16 modes)
214 unsigned int fcmask = (modes >> 5) & 7;
215 unsigned int fc = fc_from_modes(state, modes) & fcmask;
216 unsigned int ps = (state->mmu_tc >> 20) & 0xf;
217 unsigned int mode = (modes >> 10) & 7;
223 MMULOG(("PFLUSHA: mode %d\n", mode));
224 pmmu_atc_flush(state);
227 case 4: // flush by fc
228 MMULOG(("flush by fc: %d, mask %d\n", fc, fcmask));
229 for(int i=0,e;i<MMU_ATC_ENTRIES;i++)
231 e=state->mmu_atc_tag[i];
232 if ((e & M68K_MMU_ATC_VALID) && ((e >> 24) & fcmask) == fc)
234 MMULOG(("flushing entry %08x\n", e));
235 state->mmu_atc_tag[i] = 0;
240 case 6: // flush by fc + ea
242 ea = DECODE_EA_32(state, state->ir);
243 MMULOG(("flush by fc/ea: fc %d, mask %d, ea %08x\n", fc, fcmask, ea));
244 for(unsigned int i=0,e;i<MMU_ATC_ENTRIES;i++)
246 e=state->mmu_atc_tag[i];
247 if ((e & M68K_MMU_ATC_VALID) &&
248 (((e >> 24) & fcmask) == fc) &&
249 // (((e >> ps) << (ps - 8)) == ((ea >> ps) << (ps - 8))))
250 ( (e << ps) == (ea >> 8 << ps) ))
252 MMULOG(("flushing entry %08x\n", e));
253 state->mmu_atc_tag[i] = 0;
259 logerror("PFLUSH mode %d not supported\n", mode);
264 //template<bool ptest>
265 uint16 pmmu_atc_lookup(m68ki_cpu_core *state, uint32 addr_in, int fc, uint16 rw, uint32 *addr_out, int ptest)
267 MMULOG(("%s: LOOKUP addr_in=%08x, fc=%d, ptest=%d, rw=%d\n", __func__, addr_in, fc, ptest,rw));
268 unsigned int ps = (state->mmu_tc >> 20) & 0xf;
269 uint32 atc_tag = M68K_MMU_ATC_VALID | ((fc & 7) << 24) | ((addr_in >> ps) << (ps - 8));
271 for (int i = 0; i < MMU_ATC_ENTRIES; i++)
274 if (state->mmu_atc_tag[i] != atc_tag)
279 uint32 atc_data = state->mmu_atc_data[i];
283 // According to MC86030UM:
284 // "If the M bit is clear and a write access to this logical
285 // address is attempted, the MC68030 aborts the access and initiates a table
286 // search, setting the M bit in the page descriptor, invalidating the old ATC
287 // entry, and creating a new entry with the M bit set.
288 if (!(atc_data & M68K_MMU_ATC_MODIFIED))
290 state->mmu_atc_tag[i] = 0;
295 state->mmu_tmp_sr = 0;
296 if (atc_data & M68K_MMU_ATC_MODIFIED)
298 state->mmu_tmp_sr |= M68K_MMU_SR_MODIFIED;
301 if (atc_data & M68K_MMU_ATC_WRITE_PR)
303 state->mmu_tmp_sr |= M68K_MMU_SR_WRITE_PROTECT;
306 if (atc_data & M68K_MMU_ATC_BUSERROR)
308 state->mmu_tmp_sr |= M68K_MMU_SR_BUS_ERROR|M68K_MMU_SR_INVALID;
310 *addr_out = (atc_data << 8) | (addr_in & ~(((uint32)~0) << ps));
311 MMULOG(("%s: addr_in=%08x, addr_out=%08x, MMU SR %04x\n",
312 __func__, addr_in, *addr_out, state->mmu_tmp_sr));
315 MMULOG(("%s: lookup failed\n", __func__));
318 state->mmu_tmp_sr = M68K_MMU_SR_INVALID;
323 uint16 pmmu_match_tt(m68ki_cpu_core *state, uint32 addr_in, int fc, uint32 tt, uint16 rw)
325 if (!(tt & M68K_MMU_TT_ENABLE))
330 // transparent translation enabled
331 uint32 address_base = tt & 0xff000000;
332 uint32 address_mask = ((tt << 8) & 0xff000000) ^ 0xff000000;
333 uint32 fcmask = (~tt) & 7;
334 uint32 fcbits = (tt >> 4) & 7;
335 uint16 rwmask = !!(~tt & 0x100);
336 uint16 rwbit = !!(tt & 0x200);
338 if ((addr_in & address_mask) != (address_base & address_mask))
343 if ((fc & fcmask) != (fcbits & fcmask))
348 if ((rw & rwmask) != (rwbit & rwmask))
353 state->mmu_tmp_sr |= M68K_MMU_SR_TRANSPARENT;
357 void update_descriptor(m68ki_cpu_core *state, uint32 tptr, int type, uint32 entry, int16 rw)
359 // FIXME: Silence unused variable warning
362 if (type == M68K_MMU_DF_DT_PAGE && !rw &&
363 !(entry & M68K_MMU_DF_MODIFIED) &&
364 !(entry & M68K_MMU_DF_WP))
366 MMULOG(("%s: set M+U at %08x\n", __func__, tptr));
367 m68k_write_memory_32(tptr, entry | M68K_MMU_DF_USED | M68K_MMU_DF_MODIFIED);
369 else if (type != M68K_MMU_DF_DT_INVALID && !(entry & M68K_MMU_DF_USED))
371 MMULOG(("%s: set U at %08x\n", __func__, tptr));
372 m68k_write_memory_32(tptr, entry | M68K_MMU_DF_USED);
377 //template<bool _long>
378 void update_sr(m68ki_cpu_core *state, int type, uint32 tbl_entry, int fc, uint16 _long)
380 if (m_side_effects_disabled)
387 case M68K_MMU_DF_DT_INVALID:
388 // Invalid has no flags
391 case M68K_MMU_DF_DT_PAGE:
392 if (tbl_entry & M68K_MMU_DF_MODIFIED)
394 state->mmu_tmp_sr |= M68K_MMU_SR_MODIFIED;
398 case M68K_MMU_DF_DT_TABLE_4BYTE:
401 case M68K_MMU_DF_DT_TABLE_8BYTE:
403 if (tbl_entry & M68K_MMU_DF_WP)
405 state->mmu_tmp_sr |= M68K_MMU_SR_WRITE_PROTECT;
408 if (_long && !(fc & 4) && (tbl_entry & M68K_MMU_DF_SUPERVISOR))
410 state->mmu_tmp_sr |= M68K_MMU_SR_SUPERVISOR_ONLY;
418 //template<bool ptest>
419 uint16 pmmu_walk_tables(m68ki_cpu_core *state, uint32 addr_in, int type, uint32 table, uint8 fc, int limit, uint16 rw,
420 uint32 *addr_out, int ptest)
423 uint32 bits = state->mmu_tc & 0xffff;
424 int pagesize = (state->mmu_tc >> 20) & 0xf;
425 int is = (state->mmu_tc >> 16) & 0xf;
432 state->mmu_tablewalk = 1;
434 if (state->mmu_tc & M68K_MMU_TC_FCL)
441 int indexbits = (bits >> bitpos) & 0xf;
442 int table_index = (bitpos == 16) ? fc : (addr_in >> (32 - indexbits));
444 uint16 indirect = (!bitpos || !(bits >> bitpos)) && indexbits;
445 uint32 tbl_entry, tbl_entry2;
447 MMULOG(("%s: type %d, table %08x, addr_in %08x, indexbits %d, pageshift %d, indirect %d table_index %08x, rw=%d fc=%d\n",
448 __func__, type, table, addr_in, indexbits, pageshift, indirect, table_index, rw, fc));
452 case M68K_MMU_DF_DT_INVALID: // invalid, will cause MMU exception
453 state->mmu_tmp_sr = M68K_MMU_SR_INVALID;
454 MMULOG(("PMMU: DT0 PC=%x (addr_in %08x -> %08x)\n", state->ppc, addr_in, *addr_out));
458 case M68K_MMU_DF_DT_PAGE: // page descriptor, will cause direct mapping
461 table &= ((uint32)~0) << pagesize;
462 *addr_out = table + (addr_in >> pageshift);
467 case M68K_MMU_DF_DT_TABLE_4BYTE: // valid 4 byte descriptors
469 *addr_out = table + (table_index << 2);
470 tbl_entry = m68k_read_memory_32(*addr_out);
471 type = tbl_entry & M68K_MMU_DF_DT;
473 if (indirect && (type == 2 || type == 3))
476 MMULOG(("SHORT INDIRECT DESC: %08x\n", tbl_entry));
477 *addr_out = tbl_entry & M68K_MMU_DF_IND_ADDR_MASK;
478 tbl_entry = m68k_read_memory_32(*addr_out);
479 type = tbl_entry & M68K_MMU_DF_DT;
482 MMULOG(("SHORT DESC: %08x\n", tbl_entry));
483 table = tbl_entry & M68K_MMU_DF_ADDR_MASK;
484 if (!m_side_effects_disabled)
486 update_sr(state, type, tbl_entry, fc, 0);
489 update_descriptor(state, *addr_out, type, tbl_entry, rw);
494 case M68K_MMU_DF_DT_TABLE_8BYTE: // valid 8 byte descriptors
496 *addr_out = table + (table_index << 3);
497 tbl_entry = m68k_read_memory_32(*addr_out);
498 tbl_entry2 = m68k_read_memory_32((*addr_out) + 4);
499 type = tbl_entry & M68K_MMU_DF_DT;
501 if (indirect && (type == 2 || type == 3))
504 MMULOG(("LONG INDIRECT DESC: %08x%08x\n", tbl_entry, tbl_entry2));
505 *addr_out = tbl_entry2 & M68K_MMU_DF_IND_ADDR_MASK;
506 tbl_entry = m68k_read_memory_32(*addr_out);
507 tbl_entry2 = m68k_read_memory_32(*addr_out);
508 type = tbl_entry & M68K_MMU_DF_DT;
511 MMULOG(("LONG DESC: %08x %08x\n", tbl_entry, tbl_entry2));
512 table = tbl_entry2 & M68K_MMU_DF_ADDR_MASK;
513 if (!m_side_effects_disabled)
515 update_sr(state, type, tbl_entry, fc, 1);
518 update_descriptor(state, *addr_out, type, tbl_entry, rw);
524 if (state->mmu_tmp_sr & M68K_MMU_SR_BUS_ERROR)
526 // Bus error during page table walking is always fatal
531 if (!ptest && !m_side_effects_disabled)
533 if (!rw && (state->mmu_tmp_sr & M68K_MMU_SR_WRITE_PROTECT))
539 if (!(fc & 4) && (state->mmu_tmp_sr & M68K_MMU_SR_SUPERVISOR_ONLY))
546 addr_in <<= indexbits;
547 pageshift += indexbits;
548 } while(level < limit && !resolved);
551 state->mmu_tmp_sr &= 0xfff0;
552 state->mmu_tmp_sr |= level;
553 MMULOG(("MMU SR after walk: %04X\n", state->mmu_tmp_sr));
554 state->mmu_tablewalk = 0;
558 // pmmu_translate_addr_with_fc: perform 68851/68030-style PMMU address translation
559 //template<bool ptest, bool pload>
560 uint32 pmmu_translate_addr_with_fc(m68ki_cpu_core *state, uint32 addr_in, uint8 fc, uint16 rw, int limit, int ptest,
566 MMULOG(("%s: addr_in=%08x, fc=%d, ptest=%d, rw=%d, limit=%d, pload=%d\n",
567 __func__, addr_in, fc, ptest, rw, limit, pload));
568 state->mmu_tmp_sr = 0;
570 state->mmu_last_logical_addr = addr_in;
572 if (pmmu_match_tt(state, addr_in, fc, state->mmu_tt0, rw) ||
573 pmmu_match_tt(state, addr_in, fc, state->mmu_tt1, rw) ||
579 if (ptest && limit == 0)
581 pmmu_atc_lookup(state, addr_in, fc, rw, &addr_out, 1);
585 if (!ptest && !pload && pmmu_atc_lookup(state, addr_in, fc, rw, &addr_out, 0))
587 if ((state->mmu_tmp_sr & M68K_MMU_SR_BUS_ERROR) || (!rw && (state->mmu_tmp_sr & M68K_MMU_SR_WRITE_PROTECT)))
589 MMULOG(("set atc hit buserror: addr_in=%08x, addr_out=%x, rw=%x, fc=%d, sz=%d\n",
590 addr_in, addr_out, state->mmu_tmp_rw, state->mmu_tmp_fc, state->mmu_tmp_sz));
591 pmmu_set_buserror(state, addr_in);
598 // if SRP is enabled and we're in supervisor mode, use it
599 if ((state->mmu_tc & M68K_MMU_TC_SRE) && (fc & 4))
601 tbl_addr = state->mmu_srp_aptr & M68K_MMU_DF_ADDR_MASK;
602 type = state->mmu_srp_limit & M68K_MMU_DF_DT;
604 else // else use the CRP
606 tbl_addr = state->mmu_crp_aptr & M68K_MMU_DF_ADDR_MASK;
607 type = state->mmu_crp_limit & M68K_MMU_DF_DT;
610 if (!pmmu_walk_tables(state, addr_in, type, tbl_addr, fc, limit, rw, &addr_out, ptest))
612 MMULOG(("%s: addr_in=%08x, type=%x, tbl_addr=%x, fc=%d, limit=%x, rw=%x, addr_out=%x, ptest=%d\n",
613 __func__, addr_in, type, tbl_addr, fc, limit, rw, addr_out, ptest));
614 fatalerror("Table walk did not resolve\n");
622 if ((state->mmu_tmp_sr & (M68K_MMU_SR_INVALID|M68K_MMU_SR_SUPERVISOR_ONLY)) ||
623 ((state->mmu_tmp_sr & M68K_MMU_SR_WRITE_PROTECT) && !rw))
628 MMULOG(("%s: set buserror (SR %04X)\n", __func__, state->mmu_tmp_sr));
629 pmmu_set_buserror(state, addr_in);
633 // it seems like at least the 68030 sets the M bit in the MMU SR
634 // if the root descriptor is of PAGE type, so do a logical and
635 // between RW and the root type
636 if (!m_side_effects_disabled)
638 pmmu_atc_add(state, addr_in, addr_out, fc, rw && type != 1);
640 MMULOG(("PMMU: [%08x] => [%08x] (SR %04x)\n", addr_in, addr_out, state->mmu_tmp_sr));
644 // FC bits: 2 = supervisor, 1 = program, 0 = data
645 // the 68040 is a subset of the 68851 and 68030 PMMUs - the page table sizes are fixed, there is no early termination, etc, etc.
646 uint32 pmmu_translate_addr_with_fc_040(m68ki_cpu_core *state, uint32 addr_in, uint8 fc, uint8 ptest)
648 uint32 addr_out, tt0, tt1;
651 state->mmu_tmp_sr = 0;
653 // transparent translation registers are always in force even if the PMMU itself is disabled
654 // they don't do much in emulation because we never write out of order, but the write-protect and cache control features
655 // are emulatable, and apparently transparent translation regions skip the page table lookup.
656 if (fc & 1) // data, use DTT0/DTT1
658 tt0 = state->mmu_dtt0;
659 tt1 = state->mmu_dtt1;
661 else if (fc & 2) // program, use ITT0/ITT1
663 tt0 = state->mmu_itt0;
664 tt1 = state->mmu_itt1;
668 fatalerror("68040: function code %d is neither data nor program!\n", fc & 7);
671 if (tt0 & M68K_MMU_TT_ENABLE)
673 int fcmask[4] = { 4, 4, 0, 0 };
674 int fcmatch[4] = { 0, 4, 0, 0 };
675 uint32 mask = (tt0 >> 16) & 0xff;
679 if ((addr_in & mask) == (tt0 & mask) && (fc & fcmask[(tt0 >> 13) & 3]) == fcmatch[(tt0 >> 13) & 3])
681 MMULOG(("TT0 match on address %08x (TT0 = %08x, mask = %08x)\n", addr_in, tt0, mask));
682 if ((tt0 & 4) && !state->mmu_tmp_rw && !ptest) // write protect?
684 pmmu_set_buserror(state, addr_in);
691 if (tt1 & M68K_MMU_TT_ENABLE)
693 static int fcmask[4] = { 4, 4, 0, 0 };
694 static int fcmatch[4] = { 0, 4, 0, 0 };
695 uint32 mask = (tt1 >> 16) & 0xff;
699 if ((addr_in & mask) == (tt1 & mask) && (fc & fcmask[(tt1 >> 13) & 3]) == fcmatch[(tt1 >> 13) & 3])
701 MMULOG(("TT1 match on address %08x (TT0 = %08x, mask = %08x)\n", addr_in, tt1, mask));
702 if ((tt1 & 4) && !state->mmu_tmp_rw && !ptest) // write protect?
704 pmmu_set_buserror(state, addr_in);
711 if (state->pmmu_enabled)
713 uint32 root_idx = (addr_in >> 25) & 0x7f;
714 uint32 ptr_idx = (addr_in >> 18) & 0x7f;
715 uint32 page_idx, page;
716 uint32 root_ptr, pointer_ptr, page_ptr;
717 uint32 root_entry, pointer_entry, page_entry;
719 // select supervisor or user root pointer
722 root_ptr = state->mmu_srp_aptr + (root_idx<<2);
726 root_ptr = state->mmu_urp_aptr + (root_idx<<2);
729 // get the root entry
730 root_entry = m68k_read_memory_32(root_ptr);
732 // is UDT marked valid?
735 // we're accessing through this root entry, so set the U bit
736 if ((!(root_entry & 0x8)) && (!ptest) && !m_side_effects_disabled)
739 m68k_write_memory_32(root_ptr, root_entry);
742 // PTEST: any write protect bits set in the search tree will set W in SR
743 if ((ptest) && (root_entry & 4))
745 state->mmu_tmp_sr |= 4;
748 pointer_ptr = (root_entry & ~0x1ff) + (ptr_idx<<2);
749 pointer_entry = m68k_read_memory_32(pointer_ptr);
751 // PTEST: any write protect bits set in the search tree will set W in SR
752 if ((ptest) && (pointer_entry & 4))
754 state->mmu_tmp_sr |= 4;
757 // update U bit on this pointer entry too
758 if ((!(pointer_entry & 0x8)) && (!ptest) && !m_side_effects_disabled)
760 pointer_entry |= 0x8;
761 m68k_write_memory_32(pointer_ptr, pointer_entry);
764 MMULOG(("pointer entry = %08x\n", pointer_entry));
766 // write protected by the root or pointer entries?
767 if ((((root_entry & 4) && !state->mmu_tmp_rw) || ((pointer_entry & 4) && !state->mmu_tmp_rw)) && !ptest)
769 pmmu_set_buserror(state, addr_in);
773 // is UDT valid on the pointer entry?
774 if (!(pointer_entry & 2) && !ptest)
776 logerror("Invalid pointer entry! PC=%x, addr=%x\n", state->ppc, addr_in);
777 pmmu_set_buserror(state, addr_in);
781 // (fall out of these ifs into the page lookup below)
783 else // throw an error
785 logerror("Invalid root entry! PC=%x, addr=%x\n", state->ppc, addr_in);
789 pmmu_set_buserror(state, addr_in);
795 // now do the page lookup
796 if (state->mmu_tc & 0x4000) // 8k pages?
798 page_idx = (addr_in >> 13) & 0x1f;
799 page = addr_in & 0x1fff;
800 pointer_entry &= ~0x7f;
801 MMULOG(("8k pages: index %x page %x\n", page_idx, page));
805 page_idx = (addr_in >> 12) & 0x3f;
806 page = addr_in & 0xfff;
807 pointer_entry &= ~0xff;
808 MMULOG(("4k pages: index %x page %x\n", page_idx, page));
811 page_ptr = pointer_entry + (page_idx<<2);
812 page_entry = m68k_read_memory_32(page_ptr);
813 state->mmu_last_page_entry_addr = page_ptr;
815 MMULOG(("page_entry = %08x\n", page_entry));
817 // resolve indirect page pointers
818 while ((page_entry & 3) == 2)
820 page_entry = m68k_read_memory_32(page_entry & ~0x3);
821 state->mmu_last_page_entry_addr = (page_entry & ~0x3);
823 state->mmu_last_page_entry = page_entry;
825 // is the page write protected or supervisor protected?
826 if ((((page_entry & 4) && !state->mmu_tmp_rw) || ((page_entry & 0x80) && !(fc & 4))) && !ptest)
828 pmmu_set_buserror(state, addr_in);
832 switch (page_entry & 3)
835 MMULOG(("Invalid page entry! PC=%x, addr=%x\n", state->ppc, addr_in));
838 pmmu_set_buserror(state, addr_in);
845 if (state->mmu_tc & 0x4000) // 8k pages?
847 addr_out = (page_entry & ~0x1fff) | page;
851 addr_out = (page_entry & ~0xfff) | page;
856 page_entry |= 0x8; // always set the U bit
858 // if we're writing, the M bit comes into play
859 if (!state->mmu_tmp_rw)
861 page_entry |= 0x10; // set Modified
864 // if these updates resulted in a change, write the entry back where we found it
865 if (page_entry != state->mmu_last_page_entry && !m_side_effects_disabled)
867 state->mmu_last_page_entry = page_entry;
868 m68k_write_memory_32(state->mmu_last_page_entry_addr, state->mmu_last_page_entry);
873 // page entry: UR G U1 U0 S CM CM M U W PDT
874 // SR: B G U1 U0 S CM CM M 0 W T R
875 state->mmu_tmp_sr |= ((addr_out & ~0xfff) || (page_entry & 0x7f4));
879 case 2: // shouldn't happen
880 fatalerror("68040: got indirect final page pointer, shouldn't be possible\n");
883 // if (addr_in != addr_out) MMULOG(("040MMU: [%08x] => [%08x]\n", addr_in, addr_out));
889 // pmmu_translate_addr: perform 68851/68030-style PMMU address translation
890 uint32 pmmu_translate_addr(m68ki_cpu_core *state, uint32 addr_in, uint16 rw)
894 if (CPU_TYPE_IS_040_PLUS(state->cpu_type))
896 addr_out = pmmu_translate_addr_with_fc_040(state, addr_in, state->mmu_tmp_fc, 0);
900 addr_out = pmmu_translate_addr_with_fc(state, addr_in, state->mmu_tmp_fc, rw, 7, 0, 0);
901 MMULOG(("ADDRIN %08X, ADDROUT %08X\n", addr_in, addr_out));
906 int fc_from_modes(m68ki_cpu_core *state, uint16 modes)
908 if ((modes & 0x1f) == 0)
913 if ((modes & 0x1f) == 1)
918 if (state->cpu_type & CPU_TYPE_030)
920 // 68030 has 3 bits fc, but 68851 4 bits
921 if (((modes >> 3) & 3) == 1)
923 return REG_D[modes & 7] & 0x7;
926 if (((modes >> 3) & 3) == 2)
933 if (((modes >> 3) & 3) == 1)
935 return REG_D[modes & 7] & 0xf;
945 fatalerror("%s: unknown fc mode: 0x%02xn", __func__, modes & 0x1f);
949 void m68851_pload(m68ki_cpu_core *state, uint32 ea, uint16 modes)
951 uint32 ltmp = DECODE_EA_32(state, ea);
952 int fc = fc_from_modes(state, modes);
953 uint16 rw = !!(modes & 0x200);
955 MMULOG(("%s: PLOAD%c addr=%08x, fc=%d\n", __func__, rw ? 'R' : 'W', ltmp, fc));
957 // MC68851 traps if MMU is not enabled, 030 not
958 if (state->pmmu_enabled || (state->cpu_type & CPU_TYPE_030))
960 if (CPU_TYPE_IS_040_PLUS(state->cpu_type))
962 pmmu_translate_addr_with_fc_040(state, ltmp, fc, 0);
966 pmmu_translate_addr_with_fc(state, ltmp, fc, rw, 7, 0, 1);
971 MMULOG(("PLOAD with MMU disabled on MC68851\n"));
972 m68ki_exception_trap(state, 57);
977 void m68851_ptest(m68ki_cpu_core *state, uint32 ea, uint16 modes)
979 uint32 v_addr = DECODE_EA_32(state, ea);
982 int level = (modes >> 10) & 7;
983 uint16 rw = !!(modes & 0x200);
984 int fc = fc_from_modes(state, modes);
986 MMULOG(("PMMU: PTEST%c (%04X) pc=%08x sp=%08x va=%08x fc=%x level=%x a=%d, areg=%d\n",
987 rw ? 'R' : 'W', modes, state->ppc, REG_A[7], v_addr, fc, level,
988 (modes & 0x100) ? 1 : 0, (modes >> 5) & 7));
990 if (CPU_TYPE_IS_040_PLUS(state->cpu_type))
992 p_addr = pmmu_translate_addr_with_fc_040(state, v_addr, fc, 1);
996 p_addr = pmmu_translate_addr_with_fc(state, v_addr, fc, rw, level, 1, 0);
999 state->mmu_sr = state->mmu_tmp_sr;
1001 MMULOG(("PMMU: PTEST result: %04x pa=%08x\n", state->mmu_sr, p_addr));
1004 int areg = (modes >> 5) & 7;
1005 WRITE_EA_32(state, 0x08 | areg, p_addr);
1009 void m68851_pmove_get(m68ki_cpu_core *state, uint32 ea, uint16 modes)
1011 switch ((modes>>10) & 0x3f)
1013 case 0x02: // transparent translation register 0
1014 WRITE_EA_32(state, ea, state->mmu_tt0);
1015 MMULOG(("PMMU: pc=%x PMOVE from mmu_tt0=%08x\n", state->ppc, state->mmu_tt0));
1017 case 0x03: // transparent translation register 1
1018 WRITE_EA_32(state, ea, state->mmu_tt1);
1019 MMULOG(("PMMU: pc=%x PMOVE from mmu_tt1=%08x\n", state->ppc, state->mmu_tt1));
1021 case 0x10: // translation control register
1022 WRITE_EA_32(state, ea, state->mmu_tc);
1023 MMULOG(("PMMU: pc=%x PMOVE from mmu_tc=%08x\n", state->ppc, state->mmu_tc));
1026 case 0x12: // supervisor root pointer
1027 WRITE_EA_64(state, ea, (uint64)state->mmu_srp_limit<<32 | (uint64)state->mmu_srp_aptr);
1028 MMULOG(("PMMU: pc=%x PMOVE from SRP limit = %08x, aptr = %08x\n", state->ppc, state->mmu_srp_limit, state->mmu_srp_aptr));
1031 case 0x13: // CPU root pointer
1032 WRITE_EA_64(state, ea, (uint64)state->mmu_crp_limit<<32 | (uint64)state->mmu_crp_aptr);
1033 MMULOG(("PMMU: pc=%x PMOVE from CRP limit = %08x, aptr = %08x\n", state->ppc, state->mmu_crp_limit, state->mmu_crp_aptr));
1037 logerror("680x0: PMOVE from unknown MMU register %x, PC %x\n", (modes>>10) & 7, state->pc);
1041 if (!(modes & 0x100)) // flush ATC on moves to TC, SRP, CRP, TT with FD bit clear
1043 pmmu_atc_flush(state);
1048 void m68851_pmove_put(m68ki_cpu_core *state, uint32 ea, uint16 modes)
1051 switch ((modes>>13) & 7)
1055 uint32 temp = READ_EA_32(state, ea);
1057 if (((modes >> 10) & 7) == 2)
1059 MMULOG(("WRITE TT0 = 0x%08x\n", state->mmu_tt0));
1060 state->mmu_tt0 = temp;
1062 else if (((modes >> 10) & 7) == 3)
1064 MMULOG(("WRITE TT1 = 0x%08x\n", state->mmu_tt1));
1065 state->mmu_tt1 = temp;
1069 // FIXME: unreachable
1070 if (!(modes & 0x100))
1072 pmmu_atc_flush(state);
1079 logerror("680x0: unknown PMOVE case 1, PC %x\n", state->pc);
1083 switch ((modes >> 10) & 7)
1085 case 0: // translation control register
1086 state->mmu_tc = READ_EA_32(state, ea);
1087 MMULOG(("PMMU: TC = %08x\n", state->mmu_tc));
1089 if (state->mmu_tc & 0x80000000)
1092 for (int shift = 20; shift >= 0; shift -= 4)
1094 bits += (state->mmu_tc >> shift) & 0x0f;
1097 if (bits != 32 || !((state->mmu_tc >> 23) & 1))
1099 logerror("MMU: TC invalid!\n");
1100 state->mmu_tc &= ~0x80000000;
1101 m68ki_exception_trap(state, EXCEPTION_MMU_CONFIGURATION);
1103 state->pmmu_enabled = 1;
1105 MMULOG(("PMMU enabled\n"));
1109 state->pmmu_enabled = 0;
1110 MMULOG(("PMMU disabled\n"));
1113 if (!(modes & 0x100)) // flush ATC on moves to TC, SRP, CRP with FD bit clear
1115 pmmu_atc_flush(state);
1119 case 2: // supervisor root pointer
1120 temp64 = READ_EA_64(state, ea);
1121 state->mmu_srp_limit = (temp64 >> 32) & 0xffffffff;
1122 state->mmu_srp_aptr = temp64 & 0xffffffff;
1123 MMULOG(("PMMU: SRP limit = %08x aptr = %08x\n", state->mmu_srp_limit, state->mmu_srp_aptr));
1124 // SRP type 0 is not allowed
1125 if ((state->mmu_srp_limit & 3) == 0)
1127 m68ki_exception_trap(state, EXCEPTION_MMU_CONFIGURATION);
1131 if (!(modes & 0x100))
1133 pmmu_atc_flush(state);
1137 case 3: // CPU root pointer
1138 temp64 = READ_EA_64(state, ea);
1139 state->mmu_crp_limit = (temp64 >> 32) & 0xffffffff;
1140 state->mmu_crp_aptr = temp64 & 0xffffffff;
1141 MMULOG(("PMMU: CRP limit = %08x aptr = %08x\n", state->mmu_crp_limit, state->mmu_crp_aptr));
1142 // CRP type 0 is not allowed
1143 if ((state->mmu_crp_limit & 3) == 0)
1145 m68ki_exception_trap(state, EXCEPTION_MMU_CONFIGURATION);
1149 if (!(modes & 0x100))
1151 pmmu_atc_flush(state);
1155 case 7: // MC68851 Access Control Register
1156 if (state->cpu_type == CPU_TYPE_020)
1158 // DomainOS on Apollo DN3000 will only reset this to 0
1159 uint16 mmu_ac = READ_EA_16(state, ea);
1162 MMULOG(("680x0 PMMU: pc=%x PMOVE to mmu_ac=%08x\n",
1163 state->ppc, mmu_ac));
1167 // fall through; unknown PMOVE mode unless MC68020 with MC68851
1171 logerror("680x0: PMOVE to unknown MMU register %x, PC %x\n", (modes>>10) & 7, state->pc);
1175 case 3: // MMU status
1177 uint32 temp = READ_EA_32(state, ea);
1178 logerror("680x0: unsupported PMOVE %x to MMU status, PC %x\n", temp, state->pc);
1185 void m68851_pmove(m68ki_cpu_core *state, uint32 ea, uint16 modes)
1187 switch ((modes>>13) & 0x7)
1189 case 0: // MC68030/040 form with FD bit
1190 case 2: // MC68851 form, FD never set
1193 m68851_pmove_get(state, ea, modes);
1196 else // top 3 bits of modes: 010 for this, 011 for status, 000 for transparent translation regs
1198 m68851_pmove_put(state, ea, modes);
1201 case 3: // MC68030 to/from status reg
1204 MMULOG(("%s: read SR = %04x\n", __func__, state->mmu_sr));
1205 WRITE_EA_16(state, ea, state->mmu_sr);
1209 state->mmu_sr = READ_EA_16(state, ea);
1210 MMULOG(("%s: write SR = %04X\n", __func__, state->mmu_sr));
1215 logerror("680x0: unknown PMOVE mode %x (modes %04x) (PC %x)\n", (modes >> 13) & 0x7, modes, state->pc);
1222 void m68851_mmu_ops(m68ki_cpu_core *state)
1225 uint32 ea = state->ir & 0x3f;
1227 // catch the 2 "weird" encodings up front (PBcc)
1228 if ((state->ir & 0xffc0) == 0xf0c0)
1230 logerror("680x0: unhandled PBcc\n");
1233 else if ((state->ir & 0xffc0) == 0xf080)
1235 logerror("680x0: unhandled PBcc\n");
1238 else if ((state->ir & 0xffe0) == 0xf500)
1240 MMULOG(("68040 pflush: pc=%08x ir=%04x opmode=%d register=%d\n", REG_PC-4, state->ir, (state->ir >> 3) & 3, state->ir & 7));
1241 pmmu_atc_flush(state);
1243 else // the rest are 1111000xxxXXXXXX where xxx is the instruction family
1245 switch ((state->ir>>9) & 0x7)
1248 modes = OPER_I_16(state);
1250 if ((modes & 0xfde0) == 0x2000) // PLOAD
1252 m68851_pload(state, ea, modes);
1255 else if ((modes & 0xe200) == 0x2000) // PFLUSH
1257 pmmu_atc_flush_fc_ea(state, modes);
1260 else if (modes == 0xa000) // PFLUSHR
1262 pmmu_atc_flush(state);
1265 else if (modes == 0x2800) // PVALID (FORMAT 1)
1267 logerror("680x0: unhandled PVALID1\n");
1270 else if ((modes & 0xfff8) == 0x2c00) // PVALID (FORMAT 2)
1272 logerror("680x0: unhandled PVALID2\n");
1275 else if ((modes & 0xe000) == 0x8000) // PTEST
1277 m68851_ptest(state, ea, modes);
1282 m68851_pmove(state, ea, modes);
1287 logerror("680x0: unknown PMMU instruction group %d\n", (state->ir>>9) & 0x7);
1294 /* Apple HMMU translation is much simpler */
1296 inline uint32 hmmu_translate_addr(uint32 addr_in)
1302 // check if LC 24-bit mode is enabled - this simply blanks out A31, the V8 ignores A30-24 always
1303 if (state->hmmu_enabled == M68K_HMMU_ENABLE_LC)
1305 addr_out = addr_in & 0xffffff;
1307 else if (state->hmmu_enabled == M68K_HMMU_ENABLE_II) // the original II does a more complex translation
1309 addr_out = addr_in & 0xffffff;
1311 if ((addr_out >= 0x800000) && (addr_out <= 0x8fffff))
1313 addr_out |= 0x40000000; // ROM
1315 else if ((addr_out >= 0x900000) && (addr_out <= 0xefffff))
1317 addr_out = 0xf0000000; // NuBus
1318 addr_out |= ((addr_in & 0xf00000)<<4);
1319 addr_out |= (addr_in & 0xfffff);
1321 else if (addr_out >= 0xf00000)
1323 addr_out |= 0x50000000; // I/O
1326 // (RAM is at 0 and doesn't need special massaging)
1332 int m68851_buserror(u32& addr)
1334 if (!state->pmmu_enabled)
1339 if (state->mmu_tablewalk)
1341 MMULOG(("buserror during table walk\n"));
1342 state->mmu_tmp_sr |= M68K_MMU_SR_BUS_ERROR|M68K_MMU_SR_INVALID;
1346 addr = state->mmu_last_logical_addr;