[PATCH v4 4/6] target/m68k: Extract Function Codes during TLB fills
54weasels <[email protected]>
| Newsgroups | org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
High level description: The Motorola 68020 architecture utilizes 3-bit Function Codes (FC0-FC2) to distinguish between User/Supervisor Data and Program memory spaces during MMU translation. Previously, QEMU's TLB fills did not explicitly extract or pass these codes down to the translation hooks. This patch extracts the explicit Function Codes (either natively or via the `moves` instruction) and packs them into the `access_type` field. This is required for the upcoming Sun-3 emulation, whose external MMU hardware maps entirely different physical address spaces depending on the Function Code asserted on the bus. Impact on existing functionality: This change introduces no functional impact to existing ColdFire or Mac/Quadra m68k emulation targets. The extraction logic gracefully defaults to standard mapping modes for platforms that do not implement a custom MMU intercept hook, preserving existing TLB behavior. Context: This patch was originally submitted as part of the monolithic Sun-3 Machine Emulation series (https://patchew.org/QEMU/[email protected]/) and has been split into atomic components. --- target/m68k/cpu.c | 4 ++-- target/m68k/cpu.h | 10 ++++++---- target/m68k/helper.c | 26 ++++++++++++++++++++++++++ target/m68k/translate.c | 10 ++++++---- 4 files changed, 40 insertions(+), 10 deletions(-) diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c index ce2707dee5..f97f20e999 100644 --- a/target/m68k/cpu.c +++ b/target/m68k/cpu.c @@ -52,8 +52,8 @@ static TCGTBCPUState m68k_get_tb_cpu_state(CPUState *cs) flags = (env->macsr >> 4) & TB_FLAGS_MACSR; if (env->sr & SR_S) { flags |= TB_FLAGS_MSR_S; - flags |= (env->sfc << (TB_FLAGS_SFC_S_BIT - 2)) & TB_FLAGS_SFC_S; - flags |= (env->dfc << (TB_FLAGS_DFC_S_BIT - 2)) & TB_FLAGS_DFC_S; + flags |= (env->sfc << TB_FLAGS_SFC_S_BIT) & TB_FLAGS_SFC_S; + flags |= (env->dfc << TB_FLAGS_DFC_S_BIT) & TB_FLAGS_DFC_S; } if (M68K_SR_TRACE(env->sr) == M68K_SR_TRACE_ANY_INS) { flags |= TB_FLAGS_TRACE; diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h index 058777b891..42d34502fc 100644 --- a/target/m68k/cpu.h +++ b/target/m68k/cpu.h @@ -601,12 +601,14 @@ void m68k_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr, #define TB_FLAGS_MSR_S_BIT 13 #define TB_FLAGS_MSR_S (1 << TB_FLAGS_MSR_S_BIT) #define TB_FLAGS_SFC_S_BIT 14 -#define TB_FLAGS_SFC_S (1 << TB_FLAGS_SFC_S_BIT) -#define TB_FLAGS_DFC_S_BIT 15 -#define TB_FLAGS_DFC_S (1 << TB_FLAGS_DFC_S_BIT) -#define TB_FLAGS_TRACE 16 +#define TB_FLAGS_SFC_S (7 << TB_FLAGS_SFC_S_BIT) /* 3 Bits reserved */ +#define TB_FLAGS_DFC_S_BIT 17 +#define TB_FLAGS_DFC_S (7 << TB_FLAGS_DFC_S_BIT) /* 3 Bits reserved */ +#define TB_FLAGS_TRACE 20 #define TB_FLAGS_TRACE_BIT (1 << TB_FLAGS_TRACE) +#define MMU_MOVES_FC_BASE 2 /* mmu_idx 2-9 correspond to FC 0-7 */ + void dump_mmu(CPUM68KState *env); #endif diff --git a/target/m68k/helper.c b/target/m68k/helper.c index 93739ccda7..f3ee95441a 100644 --- a/target/m68k/helper.c +++ b/target/m68k/helper.c @@ -975,6 +975,32 @@ bool m68k_cpu_tlb_fill(CPUState *cs, vaddr address, int size, int ret; target_ulong page_size; + if (qemu_access_type == MMU_INST_FETCH) { + access_type = ACCESS_CODE; + } else { + access_type = ACCESS_DATA; + if (qemu_access_type == MMU_DATA_STORE) { + access_type |= ACCESS_STORE; + } + } + + /* Decode explicit Function Codes from moves instructions */ + if (mmu_idx >= MMU_MOVES_FC_BASE) { + uint8_t fc = mmu_idx - MMU_MOVES_FC_BASE; + access_type |= (fc << 8); /* Pack explicit FC into access type */ + if (fc != 1 && fc != 2) { + access_type |= ACCESS_SUPER; + } + } else { + /* Standard memory accesses map logically to normal M68K FCs */ + if (mmu_idx == MMU_KERNEL_IDX) { + access_type |= ACCESS_SUPER; + access_type |= ((qemu_access_type == MMU_INST_FETCH ? 6 : 5) << 8); + } else { + access_type |= ((qemu_access_type == MMU_INST_FETCH ? 2 : 1) << 8); + } + } + if ((env->mmu.tcr & M68K_TCR_ENABLED) == 0) { /* MMU disabled */ tlb_set_page(cs, address & TARGET_PAGE_MASK, diff --git a/target/m68k/translate.c b/target/m68k/translate.c index bdf619883c..6aa4c5fafd 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -163,10 +163,12 @@ static void do_writebacks(DisasContext *s) #define IS_USER(s) 1 #else #define IS_USER(s) (!(s->base.tb->flags & TB_FLAGS_MSR_S)) -#define SFC_INDEX(s) ((s->base.tb->flags & TB_FLAGS_SFC_S) ? \ - MMU_KERNEL_IDX : MMU_USER_IDX) -#define DFC_INDEX(s) ((s->base.tb->flags & TB_FLAGS_DFC_S) ? \ - MMU_KERNEL_IDX : MMU_USER_IDX) +#define SFC_INDEX(s) (MMU_MOVES_FC_BASE + \ + (((s)->base.tb->flags & TB_FLAGS_SFC_S) >> \ + TB_FLAGS_SFC_S_BIT)) +#define DFC_INDEX(s) (MMU_MOVES_FC_BASE + \ + (((s)->base.tb->flags & TB_FLAGS_DFC_S) >> \ + TB_FLAGS_DFC_S_BIT)) #endif typedef void (*disas_proc)(CPUM68KState *env, DisasContext *s, uint16_t insn); -- 2.50.1 (Apple Git-155)