~ubuntu-branches/ubuntu/lucid/skyeye/lucid-proposed

« back to all changes in this revision

Viewing changes to arch/mips/common/icache.c

  • Committer: Bazaar Package Importer
  • Author(s): Yu Guanghui
  • Date: 2007-02-09 20:24:29 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20070209202429-jknfb98t9ggaoz02
Tags: 1.2.1-2
Disable DBCT again.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "emul.h"
 
2
 
 
3
// Reset the L1 instruction cache.
 
4
void
 
5
reset_icache(MIPS_State* mstate)
 
6
{
 
7
        int i, j;
 
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);
 
12
        }
 
13
        mstate->ibuf[0].tag = bad_ibuf_tag;
 
14
        mstate->ibuf[1].tag = bad_ibuf_tag;
 
15
}
 
16
 
 
17
 
 
18
// Perform a cache operation (for use by decode_cache()).
 
19
void
 
20
control_icache(MIPS_State* mstate, VA va, PA pa, int op, int type)
 
21
{
 
22
        if (type)
 
23
                return; // secondary cache not presents
 
24
 
 
25
        switch (op) {
 
26
                case 0:
 
27
                {
 
28
                        mstate->icache.set[Icache_index(va)].line[Icache_block(va)].tag = bad_tag;
 
29
                        break;
 
30
                }
 
31
                case 1:
 
32
                {
 
33
                        break;
 
34
                }
 
35
                case 2:
 
36
                {
 
37
                        break;
 
38
                }
 
39
                case 4:
 
40
                {
 
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;
 
44
                        break;
 
45
                }
 
46
                case 5:
 
47
                {
 
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;
 
52
 
 
53
                        int j;
 
54
                        for(j = 0; j < 4; j++)
 
55
                                mips_mem_read((pa & ~line_mask)+8*j , line->data+j, 8);
 
56
        
 
57
                        break;
 
58
                }
 
59
                case 6:
 
60
                        // Hit Writeback.
 
61
                        break; // secondary cache not present
 
62
                case 7:
 
63
                        // Hit Set Virtual.
 
64
                        break; // secondary cache not present
 
65
                default:
 
66
                        // Everything else is ignored.
 
67
                        break;
 
68
        }
 
69
 
 
70
        // In all cases, invalidate the ibufs.
 
71
        mstate->ibuf[0].tag  = bad_ibuf_tag;
 
72
        mstate->ibuf[1].tag  = bad_ibuf_tag;
 
73
}
 
74
 
 
75
 
 
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.
 
80
 */
 
81
 
 
82
// WARNING: currently, the memory access latencies are not simulated.
 
83
 
 
84
Instr 
 
85
fetch(MIPS_State* mstate, VA va, PA pa)
 
86
{  
 
87
        int i;
 
88
 
 
89
        int ca = coherency_algorithm(pa);
 
90
 
 
91
        if (ca == 0x5) { //Shi yang 2006-08-15
 
92
                // A direct memory access.
 
93
                UInt32 x;
 
94
                mips_mem_read(pa, &x, 4);
 
95
                return x;
 
96
        }
 
97
 
 
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;
 
104
 
 
105
        // Find the correct entry in the set (if any).
 
106
        for (i = 0; i < Icache_assoc; ++i, ++line) {
 
107
 
 
108
                if (line->tag == tag) {
 
109
                        Icache_lru_touch(set->Icache_lru,i);
 
110
                        goto cache_hit;
 
111
                }
 
112
        }
 
113
    
 
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]);
 
117
 
 
118
        // Fill the cache line from the main memory.
 
119
        int j;
 
120
        for (j = 0; j < 4; j++)
 
121
                mips_mem_read((pa & ~line_mask) + 8 * j, line->data + j, 8);
 
122
        line->tag = tag;
 
123
        Icache_lru_touch(set->Icache_lru, i);
 
124
 
 
125
cache_hit:
 
126
    
 
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);
 
132
}