Revision fcb4a419

b/hw/mips_timer.c
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

  
b/target-mips/cpu.h
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;
b/target-mips/mips-defs.h
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
b/target-mips/op.c
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 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

  
b/target-mips/op_helper.c
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 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 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 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 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;
b/target-mips/translate.c
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;
b/target-mips/translate_init.c
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 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 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 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 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 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 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 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
}

Also available in: Unified diff