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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_39/] [or1ksim/] [testbench/] [cache.c] - Blame information for rev 424

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

powered by: WebSVN 2.1.0

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