mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-24 22:56:52 +01:00
[SC64][SW] Added SD card FatFs tests, rearranged SDRAM tests
This commit is contained in:
parent
a884d69308
commit
92838da349
4
sw/bootloader/src/fatfs/ffconf.h
vendored
4
sw/bootloader/src/fatfs/ffconf.h
vendored
@ -15,7 +15,7 @@
|
|||||||
/ and optional writing functions as well. */
|
/ and optional writing functions as well. */
|
||||||
|
|
||||||
|
|
||||||
#define FF_FS_MINIMIZE 2
|
#define FF_FS_MINIMIZE 0
|
||||||
/* This option defines minimization level to remove some basic API functions.
|
/* This option defines minimization level to remove some basic API functions.
|
||||||
/
|
/
|
||||||
/ 0: Basic functions are fully enabled.
|
/ 0: Basic functions are fully enabled.
|
||||||
@ -47,7 +47,7 @@
|
|||||||
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
|
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
|
||||||
|
|
||||||
|
|
||||||
#define FF_USE_LABEL 0
|
#define FF_USE_LABEL 1
|
||||||
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||||
/ (0:Disable or 1:Enable) */
|
/ (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
@ -2,15 +2,19 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "fatfs/ff.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "sc64.h"
|
#include "sc64.h"
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define TEST_BUFFER_SIZE (128 * 1024)
|
||||||
|
|
||||||
|
#define SD_TEST_FILE_SIZE (16 * 1024 * 1024)
|
||||||
|
|
||||||
#define SDRAM_ADDRESS (0x10000000)
|
#define SDRAM_ADDRESS (0x10000000)
|
||||||
#define SDRAM_SIZE (64 * 1024 * 1024)
|
#define SDRAM_SIZE (64 * 1024 * 1024)
|
||||||
#define SDRAM_BUFFER_SIZE (128 * 1024)
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -23,8 +27,8 @@ typedef struct {
|
|||||||
|
|
||||||
static uint32_t random_seed = 0;
|
static uint32_t random_seed = 0;
|
||||||
|
|
||||||
static uint32_t w_buffer[SDRAM_BUFFER_SIZE / sizeof(uint32_t)] __attribute__((aligned(8)));
|
static uint32_t w_buffer[TEST_BUFFER_SIZE / sizeof(uint32_t)] __attribute__((aligned(8)));
|
||||||
static uint32_t r_buffer[SDRAM_BUFFER_SIZE / sizeof(uint32_t)] __attribute__((aligned(8)));
|
static uint32_t r_buffer[TEST_BUFFER_SIZE / sizeof(uint32_t)] __attribute__((aligned(8)));
|
||||||
|
|
||||||
|
|
||||||
static void fill_own_address (uint32_t *buffer, int size, uint32_t pattern, uint32_t offset) {
|
static void fill_own_address (uint32_t *buffer, int size, uint32_t pattern, uint32_t offset) {
|
||||||
@ -67,17 +71,14 @@ static void test_sc64_cfg (void) {
|
|||||||
|
|
||||||
if ((error = sc64_get_identifier(&identifier)) != SC64_OK) {
|
if ((error = sc64_get_identifier(&identifier)) != SC64_OK) {
|
||||||
error_display("Command IDENTIFIER_GET failed: %d", error);
|
error_display("Command IDENTIFIER_GET failed: %d", error);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = sc64_get_version(&major, &minor, &revision)) != SC64_OK) {
|
if ((error = sc64_get_version(&major, &minor, &revision)) != SC64_OK) {
|
||||||
error_display("Command VERSION_GET failed: %d", error);
|
error_display("Command VERSION_GET failed: %d", error);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = sc64_get_diagnostic(DIAGNOSTIC_ID_VOLTAGE_TEMPERATURE, &tmp)) != SC64_OK) {
|
if ((error = sc64_get_diagnostic(DIAGNOSTIC_ID_VOLTAGE_TEMPERATURE, &tmp)) != SC64_OK) {
|
||||||
error_display("Command DIAGNOSTIC_GET failed: %d", error);
|
error_display("Command DIAGNOSTIC_GET failed: %d", error);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t voltage = (uint16_t) (tmp >> 16);
|
uint16_t voltage = (uint16_t) (tmp >> 16);
|
||||||
@ -154,7 +155,7 @@ static void test_pi (void) {
|
|||||||
display_printf("\n");
|
display_printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_sd_card (void) {
|
static void test_sd_card_io (void) {
|
||||||
sc64_error_t error;
|
sc64_error_t error;
|
||||||
sc64_sd_card_status_t card_status;
|
sc64_sd_card_status_t card_status;
|
||||||
uint8_t card_info[32] __attribute__((aligned(8)));
|
uint8_t card_info[32] __attribute__((aligned(8)));
|
||||||
@ -170,9 +171,12 @@ static void test_sd_card (void) {
|
|||||||
display_printf("SD card is not inserted\n");
|
display_printf("SD card is not inserted\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((error = sc64_sd_card_deinit()) != SC64_OK) {
|
||||||
|
return display_printf("SD card deinit error: %d", error);
|
||||||
|
}
|
||||||
|
|
||||||
if ((error = sc64_sd_card_init()) != SC64_OK) {
|
if ((error = sc64_sd_card_init()) != SC64_OK) {
|
||||||
display_printf("SD card init error: %d\n", error);
|
return display_printf("SD card init error: %d\n", error);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = sc64_sd_card_get_status(&card_status)) != SC64_OK) {
|
if ((error = sc64_sd_card_get_status(&card_status)) != SC64_OK) {
|
||||||
@ -193,8 +197,7 @@ static void test_sd_card (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((error = sc64_sd_card_get_info((uint32_t *) (SC64_BUFFERS->BUFFER))) != SC64_OK) {
|
if ((error = sc64_sd_card_get_info((uint32_t *) (SC64_BUFFERS->BUFFER))) != SC64_OK) {
|
||||||
display_printf("SD card get info error: %d\n", error);
|
return display_printf("SD card get info error: %d\n", error);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pi_dma_read((io32_t *) (SC64_BUFFERS->BUFFER), card_info, sizeof(card_info));
|
pi_dma_read((io32_t *) (SC64_BUFFERS->BUFFER), card_info, sizeof(card_info));
|
||||||
@ -214,8 +217,7 @@ static void test_sd_card (void) {
|
|||||||
display_printf("\n");
|
display_printf("\n");
|
||||||
|
|
||||||
if ((error = sc64_sd_read_sectors((void *) (SC64_BUFFERS->BUFFER), 0, 1)) != SC64_OK) {
|
if ((error = sc64_sd_read_sectors((void *) (SC64_BUFFERS->BUFFER), 0, 1)) != SC64_OK) {
|
||||||
display_printf("SD card read sector 0 error: %d\n", error);
|
return display_printf("SD card read sector 0 error: %d\n", error);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pi_dma_read((io32_t *) (SC64_BUFFERS->BUFFER), sector, sizeof(sector));
|
pi_dma_read((io32_t *) (SC64_BUFFERS->BUFFER), sector, sizeof(sector));
|
||||||
@ -232,72 +234,194 @@ static void test_sd_card (void) {
|
|||||||
display_printf(" Boot signature: 0x%02X%02X\n", sector[510], sector[511]);
|
display_printf(" Boot signature: 0x%02X%02X\n", sector[510], sector[511]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_sd_card_fatfs (void) {
|
||||||
|
sc64_error_t error;
|
||||||
|
FRESULT fresult;
|
||||||
|
FATFS fs;
|
||||||
|
TCHAR label[23];
|
||||||
|
DWORD vsn;
|
||||||
|
FIL fil;
|
||||||
|
UINT left;
|
||||||
|
UINT bytes;
|
||||||
|
|
||||||
|
if ((error = sc64_sd_card_deinit()) != SC64_OK) {
|
||||||
|
return display_printf("SD card deinit error: %d", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fresult = f_mount(&fs, "", 1)) != FR_OK) {
|
||||||
|
return display_printf("f_mount error: %d\n", fresult);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fresult = f_getlabel("", label, &vsn)) != FR_OK) {
|
||||||
|
return display_printf("f_getlabel error: %d\n", fresult);
|
||||||
|
}
|
||||||
|
|
||||||
|
display_printf("Volume [%s] / [%08lX]\n\n", label, vsn);
|
||||||
|
|
||||||
|
if ((fresult = f_open(&fil, "sc64test.bin", FA_CREATE_ALWAYS | FA_WRITE)) != FR_OK) {
|
||||||
|
return display_printf("f_open (write) error: %d\n", fresult);
|
||||||
|
}
|
||||||
|
|
||||||
|
srand(random_seed);
|
||||||
|
|
||||||
|
left = SD_TEST_FILE_SIZE;
|
||||||
|
|
||||||
|
while (left) {
|
||||||
|
if ((left % (SD_TEST_FILE_SIZE / 64)) == 0) {
|
||||||
|
display_printf("w");
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT block_size = (left > TEST_BUFFER_SIZE) ? TEST_BUFFER_SIZE : left;
|
||||||
|
|
||||||
|
fill_random(w_buffer, block_size, 0, 0);
|
||||||
|
|
||||||
|
if ((fresult = f_write(&fil, w_buffer, block_size, &bytes)) != FR_OK) {
|
||||||
|
return display_printf("\nf_write error: %d\n", fresult);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytes != block_size) {
|
||||||
|
return display_printf("\nf_write (%ld!=%ld) error: %d\n", bytes, block_size, fresult);
|
||||||
|
}
|
||||||
|
|
||||||
|
left -= block_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
display_printf("\n");
|
||||||
|
|
||||||
|
if ((fresult = f_close(&fil)) != FR_OK) {
|
||||||
|
return display_printf("f_close (write) error: %d\n", fresult);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fresult = f_open(&fil, "sc64test.bin", FA_OPEN_EXISTING | FA_READ)) != FR_OK) {
|
||||||
|
return display_printf("f_open (read) error: %d\n", fresult);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f_size(&fil) != SD_TEST_FILE_SIZE) {
|
||||||
|
return display_printf("f_size (%d!=%d) error\n", f_size(&fil), SD_TEST_FILE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
srand(random_seed);
|
||||||
|
|
||||||
|
left = SD_TEST_FILE_SIZE;
|
||||||
|
|
||||||
|
while (left) {
|
||||||
|
if ((left % (SD_TEST_FILE_SIZE / 64)) == 0) {
|
||||||
|
display_printf("r");
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT block_size = (left > TEST_BUFFER_SIZE) ? TEST_BUFFER_SIZE : left;
|
||||||
|
|
||||||
|
fill_random(w_buffer, block_size, 0, 0);
|
||||||
|
|
||||||
|
if ((fresult = f_read(&fil, r_buffer, block_size, &bytes)) != FR_OK) {
|
||||||
|
return display_printf("\nf_read error: %d\n", fresult);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytes != block_size) {
|
||||||
|
return display_printf("\nf_read (%ld!=%ld) error: %d\n", bytes, block_size, fresult);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (UINT i = 0; i < (block_size / sizeof(uint32_t)); i++) {
|
||||||
|
if (w_buffer[i] != r_buffer[i]) {
|
||||||
|
display_printf(
|
||||||
|
"\n"
|
||||||
|
" > Mismatch error at file offset 0x%08lX\n"
|
||||||
|
" > 0x%08lX (W) != 0x%08lX (R)",
|
||||||
|
f_tell(&fil) + (i * sizeof(uint32_t)),
|
||||||
|
w_buffer[i],
|
||||||
|
r_buffer[i]
|
||||||
|
);
|
||||||
|
|
||||||
|
while (true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
left -= block_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
display_printf("\n");
|
||||||
|
|
||||||
|
if ((fresult = f_close(&fil)) != FR_OK) {
|
||||||
|
return display_printf("f_close (read) error: %d\n", fresult);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fresult = f_unlink("sc64test.bin")) != FR_OK) {
|
||||||
|
return display_printf("f_unlink error: %d\n", fresult);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fresult = f_unmount("")) != FR_OK) {
|
||||||
|
return display_printf("f_unmount error: %d\n", fresult);
|
||||||
|
}
|
||||||
|
|
||||||
|
random_seed += c0_count();
|
||||||
|
}
|
||||||
|
|
||||||
static void test_sdram (void) {
|
static void test_sdram (void) {
|
||||||
static int phase = 0;
|
static int phase = 0;
|
||||||
|
|
||||||
sdram_test_t phase_0_tests[] = {
|
sdram_test_t phase_0_tests[] = {
|
||||||
{ .name = "Own address: ", .fill = fill_own_address, .pattern = 0x00000000, .fade = 0 },
|
{ .name = "Own address: ", .fill = fill_own_address, .pattern = 0x00000000, .fade = 0 },
|
||||||
{ .name = "All zeros: ", .fill = fill_pattern, .pattern = 0x00000000, .fade = 0 },
|
{ .name = "All zeros: ", .fill = fill_pattern, .pattern = 0x00000000, .fade = 0 },
|
||||||
{ .name = "All ones: ", .fill = fill_pattern, .pattern = 0xFFFFFFFF, .fade = 0 },
|
{ .name = "All ones: ", .fill = fill_pattern, .pattern = 0xFFFFFFFF, .fade = 0 },
|
||||||
{ .name = "Random (1/3): ", .fill = fill_random, .pattern = 0x00000000, .fade = 0 },
|
{ .name = "0xAAAA5555: ", .fill = fill_pattern, .pattern = 0xAAAA5555, .fade = 0 },
|
||||||
{ .name = "Random (2/3): ", .fill = fill_random, .pattern = 0x00000000, .fade = 0 },
|
{ .name = "0x5555AAAA: ", .fill = fill_pattern, .pattern = 0x5555AAAA, .fade = 0 },
|
||||||
{ .name = "Random (3/3): ", .fill = fill_random, .pattern = 0x00000000, .fade = 0 },
|
{ .name = "Random (1/3): ", .fill = fill_random, .pattern = 0x00000000, .fade = 0 },
|
||||||
{ .name = "Fadeout S (0):", .fill = fill_pattern, .pattern = 0x00000000, .fade = 60 },
|
{ .name = "Random (2/3): ", .fill = fill_random, .pattern = 0x00000000, .fade = 0 },
|
||||||
{ .name = "Fadeout S (1):", .fill = fill_pattern, .pattern = 0xFFFFFFFF, .fade = 60 },
|
{ .name = "Random (3/3): ", .fill = fill_random, .pattern = 0x00000000, .fade = 0 },
|
||||||
{ .name = NULL },
|
{ .name = NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
sdram_test_t phase_1_tests[] = {
|
sdram_test_t phase_1_tests[] = {
|
||||||
{ .name = "0x00010001: ", .fill = fill_pattern, .pattern = 0x00010001, .fade = 0 },
|
{ .name = "0x00010001: ", .fill = fill_pattern, .pattern = 0x00010001, .fade = 0 },
|
||||||
{ .name = "0xFFFEFFFE: ", .fill = fill_pattern, .pattern = 0xFFFEFFFE, .fade = 0 },
|
{ .name = "0xFFFEFFFE: ", .fill = fill_pattern, .pattern = 0xFFFEFFFE, .fade = 0 },
|
||||||
{ .name = "0x00020002: ", .fill = fill_pattern, .pattern = 0x00020002, .fade = 0 },
|
{ .name = "0x00020002: ", .fill = fill_pattern, .pattern = 0x00020002, .fade = 0 },
|
||||||
{ .name = "0xFFFDFFFD: ", .fill = fill_pattern, .pattern = 0xFFFDFFFD, .fade = 0 },
|
{ .name = "0xFFFDFFFD: ", .fill = fill_pattern, .pattern = 0xFFFDFFFD, .fade = 0 },
|
||||||
{ .name = "0x00040004: ", .fill = fill_pattern, .pattern = 0x00040004, .fade = 0 },
|
{ .name = "0x00040004: ", .fill = fill_pattern, .pattern = 0x00040004, .fade = 0 },
|
||||||
{ .name = "0xFFFBFFFB: ", .fill = fill_pattern, .pattern = 0xFFFBFFFB, .fade = 0 },
|
{ .name = "0xFFFBFFFB: ", .fill = fill_pattern, .pattern = 0xFFFBFFFB, .fade = 0 },
|
||||||
{ .name = "0x00080008: ", .fill = fill_pattern, .pattern = 0x00080008, .fade = 0 },
|
{ .name = "0x00080008: ", .fill = fill_pattern, .pattern = 0x00080008, .fade = 0 },
|
||||||
{ .name = "0xFFF7FFF7: ", .fill = fill_pattern, .pattern = 0xFFF7FFF7, .fade = 0 },
|
{ .name = "0xFFF7FFF7: ", .fill = fill_pattern, .pattern = 0xFFF7FFF7, .fade = 0 },
|
||||||
{ .name = NULL },
|
{ .name = NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
sdram_test_t phase_2_tests[] = {
|
sdram_test_t phase_2_tests[] = {
|
||||||
{ .name = "0x00100010: ", .fill = fill_pattern, .pattern = 0x00100010, .fade = 0 },
|
{ .name = "0x00100010: ", .fill = fill_pattern, .pattern = 0x00100010, .fade = 0 },
|
||||||
{ .name = "0xFFEFFFEF: ", .fill = fill_pattern, .pattern = 0xFFEFFFEF, .fade = 0 },
|
{ .name = "0xFFEFFFEF: ", .fill = fill_pattern, .pattern = 0xFFEFFFEF, .fade = 0 },
|
||||||
{ .name = "0x00200020: ", .fill = fill_pattern, .pattern = 0x00200020, .fade = 0 },
|
{ .name = "0x00200020: ", .fill = fill_pattern, .pattern = 0x00200020, .fade = 0 },
|
||||||
{ .name = "0xFFDFFFDF: ", .fill = fill_pattern, .pattern = 0xFFDFFFDF, .fade = 0 },
|
{ .name = "0xFFDFFFDF: ", .fill = fill_pattern, .pattern = 0xFFDFFFDF, .fade = 0 },
|
||||||
{ .name = "0x00400040: ", .fill = fill_pattern, .pattern = 0x00400040, .fade = 0 },
|
{ .name = "0x00400040: ", .fill = fill_pattern, .pattern = 0x00400040, .fade = 0 },
|
||||||
{ .name = "0xFFBFFFBF: ", .fill = fill_pattern, .pattern = 0xFFBFFFBF, .fade = 0 },
|
{ .name = "0xFFBFFFBF: ", .fill = fill_pattern, .pattern = 0xFFBFFFBF, .fade = 0 },
|
||||||
{ .name = "0x00800080: ", .fill = fill_pattern, .pattern = 0x00800080, .fade = 0 },
|
{ .name = "0x00800080: ", .fill = fill_pattern, .pattern = 0x00800080, .fade = 0 },
|
||||||
{ .name = "0xFF7FFF7F: ", .fill = fill_pattern, .pattern = 0xFF7FFF7F, .fade = 0 },
|
{ .name = "0xFF7FFF7F: ", .fill = fill_pattern, .pattern = 0xFF7FFF7F, .fade = 0 },
|
||||||
{ .name = NULL },
|
{ .name = NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
sdram_test_t phase_3_tests[] = {
|
sdram_test_t phase_3_tests[] = {
|
||||||
{ .name = "0x01000100: ", .fill = fill_pattern, .pattern = 0x01000100, .fade = 0 },
|
{ .name = "0x01000100: ", .fill = fill_pattern, .pattern = 0x01000100, .fade = 0 },
|
||||||
{ .name = "0xFEFFFEFF: ", .fill = fill_pattern, .pattern = 0xFEFFFEFF, .fade = 0 },
|
{ .name = "0xFEFFFEFF: ", .fill = fill_pattern, .pattern = 0xFEFFFEFF, .fade = 0 },
|
||||||
{ .name = "0x02000200: ", .fill = fill_pattern, .pattern = 0x02000200, .fade = 0 },
|
{ .name = "0x02000200: ", .fill = fill_pattern, .pattern = 0x02000200, .fade = 0 },
|
||||||
{ .name = "0xFDFFFDFF: ", .fill = fill_pattern, .pattern = 0xFDFFFDFF, .fade = 0 },
|
{ .name = "0xFDFFFDFF: ", .fill = fill_pattern, .pattern = 0xFDFFFDFF, .fade = 0 },
|
||||||
{ .name = "0x04000400: ", .fill = fill_pattern, .pattern = 0x04000400, .fade = 0 },
|
{ .name = "0x04000400: ", .fill = fill_pattern, .pattern = 0x04000400, .fade = 0 },
|
||||||
{ .name = "0xFBFFFBFF: ", .fill = fill_pattern, .pattern = 0xFBFFFBFF, .fade = 0 },
|
{ .name = "0xFBFFFBFF: ", .fill = fill_pattern, .pattern = 0xFBFFFBFF, .fade = 0 },
|
||||||
{ .name = "0x08000800: ", .fill = fill_pattern, .pattern = 0x08000800, .fade = 0 },
|
{ .name = "0x08000800: ", .fill = fill_pattern, .pattern = 0x08000800, .fade = 0 },
|
||||||
{ .name = "0xF7FFF7FF: ", .fill = fill_pattern, .pattern = 0xF7FFF7FF, .fade = 0 },
|
{ .name = "0xF7FFF7FF: ", .fill = fill_pattern, .pattern = 0xF7FFF7FF, .fade = 0 },
|
||||||
{ .name = NULL },
|
{ .name = NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
sdram_test_t phase_4_tests[] = {
|
sdram_test_t phase_4_tests[] = {
|
||||||
{ .name = "0x10001000: ", .fill = fill_pattern, .pattern = 0x10001000, .fade = 0 },
|
{ .name = "0x10001000: ", .fill = fill_pattern, .pattern = 0x10001000, .fade = 0 },
|
||||||
{ .name = "0xEFFFEFFF: ", .fill = fill_pattern, .pattern = 0xEFFFEFFF, .fade = 0 },
|
{ .name = "0xEFFFEFFF: ", .fill = fill_pattern, .pattern = 0xEFFFEFFF, .fade = 0 },
|
||||||
{ .name = "0x20002000: ", .fill = fill_pattern, .pattern = 0x20002000, .fade = 0 },
|
{ .name = "0x20002000: ", .fill = fill_pattern, .pattern = 0x20002000, .fade = 0 },
|
||||||
{ .name = "0xDFFFDFFF: ", .fill = fill_pattern, .pattern = 0xDFFFDFFF, .fade = 0 },
|
{ .name = "0xDFFFDFFF: ", .fill = fill_pattern, .pattern = 0xDFFFDFFF, .fade = 0 },
|
||||||
{ .name = "0x40004000: ", .fill = fill_pattern, .pattern = 0x40004000, .fade = 0 },
|
{ .name = "0x40004000: ", .fill = fill_pattern, .pattern = 0x40004000, .fade = 0 },
|
||||||
{ .name = "0xBFFFBFFF: ", .fill = fill_pattern, .pattern = 0xBFFFBFFF, .fade = 0 },
|
{ .name = "0xBFFFBFFF: ", .fill = fill_pattern, .pattern = 0xBFFFBFFF, .fade = 0 },
|
||||||
{ .name = "0x80008000: ", .fill = fill_pattern, .pattern = 0x80008000, .fade = 0 },
|
{ .name = "0x80008000: ", .fill = fill_pattern, .pattern = 0x80008000, .fade = 0 },
|
||||||
{ .name = "0x7FFF7FFF: ", .fill = fill_pattern, .pattern = 0x7FFF7FFF, .fade = 0 },
|
{ .name = "0x7FFF7FFF: ", .fill = fill_pattern, .pattern = 0x7FFF7FFF, .fade = 0 },
|
||||||
{ .name = NULL },
|
{ .name = NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
sdram_test_t phase_5_tests[] = {
|
sdram_test_t phase_5_tests[] = {
|
||||||
{ .name = "Fadeout L (0):", .fill = fill_pattern, .pattern = 0x00000000, .fade = 300 },
|
{ .name = "Fadeout (0): ", .fill = fill_pattern, .pattern = 0x00000000, .fade = 60 },
|
||||||
{ .name = "Fadeout L (1):", .fill = fill_pattern, .pattern = 0xFFFFFFFF, .fade = 300 },
|
{ .name = "Fadeout (1): ", .fill = fill_pattern, .pattern = 0xFFFFFFFF, .fade = 60 },
|
||||||
{ .name = NULL },
|
{ .name = NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -317,14 +441,14 @@ static void test_sdram (void) {
|
|||||||
|
|
||||||
srand(random_seed);
|
srand(random_seed);
|
||||||
|
|
||||||
for (int offset = 0; offset < SDRAM_SIZE; offset += SDRAM_BUFFER_SIZE) {
|
for (int offset = 0; offset < SDRAM_SIZE; offset += TEST_BUFFER_SIZE) {
|
||||||
if ((offset % (SDRAM_SIZE / 16)) == 0) {
|
if ((offset % (SDRAM_SIZE / 16)) == 0) {
|
||||||
display_printf("w");
|
display_printf("w");
|
||||||
}
|
}
|
||||||
|
|
||||||
test->fill(w_buffer, SDRAM_BUFFER_SIZE, test->pattern, offset);
|
test->fill(w_buffer, TEST_BUFFER_SIZE, test->pattern, offset);
|
||||||
|
|
||||||
pi_dma_write((io32_t *) (SDRAM_ADDRESS + offset), w_buffer, SDRAM_BUFFER_SIZE);
|
pi_dma_write((io32_t *) (SDRAM_ADDRESS + offset), w_buffer, TEST_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int fade = test->fade; fade > 0; fade--) {
|
for (int fade = test->fade; fade > 0; fade--) {
|
||||||
@ -335,19 +459,19 @@ static void test_sdram (void) {
|
|||||||
|
|
||||||
srand(random_seed);
|
srand(random_seed);
|
||||||
|
|
||||||
for (int offset = 0; offset < SDRAM_SIZE; offset += SDRAM_BUFFER_SIZE) {
|
for (int offset = 0; offset < SDRAM_SIZE; offset += TEST_BUFFER_SIZE) {
|
||||||
if ((offset % (SDRAM_SIZE / 16)) == 0) {
|
if ((offset % (SDRAM_SIZE / 16)) == 0) {
|
||||||
display_printf("r");
|
display_printf("r");
|
||||||
}
|
}
|
||||||
|
|
||||||
test->fill(w_buffer, SDRAM_BUFFER_SIZE, test->pattern, offset);
|
test->fill(w_buffer, TEST_BUFFER_SIZE, test->pattern, offset);
|
||||||
|
|
||||||
pi_dma_read((io32_t *) (SDRAM_ADDRESS + offset), r_buffer, SDRAM_BUFFER_SIZE);
|
pi_dma_read((io32_t *) (SDRAM_ADDRESS + offset), r_buffer, TEST_BUFFER_SIZE);
|
||||||
|
|
||||||
uint64_t *test_data = (uint64_t *) (w_buffer);
|
uint64_t *test_data = (uint64_t *) (w_buffer);
|
||||||
uint64_t *check_data = (uint64_t *) (r_buffer);
|
uint64_t *check_data = (uint64_t *) (r_buffer);
|
||||||
|
|
||||||
for (int i = 0; i < SDRAM_BUFFER_SIZE / sizeof(uint64_t); i++) {
|
for (int i = 0; i < TEST_BUFFER_SIZE / sizeof(uint64_t); i++) {
|
||||||
if (test_data[i] != check_data[i]) {
|
if (test_data[i] != check_data[i]) {
|
||||||
display_printf(
|
display_printf(
|
||||||
"\n"
|
"\n"
|
||||||
@ -399,7 +523,8 @@ static struct {
|
|||||||
} tests[] = {
|
} tests[] = {
|
||||||
{ "SC64 CFG", test_sc64_cfg },
|
{ "SC64 CFG", test_sc64_cfg },
|
||||||
{ "PI", test_pi },
|
{ "PI", test_pi },
|
||||||
{ "SD card", test_sd_card },
|
{ "SD card (I/O)", test_sd_card_io },
|
||||||
|
{ "SD card (FatFs)", test_sd_card_fatfs },
|
||||||
{ "SDRAM (1/6)", test_sdram },
|
{ "SDRAM (1/6)", test_sdram },
|
||||||
{ "SDRAM (2/6)", test_sdram },
|
{ "SDRAM (2/6)", test_sdram },
|
||||||
{ "SDRAM (3/6)", test_sdram },
|
{ "SDRAM (3/6)", test_sdram },
|
||||||
@ -415,12 +540,10 @@ void test_execute (void) {
|
|||||||
|
|
||||||
if ((error = sc64_set_config(CFG_ID_ROM_WRITE_ENABLE, true))) {
|
if ((error = sc64_set_config(CFG_ID_ROM_WRITE_ENABLE, true))) {
|
||||||
error_display("Command CONFIG_SET [ROM_WRITE_ENABLE] failed: %d", error);
|
error_display("Command CONFIG_SET [ROM_WRITE_ENABLE] failed: %d", error);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((error = sc64_set_config(CFG_ID_ROM_SHADOW_ENABLE, false))) {
|
if ((error = sc64_set_config(CFG_ID_ROM_SHADOW_ENABLE, false))) {
|
||||||
error_display("Command CONFIG_SET [ROM_SHADOW_ENABLE] failed: %d", error);
|
error_display("Command CONFIG_SET [ROM_SHADOW_ENABLE] failed: %d", error);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
random_seed = __entropy + c0_count();
|
random_seed = __entropy + c0_count();
|
||||||
|
@ -884,69 +884,68 @@ fn handle_firmware_command(
|
|||||||
fn handle_test_command(connection: Connection) -> Result<(), sc64::Error> {
|
fn handle_test_command(connection: Connection) -> Result<(), sc64::Error> {
|
||||||
let mut sc64 = init_sc64(connection, false)?;
|
let mut sc64 = init_sc64(connection, false)?;
|
||||||
|
|
||||||
println!("{}: SDRAM", "[SC64 Tests]".bold());
|
println!("{}: SDRAM (pattern)", "[SC64 Tests]".bold());
|
||||||
|
|
||||||
let sdram_tests = [
|
let sdram_pattern_tests = [
|
||||||
(sc64::MemoryTestType::OwnAddress, None),
|
(sc64::MemoryTestPattern::OwnAddress, None),
|
||||||
(sc64::MemoryTestType::AllZeros, None),
|
(sc64::MemoryTestPattern::AllZeros, None),
|
||||||
(sc64::MemoryTestType::AllOnes, None),
|
(sc64::MemoryTestPattern::AllOnes, None),
|
||||||
(sc64::MemoryTestType::Random, None),
|
(sc64::MemoryTestPattern::Custom(0xAAAA5555), None),
|
||||||
(sc64::MemoryTestType::Random, None),
|
(sc64::MemoryTestPattern::Custom(0x5555AAAA), None),
|
||||||
(sc64::MemoryTestType::Random, None),
|
(sc64::MemoryTestPattern::Random, None),
|
||||||
(sc64::MemoryTestType::AllZeros, Some(60)),
|
(sc64::MemoryTestPattern::Random, None),
|
||||||
(sc64::MemoryTestType::AllOnes, Some(60)),
|
(sc64::MemoryTestPattern::Custom(0x00010001), None),
|
||||||
(sc64::MemoryTestType::Pattern(0x00010001), None),
|
(sc64::MemoryTestPattern::Custom(0xFFFEFFFE), None),
|
||||||
(sc64::MemoryTestType::Pattern(0xFFFEFFFE), None),
|
(sc64::MemoryTestPattern::Custom(0x00020002), None),
|
||||||
(sc64::MemoryTestType::Pattern(0x00020002), None),
|
(sc64::MemoryTestPattern::Custom(0xFFFDFFFD), None),
|
||||||
(sc64::MemoryTestType::Pattern(0xFFFDFFFD), None),
|
(sc64::MemoryTestPattern::Custom(0x00040004), None),
|
||||||
(sc64::MemoryTestType::Pattern(0x00040004), None),
|
(sc64::MemoryTestPattern::Custom(0xFFFBFFFB), None),
|
||||||
(sc64::MemoryTestType::Pattern(0xFFFBFFFB), None),
|
(sc64::MemoryTestPattern::Custom(0x00080008), None),
|
||||||
(sc64::MemoryTestType::Pattern(0x00080008), None),
|
(sc64::MemoryTestPattern::Custom(0xFFF7FFF7), None),
|
||||||
(sc64::MemoryTestType::Pattern(0xFFF7FFF7), None),
|
(sc64::MemoryTestPattern::Custom(0x00100010), None),
|
||||||
(sc64::MemoryTestType::Pattern(0x00100010), None),
|
(sc64::MemoryTestPattern::Custom(0xFFEFFFEF), None),
|
||||||
(sc64::MemoryTestType::Pattern(0xFFEFFFEF), None),
|
(sc64::MemoryTestPattern::Custom(0x00200020), None),
|
||||||
(sc64::MemoryTestType::Pattern(0x00200020), None),
|
(sc64::MemoryTestPattern::Custom(0xFFDFFFDF), None),
|
||||||
(sc64::MemoryTestType::Pattern(0xFFDFFFDF), None),
|
(sc64::MemoryTestPattern::Custom(0x00400040), None),
|
||||||
(sc64::MemoryTestType::Pattern(0x00400040), None),
|
(sc64::MemoryTestPattern::Custom(0xFFBFFFBF), None),
|
||||||
(sc64::MemoryTestType::Pattern(0xFFBFFFBF), None),
|
(sc64::MemoryTestPattern::Custom(0x00800080), None),
|
||||||
(sc64::MemoryTestType::Pattern(0x00800080), None),
|
(sc64::MemoryTestPattern::Custom(0xFF7FFF7F), None),
|
||||||
(sc64::MemoryTestType::Pattern(0xFF7FFF7F), None),
|
(sc64::MemoryTestPattern::Custom(0x01000100), None),
|
||||||
(sc64::MemoryTestType::Pattern(0x01000100), None),
|
(sc64::MemoryTestPattern::Custom(0xFEFFFEFF), None),
|
||||||
(sc64::MemoryTestType::Pattern(0xFEFFFEFF), None),
|
(sc64::MemoryTestPattern::Custom(0x02000200), None),
|
||||||
(sc64::MemoryTestType::Pattern(0x02000200), None),
|
(sc64::MemoryTestPattern::Custom(0xFDFFFDFF), None),
|
||||||
(sc64::MemoryTestType::Pattern(0xFDFFFDFF), None),
|
(sc64::MemoryTestPattern::Custom(0x04000400), None),
|
||||||
(sc64::MemoryTestType::Pattern(0x04000400), None),
|
(sc64::MemoryTestPattern::Custom(0xFBFFFBFF), None),
|
||||||
(sc64::MemoryTestType::Pattern(0xFBFFFBFF), None),
|
(sc64::MemoryTestPattern::Custom(0x08000800), None),
|
||||||
(sc64::MemoryTestType::Pattern(0x08000800), None),
|
(sc64::MemoryTestPattern::Custom(0xF7FFF7FF), None),
|
||||||
(sc64::MemoryTestType::Pattern(0xF7FFF7FF), None),
|
(sc64::MemoryTestPattern::Custom(0x10001000), None),
|
||||||
(sc64::MemoryTestType::Pattern(0x10001000), None),
|
(sc64::MemoryTestPattern::Custom(0xEFFFEFFF), None),
|
||||||
(sc64::MemoryTestType::Pattern(0xEFFFEFFF), None),
|
(sc64::MemoryTestPattern::Custom(0x20002000), None),
|
||||||
(sc64::MemoryTestType::Pattern(0x20002000), None),
|
(sc64::MemoryTestPattern::Custom(0xDFFFDFFF), None),
|
||||||
(sc64::MemoryTestType::Pattern(0xDFFFDFFF), None),
|
(sc64::MemoryTestPattern::Custom(0x40004000), None),
|
||||||
(sc64::MemoryTestType::Pattern(0x40004000), None),
|
(sc64::MemoryTestPattern::Custom(0xBFFFBFFF), None),
|
||||||
(sc64::MemoryTestType::Pattern(0xBFFFBFFF), None),
|
(sc64::MemoryTestPattern::Custom(0x80008000), None),
|
||||||
(sc64::MemoryTestType::Pattern(0x80008000), None),
|
(sc64::MemoryTestPattern::Custom(0x7FFF7FFF), None),
|
||||||
(sc64::MemoryTestType::Pattern(0x7FFF7FFF), None),
|
(sc64::MemoryTestPattern::AllZeros, Some(60)),
|
||||||
(sc64::MemoryTestType::AllZeros, Some(300)),
|
(sc64::MemoryTestPattern::AllOnes, Some(60)),
|
||||||
(sc64::MemoryTestType::AllOnes, Some(300)),
|
|
||||||
];
|
];
|
||||||
let sdram_tests_count = sdram_tests.len();
|
let sdram_pattern_tests_count = sdram_pattern_tests.len();
|
||||||
|
|
||||||
let mut sdram_tests_failed = false;
|
let mut sdram_tests_failed = false;
|
||||||
|
|
||||||
for (i, (test_type, fade)) in sdram_tests.into_iter().enumerate() {
|
for (i, (pattern, fade)) in sdram_pattern_tests.into_iter().enumerate() {
|
||||||
let fadeout_text = if let Some(fade) = fade {
|
let fadeout_text = if let Some(fade) = fade {
|
||||||
format!(", fadeout {fade} seconds")
|
format!(", fadeout {fade} seconds")
|
||||||
} else {
|
} else {
|
||||||
"".to_string()
|
"".to_string()
|
||||||
};
|
};
|
||||||
print!(
|
print!(
|
||||||
" ({} / {sdram_tests_count}) Testing {test_type}{fadeout_text}... ",
|
" ({} / {sdram_pattern_tests_count}) Testing {pattern}{fadeout_text}... ",
|
||||||
i + 1
|
i + 1
|
||||||
);
|
);
|
||||||
stdout().flush().unwrap();
|
stdout().flush().unwrap();
|
||||||
|
|
||||||
let result = sc64.test_sdram(test_type, fade)?;
|
let result = sc64.test_sdram_pattern(pattern, fade)?;
|
||||||
|
|
||||||
if let Some((address, (written, read))) = result.first_error {
|
if let Some((address, (written, read))) = result.first_error {
|
||||||
sdram_tests_failed = true;
|
sdram_tests_failed = true;
|
||||||
|
@ -12,8 +12,8 @@ pub use self::{
|
|||||||
server::ServerEvent,
|
server::ServerEvent,
|
||||||
types::{
|
types::{
|
||||||
BootMode, ButtonMode, ButtonState, CicSeed, DataPacket, DdDiskState, DdDriveType, DdMode,
|
BootMode, ButtonMode, ButtonState, CicSeed, DataPacket, DdDiskState, DdDriveType, DdMode,
|
||||||
DebugPacket, DiagnosticData, DiskPacket, DiskPacketKind, FpgaDebugData, MemoryTestResult,
|
DebugPacket, DiagnosticData, DiskPacket, DiskPacketKind, FpgaDebugData, MemoryTestPattern,
|
||||||
MemoryTestType, SaveType, SaveWriteback, Switch, TvType,
|
MemoryTestPatternResult, SaveType, SaveWriteback, Switch, TvType,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -750,24 +750,24 @@ impl SC64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn test_sdram(
|
pub fn test_sdram_pattern(
|
||||||
&mut self,
|
&mut self,
|
||||||
test_type: MemoryTestType,
|
pattern: MemoryTestPattern,
|
||||||
fade: Option<u64>,
|
fade: Option<u64>,
|
||||||
) -> Result<MemoryTestResult, Error> {
|
) -> Result<MemoryTestPatternResult, Error> {
|
||||||
let item_size = std::mem::size_of::<u32>();
|
let item_size = std::mem::size_of::<u32>();
|
||||||
let mut test_data = vec![0u32; SDRAM_LENGTH / item_size];
|
let mut test_data = vec![0u32; SDRAM_LENGTH / item_size];
|
||||||
|
|
||||||
match test_type {
|
match pattern {
|
||||||
MemoryTestType::OwnAddress => {
|
MemoryTestPattern::OwnAddress => {
|
||||||
for (index, item) in test_data.iter_mut().enumerate() {
|
for (index, item) in test_data.iter_mut().enumerate() {
|
||||||
*item = (index * item_size) as u32;
|
*item = (index * item_size) as u32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MemoryTestType::AllZeros => test_data.fill(0x00000000u32),
|
MemoryTestPattern::AllZeros => test_data.fill(0x00000000u32),
|
||||||
MemoryTestType::AllOnes => test_data.fill(0xFFFFFFFFu32),
|
MemoryTestPattern::AllOnes => test_data.fill(0xFFFFFFFFu32),
|
||||||
MemoryTestType::Pattern(pattern) => test_data.fill(pattern),
|
MemoryTestPattern::Custom(pattern) => test_data.fill(pattern),
|
||||||
MemoryTestType::Random => rand::thread_rng().fill(&mut test_data[..]),
|
MemoryTestPattern::Random => rand::thread_rng().fill(&mut test_data[..]),
|
||||||
};
|
};
|
||||||
|
|
||||||
let raw_test_data: Vec<u8> = test_data.iter().flat_map(|v| v.to_be_bytes()).collect();
|
let raw_test_data: Vec<u8> = test_data.iter().flat_map(|v| v.to_be_bytes()).collect();
|
||||||
@ -799,7 +799,7 @@ impl SC64 {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok(MemoryTestResult {
|
return Ok(MemoryTestPatternResult {
|
||||||
first_error,
|
first_error,
|
||||||
all_errors,
|
all_errors,
|
||||||
});
|
});
|
||||||
|
@ -983,27 +983,27 @@ impl Display for DiagnosticData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum MemoryTestType {
|
pub enum MemoryTestPattern {
|
||||||
OwnAddress,
|
OwnAddress,
|
||||||
AllZeros,
|
AllZeros,
|
||||||
AllOnes,
|
AllOnes,
|
||||||
Pattern(u32),
|
|
||||||
Random,
|
Random,
|
||||||
|
Custom(u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MemoryTestResult {
|
pub struct MemoryTestPatternResult {
|
||||||
pub first_error: Option<(usize, (u32, u32))>,
|
pub first_error: Option<(usize, (u32, u32))>,
|
||||||
pub all_errors: Vec<(usize, (u32, u32))>,
|
pub all_errors: Vec<(usize, (u32, u32))>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for MemoryTestType {
|
impl Display for MemoryTestPattern {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
MemoryTestType::OwnAddress => f.write_str("Own address"),
|
MemoryTestPattern::OwnAddress => f.write_str("Own address"),
|
||||||
MemoryTestType::AllZeros => f.write_str("All zeros"),
|
MemoryTestPattern::AllZeros => f.write_str("All zeros"),
|
||||||
MemoryTestType::AllOnes => f.write_str("All ones"),
|
MemoryTestPattern::AllOnes => f.write_str("All ones"),
|
||||||
MemoryTestType::Random => f.write_str("Random"),
|
MemoryTestPattern::Random => f.write_str("Random"),
|
||||||
MemoryTestType::Pattern(pattern) => {
|
MemoryTestPattern::Custom(pattern) => {
|
||||||
f.write_fmt(format_args!("Pattern 0x{pattern:08X}"))
|
f.write_fmt(format_args!("Pattern 0x{pattern:08X}"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user