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

Subversion Repositories ion

[/] [ion/] [trunk/] [src/] [memtest/] [memtest.s] - Blame information for rev 214

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

Line No. Rev Author Line
1 50 ja_rd
################################################################################
2
# memtest.s -- Test external RAM memory (XRAM)
3
#-------------------------------------------------------------------------------
4
# This program tests the external RAM (connected to the core through the cache
5 109 ja_rd
# module). Currently it only finds the RAM top address if given the bottom
6 50 ja_rd
# address. Subsequent versions will add some minimal diagnostic capability,
7
# which will be needed when DRAM access is implemented.
8
#
9
# This program does only support a single continuous chunk of RAM. If the cache
10 109 ja_rd
# module ever supports more than one chunk (e.g. DRAM and SRAM as in the DE-1
11 50 ja_rd
# board) this program will be modified accordingly.
12 109 ja_rd
#
13 50 ja_rd
# The program assumes there's no useable r/w memory other than the XRAM so it
14
# does not use any memory for variables or stack.
15 109 ja_rd
#-------------------------------------------------------------------------------
16 50 ja_rd
#
17 109 ja_rd
#
18
#-------------------------------------------------------------------------------
19 50 ja_rd
# To be run from reset vector, standalone. Interrupts must be disabled.
20
#
21
################################################################################
22
 
23 109 ja_rd
    #---- Test parameters
24
    .ifndef XRAM_MAX
25
    .set XRAM_MAX,      1024                # max. no. of KB to test for
26
    .endif
27
    .ifndef XRAM_BASE
28
    .set XRAM_BASE,     0x00000000          # 1st XRAM address
29
    .endif
30
 
31
 
32 50 ja_rd
    #---- Set to >0 to enable a few debug messages
33
    .set DEBUG,         0
34
 
35 109 ja_rd
    #---- Cache parameters
36
    .set ICACHE_NUM_LINES, 256              # no. of lines in the I-Cache
37
    .set DCACHE_NUM_LINES, 256              # no. of lines in the D-Cache
38
    .set DCACHE_LINE_SIZE, 4                # D-Cache line size in words
39 50 ja_rd
 
40 109 ja_rd
 
41
    #---- UART stuff
42 50 ja_rd
    .set UART_BASE,     0x20000000          # UART base address
43
    .set UART_TX,       0x0000              # TX reg offset
44
    .set UART_STATUS,   0x0020              # status reg offset
45
 
46 213 ja_rd
    #---- Debug register block -- 4 read-write, 32-bit registers
47
    .set DEBUG_BASE,    0x2000f000          # Debug block base
48
 
49 50 ja_rd
    #---------------------------------------------------------------------------
50
 
51
    .text
52
    .align  2
53
    .globl  entry
54
    .ent    entry
55
entry:
56
    .set    noreorder
57
 
58
    b       start_test
59
    nop
60
 
61 66 ja_rd
    .ifgt   0
62 50 ja_rd
    #--- Trap handler address: we don't expect any traps -----------------------
63 66 ja_rd
    .org    0x0180
64 50 ja_rd
interrupt_vector:
65 109 ja_rd
    b       interrupt_vector    # just freeze there
66 50 ja_rd
    nop
67 66 ja_rd
    .endif
68 109 ja_rd
 
69 50 ja_rd
#-------------------------------------------------------------------------------
70
 
71 109 ja_rd
start_test:
72 152 ja_rd
    li      $a0,0x00000002
73
    mtc0    $a0,$12             # disable interrupts and cache
74 109 ja_rd
 
75 213 ja_rd
    .ifdef  TEST_CACHE          # if we're going to test the caches then
76
    jal     init_cache          # invalidate all the I- and D-Cache lines now
77 109 ja_rd
    nop
78 213 ja_rd
    jal     test_dcache
79
    nop
80 109 ja_rd
    .endif
81
 
82 50 ja_rd
    la      $a0,msg0
83
    jal     puts
84
    nop
85
    li      $a0,XRAM_BASE
86
    li      $a1,8
87
    jal     put_hex
88
    nop
89
    la      $a0,crlf
90
    jal     puts
91
    nop
92 109 ja_rd
 
