/* * Parallel NOR Flash tests * * Copyright (c) 2005-2011 Analog Devices Inc. * * Licensed under the GPL-2 or later. */ #include <common.h> #include <malloc.h> #include <post.h> #include <flash.h> #if CONFIG_POST & CONFIG_SYS_POST_FLASH /* * This code will walk over the declared sectors erasing them, * then programming them, then verifying the written contents. * Possible future work: * - verify sectors before/after are not erased/written * - verify partial writes (e.g. programming only middle of sector) * - verify the contents of the erased sector * - better seed pattern than 0x00..0xff */ #ifndef CONFIG_SYS_POST_FLASH_NUM # define CONFIG_SYS_POST_FLASH_NUM 0 #endif #if CONFIG_SYS_POST_FLASH_START >= CONFIG_SYS_POST_FLASH_END # error "invalid flash block start/end" #endif extern flash_info_t flash_info[]; static void *seed_src_data(void *ptr, ulong *old_len, ulong new_len) { unsigned char *p; ulong i; p = ptr = realloc(ptr, new_len); if (!ptr) return ptr; for (i = *old_len; i < new_len; ++i) p[i] = i; *old_len = new_len; return ptr; } int flash_post_test(int flags) { ulong len; void *src; int ret, n, n_start, n_end; flash_info_t *info; /* the output from the common flash layers needs help */ puts("\n"); len = 0; src = NULL; info = &flash_info[CONFIG_SYS_POST_FLASH_NUM]; n_start = CONFIG_SYS_POST_FLASH_START; n_end = CONFIG_SYS_POST_FLASH_END; for (n = n_start; n < n_end; ++n) { ulong s_start, s_len, s_off; s_start = info->start[n]; s_len = flash_sector_size(info, n); s_off = s_start - info->start[0]; src = seed_src_data(src, &len, s_len); if (!src) { printf("malloc(%#lx) failed\n", s_len); return 1; } printf("\tsector %i: %#lx +%#lx", n, s_start, s_len); ret = flash_erase(info, n, n + 1); if (ret) { flash_perror(ret); break; } ret = write_buff(info, src, s_start, s_len); if (ret) { flash_perror(ret); break; } ret = memcmp(src, (void *)s_start, s_len); if (ret) { printf(" verify failed with %i\n", ret); break; } } free(src); return ret; } #endif