flash/nor/mdr: add docs, remove memory leak on probe()
[openocd.git] / src / flash / nor / mdr.c
blob98e013aa355585b77d10dcac63f78eaf11fdaff1
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
8 * Copyright (C) 2011 by Andreas Fritiofson *
9 * andreas.fritiofson@gmail.com *
10 * *
11 * Copyright (C) 2013 by Paul Fertser *
12 * fercerpav@gmail.com *
13 * *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
18 * *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
28 ***************************************************************************/
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
34 #include "imp.h"
35 #include <helper/binarybuffer.h>
36 #include <target/algorithm.h>
37 #include <target/armv7m.h>
39 #define MD_RST_CLK 0x40020000
40 #define MD_PER_CLOCK (MD_RST_CLK + 0x1C)
41 #define MD_PER_CLOCK_EEPROM (1 << 3)
42 #define MD_PER_CLOCK_RST_CLK (1 << 4)
44 #define FLASH_REG_BASE 0x40018000
45 #define FLASH_CMD (FLASH_REG_BASE + 0x00)
46 #define FLASH_ADR (FLASH_REG_BASE + 0x04)
47 #define FLASH_DI (FLASH_REG_BASE + 0x08)
48 #define FLASH_DO (FLASH_REG_BASE + 0x0C)
49 #define FLASH_KEY (FLASH_REG_BASE + 0x10)
51 #define FLASH_NVSTR (1 << 13)
52 #define FLASH_PROG (1 << 12)
53 #define FLASH_MAS1 (1 << 11)
54 #define FLASH_ERASE (1 << 10)
55 #define FLASH_IFREN (1 << 9)
56 #define FLASH_SE (1 << 8)
57 #define FLASH_YE (1 << 7)
58 #define FLASH_XE (1 << 6)
59 #define FLASH_RD (1 << 2)
60 #define FLASH_WR (1 << 1)
61 #define FLASH_CON (1 << 0)
62 #define FLASH_DELAY_MASK (7 << 3)
64 #define KEY 0x8AAA5551
66 struct mdr_flash_bank {
67 int probed;
68 unsigned int mem_type;
69 unsigned int page_count;
70 unsigned int sec_count;
73 /* flash bank <name> mdr <base> <size> 0 0 <target#> <type> <page_count> <sec_count> */
74 FLASH_BANK_COMMAND_HANDLER(mdr_flash_bank_command)
76 struct mdr_flash_bank *mdr_info;
78 if (CMD_ARGC < 9)
79 return ERROR_COMMAND_SYNTAX_ERROR;
81 mdr_info = malloc(sizeof(struct mdr_flash_bank));
83 bank->driver_priv = mdr_info;
84 mdr_info->probed = 0;
85 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[6], mdr_info->mem_type);
86 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[7], mdr_info->page_count);
87 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[8], mdr_info->sec_count);
88 return ERROR_OK;
91 static int mdr_protect_check(struct flash_bank *bank)
93 return ERROR_OK;
96 static int mdr_mass_erase(struct flash_bank *bank)
98 struct target *target = bank->target;
99 struct mdr_flash_bank *mdr_info = bank->driver_priv;
100 uint32_t flash_cmd;
101 int retval;
102 unsigned int i;
104 retval = target_read_u32(target, FLASH_CMD, &flash_cmd);
105 if (retval != ERROR_OK)
106 return retval;
108 for (i = 0; i < mdr_info->sec_count; i++) {
109 retval = target_write_u32(target, FLASH_ADR, i << 2);
110 if (retval != ERROR_OK)
111 return retval;
113 flash_cmd |= FLASH_XE | FLASH_MAS1 | FLASH_ERASE;
114 retval = target_write_u32(target, FLASH_CMD, flash_cmd);
115 if (retval != ERROR_OK)
116 return retval;
117 flash_cmd |= FLASH_NVSTR;
118 retval = target_write_u32(target, FLASH_CMD, flash_cmd);
119 if (retval != ERROR_OK)
120 return retval;
121 flash_cmd &= ~FLASH_ERASE;
122 retval = target_write_u32(target, FLASH_CMD, flash_cmd);
123 if (retval != ERROR_OK)
124 return retval;
125 flash_cmd &= ~(FLASH_XE | FLASH_MAS1 | FLASH_NVSTR);
126 retval = target_write_u32(target, FLASH_CMD, flash_cmd);
127 if (retval != ERROR_OK)
128 return retval;
131 return retval;
134 static int mdr_erase(struct flash_bank *bank, int first, int last)
136 struct target *target = bank->target;
137 struct mdr_flash_bank *mdr_info = bank->driver_priv;
138 int i, retval, retval2;
139 unsigned int j;
140 uint32_t flash_cmd, cur_per_clock;
142 if (bank->target->state != TARGET_HALTED) {
143 LOG_ERROR("Target not halted");
144 return ERROR_TARGET_NOT_HALTED;
147 retval = target_read_u32(target, MD_PER_CLOCK, &cur_per_clock);
148 if (retval != ERROR_OK)
149 return retval;
151 if (!(cur_per_clock & 0x10)) {
152 LOG_ERROR("Target needs reset before flash operations");
153 return ERROR_FLASH_OPERATION_FAILED;
156 retval = target_write_u32(target, MD_PER_CLOCK, cur_per_clock | MD_PER_CLOCK_EEPROM);
157 if (retval != ERROR_OK)
158 return retval;
160 retval = target_write_u32(target, FLASH_KEY, KEY);
161 if (retval != ERROR_OK)
162 return retval;
164 retval = target_read_u32(target, FLASH_CMD, &flash_cmd);
165 if (retval != ERROR_OK)
166 goto reset_pg_and_lock;
168 /* Switch on register access */
169 flash_cmd = (flash_cmd & FLASH_DELAY_MASK) | FLASH_CON;
170 if (mdr_info->mem_type)
171 flash_cmd |= FLASH_IFREN;
172 retval = target_write_u32(target, FLASH_CMD, flash_cmd);
173 if (retval != ERROR_OK)
174 goto reset_pg_and_lock;
176 if ((first == 0) && (last == (bank->num_sectors - 1))) {
177 retval = mdr_mass_erase(bank);
178 goto reset_pg_and_lock;
181 unsigned int page_size = bank->size / mdr_info->page_count;
182 for (i = first; i <= last; i++) {
183 for (j = 0; j < mdr_info->sec_count; j++) {
184 retval = target_write_u32(target, FLASH_ADR, (i * page_size) | (j << 2));
185 if (retval != ERROR_OK)
186 goto reset_pg_and_lock;
188 flash_cmd |= FLASH_XE | FLASH_ERASE;
189 retval = target_write_u32(target, FLASH_CMD, flash_cmd);
190 if (retval != ERROR_OK)
191 goto reset_pg_and_lock;
192 flash_cmd |= FLASH_NVSTR;
193 retval = target_write_u32(target, FLASH_CMD, flash_cmd);
194 if (retval != ERROR_OK)
195 goto reset_pg_and_lock;
196 flash_cmd &= ~FLASH_ERASE;
197 retval = target_write_u32(target, FLASH_CMD, flash_cmd);
198 if (retval != ERROR_OK)
199 goto reset_pg_and_lock;
200 flash_cmd &= ~(FLASH_XE | FLASH_NVSTR);
201 retval = target_write_u32(target, FLASH_CMD, flash_cmd);
202 if (retval != ERROR_OK)
203 goto reset_pg_and_lock;
205 bank->sectors[i].is_erased = 1;
208 reset_pg_and_lock:
209 flash_cmd &= FLASH_DELAY_MASK;
210 retval2 = target_write_u32(target, FLASH_CMD, flash_cmd);
211 if (retval == ERROR_OK)
212 retval = retval2;
214 retval2 = target_write_u32(target, FLASH_KEY, 0);
215 if (retval == ERROR_OK)
216 retval = retval2;
218 return retval;
221 static int mdr_protect(struct flash_bank *bank, int set, int first, int last)
223 return ERROR_OK;
226 static int mdr_write_block(struct flash_bank *bank, const uint8_t *buffer,
227 uint32_t offset, uint32_t count)
229 struct target *target = bank->target;
230 uint32_t buffer_size = 16384;
231 struct working_area *write_algorithm;
232 struct working_area *source;
233 uint32_t address = bank->base + offset;
234 struct reg_param reg_params[5];
235 struct armv7m_algorithm armv7m_info;
236 int retval = ERROR_OK;
238 /* see contrib/loaders/flash/mdr32fx.S for src */
239 static const uint8_t mdr32fx_flash_write_code[] = {
240 0x07, 0x68, 0x16, 0x68, 0x00, 0x2e, 0x2e, 0xd0, 0x55, 0x68, 0xb5, 0x42,
241 0xf9, 0xd0, 0x2e, 0x68, 0x44, 0x60, 0x86, 0x60, 0x17, 0x4e, 0x37, 0x43,
242 0x07, 0x60, 0x05, 0x26, 0x00, 0xf0, 0x25, 0xf8, 0x15, 0x4e, 0x37, 0x43,
243 0x07, 0x60, 0x0d, 0x26, 0x00, 0xf0, 0x1f, 0xf8, 0x80, 0x26, 0x37, 0x43,
244 0x07, 0x60, 0x3d, 0x26, 0x00, 0xf0, 0x19, 0xf8, 0x80, 0x26, 0xb7, 0x43,
245 0x07, 0x60, 0x0f, 0x4e, 0xb7, 0x43, 0x07, 0x60, 0x05, 0x26, 0x00, 0xf0,
246 0x10, 0xf8, 0x0d, 0x4e, 0xb7, 0x43, 0x07, 0x60, 0x04, 0x35, 0x04, 0x34,
247 0x9d, 0x42, 0x01, 0xd3, 0x15, 0x46, 0x08, 0x35, 0x55, 0x60, 0x01, 0x39,
248 0x00, 0x29, 0x00, 0xd0, 0xcd, 0xe7, 0x30, 0x46, 0x00, 0xbe, 0x01, 0x3e,
249 0x00, 0x2e, 0xfc, 0xd1, 0x70, 0x47, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00,
250 0x00, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x40, 0x20, 0x00, 0x00
253 /* flash write code */
254 if (target_alloc_working_area(target, sizeof(mdr32fx_flash_write_code),
255 &write_algorithm) != ERROR_OK) {
256 LOG_WARNING("no working area available, can't do block memory writes");
257 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
260 retval = target_write_buffer(target, write_algorithm->address,
261 sizeof(mdr32fx_flash_write_code), mdr32fx_flash_write_code);
262 if (retval != ERROR_OK)
263 return retval;
265 /* memory buffer */
266 while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
267 buffer_size /= 2;
268 buffer_size &= ~3UL; /* Make sure it's 4 byte aligned */
269 if (buffer_size <= 256) {
270 /* we already allocated the writing code, but failed to get a
271 * buffer, free the algorithm */
272 target_free_working_area(target, write_algorithm);
274 LOG_WARNING("no large enough working area available, can't do block memory writes");
275 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
279 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* flash base (in), status (out) */
280 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* count (32bit) */
281 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* buffer start */
282 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT); /* buffer end */
283 init_reg_param(&reg_params[4], "r4", 32, PARAM_IN_OUT); /* target address */
285 buf_set_u32(reg_params[0].value, 0, 32, FLASH_REG_BASE);
286 buf_set_u32(reg_params[1].value, 0, 32, count);
287 buf_set_u32(reg_params[2].value, 0, 32, source->address);
288 buf_set_u32(reg_params[3].value, 0, 32, source->address + source->size);
289 buf_set_u32(reg_params[4].value, 0, 32, address);
291 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
292 armv7m_info.core_mode = ARM_MODE_THREAD;
294 retval = target_run_flash_async_algorithm(target, buffer, count, 4,
295 0, NULL,
296 5, reg_params,
297 source->address, source->size,
298 write_algorithm->address, 0,
299 &armv7m_info);
301 if (retval == ERROR_FLASH_OPERATION_FAILED)
302 LOG_ERROR("flash write failed at address 0x%"PRIx32,
303 buf_get_u32(reg_params[4].value, 0, 32));
305 target_free_working_area(target, source);
306 target_free_working_area(target, write_algorithm);
308 destroy_reg_param(&reg_params[0]);
309 destroy_reg_param(&reg_params[1]);
310 destroy_reg_param(&reg_params[2]);
311 destroy_reg_param(&reg_params[3]);
312 destroy_reg_param(&reg_params[4]);
314 return retval;
317 static int mdr_write(struct flash_bank *bank, const uint8_t *buffer,
318 uint32_t offset, uint32_t count)
320 struct target *target = bank->target;
321 struct mdr_flash_bank *mdr_info = bank->driver_priv;
322 uint8_t *new_buffer = NULL;
324 if (bank->target->state != TARGET_HALTED) {
325 LOG_ERROR("Target not halted");
326 return ERROR_TARGET_NOT_HALTED;
329 if (offset & 0x3) {
330 LOG_ERROR("offset 0x%" PRIx32 " breaks required 4-byte alignment", offset);
331 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
334 /* If there's an odd number of bytes, the data has to be padded. Duplicate
335 * the buffer and use the normal code path with a single block write since
336 * it's probably cheaper than to special case the last odd write using
337 * discrete accesses. */
338 int rem = count % 4;
339 if (rem) {
340 new_buffer = malloc(count + rem);
341 if (new_buffer == NULL) {
342 LOG_ERROR("odd number of bytes to write and no memory for padding buffer");
343 return ERROR_FAIL;
345 LOG_INFO("odd number of bytes to write, padding with 0xff");
346 buffer = memcpy(new_buffer, buffer, count);
347 while (rem--)
348 new_buffer[count++] = 0xff;
351 uint32_t flash_cmd, cur_per_clock;
352 int retval, retval2;
354 retval = target_read_u32(target, MD_PER_CLOCK, &cur_per_clock);
355 if (retval != ERROR_OK)
356 goto free_buffer;
358 if (!(cur_per_clock & MD_PER_CLOCK_RST_CLK)) {
359 /* Something's very wrong if the RST_CLK module is not clocked */
360 LOG_ERROR("Target needs reset before flash operations");
361 retval = ERROR_FLASH_OPERATION_FAILED;
362 goto free_buffer;
365 retval = target_write_u32(target, MD_PER_CLOCK, cur_per_clock | MD_PER_CLOCK_EEPROM);
366 if (retval != ERROR_OK)
367 goto free_buffer;
369 retval = target_write_u32(target, FLASH_KEY, KEY);
370 if (retval != ERROR_OK)
371 goto free_buffer;
373 retval = target_read_u32(target, FLASH_CMD, &flash_cmd);
374 if (retval != ERROR_OK)
375 goto reset_pg_and_lock;
377 /* Switch on register access */
378 flash_cmd = (flash_cmd & FLASH_DELAY_MASK) | FLASH_CON;
379 if (mdr_info->mem_type)
380 flash_cmd |= FLASH_IFREN;
381 retval = target_write_u32(target, FLASH_CMD, flash_cmd);
382 if (retval != ERROR_OK)
383 goto reset_pg_and_lock;
385 /* try using block write */
386 retval = mdr_write_block(bank, buffer, offset, count/4);
388 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
389 /* if block write failed (no sufficient working area),
390 * we use normal (slow) single halfword accesses */
391 LOG_WARNING("Can't use block writes, falling back to single memory accesses");
393 unsigned int page_size = bank->size / mdr_info->page_count;
394 unsigned int page_mask = page_size - 1;
395 while (count > 0) {
396 unsigned int i, j;
397 unsigned int cur_page = offset & ~page_mask;
398 unsigned int bytes_to_write = cur_page + page_size - offset;
399 if (count < bytes_to_write)
400 bytes_to_write = count;
402 /*LOG_INFO("Selecting next page: %08x", cur_page);*/
404 for (i = 0; i < mdr_info->sec_count; i++) {
405 retval = target_write_u32(target, FLASH_ADR, offset + i*4);
406 if (retval != ERROR_OK)
407 goto reset_pg_and_lock;
408 /*LOG_INFO("Selecting page/sector: %08x", offset + i*4);*/
410 flash_cmd |= FLASH_XE | FLASH_PROG;
411 retval = target_write_u32(target, FLASH_CMD, flash_cmd);
412 if (retval != ERROR_OK)
413 goto reset_pg_and_lock;
415 flash_cmd |= FLASH_NVSTR;
416 retval = target_write_u32(target, FLASH_CMD, flash_cmd);
417 if (retval != ERROR_OK)
418 goto reset_pg_and_lock;
420 for (j = 0;
421 (((offset + j + i*4) & ~page_mask) == cur_page) &&
422 (j + i*4 < count);
423 j += mdr_info->sec_count*4) {
424 uint32_t value;
425 memcpy(&value, buffer + j + i*4, sizeof(uint32_t));
426 retval = target_write_u32(target, FLASH_DI, value);
427 if (retval != ERROR_OK)
428 goto reset_pg_and_lock;
429 /*LOG_INFO("Writing to addr %08x", offset + j + i*4);*/
430 retval = target_write_u32(target, FLASH_ADR, offset + j + i*4);
431 if (retval != ERROR_OK)
432 goto reset_pg_and_lock;
434 flash_cmd |= FLASH_YE;
435 retval = target_write_u32(target, FLASH_CMD, flash_cmd);
436 if (retval != ERROR_OK)
437 goto reset_pg_and_lock;
438 flash_cmd &= ~FLASH_YE;
439 retval = target_write_u32(target, FLASH_CMD, flash_cmd);
440 if (retval != ERROR_OK)
441 goto reset_pg_and_lock;
443 flash_cmd &= ~FLASH_NVSTR;
444 retval = target_write_u32(target, FLASH_CMD, flash_cmd);
445 if (retval != ERROR_OK)
446 goto reset_pg_and_lock;
448 flash_cmd &= ~(FLASH_XE | FLASH_PROG);
449 retval = target_write_u32(target, FLASH_CMD, flash_cmd);
450 if (retval != ERROR_OK)
451 goto reset_pg_and_lock;
454 buffer += bytes_to_write;
455 offset += bytes_to_write;
456 count -= bytes_to_write;
460 reset_pg_and_lock:
461 flash_cmd &= FLASH_DELAY_MASK;
462 retval2 = target_write_u32(target, FLASH_CMD, flash_cmd);
463 if (retval == ERROR_OK)
464 retval = retval2;
466 retval2 = target_write_u32(target, FLASH_KEY, 0);
467 if (retval == ERROR_OK)
468 retval = retval2;
470 free_buffer:
471 if (new_buffer)
472 free(new_buffer);
474 return retval;
477 static int mdr_probe(struct flash_bank *bank)
479 struct mdr_flash_bank *mdr_info = bank->driver_priv;
480 unsigned int page_count, page_size, i;
482 page_count = mdr_info->page_count;
483 page_size = bank->size / page_count;
485 if (bank->sectors) {
486 free(bank->sectors);
487 bank->sectors = NULL;
490 bank->num_sectors = page_count;
491 bank->sectors = malloc(sizeof(struct flash_sector) * page_count);
493 for (i = 0; i < page_count; i++) {
494 bank->sectors[i].offset = i * page_size;
495 bank->sectors[i].size = page_size;
496 bank->sectors[i].is_erased = -1;
497 bank->sectors[i].is_protected = 0;
500 mdr_info->probed = 1;
502 return ERROR_OK;
505 static int mdr_auto_probe(struct flash_bank *bank)
507 struct mdr_flash_bank *mdr_info = bank->driver_priv;
508 if (mdr_info->probed)
509 return ERROR_OK;
510 return mdr_probe(bank);
513 static int get_mdr_info(struct flash_bank *bank, char *buf, int buf_size)
515 struct mdr_flash_bank *mdr_info = bank->driver_priv;
516 snprintf(buf, buf_size, "MDR32Fx - %s",
517 mdr_info->mem_type ? "info memory" : "main memory");
519 return ERROR_OK;
522 struct flash_driver mdr_flash = {
523 .name = "mdr",
524 .usage = "flash bank <name> mdr <base> <size> 0 0 <target#> <type> <page_count> <sec_count>\n"
525 "<type>: 0 for main memory, 1 for info memory",
526 .flash_bank_command = mdr_flash_bank_command,
527 .erase = mdr_erase,
528 .protect = mdr_protect,
529 .write = mdr_write,
530 .read = default_flash_read,
531 .probe = mdr_probe,
532 .auto_probe = mdr_auto_probe,
533 .erase_check = default_flash_blank_check,
534 .protect_check = mdr_protect_check,
535 .info = get_mdr_info,