Updated fm3.c, added Flash type 2 support, error handling improved
[openocd.git] / src / flash / nor / fm3.c
1 /***************************************************************************
2 * Copyright (C) 2011 by Marc Willam, Holger Wech *
3 * openOCD.fseu(AT)de.fujitsu.com *
4 * *
5 * Copyright (C) 2011 Ronny Strutz *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "imp.h"
28 #include <helper/binarybuffer.h>
29 #include <target/algorithm.h>
30 #include <target/armv7m.h>
31
32 #define FLASH_DQ6 0x00000040 /* Data toggle flag bit (TOGG) */
33 #define FLASH_DQ5 0x00000020 /* Time limit exceeding flag bit (TLOV) */
34
35 enum fm3_variant
36 {
37 mb9bfxx1, /* Flash Type '1' */
38 mb9bfxx2,
39 mb9bfxx3,
40 mb9bfxx4,
41 mb9bfxx5,
42 mb9bfxx6,
43 mb9afxx1, /* Flash Type '2' */
44 mb9afxx2,
45 mb9afxx3,
46 mb9afxx4,
47 mb9afxx5,
48 mb9afxx6
49 };
50
51 enum fm3_flash_type
52 {
53 fm3_no_flash_type = 0,
54 fm3_flash_type1 = 1,
55 fm3_flash_type2 = 2
56 };
57
58 struct fm3_flash_bank
59 {
60 struct working_area *write_algorithm;
61 enum fm3_variant variant;
62 enum fm3_flash_type flashtype;
63 int probed;
64 };
65
66 FLASH_BANK_COMMAND_HANDLER(fm3_flash_bank_command)
67 {
68 struct fm3_flash_bank *fm3_info;
69
70 if (CMD_ARGC < 6)
71 {
72 LOG_WARNING("incomplete flash_bank fm3 configuration");
73 return ERROR_FLASH_BANK_INVALID;
74 }
75
76 fm3_info = malloc(sizeof(struct fm3_flash_bank));
77 bank->driver_priv = fm3_info;
78
79 /* Flash type '1' */
80 if (strcmp(CMD_ARGV[5], "mb9bfxx1.cpu") == 0)
81 {
82 fm3_info->variant = mb9bfxx1;
83 fm3_info->flashtype = fm3_flash_type1;
84 }
85 else if (strcmp(CMD_ARGV[5], "mb9bfxx2.cpu") == 0)
86 {
87 fm3_info->variant = mb9bfxx2;
88 fm3_info->flashtype = fm3_flash_type1;
89 }
90 else if (strcmp(CMD_ARGV[5], "mb9bfxx3.cpu") == 0)
91 {
92 fm3_info->variant = mb9bfxx3;
93 fm3_info->flashtype = fm3_flash_type1;
94 }
95 else if (strcmp(CMD_ARGV[5], "mb9bfxx4.cpu") == 0)
96 {
97 fm3_info->variant = mb9bfxx4;
98 fm3_info->flashtype = fm3_flash_type1;
99 }
100 else if (strcmp(CMD_ARGV[5], "mb9bfxx5.cpu") == 0)
101 {
102 fm3_info->variant = mb9bfxx5;
103 fm3_info->flashtype = fm3_flash_type1;
104 }
105 else if (strcmp(CMD_ARGV[5], "mb9bfxx6.cpu") == 0)
106 {
107 fm3_info->variant = mb9bfxx6;
108 fm3_info->flashtype = fm3_flash_type1;
109 }
110
111 /* Flash type '2' */
112 else if (strcmp(CMD_ARGV[5], "mb9afxx1.cpu") == 0)
113 {
114 fm3_info->variant = mb9afxx1;
115 fm3_info->flashtype = fm3_flash_type2;
116 }
117 else if (strcmp(CMD_ARGV[5], "mb9afxx2.cpu") == 0)
118 {
119 fm3_info->variant = mb9afxx2;
120 fm3_info->flashtype = fm3_flash_type2;
121 }
122 else if (strcmp(CMD_ARGV[5], "mb9afxx3.cpu") == 0)
123 {
124 fm3_info->variant = mb9afxx3;
125 fm3_info->flashtype = fm3_flash_type2;
126 }
127 else if (strcmp(CMD_ARGV[5], "mb9afxx4.cpu") == 0)
128 {
129 fm3_info->variant = mb9afxx4;
130 fm3_info->flashtype = fm3_flash_type2;
131 }
132 else if (strcmp(CMD_ARGV[5], "mb9afxx5.cpu") == 0)
133 {
134 fm3_info->variant = mb9afxx5;
135 fm3_info->flashtype = fm3_flash_type2;
136 }
137 else if (strcmp(CMD_ARGV[5], "mb9afxx6.cpu") == 0)
138 {
139 fm3_info->variant = mb9afxx6;
140 fm3_info->flashtype = fm3_flash_type2;
141 }
142
143 /* unknown Flash type */
144 else
145 {
146 LOG_ERROR("unknown fm3 variant: %s", CMD_ARGV[5]);
147 free(fm3_info);
148 return ERROR_FLASH_BANK_INVALID;
149 }
150
151 fm3_info->write_algorithm = NULL;
152 fm3_info->probed = 0;
153
154 return ERROR_OK;
155 }
156
157 /* Data polling algorithm */
158 static int fm3_busy_wait(struct target *target, uint32_t offset, int timeout_ms)
159 {
160 int retval = ERROR_OK;
161 uint16_t state1, state2;
162 int ms = 0;
163
164 /* While(1) loop exit via "break" and "return" on error */
165 while(1)
166 {
167 /* dummy-read - see flash manual */
168 retval = target_read_u16(target, offset, &state1);
169 if (retval != ERROR_OK)
170 return retval;
171
172 /* Data polling 1 */
173 retval = target_read_u16(target, offset, &state1);
174 if (retval != ERROR_OK)
175 return retval;
176
177 /* Data polling 2 */
178 retval = target_read_u16(target, offset, &state2);
179 if (retval != ERROR_OK)
180 return retval;
181
182 /* Flash command finished via polled data equal? */
183 if ( (state1 & FLASH_DQ6) == (state2 & FLASH_DQ6) )
184 {
185 break;
186 }
187 /* Timeout Flag? */
188 else if (state1 & FLASH_DQ5)
189 {
190 /* Retry data polling */
191
192 /* Data polling 1 */
193 retval = target_read_u16(target, offset, &state1);
194 if (retval != ERROR_OK)
195 return retval;
196
197 /* Data polling 2 */
198 retval = target_read_u16(target, offset, &state2);
199 if (retval != ERROR_OK)
200 return retval;
201
202 /* Flash command finished via polled data equal? */
203 if ( (state1 & FLASH_DQ6) != (state2 & FLASH_DQ6) )
204 {
205 return ERROR_FLASH_OPERATION_FAILED;
206 }
207
208 /* finish anyway */
209 break;
210 }
211 usleep(1000);
212 ++ms;
213
214 /* Polling time exceeded? */
215 if (ms > timeout_ms)
216 {
217 LOG_ERROR("Polling data reading timed out!");
218 return ERROR_FLASH_OPERATION_FAILED;
219 }
220 }
221
222 if (retval == ERROR_OK)
223 LOG_DEBUG("fm3_busy_wait(%x) needs about %d ms", offset, ms);
224
225 return retval;
226 }
227
228 static int fm3_erase(struct flash_bank *bank, int first, int last)
229 {
230 struct fm3_flash_bank *fm3_info = bank->driver_priv;
231 struct target *target = bank->target;
232 int retval = ERROR_OK;
233 uint32_t u32DummyRead;
234 int sector, odd;
235 uint32_t u32FlashType;
236 uint32_t u32FlashSeqAddress1;
237 uint32_t u32FlashSeqAddress2;
238
239 u32FlashType = (uint32_t) fm3_info->flashtype;
240
241 if (u32FlashType == fm3_flash_type1)
242 {
243 u32FlashSeqAddress1 = 0x00001550;
244 u32FlashSeqAddress2 = 0x00000AA8;
245 }
246 else if (u32FlashType == fm3_flash_type2)
247 {
248 u32FlashSeqAddress1 = 0x00000AA8;
249 u32FlashSeqAddress2 = 0x00000554;
250 }
251 else
252 {
253 LOG_ERROR("Flash/Device type unknown!");
254 return ERROR_FLASH_OPERATION_FAILED;
255 }
256
257 if (target->state != TARGET_HALTED) {
258 LOG_ERROR("Target not halted");
259 return ERROR_TARGET_NOT_HALTED;
260 }
261
262 LOG_INFO("Fujitsu MB9Bxxx: Sector Erase ... (%d to %d)", first, last);
263
264 /* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash acccess) */
265 retval = target_write_u32(target, 0x40000000, 0x0001);
266 if (retval != ERROR_OK)
267 return retval;
268
269 /* dummy read of FASZR */
270 retval = target_read_u32(target, 0x40000000, &u32DummyRead);
271 if (retval != ERROR_OK)
272 return retval;
273
274 for (sector = first ; sector <= last ; sector++)
275 {
276 uint32_t offset = bank->sectors[sector].offset;
277
278 for (odd = 0; odd < 2 ; odd++)
279 {
280 if (odd)
281 offset += 4;
282
283 /* Flash unlock sequence */
284 retval = target_write_u16(target, u32FlashSeqAddress1, 0x00AA);
285 if (retval != ERROR_OK)
286 return retval;
287
288 retval = target_write_u16(target, u32FlashSeqAddress2, 0x0055);
289 if (retval != ERROR_OK)
290 return retval;
291
292 retval = target_write_u16(target, u32FlashSeqAddress1, 0x0080);
293 if (retval != ERROR_OK)
294 return retval;
295
296 retval = target_write_u16(target, u32FlashSeqAddress1, 0x00AA);
297 if (retval != ERROR_OK)
298 return retval;
299
300 retval = target_write_u16(target, u32FlashSeqAddress2, 0x0055);
301 if (retval != ERROR_OK)
302 return retval;
303
304 /* Sector erase command (0x0030) */
305 retval = target_write_u16(target, offset, 0x0030);
306 if (retval != ERROR_OK)
307 return retval;
308
309 retval = fm3_busy_wait(target, offset, 500);
310 if (retval != ERROR_OK)
311 return retval;
312 }
313 bank->sectors[sector].is_erased = 1;
314 }
315
316 /* FASZR = 0x02, Enables CPU Run Mode (32-bit Flash acccess) */
317 retval = target_write_u32(target, 0x40000000, 0x0002);
318 if (retval != ERROR_OK)
319 return retval;
320
321 /* dummy read of FASZR */
322 retval = target_read_u32(target, 0x40000000, &u32DummyRead);
323
324 return retval;
325 }
326
327 static int fm3_write_block(struct flash_bank *bank, uint8_t *buffer,
328 uint32_t offset, uint32_t count)
329 {
330 struct fm3_flash_bank *fm3_info = bank->driver_priv;
331 struct target *target = bank->target;
332 uint32_t buffer_size = 2048; /* 8192 for MB9Bxx6! */
333 struct working_area *source;
334 uint32_t address = bank->base + offset;
335 struct reg_param reg_params[6];
336 struct armv7m_algorithm armv7m_info;
337 int retval = ERROR_OK;
338 uint32_t u32FlashType;
339 uint32_t u32FlashSeqAddress1;
340 uint32_t u32FlashSeqAddress2;
341
342 u32FlashType = (uint32_t) fm3_info->flashtype;
343
344 if (u32FlashType == fm3_flash_type1)
345 {
346 u32FlashSeqAddress1 = 0x00001550;
347 u32FlashSeqAddress2 = 0x00000AA8;
348 }
349 else if (u32FlashType == fm3_flash_type2)
350 {
351 u32FlashSeqAddress1 = 0x00000AA8;
352 u32FlashSeqAddress2 = 0x00000554;
353 }
354 else
355 {
356 LOG_ERROR("Flash/Device type unknown!");
357 return ERROR_FLASH_OPERATION_FAILED;
358 }
359
360 /* RAMCODE used for fm3 Flash programming: */
361 /* R0 keeps source start address (u32Source) */
362 /* R1 keeps target start address (u32Target) */
363 /* R2 keeps number of halfwords to write (u32Count) */
364 /* R3 keeps Flash Sequence address 1 (u32FlashSeq1) */
365 /* R4 keeps Flash Sequence address 2 (u32FlashSeq2) */
366 /* R5 returns result value (u32FlashResult) */
367
368 const uint8_t fm3_flash_write_code[] = {
369 /* fm3_FLASH_IF->FASZ &= 0xFFFD; */
370 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
371 0x2D, 0x68, /* LDR R5, [R5] */
372 0x4F, 0xF6, 0xFD, 0x76, /* MOVW R6, #0xFFFD */
373 0x35, 0x40, /* ANDS R5, R5, R6 */
374 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
375 0x35, 0x60, /* STR R5, [R6] */
376 /* fm3_FLASH_IF->FASZ |= 1; */
377 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
378 0x2D, 0x68, /* LDR R5, [R3] */
379 0x55, 0xF0, 0x01, 0x05, /* ORRS.W R5, R5, #1 */
380 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
381 0x35, 0x60, /* STR R5, [R6] */
382 /* u32DummyRead = fm3_FLASH_IF->FASZ; */
383 0x28, 0x4D, /* LDR.N R5, ??u32DummyRead */
384 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
385 0x36, 0x68, /* LDR R6, [R6] */
386 0x2E, 0x60, /* STR R6, [R5] */
387 /* u32FlashResult = FLASH_WRITE_NO_RESULT */
388 0x26, 0x4D, /* LDR.N R5, ??u32FlashResult */
389 0x00, 0x26, /* MOVS R6, #0 */
390 0x2E, 0x60, /* STR R6, [R5] */
391 /* while ((u32Count > 0 ) */
392 /* && (u32FlashResult */
393 /* == FLASH_WRITE_NO_RESULT)) */
394 0x01, 0x2A, /* L0: CMP R2, #1 */
395 0x2C, 0xDB, /* BLT.N L1 */
396 0x24, 0x4D, /* LDR.N R5, ??u32FlashResult */
397 0x2D, 0x68, /* LDR R5, [R5] */
398 0x00, 0x2D, /* CMP R5, #0 */
399 0x28, 0xD1, /* BNE.N L1 */
400 /* *u32FlashSeq1 = FLASH_WRITE_1; */
401 0xAA, 0x25, /* MOVS R5, #0xAA */
402 0x1D, 0x60, /* STR R5, [R3] */
403 /* *u32FlashSeq2 = FLASH_WRITE_2; */
404 0x55, 0x25, /* MOVS R5, #0x55 */
405 0x25, 0x60, /* STR R5, [R4] */
406 /* *u32FlashSeq1 = FLASH_WRITE_3; */
407 0xA0, 0x25, /* MOVS R5, #0xA0 */
408 0x1D, 0x60, /* STRH R5, [R3] */
409 /* *(volatile uint16_t*)u32Target */
410 /* = *(volatile uint16_t*)u32Source; */
411 0x05, 0x88, /* LDRH R5, [R0] */
412 0x0D, 0x80, /* STRH R5, [R1] */
413 /* while (u32FlashResult */
414 /* == FLASH_WRITE_NO_RESTULT) */
415 0x1E, 0x4D, /* L2: LDR.N R5, ??u32FlashResult */
416 0x2D, 0x68, /* LDR R5, [R5] */
417 0x00, 0x2D, /* CMP R5, #0 */
418 0x11, 0xD1, /* BNE.N L3 */
419 /* if ((*(volatile uint16_t*)u32Target */
420 /* & FLASH_DQ5) == FLASH_DQ5) */
421 0x0D, 0x88, /* LDRH R5, [R1] */
422 0xAD, 0x06, /* LSLS R5, R5, #0x1A */
423 0x02, 0xD5, /* BPL.N L4 */
424 /* u32FlashResult = FLASH_WRITE_TIMEOUT */
425 0x1A, 0x4D, /* LDR.N R5, ??u32FlashResult */
426 0x02, 0x26, /* MOVS R6, #2 */
427 0x2E, 0x60, /* STR R6, [R5] */
428 /* if ((*(volatile uint16_t *)u32Target */
429 /* & FLASH_DQ7) */
430 /* == (*(volatile uint16_t*)u32Source */
431 /* & FLASH_DQ7)) */
432 0x0D, 0x88, /* L4: LDRH R5, [R1] */
433 0x15, 0xF0, 0x80, 0x05, /* ANDS.W R5, R5, #0x80 */
434 0x06, 0x88, /* LDRH R6, [R0] */
435 0x16, 0xF0, 0x80, 0x06, /* ANDS.W R6, R6, #0x80 */
436 0xB5, 0x42, /* CMP R5, R6 */
437 0xED, 0xD1, /* BNE.N L2 */
438 /* u32FlashResult = FLASH_WRITE_OKAY */
439 0x15, 0x4D, /* LDR.N R5, ??u32FlashResult */
440 0x01, 0x26, /* MOVS R6, #1 */
441 0x2E, 0x60, /* STR R6, [R5] */
442 0xE9, 0xE7, /* B.N L2 */
443 /* if (u32FlashResult */
444 /* != FLASH_WRITE_TIMEOUT) */
445 0x13, 0x4D, /* LDR.N R5, ??u32FlashResult */
446 0x2D, 0x68, /* LDR R5, [R5] */
447 0x02, 0x2D, /* CMP R5, #2 */
448 0x02, 0xD0, /* BEQ.N L5 */
449 /* u32FlashResult = FLASH_WRITE_NO_RESULT */
450 0x11, 0x4D, /* LDR.N R5, ??u32FlashResult */
451 0x00, 0x26, /* MOVS R6, #0 */
452 0x2E, 0x60, /* STR R6, [R5] */
453 /* u32Count--; */
454 0x52, 0x1E, /* L5: SUBS R2, R2, #1 */
455 /* u32Source += 2; */
456 0x80, 0x1C, /* ADDS R0, R0, #2 */
457 /* u32Target += 2; */
458 0x89, 0x1C, /* ADDS R1, R1, #2 */
459 0xD0, 0xE7, /* B.N L0 */
460 /* fm3_FLASH_IF->FASZ &= 0xFFFE; */
461 0x5F, 0xF0, 0x80, 0x45, /* L1: MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
462 0x2D, 0x68, /* LDR R5, [R5] */
463 0x4F, 0xF6, 0xFE, 0x76, /* MOVW R6, #0xFFFE */
464 0x35, 0x40, /* ANDS R5, R5, R6 */
465 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
466 0x35, 0x60, /* STR R5, [R6] */
467 /* fm3_FLASH_IF->FASZ |= 2; */
468 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
469 0x2D, 0x68, /* LDR R5, [R5] */
470 0x55, 0xF0, 0x02, 0x05, /* ORRS.W R5, R5, #2 */
471 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
472 0x35, 0x60, /* STR R5, [R6] */
473 /* u32DummyRead = fm3_FLASH_IF->FASZ; */
474 0x04, 0x4D, /* LDR.N R5, ??u32DummyRead */
475 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
476 0x36, 0x68, /* LDR R6, [R6] */
477 0x2E, 0x60, /* STR R6, [R5] */
478 /* copy u32FlashResult to R3 for return */
479 /* value */
480 0xDF, 0xF8, 0x08, 0x50, /* LDR.W R5, ??u32FlashResult */
481 0x2D, 0x68, /* LDR R5, [R5] */
482 /* Breakpoint here */
483 0x00, 0xBE, /* BKPT #0 */
484
485 /* The following address pointers assume, that the code is running from */
486 /* address 0x1FFF8008. These address pointers will be patched, if a */
487 /* different start address in RAM is used (e.g. for Flash type 2)! */
488 0x00, 0x80, 0xFF, 0x1F, /* u32DummyRead address in RAM (0x1FFF8000) */
489 0x04, 0x80, 0xFF, 0x1F /* u32FlashResult address in RAM (0x1FFF8004) */
490 };
491
492 LOG_INFO("Fujitsu MB9B500: FLASH Write ...");
493
494 /* disable HW watchdog */
495 retval = target_write_u32(target, 0x40011C00, 0x1ACCE551);
496 if (retval != ERROR_OK)
497 return retval;
498
499 retval = target_write_u32(target, 0x40011C00, 0xE5331AAE);
500 if (retval != ERROR_OK)
501 return retval;
502
503 retval = target_write_u32(target, 0x40011008, 0x00000000);
504 if (retval != ERROR_OK)
505 return retval;
506
507 count = count / 2; /* number bytes -> number halfwords */
508
509 /* check code alignment */
510 if (offset & 0x1)
511 {
512 LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset);
513 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
514 }
515
516 /* allocate working area with flash programming code */
517 if (target_alloc_working_area(target, sizeof(fm3_flash_write_code),
518 &fm3_info->write_algorithm) != ERROR_OK)
519 {
520 LOG_WARNING("no working area available, can't do block memory writes");
521 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
522 }
523
524 retval = target_write_buffer(target, fm3_info->write_algorithm->address,
525 sizeof(fm3_flash_write_code), fm3_flash_write_code);
526 if (retval != ERROR_OK)
527 return retval;
528
529 /* memory buffer */
530 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
531 {
532 buffer_size /= 2;
533 if (buffer_size <= 256)
534 {
535 /* free working area, if write algorithm already allocated */
536 if (fm3_info->write_algorithm)
537 {
538 target_free_working_area(target, fm3_info->write_algorithm);
539 }
540
541 LOG_WARNING("No large enough working area available, can't do block memory writes");
542 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
543 }
544 }
545
546 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
547 armv7m_info.core_mode = ARMV7M_MODE_ANY;
548
549 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT); /* source start address */
550 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* target start address */
551 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* number of halfwords to program */
552 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT); /* Flash Sequence address 1 */
553 init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT); /* Flash Sequence address 1 */
554 init_reg_param(&reg_params[5], "r5", 32, PARAM_IN); /* result */
555
556 /* write code buffer and use Flash programming code within fm3 */
557 /* Set breakpoint to 0 with time-out of 1000 ms */
558 while (count > 0)
559 {
560 uint32_t thisrun_count = (count > (buffer_size / 2)) ? (buffer_size / 2) : count;
561
562 retval = target_write_buffer(target, fm3_info->write_algorithm->address,
563 8, fm3_flash_write_code);
564 if (retval != ERROR_OK)
565 break;
566
567 /* Patching 'local variable address' for different RAM addresses */
568 if (fm3_info->write_algorithm->address != 0x1FFF8008)
569 {
570 /* Algorithm: u32DummyRead: */
571 retval = target_write_u32(target, (fm3_info->write_algorithm->address)
572 + sizeof(fm3_flash_write_code) - 8,
573 (fm3_info->write_algorithm->address) - 8);
574 if (retval != ERROR_OK)
575 break;
576
577 /* Algorithm: u32FlashResult: */
578 retval = target_write_u32(target, (fm3_info->write_algorithm->address)
579 + sizeof(fm3_flash_write_code) - 4, (fm3_info->write_algorithm->address) - 4);
580 if (retval != ERROR_OK)
581 break;
582 }
583
584 retval = target_write_buffer(target, source->address, thisrun_count * 2,
585 buffer);
586 if (retval != ERROR_OK)
587 break;
588
589 buf_set_u32(reg_params[0].value, 0, 32, source->address);
590 buf_set_u32(reg_params[1].value, 0, 32, address);
591 buf_set_u32(reg_params[2].value, 0, 32, thisrun_count);
592 buf_set_u32(reg_params[3].value, 0, 32, u32FlashSeqAddress1);
593 buf_set_u32(reg_params[4].value, 0, 32, u32FlashSeqAddress2);
594
595 retval = target_run_algorithm(target, 0, NULL, 6, reg_params,
596 fm3_info->write_algorithm->address, 0, 1000, &armv7m_info);
597 if (retval != ERROR_OK)
598 {
599 LOG_ERROR("Error executing fm3 Flash programming algorithm");
600 retval = ERROR_FLASH_OPERATION_FAILED;
601 break;
602 }
603
604 if (buf_get_u32(reg_params[5].value, 0, 32) != ERROR_OK)
605 {
606 LOG_ERROR("Fujitsu MB9[A/B]FXXX: Flash programming ERROR (Timeout) \
607 -> Reg R3: %x", buf_get_u32(reg_params[5].value, 0, 32));
608 retval = ERROR_FLASH_OPERATION_FAILED;
609 break;
610 }
611
612 buffer += thisrun_count * 2;
613 address += thisrun_count * 2;
614 count -= thisrun_count;
615 }
616
617 target_free_working_area(target, source);
618 target_free_working_area(target, fm3_info->write_algorithm);
619
620 destroy_reg_param(&reg_params[0]);
621 destroy_reg_param(&reg_params[1]);
622 destroy_reg_param(&reg_params[2]);
623 destroy_reg_param(&reg_params[3]);
624 destroy_reg_param(&reg_params[4]);
625 destroy_reg_param(&reg_params[5]);
626
627 return retval;
628 }
629
630 static int fm3_probe(struct flash_bank *bank)
631 {
632 struct fm3_flash_bank *fm3_info = bank->driver_priv;
633 uint16_t num_pages;
634
635 if (bank->target->state != TARGET_HALTED)
636 {
637 LOG_ERROR("Target not halted");
638 return ERROR_TARGET_NOT_HALTED;
639 }
640
641 num_pages = 6; /* max number of Flash pages for malloc */
642 fm3_info->probed = 0;
643
644 bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
645 bank->base = 0x00000000;
646 num_pages = 2; /* start with smallest Flash pages number */
647 bank->size = 32 * 1024; /* bytes */
648
649 bank->sectors[0].offset = 0;
650 bank->sectors[0].size = 16 * 1024;
651 bank->sectors[0].is_erased = -1;
652 bank->sectors[0].is_protected = -1;
653
654 bank->sectors[1].offset = 0x4000;
655 bank->sectors[1].size = 16 * 1024;
656 bank->sectors[1].is_erased = -1;
657 bank->sectors[1].is_protected = -1;
658
659 if ((fm3_info->variant == mb9bfxx1) || (fm3_info->variant == mb9afxx1))
660 {
661 num_pages = 3;
662 bank->size = 64 * 1024; /* bytes */
663 bank->num_sectors = num_pages;
664
665 bank->sectors[2].offset = 0x8000;
666 bank->sectors[2].size = 32 * 1024;
667 bank->sectors[2].is_erased = -1;
668 bank->sectors[2].is_protected = -1;
669 }
670
671 if ((fm3_info->variant == mb9bfxx2)
672 || (fm3_info->variant == mb9bfxx4)
673 || (fm3_info->variant == mb9bfxx5)
674 || (fm3_info->variant == mb9bfxx6)
675 || (fm3_info->variant == mb9afxx2)
676 || (fm3_info->variant == mb9afxx4)
677 || (fm3_info->variant == mb9afxx5)
678 || (fm3_info->variant == mb9afxx6))
679 {
680 num_pages = 3;
681 bank->size = 128 * 1024; /* bytes */
682 bank->num_sectors = num_pages;
683
684 bank->sectors[2].offset = 0x8000;
685 bank->sectors[2].size = 96 * 1024;
686 bank->sectors[2].is_erased = -1;
687 bank->sectors[2].is_protected = -1;
688 }
689
690 if ((fm3_info->variant == mb9bfxx4)
691 || (fm3_info->variant == mb9bfxx5)
692 || (fm3_info->variant == mb9bfxx6)
693 || (fm3_info->variant == mb9afxx4)
694 || (fm3_info->variant == mb9afxx5)
695 || (fm3_info->variant == mb9afxx6))
696 {
697 num_pages = 4;
698 bank->size = 256 * 1024; /* bytes */
699 bank->num_sectors = num_pages;
700
701 bank->sectors[3].offset = 0x20000;
702 bank->sectors[3].size = 128 * 1024;
703 bank->sectors[3].is_erased = -1;
704 bank->sectors[3].is_protected = -1;
705 }
706
707 if ((fm3_info->variant == mb9bfxx5)
708 || (fm3_info->variant == mb9bfxx6)
709 || (fm3_info->variant == mb9afxx5)
710 || (fm3_info->variant == mb9afxx6))
711 {
712 num_pages = 5;
713 bank->size = 384 * 1024; /* bytes */
714 bank->num_sectors = num_pages;
715
716 bank->sectors[4].offset = 0x40000;
717 bank->sectors[4].size = 128 * 1024;
718 bank->sectors[4].is_erased = -1;
719 bank->sectors[4].is_protected = -1;
720 }
721
722 if ((fm3_info->variant == mb9bfxx6)
723 || (fm3_info->variant == mb9afxx6))
724 {
725 num_pages = 6;
726 bank->size = 512 * 1024; /* bytes */
727 bank->num_sectors = num_pages;
728
729 bank->sectors[5].offset = 0x60000;
730 bank->sectors[5].size = 128 * 1024;
731 bank->sectors[5].is_erased = -1;
732 bank->sectors[5].is_protected = -1;
733 }
734
735 fm3_info->probed = 1;
736
737 return ERROR_OK;
738 }
739
740 static int fm3_auto_probe(struct flash_bank *bank)
741 {
742 struct fm3_flash_bank *fm3_info = bank->driver_priv;
743 if (fm3_info->probed)
744 return ERROR_OK;
745 return fm3_probe(bank);
746 }
747
748 static int fm3_info_cmd(struct flash_bank *bank, char *buf, int buf_size)
749 {
750 snprintf(buf, buf_size, "Fujitsu fm3 Device does not support Chip-ID (Type unknown)");
751 return ERROR_OK;
752 }
753
754 static int fm3_chip_erase(struct flash_bank *bank)
755 {
756 struct target *target = bank->target;
757 struct fm3_flash_bank *fm3_info = bank->driver_priv;
758 int retval = ERROR_OK;
759 uint32_t u32DummyRead;
760 uint32_t u32FlashType;
761 uint32_t u32FlashSeqAddress1;
762 uint32_t u32FlashSeqAddress2;
763
764 u32FlashType = (uint32_t) fm3_info->flashtype;
765
766 if (u32FlashType == fm3_flash_type1)
767 {
768 LOG_INFO("*** Erasing mb9bfxxx type");
769 u32FlashSeqAddress1 = 0x00001550;
770 u32FlashSeqAddress2 = 0x00000AA8;
771 }
772 else if (u32FlashType == fm3_flash_type2)
773 {
774 LOG_INFO("*** Erasing mb9afxxx type");
775 u32FlashSeqAddress1 = 0x00000AA8;
776 u32FlashSeqAddress2 = 0x00000554;
777 }
778 else
779 {
780 LOG_ERROR("Flash/Device type unknown!");
781 return ERROR_FLASH_OPERATION_FAILED;
782 }
783
784 if (target->state != TARGET_HALTED)
785 {
786 LOG_ERROR("Target not halted");
787 return ERROR_TARGET_NOT_HALTED;
788 }
789
790 LOG_INFO("Fujitsu MB9[AB]xxx: Chip Erase ... (may take several seconds)");
791
792 /* Implement Flash chip erase (mass erase) completely on host */
793
794 /* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash access) */
795 retval = target_write_u32(target, 0x40000000, 0x0001);
796 if (retval != ERROR_OK)
797 return retval;
798
799 /* dummy read of FASZR */
800 retval = target_read_u32(target, 0x40000000, &u32DummyRead);
801 if (retval != ERROR_OK)
802 return retval;
803
804 /* Flash unlock sequence */
805 retval = target_write_u16(target, u32FlashSeqAddress1, 0x00AA);
806 if (retval != ERROR_OK)
807 return retval;
808
809 retval = target_write_u16(target, u32FlashSeqAddress2, 0x0055);
810 if (retval != ERROR_OK)
811 return retval;
812
813 retval = target_write_u16(target, u32FlashSeqAddress1, 0x0080);
814 if (retval != ERROR_OK)
815 return retval;
816
817 retval = target_write_u16(target, u32FlashSeqAddress1, 0x00AA);
818 if (retval != ERROR_OK)
819 return retval;
820
821 retval = target_write_u16(target, u32FlashSeqAddress2, 0x0055);
822 if (retval != ERROR_OK)
823 return retval;
824
825 /* Chip Erase command (0x0010) */
826 retval = target_write_u16(target, u32FlashSeqAddress1, 0x0010);
827 if (retval != ERROR_OK)
828 return retval;
829
830 retval = fm3_busy_wait(target, u32FlashSeqAddress2, 20000); /* 20s timeout */
831 if (retval != ERROR_OK)
832 return retval;
833
834 /* FASZR = 0x02, Re-enables CPU Run Mode (32-bit Flash access) */
835 retval = target_write_u32(target, 0x40000000, 0x0002);
836 if (retval != ERROR_OK)
837 return retval;
838
839 /* dummy read of FASZR */
840 retval = target_read_u32(target, 0x40000000, &u32DummyRead);
841
842 return retval;
843 }
844
845 COMMAND_HANDLER(fm3_handle_chip_erase_command)
846 {
847 int i;
848
849 if (CMD_ARGC < 1)
850 {
851 command_print(CMD_CTX, "fm3 chip_erase <bank>");
852 return ERROR_OK;
853 }
854
855 struct flash_bank *bank;
856 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
857 if (ERROR_OK != retval)
858 return retval;
859
860 if (fm3_chip_erase(bank) == ERROR_OK)
861 {
862 /* set all sectors as erased */
863 for (i = 0; i < bank->num_sectors; i++)
864 bank->sectors[i].is_erased = 1;
865
866 command_print(CMD_CTX, "fm3 chip erase complete");
867 }
868 else
869 {
870 command_print(CMD_CTX, "fm3 chip erase failed");
871 }
872
873 return ERROR_OK;
874 }
875
876 static const struct command_registration fm3_exec_command_handlers[] = {
877 {
878 .name = "chip_erase",
879 .handler = fm3_handle_chip_erase_command,
880 .mode = COMMAND_EXEC,
881 .usage = "bank_id",
882 .help = "Erase entire Flash device.",
883 },
884 COMMAND_REGISTRATION_DONE
885 };
886
887 static const struct command_registration fm3_command_handlers[] = {
888 {
889 .name = "fm3",
890 .mode = COMMAND_ANY,
891 .help = "fm3 Flash command group",
892 .chain = fm3_exec_command_handlers,
893 },
894 COMMAND_REGISTRATION_DONE
895 };
896
897 struct flash_driver fm3_flash = {
898 .name = "fm3",
899 .commands = fm3_command_handlers,
900 .flash_bank_command = fm3_flash_bank_command,
901 .erase = fm3_erase,
902 .write = fm3_write_block,
903 .probe = fm3_probe,
904 .auto_probe = fm3_auto_probe,
905 .erase_check = default_flash_mem_blank_check,
906 .info = fm3_info_cmd,
907 };

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)