1 /***************************************************************************
2 * Copyright (C) 2011 by Marc Willam, Holger Wech *
3 * openOCD.fseu(AT)de.fujitsu.com *
5 * Copyright (C) 2011 Ronny Strutz *
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. *
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. *
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 ***************************************************************************/
28 #include <helper/binarybuffer.h>
29 #include <target/algorithm.h>
30 #include <target/armv7m.h>
32 #define FLASH_DQ6 0x00000040 /* Data toggle flag bit (TOGG) */
33 #define FLASH_DQ5 0x00000020 /* Time limit exceeding flag bit (TLOV) */
37 mb9bfxx1
, /* Flash Type '1' */
43 mb9afxx1
, /* Flash Type '2' */
53 fm3_no_flash_type
= 0,
60 struct working_area
*write_algorithm
;
61 enum fm3_variant variant
;
62 enum fm3_flash_type flashtype
;
66 FLASH_BANK_COMMAND_HANDLER(fm3_flash_bank_command
)
68 struct fm3_flash_bank
*fm3_info
;
72 return ERROR_COMMAND_SYNTAX_ERROR
;
75 fm3_info
= malloc(sizeof(struct fm3_flash_bank
));
76 bank
->driver_priv
= fm3_info
;
79 if (strcmp(CMD_ARGV
[5], "mb9bfxx1.cpu") == 0)
81 fm3_info
->variant
= mb9bfxx1
;
82 fm3_info
->flashtype
= fm3_flash_type1
;
84 else if (strcmp(CMD_ARGV
[5], "mb9bfxx2.cpu") == 0)
86 fm3_info
->variant
= mb9bfxx2
;
87 fm3_info
->flashtype
= fm3_flash_type1
;
89 else if (strcmp(CMD_ARGV
[5], "mb9bfxx3.cpu") == 0)
91 fm3_info
->variant
= mb9bfxx3
;
92 fm3_info
->flashtype
= fm3_flash_type1
;
94 else if (strcmp(CMD_ARGV
[5], "mb9bfxx4.cpu") == 0)
96 fm3_info
->variant
= mb9bfxx4
;
97 fm3_info
->flashtype
= fm3_flash_type1
;
99 else if (strcmp(CMD_ARGV
[5], "mb9bfxx5.cpu") == 0)
101 fm3_info
->variant
= mb9bfxx5
;
102 fm3_info
->flashtype
= fm3_flash_type1
;
104 else if (strcmp(CMD_ARGV
[5], "mb9bfxx6.cpu") == 0)
106 fm3_info
->variant
= mb9bfxx6
;
107 fm3_info
->flashtype
= fm3_flash_type1
;
111 else if (strcmp(CMD_ARGV
[5], "mb9afxx1.cpu") == 0)
113 fm3_info
->variant
= mb9afxx1
;
114 fm3_info
->flashtype
= fm3_flash_type2
;
116 else if (strcmp(CMD_ARGV
[5], "mb9afxx2.cpu") == 0)
118 fm3_info
->variant
= mb9afxx2
;
119 fm3_info
->flashtype
= fm3_flash_type2
;
121 else if (strcmp(CMD_ARGV
[5], "mb9afxx3.cpu") == 0)
123 fm3_info
->variant
= mb9afxx3
;
124 fm3_info
->flashtype
= fm3_flash_type2
;
126 else if (strcmp(CMD_ARGV
[5], "mb9afxx4.cpu") == 0)
128 fm3_info
->variant
= mb9afxx4
;
129 fm3_info
->flashtype
= fm3_flash_type2
;
131 else if (strcmp(CMD_ARGV
[5], "mb9afxx5.cpu") == 0)
133 fm3_info
->variant
= mb9afxx5
;
134 fm3_info
->flashtype
= fm3_flash_type2
;
136 else if (strcmp(CMD_ARGV
[5], "mb9afxx6.cpu") == 0)
138 fm3_info
->variant
= mb9afxx6
;
139 fm3_info
->flashtype
= fm3_flash_type2
;
142 /* unknown Flash type */
145 LOG_ERROR("unknown fm3 variant: %s", CMD_ARGV
[5]);
147 return ERROR_FLASH_BANK_INVALID
;
150 fm3_info
->write_algorithm
= NULL
;
151 fm3_info
->probed
= 0;
156 /* Data polling algorithm */
157 static int fm3_busy_wait(struct target
*target
, uint32_t offset
, int timeout_ms
)
159 int retval
= ERROR_OK
;
160 uint16_t state1
, state2
;
163 /* While(1) loop exit via "break" and "return" on error */
166 /* dummy-read - see flash manual */
167 retval
= target_read_u16(target
, offset
, &state1
);
168 if (retval
!= ERROR_OK
)
172 retval
= target_read_u16(target
, offset
, &state1
);
173 if (retval
!= ERROR_OK
)
177 retval
= target_read_u16(target
, offset
, &state2
);
178 if (retval
!= ERROR_OK
)
181 /* Flash command finished via polled data equal? */
182 if ( (state1
& FLASH_DQ6
) == (state2
& FLASH_DQ6
) )
187 else if (state1
& FLASH_DQ5
)
189 /* Retry data polling */
192 retval
= target_read_u16(target
, offset
, &state1
);
193 if (retval
!= ERROR_OK
)
197 retval
= target_read_u16(target
, offset
, &state2
);
198 if (retval
!= ERROR_OK
)
201 /* Flash command finished via polled data equal? */
202 if ( (state1
& FLASH_DQ6
) != (state2
& FLASH_DQ6
) )
204 return ERROR_FLASH_OPERATION_FAILED
;
213 /* Polling time exceeded? */
216 LOG_ERROR("Polling data reading timed out!");
217 return ERROR_FLASH_OPERATION_FAILED
;
221 if (retval
== ERROR_OK
)
222 LOG_DEBUG("fm3_busy_wait(%x) needs about %d ms", offset
, ms
);
227 static int fm3_erase(struct flash_bank
*bank
, int first
, int last
)
229 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
230 struct target
*target
= bank
->target
;
231 int retval
= ERROR_OK
;
232 uint32_t u32DummyRead
;
234 uint32_t u32FlashType
;
235 uint32_t u32FlashSeqAddress1
;
236 uint32_t u32FlashSeqAddress2
;
238 u32FlashType
= (uint32_t) fm3_info
->flashtype
;
240 if (u32FlashType
== fm3_flash_type1
)
242 u32FlashSeqAddress1
= 0x00001550;
243 u32FlashSeqAddress2
= 0x00000AA8;
245 else if (u32FlashType
== fm3_flash_type2
)
247 u32FlashSeqAddress1
= 0x00000AA8;
248 u32FlashSeqAddress2
= 0x00000554;
252 LOG_ERROR("Flash/Device type unknown!");
253 return ERROR_FLASH_OPERATION_FAILED
;
256 if (target
->state
!= TARGET_HALTED
) {
257 LOG_ERROR("Target not halted");
258 return ERROR_TARGET_NOT_HALTED
;
261 LOG_INFO("Fujitsu MB9Bxxx: Sector Erase ... (%d to %d)", first
, last
);
263 /* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash acccess) */
264 retval
= target_write_u32(target
, 0x40000000, 0x0001);
265 if (retval
!= ERROR_OK
)
268 /* dummy read of FASZR */
269 retval
= target_read_u32(target
, 0x40000000, &u32DummyRead
);
270 if (retval
!= ERROR_OK
)
273 for (sector
= first
; sector
<= last
; sector
++)
275 uint32_t offset
= bank
->sectors
[sector
].offset
;
277 for (odd
= 0; odd
< 2 ; odd
++)
282 /* Flash unlock sequence */
283 retval
= target_write_u16(target
, u32FlashSeqAddress1
, 0x00AA);
284 if (retval
!= ERROR_OK
)
287 retval
= target_write_u16(target
, u32FlashSeqAddress2
, 0x0055);
288 if (retval
!= ERROR_OK
)
291 retval
= target_write_u16(target
, u32FlashSeqAddress1
, 0x0080);
292 if (retval
!= ERROR_OK
)
295 retval
= target_write_u16(target
, u32FlashSeqAddress1
, 0x00AA);
296 if (retval
!= ERROR_OK
)
299 retval
= target_write_u16(target
, u32FlashSeqAddress2
, 0x0055);
300 if (retval
!= ERROR_OK
)
303 /* Sector erase command (0x0030) */
304 retval
= target_write_u16(target
, offset
, 0x0030);
305 if (retval
!= ERROR_OK
)
308 retval
= fm3_busy_wait(target
, offset
, 500);
309 if (retval
!= ERROR_OK
)
312 bank
->sectors
[sector
].is_erased
= 1;
315 /* FASZR = 0x02, Enables CPU Run Mode (32-bit Flash acccess) */
316 retval
= target_write_u32(target
, 0x40000000, 0x0002);
317 if (retval
!= ERROR_OK
)
320 /* dummy read of FASZR */
321 retval
= target_read_u32(target
, 0x40000000, &u32DummyRead
);
326 static int fm3_write_block(struct flash_bank
*bank
, uint8_t *buffer
,
327 uint32_t offset
, uint32_t count
)
329 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
330 struct target
*target
= bank
->target
;
331 uint32_t buffer_size
= 2048; /* 8192 for MB9Bxx6! */
332 struct working_area
*source
;
333 uint32_t address
= bank
->base
+ offset
;
334 struct reg_param reg_params
[6];
335 struct armv7m_algorithm armv7m_info
;
336 int retval
= ERROR_OK
;
337 uint32_t u32FlashType
;
338 uint32_t u32FlashSeqAddress1
;
339 uint32_t u32FlashSeqAddress2
;
341 u32FlashType
= (uint32_t) fm3_info
->flashtype
;
343 if (u32FlashType
== fm3_flash_type1
)
345 u32FlashSeqAddress1
= 0x00001550;
346 u32FlashSeqAddress2
= 0x00000AA8;
348 else if (u32FlashType
== fm3_flash_type2
)
350 u32FlashSeqAddress1
= 0x00000AA8;
351 u32FlashSeqAddress2
= 0x00000554;
355 LOG_ERROR("Flash/Device type unknown!");
356 return ERROR_FLASH_OPERATION_FAILED
;
359 /* RAMCODE used for fm3 Flash programming: */
360 /* R0 keeps source start address (u32Source) */
361 /* R1 keeps target start address (u32Target) */
362 /* R2 keeps number of halfwords to write (u32Count) */
363 /* R3 keeps Flash Sequence address 1 (u32FlashSeq1) */
364 /* R4 keeps Flash Sequence address 2 (u32FlashSeq2) */
365 /* R5 returns result value (u32FlashResult) */
367 const uint8_t fm3_flash_write_code
[] = {
368 /* fm3_FLASH_IF->FASZ &= 0xFFFD; */
369 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
370 0x2D, 0x68, /* LDR R5, [R5] */
371 0x4F, 0xF6, 0xFD, 0x76, /* MOVW R6, #0xFFFD */
372 0x35, 0x40, /* ANDS R5, R5, R6 */
373 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
374 0x35, 0x60, /* STR R5, [R6] */
375 /* fm3_FLASH_IF->FASZ |= 1; */
376 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
377 0x2D, 0x68, /* LDR R5, [R3] */
378 0x55, 0xF0, 0x01, 0x05, /* ORRS.W R5, R5, #1 */
379 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
380 0x35, 0x60, /* STR R5, [R6] */
381 /* u32DummyRead = fm3_FLASH_IF->FASZ; */
382 0x28, 0x4D, /* LDR.N R5, ??u32DummyRead */
383 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
384 0x36, 0x68, /* LDR R6, [R6] */
385 0x2E, 0x60, /* STR R6, [R5] */
386 /* u32FlashResult = FLASH_WRITE_NO_RESULT */
387 0x26, 0x4D, /* LDR.N R5, ??u32FlashResult */
388 0x00, 0x26, /* MOVS R6, #0 */
389 0x2E, 0x60, /* STR R6, [R5] */
390 /* while ((u32Count > 0 ) */
391 /* && (u32FlashResult */
392 /* == FLASH_WRITE_NO_RESULT)) */
393 0x01, 0x2A, /* L0: CMP R2, #1 */
394 0x2C, 0xDB, /* BLT.N L1 */
395 0x24, 0x4D, /* LDR.N R5, ??u32FlashResult */
396 0x2D, 0x68, /* LDR R5, [R5] */
397 0x00, 0x2D, /* CMP R5, #0 */
398 0x28, 0xD1, /* BNE.N L1 */
399 /* *u32FlashSeq1 = FLASH_WRITE_1; */
400 0xAA, 0x25, /* MOVS R5, #0xAA */
401 0x1D, 0x60, /* STR R5, [R3] */
402 /* *u32FlashSeq2 = FLASH_WRITE_2; */
403 0x55, 0x25, /* MOVS R5, #0x55 */
404 0x25, 0x60, /* STR R5, [R4] */
405 /* *u32FlashSeq1 = FLASH_WRITE_3; */
406 0xA0, 0x25, /* MOVS R5, #0xA0 */
407 0x1D, 0x60, /* STRH R5, [R3] */
408 /* *(volatile uint16_t*)u32Target */
409 /* = *(volatile uint16_t*)u32Source; */
410 0x05, 0x88, /* LDRH R5, [R0] */
411 0x0D, 0x80, /* STRH R5, [R1] */
412 /* while (u32FlashResult */
413 /* == FLASH_WRITE_NO_RESTULT) */
414 0x1E, 0x4D, /* L2: LDR.N R5, ??u32FlashResult */
415 0x2D, 0x68, /* LDR R5, [R5] */
416 0x00, 0x2D, /* CMP R5, #0 */
417 0x11, 0xD1, /* BNE.N L3 */
418 /* if ((*(volatile uint16_t*)u32Target */
419 /* & FLASH_DQ5) == FLASH_DQ5) */
420 0x0D, 0x88, /* LDRH R5, [R1] */
421 0xAD, 0x06, /* LSLS R5, R5, #0x1A */
422 0x02, 0xD5, /* BPL.N L4 */
423 /* u32FlashResult = FLASH_WRITE_TIMEOUT */
424 0x1A, 0x4D, /* LDR.N R5, ??u32FlashResult */
425 0x02, 0x26, /* MOVS R6, #2 */
426 0x2E, 0x60, /* STR R6, [R5] */
427 /* if ((*(volatile uint16_t *)u32Target */
429 /* == (*(volatile uint16_t*)u32Source */
431 0x0D, 0x88, /* L4: LDRH R5, [R1] */
432 0x15, 0xF0, 0x80, 0x05, /* ANDS.W R5, R5, #0x80 */
433 0x06, 0x88, /* LDRH R6, [R0] */
434 0x16, 0xF0, 0x80, 0x06, /* ANDS.W R6, R6, #0x80 */
435 0xB5, 0x42, /* CMP R5, R6 */
436 0xED, 0xD1, /* BNE.N L2 */
437 /* u32FlashResult = FLASH_WRITE_OKAY */
438 0x15, 0x4D, /* LDR.N R5, ??u32FlashResult */
439 0x01, 0x26, /* MOVS R6, #1 */
440 0x2E, 0x60, /* STR R6, [R5] */
441 0xE9, 0xE7, /* B.N L2 */
442 /* if (u32FlashResult */
443 /* != FLASH_WRITE_TIMEOUT) */
444 0x13, 0x4D, /* LDR.N R5, ??u32FlashResult */
445 0x2D, 0x68, /* LDR R5, [R5] */
446 0x02, 0x2D, /* CMP R5, #2 */
447 0x02, 0xD0, /* BEQ.N L5 */
448 /* u32FlashResult = FLASH_WRITE_NO_RESULT */
449 0x11, 0x4D, /* LDR.N R5, ??u32FlashResult */
450 0x00, 0x26, /* MOVS R6, #0 */
451 0x2E, 0x60, /* STR R6, [R5] */
453 0x52, 0x1E, /* L5: SUBS R2, R2, #1 */
454 /* u32Source += 2; */
455 0x80, 0x1C, /* ADDS R0, R0, #2 */
456 /* u32Target += 2; */
457 0x89, 0x1C, /* ADDS R1, R1, #2 */
458 0xD0, 0xE7, /* B.N L0 */
459 /* fm3_FLASH_IF->FASZ &= 0xFFFE; */
460 0x5F, 0xF0, 0x80, 0x45, /* L1: MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
461 0x2D, 0x68, /* LDR R5, [R5] */
462 0x4F, 0xF6, 0xFE, 0x76, /* MOVW R6, #0xFFFE */
463 0x35, 0x40, /* ANDS R5, R5, R6 */
464 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
465 0x35, 0x60, /* STR R5, [R6] */
466 /* fm3_FLASH_IF->FASZ |= 2; */
467 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
468 0x2D, 0x68, /* LDR R5, [R5] */
469 0x55, 0xF0, 0x02, 0x05, /* ORRS.W R5, R5, #2 */
470 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
471 0x35, 0x60, /* STR R5, [R6] */
472 /* u32DummyRead = fm3_FLASH_IF->FASZ; */
473 0x04, 0x4D, /* LDR.N R5, ??u32DummyRead */
474 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
475 0x36, 0x68, /* LDR R6, [R6] */
476 0x2E, 0x60, /* STR R6, [R5] */
477 /* copy u32FlashResult to R3 for return */
479 0xDF, 0xF8, 0x08, 0x50, /* LDR.W R5, ??u32FlashResult */
480 0x2D, 0x68, /* LDR R5, [R5] */
481 /* Breakpoint here */
482 0x00, 0xBE, /* BKPT #0 */
484 /* The following address pointers assume, that the code is running from */
485 /* address 0x1FFF8008. These address pointers will be patched, if a */
486 /* different start address in RAM is used (e.g. for Flash type 2)! */
487 0x00, 0x80, 0xFF, 0x1F, /* u32DummyRead address in RAM (0x1FFF8000) */
488 0x04, 0x80, 0xFF, 0x1F /* u32FlashResult address in RAM (0x1FFF8004) */
491 LOG_INFO("Fujitsu MB9B500: FLASH Write ...");
493 /* disable HW watchdog */
494 retval
= target_write_u32(target
, 0x40011C00, 0x1ACCE551);
495 if (retval
!= ERROR_OK
)
498 retval
= target_write_u32(target
, 0x40011C00, 0xE5331AAE);
499 if (retval
!= ERROR_OK
)
502 retval
= target_write_u32(target
, 0x40011008, 0x00000000);
503 if (retval
!= ERROR_OK
)
506 count
= count
/ 2; /* number bytes -> number halfwords */
508 /* check code alignment */
511 LOG_WARNING("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
512 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
515 /* allocate working area with flash programming code */
516 if (target_alloc_working_area(target
, sizeof(fm3_flash_write_code
),
517 &fm3_info
->write_algorithm
) != ERROR_OK
)
519 LOG_WARNING("no working area available, can't do block memory writes");
520 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
523 retval
= target_write_buffer(target
, fm3_info
->write_algorithm
->address
,
524 sizeof(fm3_flash_write_code
), fm3_flash_write_code
);
525 if (retval
!= ERROR_OK
)
529 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
532 if (buffer_size
<= 256)
534 /* free working area, if write algorithm already allocated */
535 if (fm3_info
->write_algorithm
)
537 target_free_working_area(target
, fm3_info
->write_algorithm
);
540 LOG_WARNING("No large enough working area available, can't do block memory writes");
541 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
545 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
546 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
548 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
); /* source start address */
549 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* target start address */
550 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* number of halfwords to program */
551 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
); /* Flash Sequence address 1 */
552 init_reg_param(®_params
[4], "r4", 32, PARAM_OUT
); /* Flash Sequence address 1 */
553 init_reg_param(®_params
[5], "r5", 32, PARAM_IN
); /* result */
555 /* write code buffer and use Flash programming code within fm3 */
556 /* Set breakpoint to 0 with time-out of 1000 ms */
559 uint32_t thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
561 retval
= target_write_buffer(target
, fm3_info
->write_algorithm
->address
,
562 8, fm3_flash_write_code
);
563 if (retval
!= ERROR_OK
)
566 /* Patching 'local variable address' for different RAM addresses */
567 if (fm3_info
->write_algorithm
->address
!= 0x1FFF8008)
569 /* Algorithm: u32DummyRead: */
570 retval
= target_write_u32(target
, (fm3_info
->write_algorithm
->address
)
571 + sizeof(fm3_flash_write_code
) - 8,
572 (fm3_info
->write_algorithm
->address
) - 8);
573 if (retval
!= ERROR_OK
)
576 /* Algorithm: u32FlashResult: */
577 retval
= target_write_u32(target
, (fm3_info
->write_algorithm
->address
)
578 + sizeof(fm3_flash_write_code
) - 4, (fm3_info
->write_algorithm
->address
) - 4);
579 if (retval
!= ERROR_OK
)
583 retval
= target_write_buffer(target
, source
->address
, thisrun_count
* 2,
585 if (retval
!= ERROR_OK
)
588 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
589 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
590 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
591 buf_set_u32(reg_params
[3].value
, 0, 32, u32FlashSeqAddress1
);
592 buf_set_u32(reg_params
[4].value
, 0, 32, u32FlashSeqAddress2
);
594 retval
= target_run_algorithm(target
, 0, NULL
, 6, reg_params
,
595 fm3_info
->write_algorithm
->address
, 0, 1000, &armv7m_info
);
596 if (retval
!= ERROR_OK
)
598 LOG_ERROR("Error executing fm3 Flash programming algorithm");
599 retval
= ERROR_FLASH_OPERATION_FAILED
;
603 if (buf_get_u32(reg_params
[5].value
, 0, 32) != ERROR_OK
)
605 LOG_ERROR("Fujitsu MB9[A/B]FXXX: Flash programming ERROR (Timeout) \
606 -> Reg R3: %x", buf_get_u32(reg_params
[5].value
, 0, 32));
607 retval
= ERROR_FLASH_OPERATION_FAILED
;
611 buffer
+= thisrun_count
* 2;
612 address
+= thisrun_count
* 2;
613 count
-= thisrun_count
;
616 target_free_working_area(target
, source
);
617 target_free_working_area(target
, fm3_info
->write_algorithm
);
619 destroy_reg_param(®_params
[0]);
620 destroy_reg_param(®_params
[1]);
621 destroy_reg_param(®_params
[2]);
622 destroy_reg_param(®_params
[3]);
623 destroy_reg_param(®_params
[4]);
624 destroy_reg_param(®_params
[5]);
629 static int fm3_probe(struct flash_bank
*bank
)
631 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
634 if (bank
->target
->state
!= TARGET_HALTED
)
636 LOG_ERROR("Target not halted");
637 return ERROR_TARGET_NOT_HALTED
;
640 num_pages
= 6; /* max number of Flash pages for malloc */
641 fm3_info
->probed
= 0;
643 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_pages
);
644 bank
->base
= 0x00000000;
645 bank
->size
= 32 * 1024; /* bytes */
647 bank
->sectors
[0].offset
= 0;
648 bank
->sectors
[0].size
= 16 * 1024;
649 bank
->sectors
[0].is_erased
= -1;
650 bank
->sectors
[0].is_protected
= -1;
652 bank
->sectors
[1].offset
= 0x4000;
653 bank
->sectors
[1].size
= 16 * 1024;
654 bank
->sectors
[1].is_erased
= -1;
655 bank
->sectors
[1].is_protected
= -1;
657 if ((fm3_info
->variant
== mb9bfxx1
) || (fm3_info
->variant
== mb9afxx1
))
660 bank
->size
= 64 * 1024; /* bytes */
661 bank
->num_sectors
= num_pages
;
663 bank
->sectors
[2].offset
= 0x8000;
664 bank
->sectors
[2].size
= 32 * 1024;
665 bank
->sectors
[2].is_erased
= -1;
666 bank
->sectors
[2].is_protected
= -1;
669 if ((fm3_info
->variant
== mb9bfxx2
)
670 || (fm3_info
->variant
== mb9bfxx4
)
671 || (fm3_info
->variant
== mb9bfxx5
)
672 || (fm3_info
->variant
== mb9bfxx6
)
673 || (fm3_info
->variant
== mb9afxx2
)
674 || (fm3_info
->variant
== mb9afxx4
)
675 || (fm3_info
->variant
== mb9afxx5
)
676 || (fm3_info
->variant
== mb9afxx6
))
679 bank
->size
= 128 * 1024; /* bytes */
680 bank
->num_sectors
= num_pages
;
682 bank
->sectors
[2].offset
= 0x8000;
683 bank
->sectors
[2].size
= 96 * 1024;
684 bank
->sectors
[2].is_erased
= -1;
685 bank
->sectors
[2].is_protected
= -1;
688 if ((fm3_info
->variant
== mb9bfxx4
)
689 || (fm3_info
->variant
== mb9bfxx5
)
690 || (fm3_info
->variant
== mb9bfxx6
)
691 || (fm3_info
->variant
== mb9afxx4
)
692 || (fm3_info
->variant
== mb9afxx5
)
693 || (fm3_info
->variant
== mb9afxx6
))
696 bank
->size
= 256 * 1024; /* bytes */
697 bank
->num_sectors
= num_pages
;
699 bank
->sectors
[3].offset
= 0x20000;
700 bank
->sectors
[3].size
= 128 * 1024;
701 bank
->sectors
[3].is_erased
= -1;
702 bank
->sectors
[3].is_protected
= -1;
705 if ((fm3_info
->variant
== mb9bfxx5
)
706 || (fm3_info
->variant
== mb9bfxx6
)
707 || (fm3_info
->variant
== mb9afxx5
)
708 || (fm3_info
->variant
== mb9afxx6
))
711 bank
->size
= 384 * 1024; /* bytes */
712 bank
->num_sectors
= num_pages
;
714 bank
->sectors
[4].offset
= 0x40000;
715 bank
->sectors
[4].size
= 128 * 1024;
716 bank
->sectors
[4].is_erased
= -1;
717 bank
->sectors
[4].is_protected
= -1;
720 if ((fm3_info
->variant
== mb9bfxx6
)
721 || (fm3_info
->variant
== mb9afxx6
))
724 bank
->size
= 512 * 1024; /* bytes */
725 bank
->num_sectors
= num_pages
;
727 bank
->sectors
[5].offset
= 0x60000;
728 bank
->sectors
[5].size
= 128 * 1024;
729 bank
->sectors
[5].is_erased
= -1;
730 bank
->sectors
[5].is_protected
= -1;
733 fm3_info
->probed
= 1;
738 static int fm3_auto_probe(struct flash_bank
*bank
)
740 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
741 if (fm3_info
->probed
)
743 return fm3_probe(bank
);
746 static int fm3_info_cmd(struct flash_bank
*bank
, char *buf
, int buf_size
)
748 snprintf(buf
, buf_size
, "Fujitsu fm3 Device does not support Chip-ID (Type unknown)");
752 static int fm3_chip_erase(struct flash_bank
*bank
)
754 struct target
*target
= bank
->target
;
755 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
756 int retval
= ERROR_OK
;
757 uint32_t u32DummyRead
;
758 uint32_t u32FlashType
;
759 uint32_t u32FlashSeqAddress1
;
760 uint32_t u32FlashSeqAddress2
;
762 u32FlashType
= (uint32_t) fm3_info
->flashtype
;
764 if (u32FlashType
== fm3_flash_type1
)
766 LOG_INFO("*** Erasing mb9bfxxx type");
767 u32FlashSeqAddress1
= 0x00001550;
768 u32FlashSeqAddress2
= 0x00000AA8;
770 else if (u32FlashType
== fm3_flash_type2
)
772 LOG_INFO("*** Erasing mb9afxxx type");
773 u32FlashSeqAddress1
= 0x00000AA8;
774 u32FlashSeqAddress2
= 0x00000554;
778 LOG_ERROR("Flash/Device type unknown!");
779 return ERROR_FLASH_OPERATION_FAILED
;
782 if (target
->state
!= TARGET_HALTED
)
784 LOG_ERROR("Target not halted");
785 return ERROR_TARGET_NOT_HALTED
;
788 LOG_INFO("Fujitsu MB9[AB]xxx: Chip Erase ... (may take several seconds)");
790 /* Implement Flash chip erase (mass erase) completely on host */
792 /* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash access) */
793 retval
= target_write_u32(target
, 0x40000000, 0x0001);
794 if (retval
!= ERROR_OK
)
797 /* dummy read of FASZR */
798 retval
= target_read_u32(target
, 0x40000000, &u32DummyRead
);
799 if (retval
!= ERROR_OK
)
802 /* Flash unlock sequence */
803 retval
= target_write_u16(target
, u32FlashSeqAddress1
, 0x00AA);
804 if (retval
!= ERROR_OK
)
807 retval
= target_write_u16(target
, u32FlashSeqAddress2
, 0x0055);
808 if (retval
!= ERROR_OK
)
811 retval
= target_write_u16(target
, u32FlashSeqAddress1
, 0x0080);
812 if (retval
!= ERROR_OK
)
815 retval
= target_write_u16(target
, u32FlashSeqAddress1
, 0x00AA);
816 if (retval
!= ERROR_OK
)
819 retval
= target_write_u16(target
, u32FlashSeqAddress2
, 0x0055);
820 if (retval
!= ERROR_OK
)
823 /* Chip Erase command (0x0010) */
824 retval
= target_write_u16(target
, u32FlashSeqAddress1
, 0x0010);
825 if (retval
!= ERROR_OK
)
828 retval
= fm3_busy_wait(target
, u32FlashSeqAddress2
, 20000); /* 20s timeout */
829 if (retval
!= ERROR_OK
)
832 /* FASZR = 0x02, Re-enables CPU Run Mode (32-bit Flash access) */
833 retval
= target_write_u32(target
, 0x40000000, 0x0002);
834 if (retval
!= ERROR_OK
)
837 /* dummy read of FASZR */
838 retval
= target_read_u32(target
, 0x40000000, &u32DummyRead
);
843 COMMAND_HANDLER(fm3_handle_chip_erase_command
)
849 return ERROR_COMMAND_SYNTAX_ERROR
;
852 struct flash_bank
*bank
;
853 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
854 if (ERROR_OK
!= retval
)
857 if (fm3_chip_erase(bank
) == ERROR_OK
)
859 /* set all sectors as erased */
860 for (i
= 0; i
< bank
->num_sectors
; i
++)
861 bank
->sectors
[i
].is_erased
= 1;
863 command_print(CMD_CTX
, "fm3 chip erase complete");
867 command_print(CMD_CTX
, "fm3 chip erase failed");
873 static const struct command_registration fm3_exec_command_handlers
[] = {
875 .name
= "chip_erase",
877 .handler
= fm3_handle_chip_erase_command
,
878 .mode
= COMMAND_EXEC
,
879 .help
= "Erase entire Flash device.",
881 COMMAND_REGISTRATION_DONE
884 static const struct command_registration fm3_command_handlers
[] = {
888 .help
= "fm3 Flash command group",
890 .chain
= fm3_exec_command_handlers
,
892 COMMAND_REGISTRATION_DONE
895 struct flash_driver fm3_flash
= {
897 .commands
= fm3_command_handlers
,
898 .flash_bank_command
= fm3_flash_bank_command
,
900 .write
= fm3_write_block
,
902 .auto_probe
= fm3_auto_probe
,
903 .erase_check
= default_flash_mem_blank_check
,
904 .info
= fm3_info_cmd
,
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)