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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [sw/] [tests/] [or1200/] [board/] [or1200-rfemmu.S] - Blame information for rev 868

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

Line No. Rev Author Line
1 535 julius
/*
2
        Test of return from execption and MMU behavior
3
 
4
        For now, just a simple test confirming that the instructions we l.rfe
5
        to are executed OK.
6
 
7
        In this test we are checking that execution of instructions after
8
        l.rfe enabling the MMU occurs OK.
9
 
10
        Mainly this is to test what happens when the first virtual address
11
        after a l.rfe is a cache "hit" - ensuring this instruction is not
12
        executed.
13
 
14
        Test method:
15
        Relocate a simple looping function to an unused page in memory, at
16
        offset 0xf00 within that page. Translate virtual page 0 to this page
17
        and execute it, with timer interrupts occuring, ensuring the l.rfe is
18
        being called regularly.
19
 
20
        Whenever the function in virtual space is so be resumed, code at the
21
        address matching the virtual space is executed before the l.rfe,
22
        ensuring it is in cache. If any of these instructions in the physical
23
        address are executed, then the code running in virtual space will
24
        detect this and crash.
25
 
26
        In this instance, the test function is only about 30 instructions
27
        long. It is mapped to virtual address 0xf00. The physical address
28
        0xf00 has the same number of instructions, setting r31 to -1 (0xfffffff)
29
        This string of 32 instructions is executed before any l.rfe back to the
30
        function running with MMUs on in the virtual page address. The last
31
        instruction before the l.rfe clears r31, so if any of the instructions
32
        in the physical address space get executed, r31 will return to
33
        0xffffffff and this can be detected by the code.
34
 
35
        The test finishes when the test function, running in virtual address
36
        space, has incremented a value in memory beyond the alue defined by
37
        TEST_LOOPS.
38
 
39
        The test has the possibility of being restarted and run with
40
        caches enabled.
41
 
42
        Julius Baxter, ORSoC AB, julius.baxter@orsoc.se
43
 
44
 
45
*/
46
//////////////////////////////////////////////////////////////////////
47
////                                                              ////
48
//// Copyright (C) 2010 Authors and OPENCORES.ORG                 ////
49
////                                                              ////
50
//// This source file may be used and distributed without         ////
51
//// restriction provided that this copyright statement is not    ////
52
//// removed from the file and that any derivative work contains  ////
53
//// the original copyright notice and the associated disclaimer. ////
54
////                                                              ////
55
//// This source file is free software; you can redistribute it   ////
56
//// and/or modify it under the terms of the GNU Lesser General   ////
57
//// Public License as published by the Free Software Foundation; ////
58
//// either version 2.1 of the License, or (at your option) any   ////
59
//// later version.                                               ////
60
////                                                              ////
61
//// This source is distributed in the hope that it will be       ////
62
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
63
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
64
//// PURPOSE.  See the GNU Lesser General Public License for more ////
65
//// details.                                                     ////
66
////                                                              ////
67
//// You should have received a copy of the GNU Lesser General    ////
68
//// Public License along with this source; if not, download it   ////
69
//// from http://www.opencores.org/lgpl.shtml                     ////
70
////                                                              ////
71
//////////////////////////////////////////////////////////////////////
72
 
73
#include "spr-defs.h"
74
#include "board.h"
75
#include "or1200-defines.h"
76
 
77
#define ONCE_THROUGH_WITH_CACHE_ENABLED 1
78
 
79
#define TEST_LOOPS 0xffff
80
 
81
#define PAGE_ADR_SHIFT 13
82
 
83
// Should be at least 0x1000
84
#define PAGE_OFFSET_FOR_TEST 0xf00
85
 
86
#define TIMER_CYCLES_RATE 1000
87
 
88
#define LOAD_SYMBOL_2_GPR(gpr,symbol)  \
89
        l.movhi gpr, hi(symbol) ;      \
90
        l.ori   gpr, gpr, lo(symbol)
91
 
92
/* =================================================== [ exceptions ] === */
93
        .section .vectors, "ax"
94
 
95
/* ---[ 0x100: RESET exception ]----------------------------------------- */
96
        .org 0x100
97
        l.movhi r0, 0
98
        /* Clear status register */
99
        l.ori r1, r0, SPR_SR_SM
100
        l.mtspr r0, r1, SPR_SR
101
        /* Clear timer  */
102
        l.mtspr r0, r0, SPR_TTMR
103
 
104
        /* Jump to program initialisation code */
105
        .global _start
106
        l.movhi r4, hi(_start)
107
        l.ori r4, r4, lo(_start)
108
        l.jr    r4
109
        l.nop
110
 
111
/* ---[ 0x400: itlb fault ]--------------------------------------------- */
112
        .org 0x400
113
        l.ori   r3,r0,0xa00
114
        l.nop   0x2
115
        l.movhi r3,0xbaaa
116
        l.ori   r3,r3,0xaaad
117
        l.nop   0x2
118
        l.nop   0x1 /* We should never have a itlb miss */
119
 
120
/* ---[ 0x500: timer exception ]---------------------------------------- */
121
        .org 0x500
122
        /* check test loop counter to see if test is over */
123
        LOAD_SYMBOL_2_GPR(r3,function_global)
124
        l.lwz   r3,0(r3)
125
        l.sfgeui r3,TEST_LOOPS
126
        l.bf    check_for_restart
127
        l.nop
128
        /* Write to TTMR again to clear TTMR[IP] bit */
129
        l.jal   timer_load
130
        l.nop
131
 
132
        l.j     call_rfe        /* continue execution */
133
        l.nop
134
 
135
        .org 0x600
136
        l.j     fail
137
        l.nop
138
 
139
        .org 0x700
140
        l.j     fail
141
        l.nop
142
 
143
        .org 0x800
144
        l.j     fail
145
        l.nop
146
 
147
 
148
/* ---[ 0xa00: itlb miss ]---------------------------------------------- */
149
        .org 0xa00
150
        l.ori   r3,r0,0xa00
151
        l.nop   0x2
152
        l.movhi r3,0xbaaa
153
        l.ori   r3,r3,0xaaad
154
        l.nop   0x2
155
        l.j     0
156
        l.nop   0x1 /* We should never have a itlb miss */
157
 
158
/* ---[ 0xc00: system call ]-------------------------------------------- */
159
        .org 0xc00
160
        l.movhi r3,0xbaaa
161
        l.ori   r3,r3,0xaaad
162
        l.nop   0x2     /* Simulation report */
163
        l.j     0        /* Loop here */
164
        l.nop   0x1     /* End simulation */
165
 
166
/* ---[ 0xE00: TRAP exception ]----------------------------------------- */
167
        .org 0xe00
168
        l.j     0
169
        l.nop   0x1
170
 
171
/* ---[ reserved space        ]------------------------------------ */
172
        .org PAGE_OFFSET_FOR_TEST
173
call_rfe:
174
        l.addi  r31,r0,-1
175
        l.addi  r31,r0,-1
176
        l.addi  r31,r0,-1
177
        l.addi  r31,r0,-1
178
        l.addi  r31,r0,-1
179
        l.addi  r31,r0,-1
180
        l.addi  r31,r0,-1
181
        l.addi  r31,r0,-1
182
        l.addi  r31,r0,-1
183
        l.addi  r31,r0,-1
184
        l.addi  r31,r0,-1
185
        l.addi  r31,r0,-1
186
        l.addi  r31,r0,-1
187
        l.addi  r31,r0,-1
188
        l.addi  r31,r0,-1
189
        l.addi  r31,r0,-1
190
        l.addi  r31,r0,-1
191
        l.addi  r31,r0,-1
192
        l.addi  r31,r0,-1
193
        l.addi  r31,r0,-1
194
        l.addi  r31,r0,-1
195
        l.addi  r31,r0,-1
196
        l.addi  r31,r0,-1
197
        l.addi  r31,r0,-1
198
        l.addi  r31,r0,-1
199
        l.addi  r31,r0,-1
200
        l.addi  r31,r0,-1
201
        l.addi  r31,r0,-1
202
        l.addi  r31,r0,-1
203
        l.movhi r31,0
204
        l.rfe
205
 
206
 
207
/* =================================================== [ text ] === */
208
        .section .data
209
immu_sets:
210
        .long -1
211
immu_ways:
212
        .long -1
213
dmmu_sets:
214
        .long -1
215
dmmu_ways:
216
        .long -1
217
test_page_num:
218
        .long -1
219
function_global:
220
        .long 0
