3
// Reset the L1 instruction cache.
5
reset_icache(MIPS_State* mstate)
8
for (i = 0; i < Icache_sets; ++i) {
9
for (j = 0; j < Icache_assoc; ++j)
10
mstate->icache.set[i].line[j].tag = bad_tag;
11
Icache_lru_init(mstate->icache.set[i].Icache_lru);
13
mstate->ibuf[0].tag = bad_ibuf_tag;
14
mstate->ibuf[1].tag = bad_ibuf_tag;
18
// Perform a cache operation (for use by decode_cache()).
20
control_icache(MIPS_State* mstate, VA va, PA pa, int op, int type)
23
return; // secondary cache not presents
28
mstate->icache.set[Icache_index(va)].line[Icache_block(va)].tag = bad_tag;
41
UInt32 tag = mstate->icache.set[Icache_index(va)].line[Icache_block(va)].tag;
42
if (tag == Icache_tag(pa))
43
mstate->icache.set[Icache_index(va)].line[Icache_block(va)].tag = bad_tag;
48
UInt32 tag = (UInt32) Icache_tag(pa);
49
MIPSICacheSet* set=&mstate->icache.set[Icache_index(va)];
50
MIPSICacheLine *line=&set->line[Icache_block(va)];
51
const VA line_mask = Icache_line_size - 1;
54
for(j = 0; j < 4; j++)
55
mips_mem_read((pa & ~line_mask)+8*j , line->data+j, 8);
61
break; // secondary cache not present
64
break; // secondary cache not present
66
// Everything else is ignored.
70
// In all cases, invalidate the ibufs.
71
mstate->ibuf[0].tag = bad_ibuf_tag;
72
mstate->ibuf[1].tag = bad_ibuf_tag;
76
/* Fetch an instruction from the virtual address (va). The address translation
77
* has already been performed and the physical address is (pa). The coherency
78
* algorithm to use is encoded in high-order bits of (pa) using the same
79
* encoding as that of the xkphys address space region.
82
// WARNING: currently, the memory access latencies are not simulated.
85
fetch(MIPS_State* mstate, VA va, PA pa)
89
int ca = coherency_algorithm(pa);
91
if (ca == 0x5) { //Shi yang 2006-08-15
92
// A direct memory access.
94
mips_mem_read(pa, &x, 4);
98
// A cached memory access.
99
UInt32 index = Icache_index(pa);
100
UInt32 tag = Icache_tag(pa);
101
MIPSICacheSet* set = &(mstate->icache.set[index]);
102
MIPSICacheLine* line = &(set->line[0]);
103
const PA line_mask = Icache_line_size - 1;
105
// Find the correct entry in the set (if any).
106
for (i = 0; i < Icache_assoc; ++i, ++line) {
108
if (line->tag == tag) {
109
Icache_lru_touch(set->Icache_lru,i);
114
// Otherwise, we've got a cache miss.
115
i = Icache_lru_replace(mstate->icache.set[index].Icache_lru);
116
line = &(mstate->icache.set[index].line[i]);
118
// Fill the cache line from the main memory.
120
for (j = 0; j < 4; j++)
121
mips_mem_read((pa & ~line_mask) + 8 * j, line->data + j, 8);
123
Icache_lru_touch(set->Icache_lru, i);
127
// Finally, fetch the data from the cache.
128
mstate->ibuf[mstate->lru_ibuf].tag = pa >> log2_icache_line;
129
mstate->ibuf[mstate->lru_ibuf].line = line->data;
130
mstate->lru_ibuf = !mstate->lru_ibuf;
131
return swizzle_word(line->data[(pa & line_mask) / 8], va);