mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-12-18 05:28:36 -07:00
Replace is_user variable with mmu_idx in softmmu core,
allowing support of more than 2 mmu access modes. Add backward compatibility is_user variable in targets code when needed. Implement per target cpu_mmu_index function, avoiding duplicated code and #ifdef TARGET_xxx in softmmu core functions. Implement per target mmu modes definitions. As an example, add PowerPC hypervisor mode definition and Alpha executive and kernel modes definitions. Optimize PowerPC case, precomputing mmu_idx when MSR register changes and using the same definition in code translation code. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3384 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
d0f48074db
commit
6ebbf39000
48 changed files with 362 additions and 275 deletions
119
softmmu_header.h
119
softmmu_header.h
|
|
@ -39,66 +39,19 @@
|
|||
#error unsupported data size
|
||||
#endif
|
||||
|
||||
#if ACCESS_TYPE == 0
|
||||
#if ACCESS_TYPE < (NB_MMU_MODES)
|
||||
|
||||
#define CPU_MEM_INDEX 0
|
||||
#define CPU_MMU_INDEX ACCESS_TYPE
|
||||
#define MMUSUFFIX _mmu
|
||||
|
||||
#elif ACCESS_TYPE == 1
|
||||
#elif ACCESS_TYPE == (NB_MMU_MODES)
|
||||
|
||||
#define CPU_MEM_INDEX 1
|
||||
#define CPU_MMU_INDEX (cpu_mmu_index(env))
|
||||
#define MMUSUFFIX _mmu
|
||||
|
||||
#elif ACCESS_TYPE == 2
|
||||
#elif ACCESS_TYPE == (NB_MMU_MODES + 1)
|
||||
|
||||
#ifdef TARGET_I386
|
||||
#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
|
||||
#elif defined (TARGET_PPC)
|
||||
#define CPU_MEM_INDEX (msr_pr)
|
||||
#elif defined (TARGET_MIPS)
|
||||
#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM)
|
||||
#elif defined (TARGET_SPARC)
|
||||
#define CPU_MEM_INDEX ((env->psrs) == 0)
|
||||
#elif defined (TARGET_ARM)
|
||||
#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
|
||||
#elif defined (TARGET_SH4)
|
||||
#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)
|
||||
#elif defined (TARGET_ALPHA)
|
||||
#define CPU_MEM_INDEX ((env->ps >> 3) & 3)
|
||||
#elif defined (TARGET_M68K)
|
||||
#define CPU_MEM_INDEX ((env->sr & SR_S) == 0)
|
||||
#elif defined (TARGET_CRIS)
|
||||
/* CRIS FIXME: I guess we want to validate supervisor mode acceses here. */
|
||||
#define CPU_MEM_INDEX (0)
|
||||
#else
|
||||
#error unsupported CPU
|
||||
#endif
|
||||
#define MMUSUFFIX _mmu
|
||||
|
||||
#elif ACCESS_TYPE == 3
|
||||
|
||||
#ifdef TARGET_I386
|
||||
#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
|
||||
#elif defined (TARGET_PPC)
|
||||
#define CPU_MEM_INDEX (msr_pr)
|
||||
#elif defined (TARGET_MIPS)
|
||||
#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM)
|
||||
#elif defined (TARGET_SPARC)
|
||||
#define CPU_MEM_INDEX ((env->psrs) == 0)
|
||||
#elif defined (TARGET_ARM)
|
||||
#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)
|
||||
#elif defined (TARGET_SH4)
|
||||
#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)
|
||||
#elif defined (TARGET_ALPHA)
|
||||
#define CPU_MEM_INDEX ((env->ps >> 3) & 3)
|
||||
#elif defined (TARGET_M68K)
|
||||
#define CPU_MEM_INDEX ((env->sr & SR_S) == 0)
|
||||
#elif defined (TARGET_CRIS)
|
||||
/* CRIS FIXME: I guess we want to validate supervisor mode acceses here. */
|
||||
#define CPU_MEM_INDEX (0)
|
||||
#else
|
||||
#error unsupported CPU
|
||||
#endif
|
||||
#define CPU_MMU_INDEX (cpu_mmu_index(env))
|
||||
#define MMUSUFFIX _cmmu
|
||||
|
||||
#else
|
||||
|
|
@ -111,18 +64,18 @@
|
|||
#define RES_TYPE int
|
||||
#endif
|
||||
|
||||
#if ACCESS_TYPE == 3
|
||||
#if ACCESS_TYPE == (NB_MMU_MODES + 1)
|
||||
#define ADDR_READ addr_code
|
||||
#else
|
||||
#define ADDR_READ addr_read
|
||||
#endif
|
||||
|
||||
DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
|
||||
int is_user);
|
||||
void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE v, int is_user);
|
||||
int mmu_idx);
|
||||
void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE v, int mmu_idx);
|
||||
|
||||
#if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \
|
||||
(ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU)
|
||||
(ACCESS_TYPE < NB_MMU_MODES) && defined(ASM_SOFTMMU)
|
||||
|
||||
#define CPU_TLB_ENTRY_BITS 4
|
||||
|
||||
|
|
@ -161,8 +114,8 @@ static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
|
|||
"i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
|
||||
"i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
|
||||
"i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
|
||||
"m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
|
||||
"i" (CPU_MEM_INDEX),
|
||||
"m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
|
||||
"i" (CPU_MMU_INDEX),
|
||||
"m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
|
||||
: "%eax", "%ecx", "%edx", "memory", "cc");
|
||||
return res;
|
||||
|
|
@ -208,8 +161,8 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
|
|||
"i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
|
||||
"i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
|
||||
"i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
|
||||
"m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
|
||||
"i" (CPU_MEM_INDEX),
|
||||
"m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
|
||||
"i" (CPU_MMU_INDEX),
|
||||
"m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
|
||||
: "%eax", "%ecx", "%edx", "memory", "cc");
|
||||
return res;
|
||||
|
|
@ -260,8 +213,8 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE
|
|||
"i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
|
||||
"i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
|
||||
"i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
|
||||
"m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_write)),
|
||||
"i" (CPU_MEM_INDEX),
|
||||
"m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_write)),
|
||||
"i" (CPU_MMU_INDEX),
|
||||
"m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX))
|
||||
: "%eax", "%ecx", "%edx", "memory", "cc");
|
||||
}
|
||||
|
|
@ -276,16 +229,16 @@ static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
|
|||
RES_TYPE res;
|
||||
target_ulong addr;
|
||||
unsigned long physaddr;
|
||||
int is_user;
|
||||
int mmu_idx;
|
||||
|
||||
addr = ptr;
|
||||
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
|
||||
is_user = CPU_MEM_INDEX;
|
||||
if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
|
||||
mmu_idx = CPU_MMU_INDEX;
|
||||
if (__builtin_expect(env->tlb_table[mmu_idx][index].ADDR_READ !=
|
||||
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
|
||||
res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
|
||||
res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
|
||||
} else {
|
||||
physaddr = addr + env->tlb_table[is_user][index].addend;
|
||||
physaddr = addr + env->tlb_table[mmu_idx][index].addend;
|
||||
res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
|
||||
}
|
||||
return res;
|
||||
|
|
@ -297,23 +250,23 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
|
|||
int res, index;
|
||||
target_ulong addr;
|
||||
unsigned long physaddr;
|
||||
int is_user;
|
||||
int mmu_idx;
|
||||
|
||||
addr = ptr;
|
||||
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
|
||||
is_user = CPU_MEM_INDEX;
|
||||
if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
|
||||
mmu_idx = CPU_MMU_INDEX;
|
||||
if (__builtin_expect(env->tlb_table[mmu_idx][index].ADDR_READ !=
|
||||
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
|
||||
res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
|
||||
res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
|
||||
} else {
|
||||
physaddr = addr + env->tlb_table[is_user][index].addend;
|
||||
physaddr = addr + env->tlb_table[mmu_idx][index].addend;
|
||||
res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ACCESS_TYPE != 3
|
||||
#if ACCESS_TYPE != (NB_MMU_MODES + 1)
|
||||
|
||||
/* generic store macro */
|
||||
|
||||
|
|
@ -322,25 +275,25 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE
|
|||
int index;
|
||||
target_ulong addr;
|
||||
unsigned long physaddr;
|
||||
int is_user;
|
||||
int mmu_idx;
|
||||
|
||||
addr = ptr;
|
||||
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
|
||||
is_user = CPU_MEM_INDEX;
|
||||
if (__builtin_expect(env->tlb_table[is_user][index].addr_write !=
|
||||
mmu_idx = CPU_MMU_INDEX;
|
||||
if (__builtin_expect(env->tlb_table[mmu_idx][index].addr_write !=
|
||||
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
|
||||
glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, is_user);
|
||||
glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, mmu_idx);
|
||||
} else {
|
||||
physaddr = addr + env->tlb_table[is_user][index].addend;
|
||||
physaddr = addr + env->tlb_table[mmu_idx][index].addend;
|
||||
glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ACCESS_TYPE != 3 */
|
||||
#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
|
||||
|
||||
#endif /* !asm */
|
||||
|
||||
#if ACCESS_TYPE != 3
|
||||
#if ACCESS_TYPE != (NB_MMU_MODES + 1)
|
||||
|
||||
#if DATA_SIZE == 8
|
||||
static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr)
|
||||
|
|
@ -386,7 +339,7 @@ static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
|
|||
}
|
||||
#endif /* DATA_SIZE == 4 */
|
||||
|
||||
#endif /* ACCESS_TYPE != 3 */
|
||||
#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
|
||||
|
||||
#undef RES_TYPE
|
||||
#undef DATA_TYPE
|
||||
|
|
@ -394,6 +347,6 @@ static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
|
|||
#undef SUFFIX
|
||||
#undef USUFFIX
|
||||
#undef DATA_SIZE
|
||||
#undef CPU_MEM_INDEX
|
||||
#undef CPU_MMU_INDEX
|
||||
#undef MMUSUFFIX
|
||||
#undef ADDR_READ
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue