3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * See file CREDITS for list of people who contributed to this
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 #if !defined(CFG_NO_FLASH)
31 extern flash_info_t flash_info[]; /* info for FLASH chips */
33 /*-----------------------------------------------------------------------
36 flash_info_t * addr2info(ulong addr){
40 for(i = 0, info = &flash_info[0]; i < CFG_MAX_FLASH_BANKS; ++i, ++info){
41 /* WARNING - The '- 1' is needed if the flash
42 * is at the end of the address space, since
43 * info->start[0] + info->size wraps back to 0.
44 * Please don't change this unless you understand this.
46 if(info->flash_id != FLASH_UNKNOWN && addr >= info->start[0] && addr <= info->start[0] + info->size - 1){
53 /*-----------------------------------------------------------------------
54 * Copy memory to flash.
55 * Make sure all target addresses are within Flash bounds,
56 * and no protected sectors are hit.
59 * ERR_TIMOUT 1 - write timeout
60 * ERR_NOT_ERASED 2 - Flash not erased
61 * ERR_PROTECTED 4 - target range includes protected sectors
62 * ERR_INVAL 8 - target address not in Flash memory
63 * ERR_ALIGN 16 - target address not aligned on boundary
64 * (only some targets require alignment)
66 int flash_write(char *src, ulong addr, ulong cnt){
68 ulong end = addr + cnt - 1;
69 flash_info_t *info_first = addr2info(addr);
70 flash_info_t *info_last = addr2info(end);
77 if(!info_first || !info_last){
81 for(info = info_first; info <= info_last; ++info){
82 ulong b_end = info->start[0] + info->size; /* bank end addr */
83 short s_end = info->sector_count - 1;
84 for(i = 0; i < info->sector_count; ++i){
85 ulong e_addr = (i == s_end) ? b_end : info->start[i + 1];
87 if((end >= info->start[i]) && (addr < e_addr) && (info->protect[i] != 0)){
88 return(ERR_PROTECTED);
93 /* finally write data to flash */
94 for(info = info_first; info <= info_last && cnt > 0; ++info){
97 len = info->start[0] + info->size - addr;
101 if((i = write_buff(info, (uchar *)src, addr, len)) != 0){
111 /*-----------------------------------------------------------------------
114 void flash_perror(int err){
119 puts("## Error: timeout writing to flash\n");
122 puts("## Error: flash not erased\n");
125 puts("## Error: can't write to protected sectors\n");
128 puts("## Error: outside available flash\n");
131 puts("## Error: start and/or end address not on sector boundary\n");
133 case ERR_UNKNOWN_FLASH_VENDOR:
134 puts("## Error: unknown vendor of flash\n");
136 case ERR_UNKNOWN_FLASH_TYPE:
137 puts("## Error: unknown type of flash\n");
140 puts("## Error: general flash programming error\n");
143 printf("## Error: %s[%d] FIXME: rc=%d\n", __FILE__, __LINE__, err);
148 /*-----------------------------------------------------------------------
150 #endif /* !CFG_NO_FLASH */