diff options
-rw-r--r-- | target-sparc/cpu.h | 4 | ||||
-rw-r--r-- | target-sparc/helper.c | 2 | ||||
-rw-r--r-- | target-sparc/op_helper.c | 22 | ||||
-rw-r--r-- | target-sparc/translate.c | 84 |
4 files changed, 103 insertions, 9 deletions
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index 6f95d94699..e0715a1a70 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -198,6 +198,10 @@ typedef struct CPUSPARCState { int interrupt_request; int halted; uint32_t mmu_bm; + uint32_t mmu_ctpr_mask; + uint32_t mmu_cxr_mask; + uint32_t mmu_sfsr_mask; + uint32_t mmu_trcr_mask; /* NOTE: we allow 8 more registers to handle wrapping */ target_ulong regbase[NWINDOWS * 16 + 8]; diff --git a/target-sparc/helper.c b/target-sparc/helper.c index d657c31287..894e32628d 100644 --- a/target-sparc/helper.c +++ b/target-sparc/helper.c @@ -129,7 +129,7 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot /* SPARC reference MMU table walk: Context table->L1->L2->PTE */ /* Context base + context number */ - pde_ptr = ((env->mmuregs[1] & ~63)<< 4) + (env->mmuregs[2] << 2); + pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2); pde = ldl_phys(pde_ptr); /* Ctx pde */ diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c index a36b74b0f6..2f7e7abc72 100644 --- a/target-sparc/op_helper.c +++ b/target-sparc/op_helper.c @@ -591,7 +591,7 @@ void helper_st_asi(int asi, int size) oldreg = env->mmuregs[reg]; switch(reg) { - case 0: + case 0: // Control Register env->mmuregs[reg] = (env->mmuregs[reg] & 0xff000000) | (T1 & 0x00ffffff); // Mappings generated during no-fault mode or MMU @@ -600,21 +600,27 @@ void helper_st_asi(int asi, int size) (env->mmuregs[reg] & (MMU_E | MMU_NF | env->mmu_bm))) tlb_flush(env, 1); break; - case 2: - env->mmuregs[reg] = T1; + case 1: // Context Table Pointer Register + env->mmuregs[reg] = T1 & env->mmu_ctpr_mask; + break; + case 2: // Context Register + env->mmuregs[reg] = T1 & env->mmu_cxr_mask; if (oldreg != env->mmuregs[reg]) { /* we flush when the MMU context changes because QEMU has no MMU context support */ tlb_flush(env, 1); } break; - case 3: - case 4: + case 3: // Synchronous Fault Status Register with Clear + case 4: // Synchronous Fault Address Register + break; + case 0x10: // TLB Replacement Control Register + env->mmuregs[reg] = T1 & env->mmu_trcr_mask; break; - case 0x13: - env->mmuregs[3] = T1; + case 0x13: // Synchronous Fault Status Register with Read and Clear + env->mmuregs[3] = T1 & env->mmu_sfsr_mask; break; - case 0x14: + case 0x14: // Synchronous Fault Address Register env->mmuregs[4] = T1; break; default: diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 8286c428df..eb3b23baed 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -62,6 +62,10 @@ struct sparc_def_t { uint32_t fpu_version; uint32_t mmu_version; uint32_t mmu_bm; + uint32_t mmu_ctpr_mask; + uint32_t mmu_cxr_mask; + uint32_t mmu_sfsr_mask; + uint32_t mmu_trcr_mask; }; static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name); @@ -3758,6 +3762,10 @@ CPUSPARCState *cpu_sparc_init(const char *cpu_model) env->fsr = def->fpu_version; #if !defined(TARGET_SPARC64) env->mmu_bm = def->mmu_bm; + env->mmu_ctpr_mask = def->mmu_ctpr_mask; + env->mmu_cxr_mask = def->mmu_cxr_mask; + env->mmu_sfsr_mask = def->mmu_sfsr_mask; + env->mmu_trcr_mask = def->mmu_trcr_mask; env->mmuregs[0] |= def->mmu_version; cpu_sparc_set_id(env, 0); #endif @@ -3887,6 +3895,10 @@ static const sparc_def_t sparc_defs[] = { .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */ .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, }, { .name = "Fujitsu MB86904", @@ -3894,6 +3906,10 @@ static const sparc_def_t sparc_defs[] = { .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */ .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x00ffffc0, + .mmu_cxr_mask = 0x000000ff, + .mmu_sfsr_mask = 0x00016fff, + .mmu_trcr_mask = 0x00ffffff, }, { .name = "Fujitsu MB86907", @@ -3901,6 +3917,10 @@ static const sparc_def_t sparc_defs[] = { .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */ .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0xffffffc0, + .mmu_cxr_mask = 0x000000ff, + .mmu_sfsr_mask = 0x00016fff, + .mmu_trcr_mask = 0xffffffff, }, { .name = "LSI L64811", @@ -3908,6 +3928,10 @@ static const sparc_def_t sparc_defs[] = { .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */ .mmu_version = 0x10 << 24, .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, }, { .name = "Cypress CY7C601", @@ -3915,6 +3939,10 @@ static const sparc_def_t sparc_defs[] = { .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */ .mmu_version = 0x10 << 24, .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, }, { .name = "Cypress CY7C611", @@ -3922,6 +3950,10 @@ static const sparc_def_t sparc_defs[] = { .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */ .mmu_version = 0x10 << 24, .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, }, { .name = "TI SuperSparc II", @@ -3929,6 +3961,10 @@ static const sparc_def_t sparc_defs[] = { .fpu_version = 0 << 17, .mmu_version = 0x04000000, .mmu_bm = 0x00002000, + .mmu_ctpr_mask = 0xffffffc0, + .mmu_cxr_mask = 0x0000ffff, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, }, { .name = "TI MicroSparc I", @@ -3936,6 +3972,10 @@ static const sparc_def_t sparc_defs[] = { .fpu_version = 4 << 17, .mmu_version = 0x41000000, .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0x00016fff, + .mmu_trcr_mask = 0x0000003f, }, { .name = "TI MicroSparc II", @@ -3943,6 +3983,10 @@ static const sparc_def_t sparc_defs[] = { .fpu_version = 4 << 17, .mmu_version = 0x02000000, .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x00ffffc0, + .mmu_cxr_mask = 0x000000ff, + .mmu_sfsr_mask = 0x00016bff, + .mmu_trcr_mask = 0x00ffffff, }, { .name = "TI MicroSparc IIep", @@ -3950,6 +3994,10 @@ static const sparc_def_t sparc_defs[] = { .fpu_version = 4 << 17, .mmu_version = 0x04000000, .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x00ffffc0, + .mmu_cxr_mask = 0x000000ff, + .mmu_sfsr_mask = 0x00016bff, + .mmu_trcr_mask = 0x00ffffff, }, { .name = "TI SuperSparc 51", @@ -3957,6 +4005,10 @@ static const sparc_def_t sparc_defs[] = { .fpu_version = 0 << 17, .mmu_version = 0x04000000, .mmu_bm = 0x00002000, + .mmu_ctpr_mask = 0xffffffc0, + .mmu_cxr_mask = 0x0000ffff, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, }, { .name = "TI SuperSparc 61", @@ -3964,6 +4016,10 @@ static const sparc_def_t sparc_defs[] = { .fpu_version = 0 << 17, .mmu_version = 0x04000000, .mmu_bm = 0x00002000, + .mmu_ctpr_mask = 0xffffffc0, + .mmu_cxr_mask = 0x0000ffff, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, }, { .name = "Ross RT625", @@ -3971,6 +4027,10 @@ static const sparc_def_t sparc_defs[] = { .fpu_version = 1 << 17, .mmu_version = 0x1e000000, .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, }, { .name = "Ross RT620", @@ -3978,6 +4038,10 @@ static const sparc_def_t sparc_defs[] = { .fpu_version = 1 << 17, .mmu_version = 0x1f000000, .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, }, { .name = "BIT B5010", @@ -3985,6 +4049,10 @@ static const sparc_def_t sparc_defs[] = { .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */ .mmu_version = 0x20000000, .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, }, { .name = "Matsushita MN10501", @@ -3992,6 +4060,10 @@ static const sparc_def_t sparc_defs[] = { .fpu_version = 0 << 17, .mmu_version = 0x50000000, .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, }, { .name = "Weitek W8601", @@ -3999,6 +4071,10 @@ static const sparc_def_t sparc_defs[] = { .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */ .mmu_version = 0x10 << 24, .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, }, { .name = "LEON2", @@ -4006,6 +4082,10 @@ static const sparc_def_t sparc_defs[] = { .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ .mmu_version = 0xf2000000, .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, }, { .name = "LEON3", @@ -4013,6 +4093,10 @@ static const sparc_def_t sparc_defs[] = { .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ .mmu_version = 0xf3000000, .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, }, #endif }; |