Commit fcb4a419f52e538b68510a68f30d8834dd211155
1 parent
04f20795
Choose number of TLBs at runtime, by Herve Poussineau.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2693 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
7 changed files
with
26 additions
and
27 deletions
hw/mips_timer.c
| ... | ... | @@ -10,7 +10,7 @@ uint32_t cpu_mips_get_random (CPUState *env) |
| 10 | 10 | static uint32_t seed = 0; |
| 11 | 11 | uint32_t idx; |
| 12 | 12 | seed = seed * 314159 + 1; |
| 13 | - idx = (seed >> 16) % (MIPS_TLB_NB - env->CP0_Wired) + env->CP0_Wired; | |
| 13 | + idx = (seed >> 16) % (env->nb_tlb - env->CP0_Wired) + env->CP0_Wired; | |
| 14 | 14 | return idx; |
| 15 | 15 | } |
| 16 | 16 | ... | ... |
target-mips/cpu.h
target-mips/mips-defs.h
target-mips/op.c
| ... | ... | @@ -1270,7 +1270,7 @@ void op_mfc0_desave (void) |
| 1270 | 1270 | |
| 1271 | 1271 | void op_mtc0_index (void) |
| 1272 | 1272 | { |
| 1273 | - env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 & (MIPS_TLB_NB - 1)); | |
| 1273 | + env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 % env->nb_tlb); | |
| 1274 | 1274 | RETURN(); |
| 1275 | 1275 | } |
| 1276 | 1276 | |
| ... | ... | @@ -1314,7 +1314,7 @@ void op_mtc0_pagegrain (void) |
| 1314 | 1314 | |
| 1315 | 1315 | void op_mtc0_wired (void) |
| 1316 | 1316 | { |
| 1317 | - env->CP0_Wired = T0 & (MIPS_TLB_NB - 1); | |
| 1317 | + env->CP0_Wired = T0 % env->nb_tlb; | |
| 1318 | 1318 | RETURN(); |
| 1319 | 1319 | } |
| 1320 | 1320 | ... | ... |
target-mips/op_helper.c
| ... | ... | @@ -394,7 +394,7 @@ void cpu_mips_tlb_flush (CPUState *env, int flush_global) |
| 394 | 394 | { |
| 395 | 395 | /* Flush qemu's TLB and discard all shadowed entries. */ |
| 396 | 396 | tlb_flush (env, flush_global); |
| 397 | - env->tlb_in_use = MIPS_TLB_NB; | |
| 397 | + env->tlb_in_use = env->nb_tlb; | |
| 398 | 398 | } |
| 399 | 399 | |
| 400 | 400 | static void mips_tlb_flush_extra (CPUState *env, int first) |
| ... | ... | @@ -430,12 +430,10 @@ void do_tlbwi (void) |
| 430 | 430 | /* Discard cached TLB entries. We could avoid doing this if the |
| 431 | 431 | tlbwi is just upgrading access permissions on the current entry; |
| 432 | 432 | that might be a further win. */ |
| 433 | - mips_tlb_flush_extra (env, MIPS_TLB_NB); | |
| 433 | + mips_tlb_flush_extra (env, env->nb_tlb); | |
| 434 | 434 | |
| 435 | - /* Wildly undefined effects for CP0_Index containing a too high value and | |
| 436 | - MIPS_TLB_NB not being a power of two. But so does real silicon. */ | |
| 437 | - invalidate_tlb(env, env->CP0_Index & (MIPS_TLB_NB - 1), 0); | |
| 438 | - fill_tlb(env->CP0_Index & (MIPS_TLB_NB - 1)); | |
| 435 | + invalidate_tlb(env, env->CP0_Index % env->nb_tlb, 0); | |
| 436 | + fill_tlb(env->CP0_Index % env->nb_tlb); | |
| 439 | 437 | } |
| 440 | 438 | |
| 441 | 439 | void do_tlbwr (void) |
| ... | ... | @@ -455,7 +453,7 @@ void do_tlbp (void) |
| 455 | 453 | |
| 456 | 454 | tag = env->CP0_EntryHi & (int32_t)0xFFFFE000; |
| 457 | 455 | ASID = env->CP0_EntryHi & 0xFF; |
| 458 | - for (i = 0; i < MIPS_TLB_NB; i++) { | |
| 456 | + for (i = 0; i < env->nb_tlb; i++) { | |
| 459 | 457 | tlb = &env->tlb[i]; |
| 460 | 458 | /* Check ASID, virtual page number & size */ |
| 461 | 459 | if ((tlb->G == 1 || tlb->ASID == ASID) && tlb->VPN == tag) { |
| ... | ... | @@ -464,9 +462,9 @@ void do_tlbp (void) |
| 464 | 462 | break; |
| 465 | 463 | } |
| 466 | 464 | } |
| 467 | - if (i == MIPS_TLB_NB) { | |
| 465 | + if (i == env->nb_tlb) { | |
| 468 | 466 | /* No match. Discard any shadow entries, if any of them match. */ |
| 469 | - for (i = MIPS_TLB_NB; i < env->tlb_in_use; i++) { | |
| 467 | + for (i = env->nb_tlb; i < env->tlb_in_use; i++) { | |
| 470 | 468 | tlb = &env->tlb[i]; |
| 471 | 469 | |
| 472 | 470 | /* Check ASID, virtual page number & size */ |
| ... | ... | @@ -486,13 +484,13 @@ void do_tlbr (void) |
| 486 | 484 | uint8_t ASID; |
| 487 | 485 | |
| 488 | 486 | ASID = env->CP0_EntryHi & 0xFF; |
| 489 | - tlb = &env->tlb[env->CP0_Index & (MIPS_TLB_NB - 1)]; | |
| 487 | + tlb = &env->tlb[env->CP0_Index % env->nb_tlb]; | |
| 490 | 488 | |
| 491 | 489 | /* If this will change the current ASID, flush qemu's TLB. */ |
| 492 | 490 | if (ASID != tlb->ASID) |
| 493 | 491 | cpu_mips_tlb_flush (env, 1); |
| 494 | 492 | |
| 495 | - mips_tlb_flush_extra(env, MIPS_TLB_NB); | |
| 493 | + mips_tlb_flush_extra(env, env->nb_tlb); | |
| 496 | 494 | |
| 497 | 495 | env->CP0_EntryHi = tlb->VPN | tlb->ASID; |
| 498 | 496 | env->CP0_PageMask = tlb->PageMask; | ... | ... |
target-mips/translate.c
| ... | ... | @@ -5430,10 +5430,6 @@ void cpu_reset (CPUMIPSState *env) |
| 5430 | 5430 | } |
| 5431 | 5431 | env->hflags = 0; |
| 5432 | 5432 | env->PC = (int32_t)0xBFC00000; |
| 5433 | -#if defined (MIPS_USES_R4K_TLB) | |
| 5434 | - env->CP0_Random = MIPS_TLB_NB - 1; | |
| 5435 | - env->tlb_in_use = MIPS_TLB_NB; | |
| 5436 | -#endif | |
| 5437 | 5433 | env->CP0_Wired = 0; |
| 5438 | 5434 | /* SMP not implemented */ |
| 5439 | 5435 | env->CP0_EBase = 0x80000000; | ... | ... |
target-mips/translate_init.c
| ... | ... | @@ -28,13 +28,13 @@ |
| 28 | 28 | (0x0 << CP0C0_AT) | (0x0 << CP0C0_AR) | (0x1 << CP0C0_MT) | \ |
| 29 | 29 | (0x2 << CP0C0_K0)) |
| 30 | 30 | |
| 31 | -/* Have config2, 16 TLB entries, 64 sets Icache, 16 bytes Icache line, | |
| 31 | +/* Have config2, 64 sets Icache, 16 bytes Icache line, | |
| 32 | 32 | 2-way Icache, 64 sets Dcache, 16 bytes Dcache line, 2-way Dcache, |
| 33 | 33 | no coprocessor2 attached, no MDMX support attached, |
| 34 | 34 | no performance counters, watch registers present, |
| 35 | 35 | no code compression, EJTAG present, no FPU */ |
| 36 | 36 | #define MIPS_CONFIG1 \ |
| 37 | -((1 << CP0C1_M) | ((MIPS_TLB_NB - 1) << CP0C1_MMU) | \ | |
| 37 | +((1 << CP0C1_M) | \ | |
| 38 | 38 | (0x0 << CP0C1_IS) | (0x3 << CP0C1_IL) | (0x1 << CP0C1_IA) | \ |
| 39 | 39 | (0x0 << CP0C1_DS) | (0x3 << CP0C1_DL) | (0x1 << CP0C1_DA) | \ |
| 40 | 40 | (0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) | \ |
| ... | ... | @@ -81,7 +81,7 @@ static mips_def_t mips_defs[] = |
| 81 | 81 | .name = "4Kc", |
| 82 | 82 | .CP0_PRid = 0x00018000, |
| 83 | 83 | .CP0_Config0 = MIPS_CONFIG0, |
| 84 | - .CP0_Config1 = MIPS_CONFIG1, | |
| 84 | + .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU), | |
| 85 | 85 | .CP0_Config2 = MIPS_CONFIG2, |
| 86 | 86 | .CP0_Config3 = MIPS_CONFIG3, |
| 87 | 87 | .SYNCI_Step = 32, |
| ... | ... | @@ -92,7 +92,7 @@ static mips_def_t mips_defs[] = |
| 92 | 92 | .name = "4KEcR1", |
| 93 | 93 | .CP0_PRid = 0x00018400, |
| 94 | 94 | .CP0_Config0 = MIPS_CONFIG0, |
| 95 | - .CP0_Config1 = MIPS_CONFIG1, | |
| 95 | + .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU), | |
| 96 | 96 | .CP0_Config2 = MIPS_CONFIG2, |
| 97 | 97 | .CP0_Config3 = MIPS_CONFIG3, |
| 98 | 98 | .SYNCI_Step = 32, |
| ... | ... | @@ -103,7 +103,7 @@ static mips_def_t mips_defs[] = |
| 103 | 103 | .name = "4KEc", |
| 104 | 104 | .CP0_PRid = 0x00019000, |
| 105 | 105 | .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR), |
| 106 | - .CP0_Config1 = MIPS_CONFIG1, | |
| 106 | + .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU), | |
| 107 | 107 | .CP0_Config2 = MIPS_CONFIG2, |
| 108 | 108 | .CP0_Config3 = MIPS_CONFIG3, |
| 109 | 109 | .SYNCI_Step = 32, |
| ... | ... | @@ -114,7 +114,7 @@ static mips_def_t mips_defs[] = |
| 114 | 114 | .name = "24Kc", |
| 115 | 115 | .CP0_PRid = 0x00019300, |
| 116 | 116 | .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR), |
| 117 | - .CP0_Config1 = MIPS_CONFIG1, | |
| 117 | + .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU), | |
| 118 | 118 | .CP0_Config2 = MIPS_CONFIG2, |
| 119 | 119 | .CP0_Config3 = MIPS_CONFIG3, |
| 120 | 120 | .SYNCI_Step = 32, |
| ... | ... | @@ -125,7 +125,7 @@ static mips_def_t mips_defs[] = |
| 125 | 125 | .name = "24Kf", |
| 126 | 126 | .CP0_PRid = 0x00019300, |
| 127 | 127 | .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR), |
| 128 | - .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP), | |
| 128 | + .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU), | |
| 129 | 129 | .CP0_Config2 = MIPS_CONFIG2, |
| 130 | 130 | .CP0_Config3 = MIPS_CONFIG3, |
| 131 | 131 | .SYNCI_Step = 32, |
| ... | ... | @@ -137,7 +137,7 @@ static mips_def_t mips_defs[] = |
| 137 | 137 | .name = "R4000", |
| 138 | 138 | .CP0_PRid = 0x00000400, |
| 139 | 139 | .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT), |
| 140 | - .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP), | |
| 140 | + .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (47 << CP0C1_MMU), | |
| 141 | 141 | .CP0_Config2 = MIPS_CONFIG2, |
| 142 | 142 | .CP0_Config3 = MIPS_CONFIG3, |
| 143 | 143 | .SYNCI_Step = 16, |
| ... | ... | @@ -192,5 +192,10 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def) |
| 192 | 192 | env->SYNCI_Step = def->SYNCI_Step; |
| 193 | 193 | env->CCRes = def->CCRes; |
| 194 | 194 | env->fcr0 = def->CP1_fcr0; |
| 195 | +#if defined (MIPS_USES_R4K_TLB) | |
| 196 | + env->nb_tlb = 1 + ((def->CP0_Config1 >> CP0C1_MMU) & 63); | |
| 197 | + env->CP0_Random = env->nb_tlb - 1; | |
| 198 | + env->tlb_in_use = env->nb_tlb; | |
| 199 | +#endif | |
| 195 | 200 | return 0; |
| 196 | 201 | } | ... | ... |