Commit fcb4a419f52e538b68510a68f30d8834dd211155

Authored by ths
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
hw/mips_timer.c
@@ -10,7 +10,7 @@ uint32_t cpu_mips_get_random (CPUState *env) @@ -10,7 +10,7 @@ uint32_t cpu_mips_get_random (CPUState *env)
10 static uint32_t seed = 0; 10 static uint32_t seed = 0;
11 uint32_t idx; 11 uint32_t idx;
12 seed = seed * 314159 + 1; 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 return idx; 14 return idx;
15 } 15 }
16 16
target-mips/cpu.h
@@ -99,6 +99,7 @@ struct CPUMIPSState { @@ -99,6 +99,7 @@ struct CPUMIPSState {
99 #if defined(MIPS_USES_R4K_TLB) 99 #if defined(MIPS_USES_R4K_TLB)
100 tlb_t tlb[MIPS_TLB_MAX]; 100 tlb_t tlb[MIPS_TLB_MAX];
101 uint32_t tlb_in_use; 101 uint32_t tlb_in_use;
  102 + uint32_t nb_tlb;
102 #endif 103 #endif
103 int32_t CP0_Index; 104 int32_t CP0_Index;
104 int32_t CP0_Random; 105 int32_t CP0_Random;
target-mips/mips-defs.h
@@ -10,7 +10,6 @@ @@ -10,7 +10,6 @@
10 #define TARGET_PAGE_BITS 12 10 #define TARGET_PAGE_BITS 12
11 /* Uses MIPS R4Kc TLB model */ 11 /* Uses MIPS R4Kc TLB model */
12 #define MIPS_USES_R4K_TLB 12 #define MIPS_USES_R4K_TLB
13 -#define MIPS_TLB_NB 16  
14 #define MIPS_TLB_MAX 128 13 #define MIPS_TLB_MAX 128
15 14
16 #ifdef TARGET_MIPS64 15 #ifdef TARGET_MIPS64
target-mips/op.c
@@ -1270,7 +1270,7 @@ void op_mfc0_desave (void) @@ -1270,7 +1270,7 @@ void op_mfc0_desave (void)
1270 1270
1271 void op_mtc0_index (void) 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 RETURN(); 1274 RETURN();
1275 } 1275 }
1276 1276
@@ -1314,7 +1314,7 @@ void op_mtc0_pagegrain (void) @@ -1314,7 +1314,7 @@ void op_mtc0_pagegrain (void)
1314 1314
1315 void op_mtc0_wired (void) 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 RETURN(); 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,7 +394,7 @@ void cpu_mips_tlb_flush (CPUState *env, int flush_global)
394 { 394 {
395 /* Flush qemu's TLB and discard all shadowed entries. */ 395 /* Flush qemu's TLB and discard all shadowed entries. */
396 tlb_flush (env, flush_global); 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 static void mips_tlb_flush_extra (CPUState *env, int first) 400 static void mips_tlb_flush_extra (CPUState *env, int first)
@@ -430,12 +430,10 @@ void do_tlbwi (void) @@ -430,12 +430,10 @@ void do_tlbwi (void)
430 /* Discard cached TLB entries. We could avoid doing this if the 430 /* Discard cached TLB entries. We could avoid doing this if the
431 tlbwi is just upgrading access permissions on the current entry; 431 tlbwi is just upgrading access permissions on the current entry;
432 that might be a further win. */ 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 void do_tlbwr (void) 439 void do_tlbwr (void)
@@ -455,7 +453,7 @@ void do_tlbp (void) @@ -455,7 +453,7 @@ void do_tlbp (void)
455 453
456 tag = env->CP0_EntryHi & (int32_t)0xFFFFE000; 454 tag = env->CP0_EntryHi & (int32_t)0xFFFFE000;
457 ASID = env->CP0_EntryHi & 0xFF; 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 tlb = &env->tlb[i]; 457 tlb = &env->tlb[i];
460 /* Check ASID, virtual page number & size */ 458 /* Check ASID, virtual page number & size */
461 if ((tlb->G == 1 || tlb->ASID == ASID) && tlb->VPN == tag) { 459 if ((tlb->G == 1 || tlb->ASID == ASID) && tlb->VPN == tag) {
@@ -464,9 +462,9 @@ void do_tlbp (void) @@ -464,9 +462,9 @@ void do_tlbp (void)
464 break; 462 break;
465 } 463 }
466 } 464 }
467 - if (i == MIPS_TLB_NB) { 465 + if (i == env->nb_tlb) {
468 /* No match. Discard any shadow entries, if any of them match. */ 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 tlb = &env->tlb[i]; 468 tlb = &env->tlb[i];
471 469
472 /* Check ASID, virtual page number & size */ 470 /* Check ASID, virtual page number & size */
@@ -486,13 +484,13 @@ void do_tlbr (void) @@ -486,13 +484,13 @@ void do_tlbr (void)
486 uint8_t ASID; 484 uint8_t ASID;
487 485
488 ASID = env->CP0_EntryHi & 0xFF; 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 /* If this will change the current ASID, flush qemu's TLB. */ 489 /* If this will change the current ASID, flush qemu's TLB. */
492 if (ASID != tlb->ASID) 490 if (ASID != tlb->ASID)
493 cpu_mips_tlb_flush (env, 1); 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 env->CP0_EntryHi = tlb->VPN | tlb->ASID; 495 env->CP0_EntryHi = tlb->VPN | tlb->ASID;
498 env->CP0_PageMask = tlb->PageMask; 496 env->CP0_PageMask = tlb->PageMask;
target-mips/translate.c
@@ -5430,10 +5430,6 @@ void cpu_reset (CPUMIPSState *env) @@ -5430,10 +5430,6 @@ void cpu_reset (CPUMIPSState *env)
5430 } 5430 }
5431 env->hflags = 0; 5431 env->hflags = 0;
5432 env->PC = (int32_t)0xBFC00000; 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 env->CP0_Wired = 0; 5433 env->CP0_Wired = 0;
5438 /* SMP not implemented */ 5434 /* SMP not implemented */
5439 env->CP0_EBase = 0x80000000; 5435 env->CP0_EBase = 0x80000000;
target-mips/translate_init.c
@@ -28,13 +28,13 @@ @@ -28,13 +28,13 @@
28 (0x0 << CP0C0_AT) | (0x0 << CP0C0_AR) | (0x1 << CP0C0_MT) | \ 28 (0x0 << CP0C0_AT) | (0x0 << CP0C0_AR) | (0x1 << CP0C0_MT) | \
29 (0x2 << CP0C0_K0)) 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 2-way Icache, 64 sets Dcache, 16 bytes Dcache line, 2-way Dcache, 32 2-way Icache, 64 sets Dcache, 16 bytes Dcache line, 2-way Dcache,
33 no coprocessor2 attached, no MDMX support attached, 33 no coprocessor2 attached, no MDMX support attached,
34 no performance counters, watch registers present, 34 no performance counters, watch registers present,
35 no code compression, EJTAG present, no FPU */ 35 no code compression, EJTAG present, no FPU */
36 #define MIPS_CONFIG1 \ 36 #define MIPS_CONFIG1 \
37 -((1 << CP0C1_M) | ((MIPS_TLB_NB - 1) << CP0C1_MMU) | \ 37 +((1 << CP0C1_M) | \
38 (0x0 << CP0C1_IS) | (0x3 << CP0C1_IL) | (0x1 << CP0C1_IA) | \ 38 (0x0 << CP0C1_IS) | (0x3 << CP0C1_IL) | (0x1 << CP0C1_IA) | \
39 (0x0 << CP0C1_DS) | (0x3 << CP0C1_DL) | (0x1 << CP0C1_DA) | \ 39 (0x0 << CP0C1_DS) | (0x3 << CP0C1_DL) | (0x1 << CP0C1_DA) | \
40 (0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) | \ 40 (0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) | \
@@ -81,7 +81,7 @@ static mips_def_t mips_defs[] = @@ -81,7 +81,7 @@ static mips_def_t mips_defs[] =
81 .name = "4Kc", 81 .name = "4Kc",
82 .CP0_PRid = 0x00018000, 82 .CP0_PRid = 0x00018000,
83 .CP0_Config0 = MIPS_CONFIG0, 83 .CP0_Config0 = MIPS_CONFIG0,
84 - .CP0_Config1 = MIPS_CONFIG1, 84 + .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU),
85 .CP0_Config2 = MIPS_CONFIG2, 85 .CP0_Config2 = MIPS_CONFIG2,
86 .CP0_Config3 = MIPS_CONFIG3, 86 .CP0_Config3 = MIPS_CONFIG3,
87 .SYNCI_Step = 32, 87 .SYNCI_Step = 32,
@@ -92,7 +92,7 @@ static mips_def_t mips_defs[] = @@ -92,7 +92,7 @@ static mips_def_t mips_defs[] =
92 .name = "4KEcR1", 92 .name = "4KEcR1",
93 .CP0_PRid = 0x00018400, 93 .CP0_PRid = 0x00018400,
94 .CP0_Config0 = MIPS_CONFIG0, 94 .CP0_Config0 = MIPS_CONFIG0,
95 - .CP0_Config1 = MIPS_CONFIG1, 95 + .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU),
96 .CP0_Config2 = MIPS_CONFIG2, 96 .CP0_Config2 = MIPS_CONFIG2,
97 .CP0_Config3 = MIPS_CONFIG3, 97 .CP0_Config3 = MIPS_CONFIG3,
98 .SYNCI_Step = 32, 98 .SYNCI_Step = 32,
@@ -103,7 +103,7 @@ static mips_def_t mips_defs[] = @@ -103,7 +103,7 @@ static mips_def_t mips_defs[] =
103 .name = "4KEc", 103 .name = "4KEc",
104 .CP0_PRid = 0x00019000, 104 .CP0_PRid = 0x00019000,
105 .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR), 105 .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR),
106 - .CP0_Config1 = MIPS_CONFIG1, 106 + .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU),
107 .CP0_Config2 = MIPS_CONFIG2, 107 .CP0_Config2 = MIPS_CONFIG2,
108 .CP0_Config3 = MIPS_CONFIG3, 108 .CP0_Config3 = MIPS_CONFIG3,
109 .SYNCI_Step = 32, 109 .SYNCI_Step = 32,
@@ -114,7 +114,7 @@ static mips_def_t mips_defs[] = @@ -114,7 +114,7 @@ static mips_def_t mips_defs[] =
114 .name = "24Kc", 114 .name = "24Kc",
115 .CP0_PRid = 0x00019300, 115 .CP0_PRid = 0x00019300,
116 .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR), 116 .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR),
117 - .CP0_Config1 = MIPS_CONFIG1, 117 + .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU),
118 .CP0_Config2 = MIPS_CONFIG2, 118 .CP0_Config2 = MIPS_CONFIG2,
119 .CP0_Config3 = MIPS_CONFIG3, 119 .CP0_Config3 = MIPS_CONFIG3,
120 .SYNCI_Step = 32, 120 .SYNCI_Step = 32,
@@ -125,7 +125,7 @@ static mips_def_t mips_defs[] = @@ -125,7 +125,7 @@ static mips_def_t mips_defs[] =
125 .name = "24Kf", 125 .name = "24Kf",
126 .CP0_PRid = 0x00019300, 126 .CP0_PRid = 0x00019300,
127 .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR), 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 .CP0_Config2 = MIPS_CONFIG2, 129 .CP0_Config2 = MIPS_CONFIG2,
130 .CP0_Config3 = MIPS_CONFIG3, 130 .CP0_Config3 = MIPS_CONFIG3,
131 .SYNCI_Step = 32, 131 .SYNCI_Step = 32,
@@ -137,7 +137,7 @@ static mips_def_t mips_defs[] = @@ -137,7 +137,7 @@ static mips_def_t mips_defs[] =
137 .name = "R4000", 137 .name = "R4000",
138 .CP0_PRid = 0x00000400, 138 .CP0_PRid = 0x00000400,
139 .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT), 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 .CP0_Config2 = MIPS_CONFIG2, 141 .CP0_Config2 = MIPS_CONFIG2,
142 .CP0_Config3 = MIPS_CONFIG3, 142 .CP0_Config3 = MIPS_CONFIG3,
143 .SYNCI_Step = 16, 143 .SYNCI_Step = 16,
@@ -192,5 +192,10 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def) @@ -192,5 +192,10 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def)
192 env->SYNCI_Step = def->SYNCI_Step; 192 env->SYNCI_Step = def->SYNCI_Step;
193 env->CCRes = def->CCRes; 193 env->CCRes = def->CCRes;
194 env->fcr0 = def->CP1_fcr0; 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 return 0; 200 return 0;
196 } 201 }