93 66 ja_rd
    la      $t0,XRAM_BASE+4     # address of memory word being tested
94 50 ja_rd
    li      $t2,XRAM_MAX        # max amount of KBs to test for
95
    li      $t3,1               # (used to decrement $t2)
96
    li      $t4,0               # no. of KBs found
97
    move    $t5,$t0             # keep the start addr at hand for comparison
98 109 ja_rd
 
99 50 ja_rd
    sw      $zero,0($t0)        # clear 1st test word (in case of prev. run)
100 109 ja_rd
 
101 50 ja_rd
test_loop:
102
    lw      $t1,0($t0)          # read word contents
103
    beq     $t5,$t1,hit_mirror  # if it's the start address, we hit a mirror
104
    nop                         # we rolled off the end of the RAM back here
105
    sw      $t0,0($t0)          # word = word address
106
    lw      $t1,0($t0)          # read word back...
107
    bne     $t1,$t0,bad_word    # ...and if no match, we run off the RAM
108 109 ja_rd
    nop                         #
109 50 ja_rd
    sub     $t2,$t2,$t3         # decrement loop counter...
110
    bnez    $t2,test_loop       # ...and go back if there's more to go
111
    addiu   $t0,0x400           # in any case, increment test address by 1KB
112 109 ja_rd
 
113 50 ja_rd
    b       end_test            # end of memory found, result is in $t4
114
    nop
115 109 ja_rd
 
116 50 ja_rd
hit_mirror:                     # memory mirror detected
117
    .ifgt   DEBUG
118
    la      $a0,msg_mirror
119
    jal     puts
120
    nop
121
    .endif
122
    b       end_test
123
    nop
124 109 ja_rd
 
125 50 ja_rd
bad_word:                       # readback error detected (maybe r/o area?)
126
    .ifgt   DEBUG
127
    la      $a0,msg_bad
128
    jal     puts
129
    nop
130
    .endif
131
    b       end_test
132
    nop
133
 
134 78 ja_rd
end_test:                       # test done, ramtop+4 in $t0, #KB in $t4
135
 
136 109 ja_rd
 
137 50 ja_rd
    la      $a0,msg1            # Print ramtop message...
138
    jal     puts
139
    nop
140 109 ja_rd
 
141 66 ja_rd
    addi    $a0,$t0,-4          # substract the +4 offset we added before
142 78 ja_rd
    move    $sp,$t0             # init SP at the top of RAM space
143 90 ja_rd
    addi    $sp,$sp,-16
144 50 ja_rd
    li      $a1,8
145
    jal     put_hex
146
    nop
147
    la      $a0,crlf
148
    jal     puts
149
    nop
150 109 ja_rd
 
151
    # Clear RAM (only first words, so that simulation is not eternal)
152
    .ifgt 1
153
    li      $a0,XRAM_BASE
154
    addi    $a1,$a0,80*4
155
clear_xram_loop:
156
    sw      $zero,0($a0)
157
    blt     $a0,$a1,clear_xram_loop
158
    addi    $a0,$a0,4
159
    .endif
160
 
161
    # Test code execution from SRAM. We copy the test_exec_sram routine to
162 90 ja_rd
    # the base of the SRAM and then jal to it
163
    li      $a1,64
164
    li      $a0,XRAM_BASE
165
    la      $a3,test_exec_sram
166
copy_to_sram:
167
    lw      $a2,0($a3)
168
    nop
169
    sw      $a2,0($a0)
170
    addi    $a1,$a1,-4
171
    addi    $a3,$a3,4
172
    bnez    $a1,copy_to_sram
173
    addi    $a0,$a0,4
174 109 ja_rd
 
175
    # Optionally dump first few words of XRAM and jump onto XRAM
176
    .ifgt 1
177
    la      $a0,msg5
178
    jal     puts
179
    nop
180
    li      $a0,XRAM_BASE
181 90 ja_rd
    jal     dump_hex
182 109 ja_rd
    ori     $a1,$zero,20
183 90 ja_rd
    .endif
184 109 ja_rd
 
185
    .ifgt   1
186 90 ja_rd
    li      $a0,XRAM_BASE
187 109 ja_rd
    nop
