dfeea5b0d24049db7080aa35501be54bdba8c353
[openocd.git] / src / flash / flash.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2007,2008 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
7 * *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "flash.h"
31 #include "common.h"
32 #include <target/image.h>
33 #include <helper/time_support.h>
34
35 struct flash_bank *flash_banks;
36
37 struct flash_bank *get_flash_bank_by_num_noprobe(int num)
38 {
39 struct flash_bank *p;
40 int i = 0;
41
42 for (p = flash_banks; p; p = p->next)
43 {
44 if (i++ == num)
45 {
46 return p;
47 }
48 }
49 LOG_ERROR("flash bank %d does not exist", num);
50 return NULL;
51 }
52
53 int flash_get_bank_count(void)
54 {
55 struct flash_bank *p;
56 int i = 0;
57 for (p = flash_banks; p; p = p->next)
58 {
59 i++;
60 }
61 return i;
62 }
63
64 struct flash_bank *get_flash_bank_by_name(const char *name)
65 {
66 unsigned requested = get_flash_name_index(name);
67 unsigned found = 0;
68
69 struct flash_bank *bank;
70 for (bank = flash_banks; NULL != bank; bank = bank->next)
71 {
72 if (strcmp(bank->name, name) == 0)
73 return bank;
74 if (!flash_driver_name_matches(bank->driver->name, name))
75 continue;
76 if (++found < requested)
77 continue;
78 return bank;
79 }
80 return NULL;
81 }
82
83 struct flash_bank *get_flash_bank_by_num(int num)
84 {
85 struct flash_bank *p = get_flash_bank_by_num_noprobe(num);
86 int retval;
87
88 if (p == NULL)
89 return NULL;
90
91 retval = p->driver->auto_probe(p);
92
93 if (retval != ERROR_OK)
94 {
95 LOG_ERROR("auto_probe failed %d\n", retval);
96 return NULL;
97 }
98 return p;
99 }
100
101 /* lookup flash bank by address */
102 struct flash_bank *get_flash_bank_by_addr(struct target *target, uint32_t addr)
103 {
104 struct flash_bank *c;
105
106 /* cycle through bank list */
107 for (c = flash_banks; c; c = c->next)
108 {
109 int retval;
110 retval = c->driver->auto_probe(c);
111
112 if (retval != ERROR_OK)
113 {
114 LOG_ERROR("auto_probe failed %d\n", retval);
115 return NULL;
116 }
117 /* check whether address belongs to this flash bank */
118 if ((addr >= c->base) && (addr <= c->base + (c->size - 1)) && target == c->target)
119 return c;
120 }
121 LOG_ERROR("No flash at address 0x%08" PRIx32 "\n", addr);
122 return NULL;
123 }
124
125 int default_flash_mem_blank_check(struct flash_bank *bank)
126 {
127 struct target *target = bank->target;
128 const int buffer_size = 1024;
129 int i;
130 uint32_t nBytes;
131 int retval = ERROR_OK;
132
133 if (bank->target->state != TARGET_HALTED)
134 {
135 LOG_ERROR("Target not halted");
136 return ERROR_TARGET_NOT_HALTED;
137 }
138
139 uint8_t *buffer = malloc(buffer_size);
140
141 for (i = 0; i < bank->num_sectors; i++)
142 {
143 uint32_t j;
144 bank->sectors[i].is_erased = 1;
145
146 for (j = 0; j < bank->sectors[i].size; j += buffer_size)
147 {
148 uint32_t chunk;
149 chunk = buffer_size;
150 if (chunk > (j - bank->sectors[i].size))
151 {
152 chunk = (j - bank->sectors[i].size);
153 }
154
155 retval = target_read_memory(target, bank->base + bank->sectors[i].offset + j, 4, chunk/4, buffer);
156 if (retval != ERROR_OK)
157 {
158 goto done;
159 }
160
161 for (nBytes = 0; nBytes < chunk; nBytes++)
162 {
163 if (buffer[nBytes] != 0xFF)
164 {
165 bank->sectors[i].is_erased = 0;
166 break;
167 }
168 }
169 }
170 }
171
172 done:
173 free(buffer);
174
175 return retval;
176 }
177
178 int default_flash_blank_check(struct flash_bank *bank)
179 {
180 struct target *target = bank->target;
181 int i;
182 int retval;
183 int fast_check = 0;
184 uint32_t blank;
185
186 if (bank->target->state != TARGET_HALTED)
187 {
188 LOG_ERROR("Target not halted");
189 return ERROR_TARGET_NOT_HALTED;
190 }
191
192 for (i = 0; i < bank->num_sectors; i++)
193 {
194 uint32_t address = bank->base + bank->sectors[i].offset;
195 uint32_t size = bank->sectors[i].size;
196
197 if ((retval = target_blank_check_memory(target, address, size, &blank)) != ERROR_OK)
198 {
199 fast_check = 0;
200 break;
201 }
202 if (blank == 0xFF)
203 bank->sectors[i].is_erased = 1;
204 else
205 bank->sectors[i].is_erased = 0;
206 fast_check = 1;
207 }
208
209 if (!fast_check)
210 {
211 LOG_USER("Running slow fallback erase check - add working memory");
212 return default_flash_mem_blank_check(bank);
213 }
214
215 return ERROR_OK;
216 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)