blob: 501f99b066a3e48b61a27ae5eb2af1687cdcc1b0 [file] [log] [blame]
/*
* (C) Copyright 2015 Google, Inc.
* All rights reserved.
*
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "flash.h"
#include "../common/util.h"
#define MAX_NAME_SIZE 64
int flash_test_patterns[] = {0x5A, 0xA5, 0x55, 0xAA, 0x00, 0x0F, 0xF0, 0xFF};
static int flash_test_usage() {
printf("flash_test\n");
printf("Example:\n");
printf("flash_test\n");
printf("This runs tests on the spare section of the NOR flash\n");
return -1;
}
int flash_test(int argc, char *argv[]) {
FILE *fp;
char flash_filename[MAX_NAME_SIZE], size_str[MAX_NAME_SIZE];
char flash[MAX_NAME_SIZE], erase_flash_cmd[MAX_NAME_SIZE];
char read_flash_cmd[MAX_NAME_SIZE], write_flash_cmd[MAX_NAME_SIZE];
char erase_size_str[MAX_NAME_SIZE];
int size, erase_size, i, j, ch, int_size = sizeof(int);
int pattern_size = sizeof(flash_test_patterns), num_blocks;
bool test_passed = true;
if ((argc != 1) || (argv[0] == NULL)) {
return flash_test_usage();
}
fp = popen(GET_SPARE_FLASH_CMD, "r");
if (fp == NULL) {
printf("No flash file\n");
return -1;
}
if (fscanf(fp, "%s", flash_filename) == EOF) {
printf("Cannot find flash file name\n");
pclose(fp);
return -1;
}
if (fscanf(fp, "%s", size_str) == EOF) {
printf("Cannot find flash file size\n");
pclose(fp);
return -1;
}
if (fscanf(fp, "%s", erase_size_str) == EOF) {
printf("Cannot find flash file erase size\n");
pclose(fp);
return -1;
}
pclose(fp);
size = strlen(flash_filename);
if ((size > 1) && (flash_filename[size - 1] == ':')) {
// Get rid of : from the name
flash_filename[size - 1] = '\0';
}
size = strtoul(size_str, NULL, 16);
erase_size = strtoul(erase_size_str, NULL, 16);
if (erase_size == 0) {
printf("Invalid file erase size %d\n", erase_size);
return -1;
}
num_blocks = size / erase_size;
flash[0] = '\0';
strcpy(flash, "/dev/");
strcat(flash, flash_filename);
sprintf(write_flash_cmd, "cat %s > %s", FLASH_TEST_FILE_NAME, flash);
sprintf(read_flash_cmd, "cat %s > %s", flash, FLASH_RESULT_FILE_NAME);
sprintf(erase_flash_cmd, "flash_erase %s 0 %d", flash, num_blocks);
printf("Test flash %s size %d blocks %d\n", flash, size, num_blocks);
for (i = 0; i < (pattern_size / int_size); ++i) {
fp = fopen(FLASH_TEST_FILE_NAME, "w+");
if (fp == NULL) {
printf("Failed to open flash test file: %s\n", FLASH_TEST_FILE_NAME);
return -1;
}
printf("Writing 0x%02x to flash test file ... \n", flash_test_patterns[i]);
for (j = 0; j < size; ++j) {
if (fputc(flash_test_patterns[i], fp) == EOF) {
printf("Write 0x%x to flash test location %d failed.\n",
flash_test_patterns[i], j);
test_passed = false;
break;
}
}
fclose(fp);
printf("erase flash ...\n");
system_cmd(erase_flash_cmd);
printf("Write test pattern to flash ...\n");
system_cmd(write_flash_cmd);
printf("Read back flash ...\n");
system_cmd(read_flash_cmd);
fp = fopen(FLASH_RESULT_FILE_NAME, "r");
if (fp == NULL) {
printf("Failed to open flash result file: %s\n", FLASH_RESULT_FILE_NAME);
return -1;
}
printf("Verifying flash ...\n");
for (j = 0; j < size; ++j) {
ch = fgetc(fp);
if (feof(fp)) {
printf("Read from flash result location %d failed.\n", j);
test_passed = false;
break;
}
if (ch != (flash_test_patterns[i])) {
printf("Flash test failed at location %d of pattern 0x%02x:0x%02x\n", j,
ch, flash_test_patterns[i]);
test_passed = false;
break;
}
}
fclose(fp);
if (test_passed) {
printf("Flash passed test pattern 0x%02x\n", flash_test_patterns[i]);
} else {
printf("Flash failed test pattern 0x%02x\n", flash_test_patterns[i]);
break;
}
}
if (test_passed) {
printf("Flash test passed\n");
} else {
printf("Flash test failed\n");
}
return 0;
}