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 322

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

powered by: WebSVN 2.1.0

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