188 90 ja_rd
    jalr    $a0
189
    nop
190 109 ja_rd
    .endif
191
 
192
    # If all went well in the SRAM we'll have returned here
193 90 ja_rd
    .ifgt   0
194 109 ja_rd
    # FIXME now we should do some strong test on the RAM to see if it's wired
195 78 ja_rd
    # correctly, using the right timing, etc.
196 109 ja_rd
 
197 78 ja_rd
    # Ok, now we know we have some RAM and stack space we can do some further
198
    # testing.
199
    # dump the first few words of FLASH
200 109 ja_rd
 
201 78 ja_rd
    la      $a0,msg2
202
    jal     puts
203
    nop
204 109 ja_rd
 
205 78 ja_rd
    # FIXME flash base address is hardcoded
206
    li      $a0,0xb0000000
207
    jal     put_hex
208
    ori     $a1,$zero,8
209 109 ja_rd
 
210 78 ja_rd
    la      $a0,crlf
211
    jal     puts
212
    nop
213
 
214
    la      $a0,crlf
215
    jal     puts
216
    nop
217 109 ja_rd
 
218 78 ja_rd
    li      $a0,0xb0000000
219
    jal     dump_hex
220 109 ja_rd
    ori     $a1,$zero,6
221 90 ja_rd
    .endif
222 109 ja_rd
 
223
 
224
    # Optionally jump to FLASH. This is only useful in simulation.
225
    .ifgt 1
226
    .ifdef  EXEC_FLASH
227
    la      $a0,msg8
228
    jal     puts
229
    nop
230
    li      $a0,0xb0000000
231
    nop
232
    jalr    $a0
233
    nop
234
    .endif
235
    .endif
236
 
237
    la      $a0,msg4
238
    jal     puts
239
    nop
240
 
241
 
242 50 ja_rd
$DONE:
243
    j       $DONE               # ...and freeze here
244
    nop
245
 
246 213 ja_rd
test_dcache:
247
    # This D-Cache test is extremely simplistic:
248
    # We'll make a few I/O writes to a block of test registers and then readback
249
    # all the data. The writes and reads will be done as fast as the CPU can,
250
    # i.e. back to back. We rely on the I-Cache being active for this.
251
    # Note that, while the CPU 'wants' to do the WR cycles back to back, it
252
    # can't because of the D-Cache stalls. That's the interaction we want to
253
    # test here, for both WR and RD cycles.
254 50 ja_rd
 
255 213 ja_rd
    move    $t8,$ra             # Save $ra -- remember, there's no stack
256
    la      $a0,msg9            # Display 'testing cache' message
257
    jal     puts
258
    nop
259
    li      $a0,DEBUG_BASE      # We'll use the debug register block as the
260
    li      $a1,0x112200aa      # target of a series of RD and WR cycles.
261
    addi    $a2,$a1,0x100       # Load $a1..$a2 with dummy data.
262
    addi    $a3,$a2,0x100
263
    .align  4                   # Align to 16 bytes (start of I-Cache line)
264
    sw      $a1,0x0($a0)        # Perform 3 WR cycles...
265
    sw      $a2,0x4($a0)
266
    sw      $a3,0x8($a0)
267
 
268
    lw      $t0,0x0($a0)        # ...followed by a RD cycle
269
    bne     $a1,$t0,test_dcache_ww_error
270
    nop
271
    lw      $t0,0x4($a0)        # Verify the other 2 WR cycles
272
    bne     $a2,$t0,test_dcache_ww_error
273
    nop
274
    lw      $t0,0x8($a0)
275
    bne     $a3,$t0,test_dcache_ww_error
276
    nop
277
 
278
    la      $a0,msg11           # display OK message...
279
    jal     puts
280
    nop
281
 
282
test_dcache_done:               # ...and quit.
283
    move    $ra,$t8             # Recover $ra and return
284
    jr      $ra
285
    nop
286
 
287
test_dcache_ww_error:           # We'll print the same error for all kinds of
288
    la      $a0,msg10           # failure; we'll diagnose it in simulation.
289
test_dcache_error:
290
    jal     puts
291
    nop
292
    b       test_dcache_done
293
 
294
 
