OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [branches/] [stable_0_2_x/] [or1ksim/] [testbench/] [cache.c] - Blame information for rev 574

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 224 markom
/* Cache test */
2
#include "support.h"
3
#include "spr_defs.h"
4
 
5 484 simons
#define MEM_RAM 0x40100000
6 424 markom
 
7 224 markom
/* Number of IC sets (power of 2) */
8
#define IC_SETS 512
9
#define DC_SETS 512
10
 
11
/* Block size in bytes (1, 2, 4, 8, 16, 32 etc.) */
12
#define IC_BLOCK_SIZE 16
13
#define DC_BLOCK_SIZE 16
14
 
15
/* Number of IC ways (1, 2, 3 etc.). */
16
#define IC_WAYS 1
17
#define DC_WAYS 1
18
 
19
/* Cache size */
20
#define IC_SIZE (IC_WAYS*IC_SETS*IC_BLOCK_SIZE)
21
#define DC_SIZE (DC_WAYS*DC_SETS*DC_BLOCK_SIZE)
22
 
23
/* Memory access macros */
24
#define REG8(add) *((volatile unsigned char *)(add))
25
#define REG16(add) *((volatile unsigned short *)(add))
26
#define REG32(add) *((volatile unsigned long *)(add))
27
 
28
extern void (*jalr)(void);
29
extern void (*jr)(void);
30
 
31 484 simons
/* Index on jump table */
32
unsigned long jump_indx;
33
 
34
/* Jump address table */
35
unsigned long jump_add[15*IC_WAYS];
36
 
37 224 markom
void dummy();
38
 
39
void jump_and_link(void)
40
{
41
        asm("_jalr:");
42
}
43
 
44
void jump(void)
45
{
46
        asm("_jr:");
47
        /* Read and increment index */
48 484 simons
        asm("l.lwz\t\tr3,0(r11)");
49 224 markom
        asm("l.addi\t\tr3,r3,4");
50 484 simons
        asm("l.sw\t\t0(r11),r3");
51 224 markom
        /* Load next executin address from table */
52
        asm("l.lwz\t\tr3,0(r3)");
53
        /* Jump to that address */
54
        asm("l.jr\t\tr3") ;
55
        /* Report that we succeeded */
56 534 simons
        asm("l.nop\t1");
57 224 markom
}
58
 
59
void copy_jr(unsigned long add)
60
{
61 322 simons
        memcpy((void *)add, (void *)&jr, 24);
62 224 markom
}
63
 
64
void call(unsigned long add)
65
{
66 484 simons
  asm("l.movhi\tr11,hi(_jump_indx)" : :);
67
  asm("l.ori\tr11,r11,lo(_jump_indx)" : :);
68 322 simons
        asm("l.jr\t\t%0" : : "r" (add) : "r11");
69 224 markom
        asm("l.nop" : :);
70
}
71
 
72
void icache_enable(void)
73
{
74
        unsigned long add;
75
 
76
        /* First invalidate the cache. As at this point cache is disabled,
77
           the cache acts as it contains image of lowest memory block */
78
        for(add = 1; add <= IC_SIZE; add += IC_BLOCK_SIZE)
79
                mtspr(SPR_ICBIR, add);
80
 
81
        mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_ICE);
82
}
83
 
84
void dcache_enable(void)
85
{
86
        unsigned long add;
87
 
88
        /* First invalidate the cache. As at this point cache is disabled,
89
           the cache acts as it contains image of lowest memory block */
90
        for(add = 1; add <= DC_SIZE; add += DC_BLOCK_SIZE)
91
                mtspr(SPR_DCBIR, add);
92
 
93
        mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_DCE);
94
}
95
 
96
void icache_disable(void)
97
{
98
 
99
        /* This is write trough cache so we dont have to flush it */
100
        mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_ICE);
101
}
102
 
103
void dcache_disable(void)
104
{
105
 
106
        /* This is write trough cache so we dont have to flush it */
107
        mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_DCE);
108
}
109
 
