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 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
... ... @@ -99,6 +99,7 @@ struct CPUMIPSState {
99 99 #if defined(MIPS_USES_R4K_TLB)
100 100 tlb_t tlb[MIPS_TLB_MAX];
101 101 uint32_t tlb_in_use;
  102 + uint32_t nb_tlb;
102 103 #endif
103 104 int32_t CP0_Index;
104 105 int32_t CP0_Random;
... ...
target-mips/mips-defs.h
... ... @@ -10,7 +10,6 @@
10 10 #define TARGET_PAGE_BITS 12
11 11 /* Uses MIPS R4Kc TLB model */
12 12 #define MIPS_USES_R4K_TLB
13   -#define MIPS_TLB_NB 16
14 13 #define MIPS_TLB_MAX 128
15 14  
16 15 #ifdef TARGET_MIPS64
... ...
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 }
... ...