Loading target/m68k/cpu.h +3 −0 Original line number Diff line number Diff line Loading @@ -131,6 +131,7 @@ typedef struct CPUM68KState { uint32_t srp; bool fault; uint32_t ttr[4]; uint32_t mmusr; } mmu; /* Control registers. */ Loading Loading @@ -512,6 +513,8 @@ enum { ACCESS_STORE = 0x02, /* 1 bit to indicate debug access */ ACCESS_DEBUG = 0x04, /* PTEST instruction */ ACCESS_PTEST = 0x08, /* Type of instruction that generated the access */ ACCESS_CODE = 0x10, /* Code fetch access */ ACCESS_DATA = 0x20, /* Data load/store access */ Loading target/m68k/helper.c +73 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,9 @@ void HELPER(m68k_movec_to)(CPUM68KState *env, uint32_t reg, uint32_t val) case M68K_CR_TC: env->mmu.tcr = val; return; case M68K_CR_MMUSR: env->mmu.mmusr = val; return; case M68K_CR_SRP: env->mmu.srp = val; return; Loading Loading @@ -272,6 +275,8 @@ uint32_t HELPER(m68k_movec_from)(CPUM68KState *env, uint32_t reg) /* MC680[34]0 */ case M68K_CR_TC: return env->mmu.tcr; case M68K_CR_MMUSR: return env->mmu.mmusr; case M68K_CR_SRP: return env->mmu.srp; case M68K_CR_USP: Loading Loading @@ -433,6 +438,10 @@ static int get_physical_address(CPUM68KState *env, hwaddr *physical, for (i = 0; i < M68K_MAX_TTR; i++) { if (check_TTR(env->mmu.TTR(access_type, i), prot, address, access_type)) { if (access_type & ACCESS_PTEST) { /* Transparent Translation Register bit */ env->mmu.mmusr = M68K_MMU_T_040 | M68K_MMU_R_040; } *physical = address & TARGET_PAGE_MASK; *page_size = TARGET_PAGE_SIZE; return 0; Loading Loading @@ -461,6 +470,9 @@ static int get_physical_address(CPUM68KState *env, hwaddr *physical, stl_phys(cs->as, entry, next | M68K_DESC_USED); } if (next & M68K_DESC_WRITEPROT) { if (access_type & ACCESS_PTEST) { env->mmu.mmusr |= M68K_MMU_WP_040; } *prot &= ~PAGE_WRITE; if (access_type & ACCESS_STORE) { return -1; Loading @@ -478,6 +490,9 @@ static int get_physical_address(CPUM68KState *env, hwaddr *physical, stl_phys(cs->as, entry, next | M68K_DESC_USED); } if (next & M68K_DESC_WRITEPROT) { if (access_type & ACCESS_PTEST) { env->mmu.mmusr |= M68K_MMU_WP_040; } *prot &= ~PAGE_WRITE; if (access_type & ACCESS_STORE) { return -1; Loading Loading @@ -524,6 +539,12 @@ static int get_physical_address(CPUM68KState *env, hwaddr *physical, page_mask = ~(*page_size - 1); *physical = next & page_mask; if (access_type & ACCESS_PTEST) { env->mmu.mmusr |= next & M68K_MMU_SR_MASK_040; env->mmu.mmusr |= *physical & 0xfffff000; env->mmu.mmusr |= M68K_MMU_R_040; } if (next & M68K_DESC_WRITEPROT) { *prot &= ~PAGE_WRITE; if (access_type & ACCESS_STORE) { Loading Loading @@ -1078,6 +1099,58 @@ void HELPER(set_mac_extu)(CPUM68KState *env, uint32_t val, uint32_t acc) } #if defined(CONFIG_SOFTMMU) void HELPER(ptest)(CPUM68KState *env, uint32_t addr, uint32_t is_read) { M68kCPU *cpu = m68k_env_get_cpu(env); CPUState *cs = CPU(cpu); hwaddr physical; int access_type; int prot; int ret; target_ulong page_size; access_type = ACCESS_PTEST; if (env->dfc & 4) { access_type |= ACCESS_SUPER; } if ((env->dfc & 3) == 2) { access_type |= ACCESS_CODE; } if (!is_read) { access_type |= ACCESS_STORE; } env->mmu.mmusr = 0; env->mmu.ssw = 0; ret = get_physical_address(env, &physical, &prot, addr, access_type, &page_size); if (ret == 0) { addr &= TARGET_PAGE_MASK; physical += addr & (page_size - 1); tlb_set_page(cs, addr, physical, prot, access_type & ACCESS_SUPER ? MMU_KERNEL_IDX : MMU_USER_IDX, page_size); } } void HELPER(pflush)(CPUM68KState *env, uint32_t addr, uint32_t opmode) { M68kCPU *cpu = m68k_env_get_cpu(env); switch (opmode) { case 0: /* Flush page entry if not global */ case 1: /* Flush page entry */ tlb_flush_page(CPU(cpu), addr); break; case 2: /* Flush all except global entries */ tlb_flush(CPU(cpu)); break; case 3: /* Flush all entries */ tlb_flush(CPU(cpu)); break; } } void HELPER(reset)(CPUM68KState *env) { /* FIXME: reset all except CPU */ Loading target/m68k/helper.h +2 −0 Original line number Diff line number Diff line Loading @@ -101,5 +101,7 @@ DEF_HELPER_3(chk, void, env, s32, s32) DEF_HELPER_4(chk2, void, env, s32, s32, s32) #if defined(CONFIG_SOFTMMU) DEF_HELPER_3(ptest, void, env, i32, i32) DEF_HELPER_3(pflush, void, env, i32, i32) DEF_HELPER_FLAGS_1(reset, TCG_CALL_NO_RWG, void, env) #endif target/m68k/monitor.c +1 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ static const MonitorDef monitor_defs[] = { { "dttr1", offsetof(CPUM68KState, mmu.ttr[M68K_DTTR1]) }, { "ittr0", offsetof(CPUM68KState, mmu.ttr[M68K_ITTR0]) }, { "ittr1", offsetof(CPUM68KState, mmu.ttr[M68K_ITTR1]) }, { "mmusr", offsetof(CPUM68KState, mmu.mmusr) }, { NULL }, }; Loading target/m68k/op_helper.c +1 −0 Original line number Diff line number Diff line Loading @@ -466,6 +466,7 @@ void m68k_cpu_unassigned_access(CPUState *cs, hwaddr addr, bool is_write, } if (m68k_feature(env, M68K_FEATURE_M68040)) { env->mmu.mmusr = 0; env->mmu.ssw |= M68K_ATC_040; /* FIXME: manage MMU table access error */ env->mmu.ssw &= ~M68K_TM_040; Loading Loading
target/m68k/cpu.h +3 −0 Original line number Diff line number Diff line Loading @@ -131,6 +131,7 @@ typedef struct CPUM68KState { uint32_t srp; bool fault; uint32_t ttr[4]; uint32_t mmusr; } mmu; /* Control registers. */ Loading Loading @@ -512,6 +513,8 @@ enum { ACCESS_STORE = 0x02, /* 1 bit to indicate debug access */ ACCESS_DEBUG = 0x04, /* PTEST instruction */ ACCESS_PTEST = 0x08, /* Type of instruction that generated the access */ ACCESS_CODE = 0x10, /* Code fetch access */ ACCESS_DATA = 0x20, /* Data load/store access */ Loading
target/m68k/helper.c +73 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,9 @@ void HELPER(m68k_movec_to)(CPUM68KState *env, uint32_t reg, uint32_t val) case M68K_CR_TC: env->mmu.tcr = val; return; case M68K_CR_MMUSR: env->mmu.mmusr = val; return; case M68K_CR_SRP: env->mmu.srp = val; return; Loading Loading @@ -272,6 +275,8 @@ uint32_t HELPER(m68k_movec_from)(CPUM68KState *env, uint32_t reg) /* MC680[34]0 */ case M68K_CR_TC: return env->mmu.tcr; case M68K_CR_MMUSR: return env->mmu.mmusr; case M68K_CR_SRP: return env->mmu.srp; case M68K_CR_USP: Loading Loading @@ -433,6 +438,10 @@ static int get_physical_address(CPUM68KState *env, hwaddr *physical, for (i = 0; i < M68K_MAX_TTR; i++) { if (check_TTR(env->mmu.TTR(access_type, i), prot, address, access_type)) { if (access_type & ACCESS_PTEST) { /* Transparent Translation Register bit */ env->mmu.mmusr = M68K_MMU_T_040 | M68K_MMU_R_040; } *physical = address & TARGET_PAGE_MASK; *page_size = TARGET_PAGE_SIZE; return 0; Loading Loading @@ -461,6 +470,9 @@ static int get_physical_address(CPUM68KState *env, hwaddr *physical, stl_phys(cs->as, entry, next | M68K_DESC_USED); } if (next & M68K_DESC_WRITEPROT) { if (access_type & ACCESS_PTEST) { env->mmu.mmusr |= M68K_MMU_WP_040; } *prot &= ~PAGE_WRITE; if (access_type & ACCESS_STORE) { return -1; Loading @@ -478,6 +490,9 @@ static int get_physical_address(CPUM68KState *env, hwaddr *physical, stl_phys(cs->as, entry, next | M68K_DESC_USED); } if (next & M68K_DESC_WRITEPROT) { if (access_type & ACCESS_PTEST) { env->mmu.mmusr |= M68K_MMU_WP_040; } *prot &= ~PAGE_WRITE; if (access_type & ACCESS_STORE) { return -1; Loading Loading @@ -524,6 +539,12 @@ static int get_physical_address(CPUM68KState *env, hwaddr *physical, page_mask = ~(*page_size - 1); *physical = next & page_mask; if (access_type & ACCESS_PTEST) { env->mmu.mmusr |= next & M68K_MMU_SR_MASK_040; env->mmu.mmusr |= *physical & 0xfffff000; env->mmu.mmusr |= M68K_MMU_R_040; } if (next & M68K_DESC_WRITEPROT) { *prot &= ~PAGE_WRITE; if (access_type & ACCESS_STORE) { Loading Loading @@ -1078,6 +1099,58 @@ void HELPER(set_mac_extu)(CPUM68KState *env, uint32_t val, uint32_t acc) } #if defined(CONFIG_SOFTMMU) void HELPER(ptest)(CPUM68KState *env, uint32_t addr, uint32_t is_read) { M68kCPU *cpu = m68k_env_get_cpu(env); CPUState *cs = CPU(cpu); hwaddr physical; int access_type; int prot; int ret; target_ulong page_size; access_type = ACCESS_PTEST; if (env->dfc & 4) { access_type |= ACCESS_SUPER; } if ((env->dfc & 3) == 2) { access_type |= ACCESS_CODE; } if (!is_read) { access_type |= ACCESS_STORE; } env->mmu.mmusr = 0; env->mmu.ssw = 0; ret = get_physical_address(env, &physical, &prot, addr, access_type, &page_size); if (ret == 0) { addr &= TARGET_PAGE_MASK; physical += addr & (page_size - 1); tlb_set_page(cs, addr, physical, prot, access_type & ACCESS_SUPER ? MMU_KERNEL_IDX : MMU_USER_IDX, page_size); } } void HELPER(pflush)(CPUM68KState *env, uint32_t addr, uint32_t opmode) { M68kCPU *cpu = m68k_env_get_cpu(env); switch (opmode) { case 0: /* Flush page entry if not global */ case 1: /* Flush page entry */ tlb_flush_page(CPU(cpu), addr); break; case 2: /* Flush all except global entries */ tlb_flush(CPU(cpu)); break; case 3: /* Flush all entries */ tlb_flush(CPU(cpu)); break; } } void HELPER(reset)(CPUM68KState *env) { /* FIXME: reset all except CPU */ Loading
target/m68k/helper.h +2 −0 Original line number Diff line number Diff line Loading @@ -101,5 +101,7 @@ DEF_HELPER_3(chk, void, env, s32, s32) DEF_HELPER_4(chk2, void, env, s32, s32, s32) #if defined(CONFIG_SOFTMMU) DEF_HELPER_3(ptest, void, env, i32, i32) DEF_HELPER_3(pflush, void, env, i32, i32) DEF_HELPER_FLAGS_1(reset, TCG_CALL_NO_RWG, void, env) #endif
target/m68k/monitor.c +1 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ static const MonitorDef monitor_defs[] = { { "dttr1", offsetof(CPUM68KState, mmu.ttr[M68K_DTTR1]) }, { "ittr0", offsetof(CPUM68KState, mmu.ttr[M68K_ITTR0]) }, { "ittr1", offsetof(CPUM68KState, mmu.ttr[M68K_ITTR1]) }, { "mmusr", offsetof(CPUM68KState, mmu.mmusr) }, { NULL }, }; Loading
target/m68k/op_helper.c +1 −0 Original line number Diff line number Diff line Loading @@ -466,6 +466,7 @@ void m68k_cpu_unassigned_access(CPUState *cs, hwaddr addr, bool is_write, } if (m68k_feature(env, M68K_FEATURE_M68040)) { env->mmu.mmusr = 0; env->mmu.ssw |= M68K_ATC_040; /* FIXME: manage MMU table access error */ env->mmu.ssw &= ~M68K_TM_040; Loading