221
 
222
 
223
/* =================================================== [ text ] === */
224
        .section .text
225
 
226
/* =================================================== [ start ] === */
227
 
228
        .global _start
229
_start:
230
 
231
#if ONCE_THROUGH_WITH_CACHE_ENABLED==1
232
        l.jal   _cache_init
233
        l.nop
234
#endif
235
 
236
        // Kick off test
237
        l.jal   _main
238
        l.nop
239
 
240
/* =================================================== [ main ] === */
241
        .global _main
242
_main:
243
        // Get MMU configuration
244
        l.jal   immu_get_config
245
        l.nop
246
        l.jal   dmmu_get_config
247
        l.nop
248
 
249
        // Clear IMMU
250
        l.jal   immu_clear
251
        l.nop
252
        // Clear DMMU
253
        l.jal   dmmu_clear
254
        l.nop
255
 
256
        // Set up stack pointer, but kind of don't need it
257
        LOAD_SYMBOL_2_GPR(r1,_stack)
258
 
259
        // What is next page above stack?
260
        l.srli  r4,r1,PAGE_ADR_SHIFT
261
        l.addi  r4,r4,1         /* Next page past */
262
        LOAD_SYMBOL_2_GPR(r5,test_page_num)
263
        l.sw    0(r5),r4        /* We will do tests with code in this PPN */
264
 
265
 
266
        LOAD_SYMBOL_2_GPR(r2,test_function)
267
        LOAD_SYMBOL_2_GPR(r3,test_function_end)
268
        /* Convert physical page number back to physical address */
269
        l.slli  r4,r4,PAGE_ADR_SHIFT
270
        /* r4 has physical address of where we'll relocate our test program to
271
        but we want it at an offset of PAGE_OFFSET_FOR_TEST inside that page.
272
        */
273
 
274
        l.addi  r4,r4,PAGE_OFFSET_FOR_TEST
275
program_relocate_loop:
276
        l.lwz   r5,0(r2)
277
        l.sw    0(r4),r5
278
        l.sfeq  r2,r3
279
        l.mtspr r0,r4,SPR_DCBIR /* flush dcache */
280
        l.addi  r4,r4,4         /* increment dest ptr */
281
        l.bnf   program_relocate_loop
282
        l.addi  r2,r2,4         /* increment src ptr */
283
 
284
mmu_setup:
285
        /* Program relocated, setup MMU mappings */
286
        /* Physical page number of test-code is in test_page_num. We need
287
        to set up a mapping for this page in the MMU, then launch execution
288
        of it.
289
        */
290
        LOAD_SYMBOL_2_GPR(r5,test_page_num)
291
        l.lwz   r5,0(r5)
292
        /* Basically should be match-PPN of 0 translates to page
293
        number test_page_num.
294
        Set up entry 0, then, and have translate address to test_page_num*/
295
        // Match register
296
        l.ori   r3,r0,SPR_ITLBMR_V      /* Just this */
297
        l.mtspr r0,r3,SPR_ITLBMR_BASE(0)
298
        // Setup TR page number
299
        l.slli  r3,r5,PAGE_ADR_SHIFT //r5 = page number of target page
300
        l.ori   r3,r3,ITLB_PR_NOLIMIT
301
        l.mtspr r0,r3,SPR_ITLBTR_BASE(0)
302
 
303
timer_setup:
304
        /* Init timer to fire at rate of TIMER_CYCLES_RATE */
305
        l.jal   timer_load
306
        l.nop
307
 
308
sr_setup:
309
        // Start test - set up EPCR to jump to PAGE_OFFSET_FOR_TEST
310
        l.ori   r3,r0,PAGE_OFFSET_FOR_TEST
311
        l.mtspr r0,r3,SPR_EPCR_BASE
312
 
313
        l.mfspr r3,r0,SPR_SR
314
        l.ori   r3,r3,(SPR_SR_IME|SPR_SR_TEE)   /* IMMU, tick timer enable */
315
        l.mtspr r0,r3,SPR_ESR_BASE
316
 
317
        // Ensure global counter variable is zero
318
        LOAD_SYMBOL_2_GPR(r3,function_global)
319
        l.sw    0(r3),r0
320
 
321
        // Call function entry point, check bug doesn't occur
322
        l.j     call_rfe
323
        l.nop
