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 575

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

powered by: WebSVN 2.1.0

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