60 struct m8820x_cmmu *cmmu, uint32_t apr, uint32_t vaddr)
62 int seg_nr = vaddr >> 22, page_nr = (vaddr >> 12) & 0x3ff;
63 uint32_t *seg_base, *page_base;
69 cpu->
mem, apr & 0xfffff000, 1);
70 seg_descriptor = seg_base[seg_nr];
78 cpu->
mem, seg_descriptor & 0xfffff000, 1);
79 page_descriptor = page_base[page_nr];
93 page_base[page_nr] = page_descriptor;
104 uint64_t *return_paddr,
int flags)
113 uint32_t vaddr = vaddr64;
115 uint32_t *seg_base, *page_base;
120 int accumulated_flags;
121 int i, seg_nr = vaddr >> 22, page_nr = (vaddr >> 12) & 0x3ff;
130 *return_paddr = vaddr;
160 if ((supervisor && !(batc &
BATC_SO)) ||
161 (!supervisor && (batc & BATC_SO)))
165 if ((vaddr & 0xfff80000) != (batc & 0xfff80000))
176 *return_paddr = ((batc & 0x0007ffc0) << 13)
177 | (vaddr & 0x0007ffff);
179 return batc & BATC_PROT? 1 : 2;
195 if (!(vaddr_and_control &
PG_V))
199 if ((vaddr & 0xfffff000) != (vaddr_and_control & 0xfffff000))
204 && !supervisor) || (supervisor &&
205 !(paddr_and_sbit & M8820X_PATC_SUPERVISOR_BIT)))
211 if ((vaddr_and_control &
PG_PROT) && writeflag) {
217 if (!(vaddr_and_control &
PG_M) && writeflag &&
232 *return_paddr = (paddr_and_sbit & 0xfffff000) | (vaddr & 0xfff);
233 return vaddr_and_control & PG_PROT? 1 : 2;
244 cpu->
mem, apr & 0xfffff000, 1);
246 seg_descriptor = seg_base[seg_nr];
252 #ifdef M8820X_TABLE_SEARCH_DEBUG 253 printf(
"+--- M8820x page table search debug:\n");
254 printf(
"| vaddr 0x%08"PRIx32
"\n", vaddr);
255 printf(
"| apr 0x%08"PRIx32
"\n", apr);
256 printf(
"| seg_base %p (on the host)\n", seg_base);
257 printf(
"| seg_nr 0x%03x\n", seg_nr);
258 printf(
"| page_nr 0x%03x\n", page_nr);
259 printf(
"| sd 0x%08"PRIx32
"\n", seg_descriptor);
263 if (!(seg_descriptor &
SG_V)) {
265 pfar = (apr & 0xfffff000) + seg_nr *
sizeof(uint32_t);
271 if ((seg_descriptor &
SG_SO) && !supervisor) {
273 pfar = (apr & 0xfffff000) + seg_nr *
sizeof(uint32_t);
278 accumulated_flags = seg_descriptor &
SG_RO;
281 cpu->
mem, seg_descriptor & 0xfffff000, 1);
283 page_descriptor = page_base[page_nr];
289 #ifdef M8820X_TABLE_SEARCH_DEBUG 290 printf(
"| page_base %p (on the host)\n", page_base);
291 printf(
"| pd 0x%08"PRIx32
"\n", page_descriptor);
295 if (!(page_descriptor &
PG_V)) {
297 pfar = (seg_descriptor & 0xfffff000)
298 + page_nr *
sizeof(uint32_t);
304 if ((page_descriptor &
PG_SO) && !supervisor) {
306 pfar = (seg_descriptor & 0xfffff000)
307 + page_nr *
sizeof(uint32_t);
312 accumulated_flags |= (page_descriptor &
PG_RO);
319 if (!no_exceptions) {
332 (vaddr & 0xfffff000) | accumulated_flags | PG_V;
334 (page_descriptor & 0xfffff000) |
339 if (writeflag && (accumulated_flags &
PG_RO)) {
344 if (!no_exceptions) {
356 tmp = page_descriptor |
PG_U;
365 page_base[page_nr] = tmp;
369 *return_paddr = (page_descriptor & 0xfffff000) | (vaddr & 0xfff);
370 return (accumulated_flags & PG_RO)? 1 : 2;
388 switch (pfsr_status) {
391 fatal(
"HUH? CMMU_PFSR_SUCCESS:, but exception? TODO\n");
407 fatal(
"Internal error in memory_m88k? pfsr_status = %i\n",
void fatal(const char *fmt,...)
#define FLAG_NOEXCEPTIONS
uint32_t patc_v_and_control[N_M88200_PATC_ENTRIES]
void m88k_exception(struct cpu *cpu, int vector, int is_trap)
uint32_t patc_p_and_supervisorbit[N_M88200_PATC_ENTRIES]
int m88k_translate_v2p(struct cpu *cpu, uint64_t vaddr64, uint64_t *return_paddr, int flags)
#define EMUL_LITTLE_ENDIAN
void m8820x_mark_page_as_modified(struct cpu *cpu, struct m8820x_cmmu *cmmu, uint32_t apr, uint32_t vaddr)
#define M8820X_PATC_SUPERVISOR_BIT
#define CMMU_PFSR_SUCCESS
#define N_M88200_PATC_ENTRIES
uint32_t cr[N_M88K_CONTROL_REGS]
#define N_M88200_BATC_REGS
#define MEMORY_USER_ACCESS
#define M88K_EXCEPTION_INSTRUCTION_ACCESS
uint32_t reg[M8820X_LENGTH/sizeof(uint32_t)]
#define M88K_EXCEPTION_DATA_ACCESS
struct m8820x_cmmu * cmmu[MAX_M8820X_CMMUS]
uint32_t batc[N_M88200_BATC_REGS]
void(* invalidate_translation_caches)(struct cpu *, uint64_t paddr, int flags)
unsigned char * memory_paddr_to_hostaddr(struct memory *mem, uint64_t paddr, int writeflag)