324
 
325
        // Should never get here - test is detected as finished from the
326
        // timer interrupt.
327
 
328
check_for_restart:
329
        l.mfspr r4,r0,SPR_SR
330
        l.andi  r4,r4,SPR_SR_ICE /* is instruction cache enabled? */
331
        l.sfgtu r4,r0
332
        l.bnf   restart_with_caches
333
        l.nop
334
 
335
finish:
336
        l.movhi r3,0x8000
337
        l.ori   r3,r3,0x000d
338
        l.nop   0x2
339
        l.j     0
340
        l.nop   0x1
341
 
342
fail:
343
        l.movhi r3,0xbaaa
344
        l.ori   r3,r3,0xaaad
345
        l.nop   0x2
346
        l.j     0
347
        l.nop   0x1
348
 
349
 
350
        /* A stilly test function - doing some loads/stores, and some
351
        branches
352
        only touches r13 and r14*/
353
        /* Should be relocatable */
354
test_function:
355
        // Check for error - r31 should be 0
356
        l.sfne  r31,r0
357
        l.bf    test_function_fail
358
 
359
        LOAD_SYMBOL_2_GPR(r13,function_global)
360
        l.lwz   r14,0(r13)      /* Load value of global */
361
        l.addi  r14,r14,1
362
        l.sw    0(r13),r14      /* Store it back */
363
        l.mtspr r0,r13,SPR_DCBIR /* flush dcache */
364
        /* Every 8, branch away and back */
365
        l.andi  r14,r14,0xf
366
        l.sfeq  r14,r0
367
        l.bf    test_function_sub
368
        l.nop
369
        l.j     test_function
370
        l.nop
371
 
372
test_function_sub:
373
        l.j     test_function
374
        l.nop
375
 
376
test_function_fail:
377
        l.sys   0 /* Bail out with syscall */
378
 
379
test_function_end:
380
        l.nop   0x1
381
 
382
 
383
 
384
restart_with_caches:
385
        l.jal   _cache_init
386
        l.nop
387
        l.movhi r4, hi(_start)
388
        l.ori r4, r4, lo(_start)
389
        l.jr    r4
390
        l.nop
391
 
392
 
393
        /* MMU configuration functions */
394
 
395
immu_get_config:
396
        l.mfspr r3,r0,SPR_IMMUCFGR
397
        // Number of ways
398
        l.andi  r4,r3,SPR_IMMUCFGR_NTW
399
        l.addi  r4,r4,1
400
        // Store the ways in immu_ways
401
        l.movhi r5,hi(immu_ways)
402
        l.ori   r5,r5,lo(immu_ways)
403
        l.sw    0(r5),r4
404
        // Number of sets
405
        l.andi  r4,r3,SPR_IMMUCFGR_NTS
406
        l.srli  r4,r4,SPR_IMMUCFGR_NTS_OFF
407
        l.ori   r6,r0,1
408
        l.sll   r4,r6,r4
409
        // Store the ways in immu_ways
410
        l.movhi r5,hi(immu_sets)
411
        l.ori   r5,r5,lo(immu_sets)
412
        l.jr    r9      // Return
413
        l.sw    0(r5),r4
414
 
415
dmmu_get_config:
416
        l.mfspr r3,r0,SPR_DMMUCFGR
417
        // Number of ways
418
        l.andi  r4,r3,SPR_DMMUCFGR_NTW
419
        l.addi  r4,r4,1
420
        // Store the ways in dmmu_ways
421
        l.movhi r5,hi(dmmu_ways)
422
        l.ori   r5,r5,lo(dmmu_ways)
423
        l.sw    0(r5),r4
424
        // Number of sets
425
        l.andi  r4,r3,SPR_DMMUCFGR_NTS
426
        l.srli  r4,r4,SPR_DMMUCFGR_NTS_OFF
427
        l.ori   r6,r0,1
428
        l.sll   r4,r6,r4
429
        // Store the ways in dmmu_ways
430
        l.movhi r5,hi(dmmu_sets)
431
        l.ori   r5,r5,lo(dmmu_sets)
432
        l.jr    r9      // Return
433
        l.sw    0(r5),r4
434
 
435
 
436
immu_clear:
437
        // r3 - immu_ways
438
        // r4 - immu_sets
439
        // r5 - work
