1*f6f7395eSMike Frysinger /* 2*f6f7395eSMike Frysinger * Parallel NOR Flash tests 3*f6f7395eSMike Frysinger * 4*f6f7395eSMike Frysinger * Copyright (c) 2005-2011 Analog Devices Inc. 5*f6f7395eSMike Frysinger * 6*f6f7395eSMike Frysinger * Licensed under the GPL-2 or later. 7*f6f7395eSMike Frysinger */ 8*f6f7395eSMike Frysinger 9*f6f7395eSMike Frysinger #include <common.h> 10*f6f7395eSMike Frysinger #include <malloc.h> 11*f6f7395eSMike Frysinger #include <post.h> 12*f6f7395eSMike Frysinger #include <flash.h> 13*f6f7395eSMike Frysinger 14*f6f7395eSMike Frysinger #if CONFIG_POST & CONFIG_SYS_POST_FLASH 15*f6f7395eSMike Frysinger 16*f6f7395eSMike Frysinger /* 17*f6f7395eSMike Frysinger * This code will walk over the declared sectors erasing them, 18*f6f7395eSMike Frysinger * then programming them, then verifying the written contents. 19*f6f7395eSMike Frysinger * Possible future work: 20*f6f7395eSMike Frysinger * - verify sectors before/after are not erased/written 21*f6f7395eSMike Frysinger * - verify partial writes (e.g. programming only middle of sector) 22*f6f7395eSMike Frysinger * - verify the contents of the erased sector 23*f6f7395eSMike Frysinger * - better seed pattern than 0x00..0xff 24*f6f7395eSMike Frysinger */ 25*f6f7395eSMike Frysinger 26*f6f7395eSMike Frysinger #ifndef CONFIG_SYS_POST_FLASH_NUM 27*f6f7395eSMike Frysinger # define CONFIG_SYS_POST_FLASH_NUM 0 28*f6f7395eSMike Frysinger #endif 29*f6f7395eSMike Frysinger #if CONFIG_SYS_POST_FLASH_START >= CONFIG_SYS_POST_FLASH_END 30*f6f7395eSMike Frysinger # error "invalid flash block start/end" 31*f6f7395eSMike Frysinger #endif 32*f6f7395eSMike Frysinger 33*f6f7395eSMike Frysinger extern flash_info_t flash_info[]; 34*f6f7395eSMike Frysinger 35*f6f7395eSMike Frysinger static void *seed_src_data(void *ptr, ulong *old_len, ulong new_len) 36*f6f7395eSMike Frysinger { 37*f6f7395eSMike Frysinger unsigned char *p; 38*f6f7395eSMike Frysinger ulong i; 39*f6f7395eSMike Frysinger 40*f6f7395eSMike Frysinger p = ptr = realloc(ptr, new_len); 41*f6f7395eSMike Frysinger if (!ptr) 42*f6f7395eSMike Frysinger return ptr; 43*f6f7395eSMike Frysinger 44*f6f7395eSMike Frysinger for (i = *old_len; i < new_len; ++i) 45*f6f7395eSMike Frysinger p[i] = i; 46*f6f7395eSMike Frysinger 47*f6f7395eSMike Frysinger *old_len = new_len; 48*f6f7395eSMike Frysinger 49*f6f7395eSMike Frysinger return ptr; 50*f6f7395eSMike Frysinger } 51*f6f7395eSMike Frysinger 52*f6f7395eSMike Frysinger int flash_post_test(int flags) 53*f6f7395eSMike Frysinger { 54*f6f7395eSMike Frysinger ulong len; 55*f6f7395eSMike Frysinger void *src; 56*f6f7395eSMike Frysinger int ret, n, n_start, n_end; 57*f6f7395eSMike Frysinger flash_info_t *info; 58*f6f7395eSMike Frysinger 59*f6f7395eSMike Frysinger /* the output from the common flash layers needs help */ 60*f6f7395eSMike Frysinger puts("\n"); 61*f6f7395eSMike Frysinger 62*f6f7395eSMike Frysinger len = 0; 63*f6f7395eSMike Frysinger src = NULL; 64*f6f7395eSMike Frysinger info = &flash_info[CONFIG_SYS_POST_FLASH_NUM]; 65*f6f7395eSMike Frysinger n_start = CONFIG_SYS_POST_FLASH_START; 66*f6f7395eSMike Frysinger n_end = CONFIG_SYS_POST_FLASH_END; 67*f6f7395eSMike Frysinger 68*f6f7395eSMike Frysinger for (n = n_start; n < n_end; ++n) { 69*f6f7395eSMike Frysinger ulong s_start, s_len, s_off; 70*f6f7395eSMike Frysinger 71*f6f7395eSMike Frysinger s_start = info->start[n]; 72*f6f7395eSMike Frysinger s_len = flash_sector_size(info, n); 73*f6f7395eSMike Frysinger s_off = s_start - info->start[0]; 74*f6f7395eSMike Frysinger 75*f6f7395eSMike Frysinger src = seed_src_data(src, &len, s_len); 76*f6f7395eSMike Frysinger if (!src) { 77*f6f7395eSMike Frysinger printf("malloc(%#lx) failed\n", s_len); 78*f6f7395eSMike Frysinger return 1; 79*f6f7395eSMike Frysinger } 80*f6f7395eSMike Frysinger 81*f6f7395eSMike Frysinger printf("\tsector %i: %#lx +%#lx", n, s_start, s_len); 82*f6f7395eSMike Frysinger 83*f6f7395eSMike Frysinger ret = flash_erase(info, n, n + 1); 84*f6f7395eSMike Frysinger if (ret) { 85*f6f7395eSMike Frysinger flash_perror(ret); 86*f6f7395eSMike Frysinger break; 87*f6f7395eSMike Frysinger } 88*f6f7395eSMike Frysinger 89*f6f7395eSMike Frysinger ret = write_buff(info, src, s_start, s_len); 90*f6f7395eSMike Frysinger if (ret) { 91*f6f7395eSMike Frysinger flash_perror(ret); 92*f6f7395eSMike Frysinger break; 93*f6f7395eSMike Frysinger } 94*f6f7395eSMike Frysinger 95*f6f7395eSMike Frysinger ret = memcmp(src, (void *)s_start, s_len); 96*f6f7395eSMike Frysinger if (ret) { 97*f6f7395eSMike Frysinger printf(" verify failed with %i\n", ret); 98*f6f7395eSMike Frysinger break; 99*f6f7395eSMike Frysinger } 100*f6f7395eSMike Frysinger } 101*f6f7395eSMike Frysinger 102*f6f7395eSMike Frysinger free(src); 103*f6f7395eSMike Frysinger 104*f6f7395eSMike Frysinger return ret; 105*f6f7395eSMike Frysinger } 106*f6f7395eSMike Frysinger 107*f6f7395eSMike Frysinger #endif 108