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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [testbench/] [cache.c] - Blame information for rev 224

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

powered by: WebSVN 2.1.0

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