295 109 ja_rd
    # This short routine will be copied to RAM and then executed there. This
296
    # will test the behavior of the I-Cache.
297 90 ja_rd
test_exec_sram:
298
    #jr      $ra
299
    #nop
300
    sw      $ra,0($sp)
301
    addi    $sp,$sp,-4
302
    la      $a0,msg3
303
    la      $a1,puts
304
    jalr    $a1
305
    nop
306
    lw      $ra,4($sp)
307
    jr      $ra
308
    addi    $sp,$sp,4
309
test_exec_sram_end:
310 109 ja_rd
    nop
311 90 ja_rd
 
312
 
313
 
314 50 ja_rd
#---- Functions ----------------------------------------------------------------
315 78 ja_rd
 
316 109 ja_rd
# void dump_hex(int *address {a0}, int len {a1})
317 78 ja_rd
dump_hex:
318
    move    $t7,$a0
319 109 ja_rd
    move    $t6,$a1
320 78 ja_rd
    sw      $ra,0($sp)
321
    addi    $sp,$sp,-4
322 109 ja_rd
 
323
dump_hex_loop_lines:
324
    move    $a0,$t7
325
    li      $a1,8
326
    jal     put_hex
327
    nop
328
    la      $a0,msg6
329
    jal     puts
330
    nop
331
    li      $t9,4
332
 
333
dump_hex_loop_words:
334 78 ja_rd
    lw      $a0,0($t7)
335
    jal     put_hex
336
    li      $a1,8
337 109 ja_rd
 
338 78 ja_rd
    la      $a0,space
339
    jal     puts
340
    addi    $t7,4
341 109 ja_rd
 
342
    addi    $t9,$t9,-1
343
    bnez    $t9,dump_hex_loop_words
344 78 ja_rd
    nop
345 109 ja_rd
 
346
    la      $a0,crlf
347
    jal     puts
348
    nop
349
 
350
    addi    $t6,$t6,-1
351
    bnez    $t6,dump_hex_loop_lines
352
    nop
353
 
354
    la      $a0,msg7
355
    jal     puts
356
    addi    $t7,4
357
 
358 213 ja_rd
    # Some debug hex dump...
359 109 ja_rd
    .ifgt 0
360 78 ja_rd
    lw      $ra,4($sp)
361 109 ja_rd
    move    $a0,$ra
362
    li      $a1,8
363
    jal     put_hex
364
    nop
365 213 ja_rd
stop_here:
366
    j       stop_here
367 109 ja_rd
    nop
368
    .endif
369
 
370
    nop
371
    lw      $ra,4($sp)
372 78 ja_rd
    jr      $ra
373
    addi    $sp,$sp,4
374
 
375
 
376 109 ja_rd
#---- Cache-related functions --------------------------------------------------
377
 
378
# void init_cache(void) -- invalidates all I-Cache lines (uses no RAM)
379
init_cache:
380
    li      $a0,0x00010000      # Disable cache, enable I-cache line invalidation
381 152 ja_rd
    mfc0    $a1,$12
382
    or      $a0,$a0,$a1
383 109 ja_rd
    mtc0    $a0,$12
384
 
385
    # In order to invalidate a I-Cache line we have to write its tag number to
386
    # any address while bits CP0[12].17:16=01. The write will be executed as a
387
    # regular write too, as a side effect, so we need to choose a harmless
388
    # target address.
389
 
390
    li      $a0,XRAM_BASE
391
    li      $a2,0
392
    li      $a1,ICACHE_NUM_LINES-1
393
 
394
inv_i_cache_loop:
395
    sw      $a2,0($a0)
396
    blt     $a2,$a1,inv_i_cache_loop
397
    addi    $a2,1
398
 
399
    mfc0    $a0,$12
400
    li      $a1,0x00020000      # Leave cache enabled
401 152 ja_rd
    or      $a0,$a0,$a1
402 109 ja_rd
    jr      $ra
403
    mtc0    $a0,$12
404
 
405
 
406
 
