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

Subversion Repositories ion

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

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

powered by: WebSVN 2.1.0

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