110
int dc_test(void)
111
{
112
        int i;
113
        unsigned long base, add, ul;
114
 
115 484 simons
        base = (((unsigned long)MEM_RAM / (IC_SETS*IC_BLOCK_SIZE)) * IC_SETS*IC_BLOCK_SIZE) + IC_SETS*IC_BLOCK_SIZE;
116 224 markom
 
117
        dcache_enable();
118
 
119
        /* Cache miss r */
120
        add = base;
121
        for(i = 0; i < DC_WAYS; i++) {
122
                ul = REG32(add);
123
                ul = REG32(add + DC_BLOCK_SIZE);
124
                ul = REG32(add + 2*DC_BLOCK_SIZE);
125
                ul = REG32(add + 3*DC_BLOCK_SIZE);
126
                add += DC_SETS*DC_BLOCK_SIZE;
127
        }
128
 
129
        /* Cache hit w */
130
        add = base;
131
        for(i = 0; i < DC_WAYS; i++) {
132
                REG32(add + 0) = 0x00000001;
133
                REG32(add + DC_BLOCK_SIZE + 4) = 0x00000002;
134
                REG32(add + 2*DC_BLOCK_SIZE + 8) = 0x00000003;
135
                REG32(add + 3*DC_BLOCK_SIZE + 12) = 0x00000004;
136
                add += DC_SETS*DC_BLOCK_SIZE;
137
        }
138
 
139
        /* Cache hit r/w */
140
        add = base;
141
        for(i = 0; i < DC_WAYS; i++) {
142
                REG8(add + DC_BLOCK_SIZE - 4) = REG8(add + 3);
143
                REG8(add + 2*DC_BLOCK_SIZE - 8) = REG8(add + DC_BLOCK_SIZE + 7);
144
                REG8(add + 3*DC_BLOCK_SIZE - 12) = REG8(add + 2*DC_BLOCK_SIZE + 11);
145
                REG8(add + 4*DC_BLOCK_SIZE - 16) = REG8(add + 3*DC_BLOCK_SIZE + 15);
146
                add += DC_SETS*DC_BLOCK_SIZE;
147
        }
148
 
149
        /* Cache hit/miss r/w */
150
        add = base;
151
        for(i = 0; i < DC_WAYS; i++) {
152
                REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE) = REG16(add + DC_BLOCK_SIZE - 4) + REG16(add + 2);
153
                REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 2) = REG16(add + DC_BLOCK_SIZE - 8) + REG16(add + DC_BLOCK_SIZE + 6);
154
                REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 4) = REG16(add + DC_BLOCK_SIZE - 12) + REG16(add + 2*DC_BLOCK_SIZE + 10);
155
                REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 6) = REG16(add+ DC_BLOCK_SIZE - 16) + REG16(add + 2*DC_BLOCK_SIZE + 14);
156
                add += DC_SETS*DC_BLOCK_SIZE;
157
        }
158
 
159
        /* Fill cache with unused data */
160
        add = base + DC_WAYS*DC_SETS*DC_BLOCK_SIZE;
161
        for(i = 0; i < DC_WAYS; i++) {
162
                ul = REG32(add);
163
                ul = REG32(add + DC_BLOCK_SIZE);
164
                ul = REG32(add + 2*DC_BLOCK_SIZE);
165
                ul = REG32(add + 3*DC_BLOCK_SIZE);
166
                add += DC_SETS*DC_BLOCK_SIZE;
167
        }
168
 
169
        /* Cache hit/miss r */
170
        ul = 0;
171
        add = base;
172
        for(i = 0; i < DC_WAYS; i++) {
173
                ul +=   REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE) +
174
                        REG16(add + DC_BLOCK_SIZE - 4) +
175
                        REG16(add + 2);
176
                ul +=   REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 2) +
177
                        REG16(add + DC_BLOCK_SIZE - 8) +
178
                        REG16(add + DC_BLOCK_SIZE + 6);
179
                ul +=   REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 4) +
180
                        REG16(add + DC_BLOCK_SIZE - 12) +
181
                        REG16(add + 2*DC_BLOCK_SIZE + 10);
182
                ul +=   REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 6) +
183
                        REG16(add+ DC_BLOCK_SIZE - 16) +
184
                        REG16(add + 2*DC_BLOCK_SIZE + 14);
185
                add += DC_SETS*DC_BLOCK_SIZE;
186
        }
187
 
188
        dcache_disable();
189
 
190
        return ul;
191
}
192
 