407 78 ja_rd
#--- Special functions that do not use any RAM ---------------------------------
408 50 ja_rd
# WARNING: Not for general use!
409
# All parameters in $a0..$a4, stack unused. No attempt to comply with any ABI
410
# has been made.
411 109 ja_rd
# Since we can't use any RAM, registers have been used with no regard for
412
# intended usage -- have to share reg bank with calling function.
413
 
414 50 ja_rd
# void puts(char *s) -- print zero-terminated string
415 109 ja_rd
puts:
416 78 ja_rd
    la      $a2,UART_BASE       # UART base address
417 50 ja_rd
puts_loop:
418
    lb      $v0,0($a0)
419
    beqz    $v0,puts_end
420
    addiu   $a0,1
421 109 ja_rd
puts_wait_tx_rdy:
422 78 ja_rd
    lw      $v1,UART_STATUS($a2)
423 50 ja_rd
    andi    $v1,$v1,0x02
424
    beqz    $v1,puts_wait_tx_rdy
425
    nop
426 78 ja_rd
    sw      $v0,UART_TX($a2)
427 50 ja_rd
    b       puts_loop
428
    nop
429 109 ja_rd
 
430 50 ja_rd
puts_end:
431
    jr      $ra
432 109 ja_rd
    nop
433 50 ja_rd
 
434
# void put_hex(int n, int d) -- print integer as d-digit hex
435
put_hex:
436 78 ja_rd
    la      $a2,UART_BASE
437
    la      $a3,put_hex_table
438 50 ja_rd
    addi    $a1,-1
439
    add     $a1,$a1,$a1
440
    add     $a1,$a1,$a1
441
 
442
put_hex_loop:
443
    srlv    $v0,$a0,$a1
444
    andi    $v0,$v0,0x0f
445 78 ja_rd
    addu    $s2,$a3,$v0
446 50 ja_rd
    lb      $v0,0($s2)
447
put_hex_wait_tx_rdy:
448 78 ja_rd
    lw      $v1,UART_STATUS($a2)
449 50 ja_rd
    andi    $v1,$v1,0x02
450
    beqz    $v1,put_hex_wait_tx_rdy
451
    nop
452 78 ja_rd
    sw      $v0,UART_TX($a2)
453 109 ja_rd
 
454 50 ja_rd
    bnez    $a1,put_hex_loop
455
    addi    $a1,-4
456
 
457
    jr      $ra
458
    nop
459
 
460 109 ja_rd
 
461 50 ja_rd
#---- Constant data (note we keep it in the text section) ----------------------
462
 
463
put_hex_table:
464
    .ascii  "0123456789abcdef"
465
 
466 109 ja_rd
msg0:
467 50 ja_rd
    .ascii  "\n\r"
468
    .asciz  "Scanning external memory at 0x"
469
msg1:
470
    .asciz  "Found XRAM top at           0x"
471
crlf:
472
    .asciz "\n\r"
473
space:
474
    .asciz "  "
475
msg_mirror:
476
    .asciz "hit mirror!\n\r"
477
msg_bad:
478
    .asciz "bad readback!\n\r"
479 78 ja_rd
msg2:
480
    .asciz "\n\rDumping the first few words of FLASH at address 0x"
481 90 ja_rd
msg3:
482
    .ascii "\n\rTesting code execution from SRAM...  "
483
    .asciz "if you see this, it worked\n\r"
484 109 ja_rd
msg4:
485
    .ascii  "\n\r\n\r"
486
    .asciz  "End of test.\n\r\n\r"
487
msg5:
488
    .asciz  "Dump of first few words of XRAM after initialization:\n\r"
489
msg6:
490
    .asciiz ": "
491
msg7:
492
    .asciiz "<end of dump>"
493
msg8:
494
    .ascii  "\n\r"
495 213 ja_rd
    .asciz  "Testing execution from 8-bit static memory (FLASH)\n\r"
496
msg9:
497
    .asciz  "Testing D-Cache with back-to-back pairs of RD & WR cycles...\n\r"
498
msg10:
499
    .asciz  "Error in WR+WR sequence\n\r"
500
msg11:
501
    .asciz  "OK\n\r"
502 109 ja_rd
 
503 213 ja_rd
 
504 50 ja_rd
    .set    reorder
505
    .end    entry
506 109 ja_rd
 

powered by: WebSVN 2.1.0

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