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