193
int ic_test(void)
194
{
195 322 simons
        int i;
196
        unsigned long base, add;
197
 
198 484 simons
        base = (((unsigned long)MEM_RAM / (IC_SETS*IC_BLOCK_SIZE)) * IC_SETS*IC_BLOCK_SIZE) + IC_SETS*IC_BLOCK_SIZE;
199 349 simons
 
200 322 simons
        /* Copy jr to various location */
201
        add = base;
202
        for(i = 0; i < IC_WAYS; i++) {
203
                copy_jr(add);
204
                copy_jr(add + 2*IC_BLOCK_SIZE + 4);
205
                copy_jr(add + 4*IC_BLOCK_SIZE + 8);
206
                copy_jr(add + 6*IC_BLOCK_SIZE + 12);
207
 
208
                copy_jr(add + (IC_SETS - 2)*IC_BLOCK_SIZE + 0);
209
                copy_jr(add + (IC_SETS - 4)*IC_BLOCK_SIZE + 4);
210
                copy_jr(add + (IC_SETS - 6)*IC_BLOCK_SIZE + 8);
211
                copy_jr(add + (IC_SETS - 8)*IC_BLOCK_SIZE + 12);
212
                add += IC_SETS*IC_BLOCK_SIZE;
213
        }
214
 
215
        /* Load execution table which starts at address 4 (at address 0 is table index) */
216
        add = base;
217
        for(i = 0; i < IC_WAYS; i++) {
218
                /* Cache miss */
219 484 simons
                jump_add[15*i + 0] = add + 2*IC_BLOCK_SIZE + 4;
220
                jump_add[15*i + 1] = add + 4*IC_BLOCK_SIZE + 8;
221
                jump_add[15*i + 2] = add + 6*IC_BLOCK_SIZE + 12;
222 322 simons
                /* Cache hit/miss */
223 484 simons
                jump_add[15*i + 3] = add;
224
                jump_add[15*i + 4] = add + (IC_SETS - 2)*IC_BLOCK_SIZE + 0;
225
                jump_add[15*i + 5] = add + 2*IC_BLOCK_SIZE + 4;
226
                jump_add[15*i + 6] = add + (IC_SETS - 4)*IC_BLOCK_SIZE + 4;
227
                jump_add[15*i + 7] = add + 4*IC_BLOCK_SIZE + 8;
228
                jump_add[15*i + 8] = add + (IC_SETS - 6)*IC_BLOCK_SIZE + 8;
229
                jump_add[15*i + 9] = add + 6*IC_BLOCK_SIZE + 12;
230
                jump_add[15*i + 10] = add + (IC_SETS - 8)*IC_BLOCK_SIZE + 12;
231 322 simons
                /* Cache hit */
232 484 simons
                jump_add[15*i + 11] = add + (IC_SETS - 2)*IC_BLOCK_SIZE + 0;
233
                jump_add[15*i + 12] = add + (IC_SETS - 4)*IC_BLOCK_SIZE + 4;
234
                jump_add[15*i + 13] = add + (IC_SETS - 6)*IC_BLOCK_SIZE + 8;
235
                jump_add[15*i + 14] = add + (IC_SETS - 8)*IC_BLOCK_SIZE + 12;
236
 
237 322 simons
                add += IC_SETS*IC_BLOCK_SIZE;
238
        }
239
 
240
        /* Go home */
241 484 simons
        jump_add[15*i] = (unsigned long)&jalr;
242 322 simons
 
243
        /* Initilalize table index */
244 484 simons
        jump_indx = &jump_add[0];
245 322 simons
 
246 349 simons
        icache_enable();
247
 
248 322 simons
        /* Go */
249
        call(base);
250
 
251
        icache_disable();
252
 
253
        return 0xdeaddead;
254 224 markom
}
255
 
256
int main(void)
257
{
258
        int rc;
259
 
260
        rc = dc_test();
261
        report(rc + 0xdeaddca1);
262
 
263
        /* Be aware that this test doesn't report result troug report call.
264
           It writes to spr 0x1234 directly (in jump function)!!!
265
 
266
           This test can not be run on or1ksim. */
267 322 simons
        rc = ic_test();
268 224 markom
        report(rc);
269 574 markom
 
270
        return 0;
271 224 markom
}
272
 
273
/* just for size calculation */
274
void dummy()
275
{
276
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.