@@ -35,7 +35,7 @@ uint32_t cpu_mips_get_random (CPUState *env)
/* Don't return same value twice, so get another value */
do {
lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xd0000001u);
- idx = lfsr % (env->tlb->nb_tlb - env->CP0_Wired) + env->CP0_Wired;
+ idx = lfsr % (env->tlb.nb_tlb - env->CP0_Wired) + env->CP0_Wired;
} while (idx == prev_idx);
prev_idx = idx;
return idx;
@@ -475,7 +475,7 @@ struct CPUMIPSState {
CPUMIPSMVPContext mvp;
#if !defined(CONFIG_USER_ONLY)
- CPUMIPSTLBContext *tlb;
+ CPUMIPSTLBContext tlb;
#endif
const mips_def_t *cpu_model;
@@ -69,8 +69,8 @@ int r4k_map_address (CPUState *env, target_phys_addr_t *physical, int *prot,
uint8_t ASID = env->CP0_EntryHi & 0xFF;
int i;
- for (i = 0; i < env->tlb->tlb_in_use; i++) {
- r4k_tlb_t *tlb = &env->tlb->mmu.r4k.tlb[i];
+ for (i = 0; i < env->tlb.tlb_in_use; i++) {
+ r4k_tlb_t *tlb = &env->tlb.mmu.r4k.tlb[i];
/* 1k pages are not supported. */
target_ulong mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
target_ulong tag = address & ~mask;
@@ -124,13 +124,15 @@ static int get_physical_address (CPUState *env, target_phys_addr_t *physical,
*physical = address & 0xFFFFFFFF;
*prot = PAGE_READ | PAGE_WRITE;
} else {
- ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
+ ret = env->tlb.map_address(env, physical, prot, address, rw,
+ access_type);
}
#if defined(TARGET_MIPS64)
} else if (address < 0x4000000000000000ULL) {
/* xuseg */
if (UX && address <= (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) {
- ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
+ ret = env->tlb.map_address(env, physical, prot, address, rw,
+ access_type);
} else {
ret = TLBRET_BADADDR;
}
@@ -138,7 +140,8 @@ static int get_physical_address (CPUState *env, target_phys_addr_t *physical,
/* xsseg */
if ((supervisor_mode || kernel_mode) &&
SX && address <= (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) {
- ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
+ ret = env->tlb.map_address(env, physical, prot, address, rw,
+ access_type);
} else {
ret = TLBRET_BADADDR;
}
@@ -155,7 +158,8 @@ static int get_physical_address (CPUState *env, target_phys_addr_t *physical,
/* xkseg */
if (kernel_mode && KX &&
address <= (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) {
- ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
+ ret = env->tlb.map_address(env, physical, prot, address, rw,
+ access_type);
} else {
ret = TLBRET_BADADDR;
}
@@ -179,7 +183,8 @@ static int get_physical_address (CPUState *env, target_phys_addr_t *physical,
} else if (address < (int32_t)0xE0000000UL) {
/* sseg (kseg2) */
if (supervisor_mode || kernel_mode) {
- ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
+ ret = env->tlb.map_address(env, physical, prot, address, rw,
+ access_type);
} else {
ret = TLBRET_BADADDR;
}
@@ -187,7 +192,8 @@ static int get_physical_address (CPUState *env, target_phys_addr_t *physical,
/* kseg3 */
/* XXX: debug segment is not emulated */
if (kernel_mode) {
- ret = env->tlb->map_address(env, physical, prot, address, rw, access_type);
+ ret = env->tlb.map_address(env, physical, prot, address, rw,
+ access_type);
} else {
ret = TLBRET_BADADDR;
}
@@ -645,19 +651,19 @@ void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra)
uint8_t ASID = env->CP0_EntryHi & 0xFF;
target_ulong mask;
- tlb = &env->tlb->mmu.r4k.tlb[idx];
+ tlb = &env->tlb.mmu.r4k.tlb[idx];
/* The qemu TLB is flushed when the ASID changes, so no need to
flush these entries again. */
if (tlb->G == 0 && tlb->ASID != ASID) {
return;
}
- if (use_extra && env->tlb->tlb_in_use < MIPS_TLB_MAX) {
+ if (use_extra && env->tlb.tlb_in_use < MIPS_TLB_MAX) {
/* For tlbwr, we can shadow the discarded entry into
a new (fake) TLB entry, as long as the guest can not
tell that it's there. */
- env->tlb->mmu.r4k.tlb[env->tlb->tlb_in_use] = *tlb;
- env->tlb->tlb_in_use++;
+ env->tlb.mmu.r4k.tlb[env->tlb.tlb_in_use] = *tlb;
+ env->tlb.tlb_in_use++;
return;
}
@@ -57,25 +57,25 @@ void cpu_save(QEMUFile *f, void *opaque)
qemu_put_sbe32s(f, &env->mvp.CP0_MVPConf1);
/* Save TLB */
- qemu_put_be32s(f, &env->tlb->nb_tlb);
- qemu_put_be32s(f, &env->tlb->tlb_in_use);
+ qemu_put_be32s(f, &env->tlb.nb_tlb);
+ qemu_put_be32s(f, &env->tlb.tlb_in_use);
for(i = 0; i < MIPS_TLB_MAX; i++) {
- uint16_t flags = ((env->tlb->mmu.r4k.tlb[i].G << 10) |
- (env->tlb->mmu.r4k.tlb[i].C0 << 7) |
- (env->tlb->mmu.r4k.tlb[i].C1 << 4) |
- (env->tlb->mmu.r4k.tlb[i].V0 << 3) |
- (env->tlb->mmu.r4k.tlb[i].V1 << 2) |
- (env->tlb->mmu.r4k.tlb[i].D0 << 1) |
- (env->tlb->mmu.r4k.tlb[i].D1 << 0));
+ uint16_t flags = ((env->tlb.mmu.r4k.tlb[i].G << 10) |
+ (env->tlb.mmu.r4k.tlb[i].C0 << 7) |
+ (env->tlb.mmu.r4k.tlb[i].C1 << 4) |
+ (env->tlb.mmu.r4k.tlb[i].V0 << 3) |
+ (env->tlb.mmu.r4k.tlb[i].V1 << 2) |
+ (env->tlb.mmu.r4k.tlb[i].D0 << 1) |
+ (env->tlb.mmu.r4k.tlb[i].D1 << 0));
uint8_t asid;
- qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].VPN);
- qemu_put_be32s(f, &env->tlb->mmu.r4k.tlb[i].PageMask);
- asid = env->tlb->mmu.r4k.tlb[i].ASID;
+ qemu_put_betls(f, &env->tlb.mmu.r4k.tlb[i].VPN);
+ qemu_put_be32s(f, &env->tlb.mmu.r4k.tlb[i].PageMask);
+ asid = env->tlb.mmu.r4k.tlb[i].ASID;
qemu_put_8s(f, &asid);
qemu_put_be16s(f, &flags);
- qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[0]);
- qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[1]);
+ qemu_put_betls(f, &env->tlb.mmu.r4k.tlb[i].PFN[0]);
+ qemu_put_betls(f, &env->tlb.mmu.r4k.tlb[i].PFN[1]);
}
/* Save CPU metastate */
@@ -208,26 +208,26 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
qemu_get_sbe32s(f, &env->mvp.CP0_MVPConf1);
/* Load TLB */
- qemu_get_be32s(f, &env->tlb->nb_tlb);
- qemu_get_be32s(f, &env->tlb->tlb_in_use);
+ qemu_get_be32s(f, &env->tlb.nb_tlb);
+ qemu_get_be32s(f, &env->tlb.tlb_in_use);
for(i = 0; i < MIPS_TLB_MAX; i++) {
uint16_t flags;
uint8_t asid;
- qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].VPN);
- qemu_get_be32s(f, &env->tlb->mmu.r4k.tlb[i].PageMask);
+ qemu_get_betls(f, &env->tlb.mmu.r4k.tlb[i].VPN);
+ qemu_get_be32s(f, &env->tlb.mmu.r4k.tlb[i].PageMask);
qemu_get_8s(f, &asid);
- env->tlb->mmu.r4k.tlb[i].ASID = asid;
+ env->tlb.mmu.r4k.tlb[i].ASID = asid;
qemu_get_be16s(f, &flags);
- env->tlb->mmu.r4k.tlb[i].G = (flags >> 10) & 1;
- env->tlb->mmu.r4k.tlb[i].C0 = (flags >> 7) & 3;
- env->tlb->mmu.r4k.tlb[i].C1 = (flags >> 4) & 3;
- env->tlb->mmu.r4k.tlb[i].V0 = (flags >> 3) & 1;
- env->tlb->mmu.r4k.tlb[i].V1 = (flags >> 2) & 1;
- env->tlb->mmu.r4k.tlb[i].D0 = (flags >> 1) & 1;
- env->tlb->mmu.r4k.tlb[i].D1 = (flags >> 0) & 1;
- qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[0]);
- qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[1]);
+ env->tlb.mmu.r4k.tlb[i].G = (flags >> 10) & 1;
+ env->tlb.mmu.r4k.tlb[i].C0 = (flags >> 7) & 3;
+ env->tlb.mmu.r4k.tlb[i].C1 = (flags >> 4) & 3;
+ env->tlb.mmu.r4k.tlb[i].V0 = (flags >> 3) & 1;
+ env->tlb.mmu.r4k.tlb[i].V1 = (flags >> 2) & 1;
+ env->tlb.mmu.r4k.tlb[i].D0 = (flags >> 1) & 1;
+ env->tlb.mmu.r4k.tlb[i].D1 = (flags >> 0) & 1;
+ qemu_get_betls(f, &env->tlb.mmu.r4k.tlb[i].PFN[0]);
+ qemu_get_betls(f, &env->tlb.mmu.r4k.tlb[i].PFN[1]);
}
/* Load CPU metastate */
@@ -1155,7 +1155,7 @@ target_ulong helper_dmfc0_watchlo (uint32_t sel)
void helper_mtc0_index (target_ulong arg1)
{
int num = 1;
- unsigned int tmp = env->tlb->nb_tlb;
+ unsigned int tmp = env->tlb.nb_tlb;
do {
tmp >>= 1;
@@ -1486,7 +1486,7 @@ void helper_mtc0_pagegrain (target_ulong arg1)
void helper_mtc0_wired (target_ulong arg1)
{
- env->CP0_Wired = arg1 % env->tlb->nb_tlb;
+ env->CP0_Wired = arg1 % env->tlb.nb_tlb;
}
void helper_mtc0_srsconf0 (target_ulong arg1)
@@ -1989,14 +1989,14 @@ static void cpu_mips_tlb_flush (CPUState *env, int flush_global)
{
/* Flush qemu's TLB and discard all shadowed entries. */
tlb_flush (env, flush_global);
- env->tlb->tlb_in_use = env->tlb->nb_tlb;
+ env->tlb.tlb_in_use = env->tlb.nb_tlb;
}
static void r4k_mips_tlb_flush_extra (CPUState *env, int first)
{
/* Discard entries from env->tlb[first] onwards. */
- while (env->tlb->tlb_in_use > first) {
- r4k_invalidate_tlb(env, --env->tlb->tlb_in_use, 0);
+ while (env->tlb.tlb_in_use > first) {
+ r4k_invalidate_tlb(env, --env->tlb.tlb_in_use, 0);
}
}
@@ -2005,7 +2005,7 @@ static void r4k_fill_tlb (int idx)
r4k_tlb_t *tlb;
/* XXX: detect conflicting TLBs and raise a MCHECK exception when needed */
- tlb = &env->tlb->mmu.r4k.tlb[idx];
+ tlb = &env->tlb.mmu.r4k.tlb[idx];
tlb->VPN = env->CP0_EntryHi & (TARGET_PAGE_MASK << 1);
#if defined(TARGET_MIPS64)
tlb->VPN &= env->SEGMask;
@@ -2027,12 +2027,12 @@ void r4k_helper_tlbwi (void)
{
int idx;
- idx = (env->CP0_Index & ~0x80000000) % env->tlb->nb_tlb;
+ idx = (env->CP0_Index & ~0x80000000) % env->tlb.nb_tlb;
/* Discard cached TLB entries. We could avoid doing this if the
tlbwi is just upgrading access permissions on the current entry;
that might be a further win. */
- r4k_mips_tlb_flush_extra (env, env->tlb->nb_tlb);
+ r4k_mips_tlb_flush_extra(env, env->tlb.nb_tlb);
r4k_invalidate_tlb(env, idx, 0);
r4k_fill_tlb(idx);
@@ -2056,8 +2056,8 @@ void r4k_helper_tlbp (void)
int i;
ASID = env->CP0_EntryHi & 0xFF;
- for (i = 0; i < env->tlb->nb_tlb; i++) {
- tlb = &env->tlb->mmu.r4k.tlb[i];
+ for (i = 0; i < env->tlb.nb_tlb; i++) {
+ tlb = &env->tlb.mmu.r4k.tlb[i];
/* 1k pages are not supported. */
mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
tag = env->CP0_EntryHi & ~mask;
@@ -2069,10 +2069,10 @@ void r4k_helper_tlbp (void)
break;
}
}
- if (i == env->tlb->nb_tlb) {
+ if (i == env->tlb.nb_tlb) {
/* No match. Discard any shadow entries, if any of them match. */
- for (i = env->tlb->nb_tlb; i < env->tlb->tlb_in_use; i++) {
- tlb = &env->tlb->mmu.r4k.tlb[i];
+ for (i = env->tlb.nb_tlb; i < env->tlb.tlb_in_use; i++) {
+ tlb = &env->tlb.mmu.r4k.tlb[i];
/* 1k pages are not supported. */
mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
tag = env->CP0_EntryHi & ~mask;
@@ -2095,14 +2095,14 @@ void r4k_helper_tlbr (void)
int idx;
ASID = env->CP0_EntryHi & 0xFF;
- idx = (env->CP0_Index & ~0x80000000) % env->tlb->nb_tlb;
- tlb = &env->tlb->mmu.r4k.tlb[idx];
+ idx = (env->CP0_Index & ~0x80000000) % env->tlb.nb_tlb;
+ tlb = &env->tlb.mmu.r4k.tlb[idx];
/* If this will change the current ASID, flush qemu's TLB. */
if (ASID != tlb->ASID)
cpu_mips_tlb_flush (env, 1);
- r4k_mips_tlb_flush_extra(env, env->tlb->nb_tlb);
+ r4k_mips_tlb_flush_extra(env, env->tlb.nb_tlb);
env->CP0_EntryHi = tlb->VPN | tlb->ASID;
env->CP0_PageMask = tlb->PageMask;
@@ -2114,22 +2114,22 @@ void r4k_helper_tlbr (void)
void helper_tlbwi(void)
{
- env->tlb->helper_tlbwi();
+ env->tlb.helper_tlbwi();
}
void helper_tlbwr(void)
{
- env->tlb->helper_tlbwr();
+ env->tlb.helper_tlbwr();
}
void helper_tlbp(void)
{
- env->tlb->helper_tlbp();
+ env->tlb.helper_tlbp();
}
void helper_tlbr(void)
{
- env->tlb->helper_tlbr();
+ env->tlb.helper_tlbr();
}
/* Specials */
@@ -5999,26 +5999,30 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int
break;
case OPC_TLBWI:
opn = "tlbwi";
- if (!env->tlb->helper_tlbwi)
+ if (!env->tlb.helper_tlbwi) {
goto die;
+ }
gen_helper_tlbwi();
break;
case OPC_TLBWR:
opn = "tlbwr";
- if (!env->tlb->helper_tlbwr)
+ if (!env->tlb.helper_tlbwr) {
goto die;
+ }
gen_helper_tlbwr();
break;
case OPC_TLBP:
opn = "tlbp";
- if (!env->tlb->helper_tlbp)
+ if (!env->tlb.helper_tlbp) {
goto die;
+ }
gen_helper_tlbp();
break;
case OPC_TLBR:
opn = "tlbr";
- if (!env->tlb->helper_tlbr)
+ if (!env->tlb.helper_tlbr) {
goto die;
+ }
gen_helper_tlbr();
break;
case OPC_ERET:
@@ -12792,8 +12796,8 @@ void cpu_reset (CPUMIPSState *env)
env->CP0_ErrorEPC = env->active_tc.PC;
}
env->active_tc.PC = (int32_t)0xBFC00000;
- env->CP0_Random = env->tlb->nb_tlb - 1;
- env->tlb->tlb_in_use = env->tlb->nb_tlb;
+ env->CP0_Random = env->tlb.nb_tlb - 1;
+ env->tlb.tlb_in_use = env->tlb.nb_tlb;
env->CP0_Wired = 0;
env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
@@ -513,30 +513,28 @@ void mips_cpu_list (FILE *f, fprintf_function cpu_fprintf)
#ifndef CONFIG_USER_ONLY
static void no_mmu_init (CPUMIPSState *env, const mips_def_t *def)
{
- env->tlb->nb_tlb = 1;
- env->tlb->map_address = &no_mmu_map_address;
+ env->tlb.nb_tlb = 1;
+ env->tlb.map_address = &no_mmu_map_address;
}
static void fixed_mmu_init (CPUMIPSState *env, const mips_def_t *def)
{
- env->tlb->nb_tlb = 1;
- env->tlb->map_address = &fixed_mmu_map_address;
+ env->tlb.nb_tlb = 1;
+ env->tlb.map_address = &fixed_mmu_map_address;
}
static void r4k_mmu_init (CPUMIPSState *env, const mips_def_t *def)
{
- env->tlb->nb_tlb = 1 + ((def->CP0_Config1 >> CP0C1_MMU) & 63);
- env->tlb->map_address = &r4k_map_address;
- env->tlb->helper_tlbwi = r4k_helper_tlbwi;
- env->tlb->helper_tlbwr = r4k_helper_tlbwr;
- env->tlb->helper_tlbp = r4k_helper_tlbp;
- env->tlb->helper_tlbr = r4k_helper_tlbr;
+ env->tlb.nb_tlb = 1 + ((def->CP0_Config1 >> CP0C1_MMU) & 63);
+ env->tlb.map_address = &r4k_map_address;
+ env->tlb.helper_tlbwi = r4k_helper_tlbwi;
+ env->tlb.helper_tlbwr = r4k_helper_tlbwr;
+ env->tlb.helper_tlbp = r4k_helper_tlbp;
+ env->tlb.helper_tlbr = r4k_helper_tlbr;
}
static void mmu_init (CPUMIPSState *env, const mips_def_t *def)
{
- env->tlb = g_malloc0(sizeof(CPUMIPSTLBContext));
-
switch (def->mmu_type) {
case MMU_TYPE_NONE:
no_mmu_init(env, def);
@@ -581,7 +579,7 @@ static void mvp_init (CPUMIPSState *env, const mips_def_t *def)
(0x00 << CP0MVPC0_PTC);
#if !defined(CONFIG_USER_ONLY)
/* Usermode has no TLB support */
- env->mvp.CP0_MVPConf0 |= (env->tlb->nb_tlb << CP0MVPC0_PTLBE);
+ env->mvp.CP0_MVPConf0 |= (env->tlb.nb_tlb << CP0MVPC0_PTLBE);
#endif
/* Allocatable CP1 have media extensions, allocatable CP1 have FP support,
Adjust all callers. Signed-off-by: Juan Quintela <quintela@redhat.com> CC: Aurelien Jarno <aurelien@aurel32.net> --- hw/mips_timer.c | 2 +- target-mips/cpu.h | 2 +- target-mips/helper.c | 30 +++++++++++++--------- target-mips/machine.c | 56 +++++++++++++++++++++--------------------- target-mips/op_helper.c | 40 +++++++++++++++--------------- target-mips/translate.c | 16 +++++++---- target-mips/translate_init.c | 24 ++++++++--------- 7 files changed, 89 insertions(+), 81 deletions(-)