440
        // r6 - ways counter
441
        // r7 - sets counter
442
        // r10 - match regs spr address
443
        // r11 - translate regs spr address
444
 
445
        /* Clear all IMMU match/translate register pairs */
446
        l.movhi r5,hi(immu_ways)
447
        l.ori   r5,r5,lo(immu_ways)
448
        l.lwz   r3,0(r5)
449
        l.movhi r5,hi(immu_sets)
450
        l.ori   r5,r5,lo(immu_sets)
451
        l.lwz   r4,0(r5)
452
 
453
        l.movhi r6, 0   // Clear ways counters
454
 
455
immu_clear_set:
456
        l.movhi r7, 0   // Clear sets counter
457
        // Calculate base of IMMU match & translate registers
458
        l.ori   r10,r0,SPR_ITLBMR_BASE(0)
459
        l.ori   r11,r0,SPR_ITLBTR_BASE(0)
460
        l.slli  r5,r6,8 /* Multiply ways by 256  (ways<<8) */
461
        l.add   r10,r10,r5
462
        l.add   r11,r11,r5
463
immu_clear_set_loop:
464
        l.mtspr r10,r0,0 /* ITLBMR_BASE(way) + set = 0 */
465
        l.mtspr r11,r0,0 /* ITLBTR_BASE(way) + set = 0 */
466
        l.addi  r7,r7,1
467
        l.sfne  r4,r7
468
        l.addi  r10,r10,1
469
        l.bf    immu_clear_set_loop
470
        l.addi  r11,r11,1
471
 
472
        l.addi  r6,r6,1 /* Increment ways counter */
473
        l.sfne  r3,r6   /* Cleared all ways? */
474
        l.bf    immu_clear_set
475
        l.nop
476
 
477
        /* Finished */
478
        l.jr    r9
479
        l.nop
480
 
481
dmmu_clear:
482
        // r3 - dmmu_ways
483
        // r4 - dmmu_sets
484
        // r5 - work
485
        // r6 - ways counter
486
        // r7 - sets counter
487
        // r10 - match regs spr address
488
        // r11 - translate regs spr address
489
 
490
        /* Clear all DMMU match/translate register pairs */
491
        l.movhi r5,hi(dmmu_ways)
492
        l.ori   r5,r5,lo(dmmu_ways)
493
        l.lwz   r3,0(r5)
494
        l.movhi r5,hi(dmmu_sets)
495
        l.ori   r5,r5,lo(dmmu_sets)
496
        l.lwz   r4,0(r5)
497
 
498
        l.movhi r6, 0   // Clear ways counters
499
 
500
dmmu_clear_set:
501
        l.movhi r7, 0   // Clear sets counter
502
        // Calculate base of DMMU match & translate registers
503
        l.ori   r10,r0,SPR_DTLBMR_BASE(0)
504
        l.ori   r11,r0,SPR_DTLBTR_BASE(0)
505
        l.slli  r5,r6,8 /* Multiply ways by 256  (ways<<8) */
506
        l.add   r10,r10,r5
507
        l.add   r11,r11,r5
508
dmmu_clear_set_loop:
509
        l.mtspr r10,r0,0 /* ITLBMR_BASE(way) + set = 0 */
510
        l.mtspr r11,r0,0 /* ITLBTR_BASE(way) + set = 0 */
511
        l.addi  r7,r7,1
512
        l.sfne  r4,r7
513
        l.addi  r10,r10,1
514
        l.bf    dmmu_clear_set_loop
515
        l.addi  r11,r11,1
516
 
517
        l.addi  r6,r6,1 /* Increment ways counter */
518
        l.sfne  r3,r6   /* Cleared all ways? */
519
        l.bf    dmmu_clear_set
520
        l.nop
521
 
522
        /* Finished */
523
        l.jr    r9
524
        l.nop
525
 
526
 
527
 
528
#define TTMR_RELOAD_VALUE (SPR_TTMR_IE | SPR_TTMR_RT | TIMER_CYCLES_RATE)
529
timer_load:
530
        l.movhi r3,hi(TTMR_RELOAD_VALUE)
531
        l.ori   r3,r3,lo(TTMR_RELOAD_VALUE)
532
        l.jr r9
533
        l.mtspr r0,r3,SPR_TTMR

powered by: WebSVN 2.1.0

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