@@ -283,52 +283,106 @@ void sdram_leave_low_power(void) {
283
283
#pragma GCC diagnostic ignored "-Wstringop-overflow"
284
284
#endif
285
285
286
- bool sdram_test (bool fast ) {
286
+ bool __attribute__(( optimize ( "O0" ))) sdram_test (bool exhaustive ) {
287
287
uint8_t const pattern = 0xaa ;
288
288
uint8_t const antipattern = 0x55 ;
289
289
uint8_t * const mem_base = (uint8_t * )sdram_start ();
290
290
291
- /* test data bus */
292
- for (uint8_t i = 1 ; i ; i <<= 1 ) {
293
- * mem_base = i ;
294
- if (* mem_base != i ) {
295
- printf ("data bus lines test failed! data (%d)\n" , i );
291
+ #if MICROPY_HW_SDRAM_TEST_FAIL_ON_ERROR
292
+ char error_buffer [1024 ];
293
+ #endif
294
+
295
+ #if (__DCACHE_PRESENT == 1 )
296
+ bool i_cache_disabled = false;
297
+ bool d_cache_disabled = false;
298
+
299
+ // Disable caches for testing.
300
+ if (SCB -> CCR & (uint32_t )SCB_CCR_IC_Msk ) {
301
+ SCB_DisableICache ();
302
+ i_cache_disabled = true;
303
+ }
304
+
305
+ if (SCB -> CCR & (uint32_t )SCB_CCR_DC_Msk ) {
306
+ SCB_DisableDCache ();
307
+ d_cache_disabled = true;
308
+ }
309
+ #endif
310
+
311
+ // Test data bus
312
+ for (uint32_t i = 0 ; i < MICROPY_HW_SDRAM_MEM_BUS_WIDTH ; i ++ ) {
313
+ * ((uint32_t * )mem_base ) = (1 << i );
314
+ if (* ((uint32_t * )mem_base ) != (1 << i )) {
315
+ #if MICROPY_HW_SDRAM_TEST_FAIL_ON_ERROR
316
+ snprintf (error_buffer , sizeof (error_buffer ),
317
+ "Data bus test failed at 0x%p expected 0x%x found 0x%lx" ,
318
+ & mem_base [0 ], (1 << i ), ((uint32_t * )mem_base )[0 ]);
319
+ __fatal_error (error_buffer );
320
+ #endif
296
321
return false;
297
322
}
298
323
}
299
324
300
- /* test address bus */
301
- /* Check individual address lines */
325
+ // Test address bus
302
326
for (uint32_t i = 1 ; i < MICROPY_HW_SDRAM_SIZE ; i <<= 1 ) {
303
327
mem_base [i ] = pattern ;
304
328
if (mem_base [i ] != pattern ) {
305
- printf ("address bus lines test failed! address (%p)\n" , & mem_base [i ]);
329
+ #if MICROPY_HW_SDRAM_TEST_FAIL_ON_ERROR
330
+ snprintf (error_buffer , sizeof (error_buffer ),
331
+ "Address bus test failed at 0x%p expected 0x%x found 0x%x" ,
332
+ & mem_base [i ], pattern , mem_base [i ]);
333
+ __fatal_error (error_buffer );
334
+ #endif
306
335
return false;
307
336
}
308
337
}
309
338
310
- /* Check for aliasing (overlaping addresses) */
339
+ // Check for aliasing (overlaping addresses)
311
340
mem_base [0 ] = antipattern ;
312
341
for (uint32_t i = 1 ; i < MICROPY_HW_SDRAM_SIZE ; i <<= 1 ) {
313
342
if (mem_base [i ] != pattern ) {
314
- printf ("address bus overlap %p\n" , & mem_base [i ]);
343
+ #if MICROPY_HW_SDRAM_TEST_FAIL_ON_ERROR
344
+ snprintf (error_buffer , sizeof (error_buffer ),
345
+ "Address bus overlap at 0x%p expected 0x%x found 0x%x" ,
346
+ & mem_base [i ], pattern , mem_base [i ]);
347
+ __fatal_error (error_buffer );
348
+ #endif
315
349
return false;
316
350
}
317
351
}
318
352
319
- /* test all ram cells */
320
- if (!fast ) {
321
- for (uint32_t i = 0 ; i < MICROPY_HW_SDRAM_SIZE ; ++ i ) {
353
+ // Test all RAM cells
354
+ if (exhaustive ) {
355
+ // Write all memory first then compare, so even if the cache
356
+ // is enabled, it's not just writing and reading from cache.
357
+ // Note: This test should also detect refresh rate issues.
358
+ for (uint32_t i = 0 ; i < MICROPY_HW_SDRAM_SIZE ; i ++ ) {
322
359
mem_base [i ] = pattern ;
360
+ }
361
+
362
+ for (uint32_t i = 0 ; i < MICROPY_HW_SDRAM_SIZE ; i ++ ) {
323
363
if (mem_base [i ] != pattern ) {
324
- printf ("address bus test failed! address (%p)\n" , & mem_base [i ]);
364
+ #if MICROPY_HW_SDRAM_TEST_FAIL_ON_ERROR
365
+ snprintf (error_buffer , sizeof (error_buffer ),
366
+ "Address bus slow test failed at 0x%p expected 0x%x found 0x%x" ,
367
+ & mem_base [i ], pattern , mem_base [i ]);
368
+ __fatal_error (error_buffer );
369
+ #endif
325
370
return false;
326
371
}
327
372
}
328
- } else {
329
- memset (mem_base , pattern , MICROPY_HW_SDRAM_SIZE );
330
373
}
331
374
375
+ #if (__DCACHE_PRESENT == 1 )
376
+ // Re-enable caches if they were enabled before the test started.
377
+ if (i_cache_disabled ) {
378
+ SCB_EnableICache ();
379
+ }
380
+
381
+ if (d_cache_disabled ) {
382
+ SCB_EnableDCache ();
383
+ }
384
+ #endif
385
+
332
386
return true;
333
387
}
334
388
0 commit comments