1 /***************************************************************************
2 * Copyright (C) 2011 by Marc Willam, Holger Wech *
3 * openOCD.fseu(AT)de.fujitsu.com *
4 * Copyright (C) 2011 Ronny Strutz *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
20 ***************************************************************************/
27 #include <helper/binarybuffer.h>
28 #include <target/algorithm.h>
29 #include <target/armv7m.h>
31 #define FLASH_DQ6 0x00000040 /* Data toggle flag bit (TOGG) position */
32 #define FLASH_DQ5 0x00000020 /* Time limit exceeding flag bit (TLOV) position */
35 mb9bfxx1
, /* Flash Type '1' */
44 mb9afxx1
, /* Flash Type '2' */
55 fm3_no_flash_type
= 0,
60 struct fm3_flash_bank
{
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
;
71 return ERROR_COMMAND_SYNTAX_ERROR
;
73 fm3_info
= malloc(sizeof(struct fm3_flash_bank
));
74 bank
->driver_priv
= fm3_info
;
77 if (strcmp(CMD_ARGV
[5], "mb9bfxx1.cpu") == 0) {
78 fm3_info
->variant
= mb9bfxx1
;
79 fm3_info
->flashtype
= fm3_flash_type1
;
80 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx2.cpu") == 0) {
81 fm3_info
->variant
= mb9bfxx2
;
82 fm3_info
->flashtype
= fm3_flash_type1
;
83 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx3.cpu") == 0) {
84 fm3_info
->variant
= mb9bfxx3
;
85 fm3_info
->flashtype
= fm3_flash_type1
;
86 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx4.cpu") == 0) {
87 fm3_info
->variant
= mb9bfxx4
;
88 fm3_info
->flashtype
= fm3_flash_type1
;
89 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx5.cpu") == 0) {
90 fm3_info
->variant
= mb9bfxx5
;
91 fm3_info
->flashtype
= fm3_flash_type1
;
92 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx6.cpu") == 0) {
93 fm3_info
->variant
= mb9bfxx6
;
94 fm3_info
->flashtype
= fm3_flash_type1
;
95 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx7.cpu") == 0) {
96 fm3_info
->variant
= mb9bfxx7
;
97 fm3_info
->flashtype
= fm3_flash_type1
;
98 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx8.cpu") == 0) {
99 fm3_info
->variant
= mb9bfxx8
;
100 fm3_info
->flashtype
= fm3_flash_type1
;
101 } else if (strcmp(CMD_ARGV
[5], "mb9afxx1.cpu") == 0) { /* Flash type '2' */
102 fm3_info
->variant
= mb9afxx1
;
103 fm3_info
->flashtype
= fm3_flash_type2
;
104 } else if (strcmp(CMD_ARGV
[5], "mb9afxx2.cpu") == 0) {
105 fm3_info
->variant
= mb9afxx2
;
106 fm3_info
->flashtype
= fm3_flash_type2
;
107 } else if (strcmp(CMD_ARGV
[5], "mb9afxx3.cpu") == 0) {
108 fm3_info
->variant
= mb9afxx3
;
109 fm3_info
->flashtype
= fm3_flash_type2
;
110 } else if (strcmp(CMD_ARGV
[5], "mb9afxx4.cpu") == 0) {
111 fm3_info
->variant
= mb9afxx4
;
112 fm3_info
->flashtype
= fm3_flash_type2
;
113 } else if (strcmp(CMD_ARGV
[5], "mb9afxx5.cpu") == 0) {
114 fm3_info
->variant
= mb9afxx5
;
115 fm3_info
->flashtype
= fm3_flash_type2
;
116 } else if (strcmp(CMD_ARGV
[5], "mb9afxx6.cpu") == 0) {
117 fm3_info
->variant
= mb9afxx6
;
118 fm3_info
->flashtype
= fm3_flash_type2
;
119 } else if (strcmp(CMD_ARGV
[5], "mb9afxx7.cpu") == 0) {
120 fm3_info
->variant
= mb9afxx7
;
121 fm3_info
->flashtype
= fm3_flash_type2
;
122 } else if (strcmp(CMD_ARGV
[5], "mb9afxx8.cpu") == 0) {
123 fm3_info
->variant
= mb9afxx8
;
124 fm3_info
->flashtype
= fm3_flash_type2
;
127 /* unknown Flash type */
129 LOG_ERROR("unknown fm3 variant: %s", CMD_ARGV
[5]);
131 return ERROR_FLASH_BANK_INVALID
;
134 fm3_info
->probed
= 0;
139 /* Data polling algorithm */
140 static int fm3_busy_wait(struct target
*target
, uint32_t offset
, int timeout_ms
)
142 int retval
= ERROR_OK
;
143 uint16_t state1
, state2
;
146 /* While(1) loop exit via "break" and "return" on error */
148 /* dummy-read - see flash manual */
149 retval
= target_read_u16(target
, offset
, &state1
);
150 if (retval
!= ERROR_OK
)
154 retval
= target_read_u16(target
, offset
, &state1
);
155 if (retval
!= ERROR_OK
)
159 retval
= target_read_u16(target
, offset
, &state2
);
160 if (retval
!= ERROR_OK
)
163 /* Flash command finished via polled data equal? */
164 if ((state1
& FLASH_DQ6
) == (state2
& FLASH_DQ6
))
167 else if (state1
& FLASH_DQ5
) {
168 /* Retry data polling */
171 retval
= target_read_u16(target
, offset
, &state1
);
172 if (retval
!= ERROR_OK
)
176 retval
= target_read_u16(target
, offset
, &state2
);
177 if (retval
!= ERROR_OK
)
180 /* Flash command finished via polled data equal? */
181 if ((state1
& FLASH_DQ6
) != (state2
& FLASH_DQ6
))
182 return ERROR_FLASH_OPERATION_FAILED
;
190 /* Polling time exceeded? */
191 if (ms
> timeout_ms
) {
192 LOG_ERROR("Polling data reading timed out!");
193 return ERROR_FLASH_OPERATION_FAILED
;
197 if (retval
== ERROR_OK
)
198 LOG_DEBUG("fm3_busy_wait(%" PRIx32
") needs about %d ms", offset
, ms
);
203 static int fm3_erase(struct flash_bank
*bank
, int first
, int last
)
205 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
206 struct target
*target
= bank
->target
;
207 int retval
= ERROR_OK
;
208 uint32_t u32DummyRead
;
210 uint32_t u32FlashType
;
211 uint32_t u32FlashSeqAddress1
;
212 uint32_t u32FlashSeqAddress2
;
214 u32FlashType
= (uint32_t) fm3_info
->flashtype
;
216 if (u32FlashType
== fm3_flash_type1
) {
217 u32FlashSeqAddress1
= 0x00001550;
218 u32FlashSeqAddress2
= 0x00000AA8;
219 } else if (u32FlashType
== fm3_flash_type2
) {
220 u32FlashSeqAddress1
= 0x00000AA8;
221 u32FlashSeqAddress2
= 0x00000554;
223 LOG_ERROR("Flash/Device type unknown!");
224 return ERROR_FLASH_OPERATION_FAILED
;
227 if (target
->state
!= TARGET_HALTED
) {
228 LOG_ERROR("Target not halted");
229 return ERROR_TARGET_NOT_HALTED
;
232 LOG_INFO("Fujitsu MB9[A/B]FXXX: Sector Erase ... (%d to %d)", first
, last
);
234 /* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash acccess) */
235 retval
= target_write_u32(target
, 0x40000000, 0x0001);
236 if (retval
!= ERROR_OK
)
239 /* dummy read of FASZR */
240 retval
= target_read_u32(target
, 0x40000000, &u32DummyRead
);
241 if (retval
!= ERROR_OK
)
244 for (sector
= first
; sector
<= last
; sector
++) {
245 uint32_t offset
= bank
->sectors
[sector
].offset
;
247 for (odd
= 0; odd
< 2 ; odd
++) {
251 /* Flash unlock sequence */
252 retval
= target_write_u16(target
, u32FlashSeqAddress1
, 0x00AA);
253 if (retval
!= ERROR_OK
)
256 retval
= target_write_u16(target
, u32FlashSeqAddress2
, 0x0055);
257 if (retval
!= ERROR_OK
)
260 retval
= target_write_u16(target
, u32FlashSeqAddress1
, 0x0080);
261 if (retval
!= ERROR_OK
)
264 retval
= target_write_u16(target
, u32FlashSeqAddress1
, 0x00AA);
265 if (retval
!= ERROR_OK
)
268 retval
= target_write_u16(target
, u32FlashSeqAddress2
, 0x0055);
269 if (retval
!= ERROR_OK
)
272 /* Sector erase command (0x0030) */
273 retval
= target_write_u16(target
, offset
, 0x0030);
274 if (retval
!= ERROR_OK
)
277 retval
= fm3_busy_wait(target
, offset
, 500);
278 if (retval
!= ERROR_OK
)
281 bank
->sectors
[sector
].is_erased
= 1;
284 /* FASZR = 0x02, Enables CPU Run Mode (32-bit Flash acccess) */
285 retval
= target_write_u32(target
, 0x40000000, 0x0002);
286 if (retval
!= ERROR_OK
)
289 retval
= target_read_u32(target
, 0x40000000, &u32DummyRead
); /* dummy read of FASZR */
294 static int fm3_write_block(struct flash_bank
*bank
, uint8_t *buffer
,
295 uint32_t offset
, uint32_t count
)
297 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
298 struct target
*target
= bank
->target
;
299 uint32_t buffer_size
= 2048; /* Default minimum value */
300 struct working_area
*write_algorithm
;
301 struct working_area
*source
;
302 uint32_t address
= bank
->base
+ offset
;
303 struct reg_param reg_params
[6];
304 struct armv7m_algorithm armv7m_info
;
305 int retval
= ERROR_OK
;
306 uint32_t u32FlashType
;
307 uint32_t u32FlashSeqAddress1
;
308 uint32_t u32FlashSeqAddress2
;
310 /* Increase buffer_size if needed */
311 if (buffer_size
< (target
->working_area_size
/ 2))
312 buffer_size
= (target
->working_area_size
/ 2);
314 u32FlashType
= (uint32_t) fm3_info
->flashtype
;
316 if (u32FlashType
== fm3_flash_type1
) {
317 u32FlashSeqAddress1
= 0x00001550;
318 u32FlashSeqAddress2
= 0x00000AA8;
319 } else if (u32FlashType
== fm3_flash_type2
) {
320 u32FlashSeqAddress1
= 0x00000AA8;
321 u32FlashSeqAddress2
= 0x00000554;
323 LOG_ERROR("Flash/Device type unknown!");
324 return ERROR_FLASH_OPERATION_FAILED
;
327 /* RAMCODE used for fm3 Flash programming: */
328 /* R0 keeps source start address (u32Source) */
329 /* R1 keeps target start address (u32Target) */
330 /* R2 keeps number of halfwords to write (u32Count) */
331 /* R3 keeps Flash Sequence address 1 (u32FlashSeq1) */
332 /* R4 keeps Flash Sequence address 2 (u32FlashSeq2) */
333 /* R5 returns result value (u32FlashResult) */
335 static const uint8_t fm3_flash_write_code
[] = {
336 /* fm3_FLASH_IF->FASZ &= 0xFFFD; */
337 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
338 0x2D, 0x68, /* LDR R5, [R5] */
339 0x4F, 0xF6, 0xFD, 0x76, /* MOVW R6, #0xFFFD */
340 0x35, 0x40, /* ANDS R5, R5, R6 */
341 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
342 0x35, 0x60, /* STR R5, [R6] */
343 /* fm3_FLASH_IF->FASZ |= 1; */
344 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
345 0x2D, 0x68, /* LDR R5, [R3] */
346 0x55, 0xF0, 0x01, 0x05, /* ORRS.W R5, R5, #1 */
347 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
348 0x35, 0x60, /* STR R5, [R6] */
349 /* u32DummyRead = fm3_FLASH_IF->FASZ; */
350 0x28, 0x4D, /* LDR.N R5, ??u32DummyRead */
351 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
352 0x36, 0x68, /* LDR R6, [R6] */
353 0x2E, 0x60, /* STR R6, [R5] */
354 /* u32FlashResult = FLASH_WRITE_NO_RESULT */
355 0x26, 0x4D, /* LDR.N R5, ??u32FlashResult */
356 0x00, 0x26, /* MOVS R6, #0 */
357 0x2E, 0x60, /* STR R6, [R5] */
358 /* while ((u32Count > 0 ) */
359 /* && (u32FlashResult */
360 /* == FLASH_WRITE_NO_RESULT)) */
361 0x01, 0x2A, /* L0: CMP R2, #1 */
362 0x2C, 0xDB, /* BLT.N L1 */
363 0x24, 0x4D, /* LDR.N R5, ??u32FlashResult */
364 0x2D, 0x68, /* LDR R5, [R5] */
365 0x00, 0x2D, /* CMP R5, #0 */
366 0x28, 0xD1, /* BNE.N L1 */
367 /* *u32FlashSeq1 = FLASH_WRITE_1; */
368 0xAA, 0x25, /* MOVS R5, #0xAA */
369 0x1D, 0x60, /* STR R5, [R3] */
370 /* *u32FlashSeq2 = FLASH_WRITE_2; */
371 0x55, 0x25, /* MOVS R5, #0x55 */
372 0x25, 0x60, /* STR R5, [R4] */
373 /* *u32FlashSeq1 = FLASH_WRITE_3; */
374 0xA0, 0x25, /* MOVS R5, #0xA0 */
375 0x1D, 0x60, /* STRH R5, [R3] */
376 /* *(volatile uint16_t*)u32Target */
377 /* = *(volatile uint16_t*)u32Source; */
378 0x05, 0x88, /* LDRH R5, [R0] */
379 0x0D, 0x80, /* STRH R5, [R1] */
380 /* while (u32FlashResult */
381 /* == FLASH_WRITE_NO_RESTULT) */
382 0x1E, 0x4D, /* L2: LDR.N R5, ??u32FlashResult */
383 0x2D, 0x68, /* LDR R5, [R5] */
384 0x00, 0x2D, /* CMP R5, #0 */
385 0x11, 0xD1, /* BNE.N L3 */
386 /* if ((*(volatile uint16_t*)u32Target */
387 /* & FLASH_DQ5) == FLASH_DQ5) */
388 0x0D, 0x88, /* LDRH R5, [R1] */
389 0xAD, 0x06, /* LSLS R5, R5, #0x1A */
390 0x02, 0xD5, /* BPL.N L4 */
391 /* u32FlashResult = FLASH_WRITE_TIMEOUT */
392 0x1A, 0x4D, /* LDR.N R5, ??u32FlashResult */
393 0x02, 0x26, /* MOVS R6, #2 */
394 0x2E, 0x60, /* STR R6, [R5] */
395 /* if ((*(volatile uint16_t *)u32Target */
397 /* == (*(volatile uint16_t*)u32Source */
399 0x0D, 0x88, /* L4: LDRH R5, [R1] */
400 0x15, 0xF0, 0x80, 0x05, /* ANDS.W R5, R5, #0x80 */
401 0x06, 0x88, /* LDRH R6, [R0] */
402 0x16, 0xF0, 0x80, 0x06, /* ANDS.W R6, R6, #0x80 */
403 0xB5, 0x42, /* CMP R5, R6 */
404 0xED, 0xD1, /* BNE.N L2 */
405 /* u32FlashResult = FLASH_WRITE_OKAY */
406 0x15, 0x4D, /* LDR.N R5, ??u32FlashResult */
407 0x01, 0x26, /* MOVS R6, #1 */
408 0x2E, 0x60, /* STR R6, [R5] */
409 0xE9, 0xE7, /* B.N L2 */
410 /* if (u32FlashResult */
411 /* != FLASH_WRITE_TIMEOUT) */
412 0x13, 0x4D, /* LDR.N R5, ??u32FlashResult */
413 0x2D, 0x68, /* LDR R5, [R5] */
414 0x02, 0x2D, /* CMP R5, #2 */
415 0x02, 0xD0, /* BEQ.N L5 */
416 /* u32FlashResult = FLASH_WRITE_NO_RESULT */
417 0x11, 0x4D, /* LDR.N R5, ??u32FlashResult */
418 0x00, 0x26, /* MOVS R6, #0 */
419 0x2E, 0x60, /* STR R6, [R5] */
421 0x52, 0x1E, /* L5: SUBS R2, R2, #1 */
422 /* u32Source += 2; */
423 0x80, 0x1C, /* ADDS R0, R0, #2 */
424 /* u32Target += 2; */
425 0x89, 0x1C, /* ADDS R1, R1, #2 */
426 0xD0, 0xE7, /* B.N L0 */
427 /* fm3_FLASH_IF->FASZ &= 0xFFFE; */
428 0x5F, 0xF0, 0x80, 0x45, /* L1: MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
429 0x2D, 0x68, /* LDR R5, [R5] */
430 0x4F, 0xF6, 0xFE, 0x76, /* MOVW R6, #0xFFFE */
431 0x35, 0x40, /* ANDS R5, R5, R6 */
432 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
433 0x35, 0x60, /* STR R5, [R6] */
434 /* fm3_FLASH_IF->FASZ |= 2; */
435 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
436 0x2D, 0x68, /* LDR R5, [R5] */
437 0x55, 0xF0, 0x02, 0x05, /* ORRS.W R5, R5, #2 */
438 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
439 0x35, 0x60, /* STR R5, [R6] */
440 /* u32DummyRead = fm3_FLASH_IF->FASZ; */
441 0x04, 0x4D, /* LDR.N R5, ??u32DummyRead */
442 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
443 0x36, 0x68, /* LDR R6, [R6] */
444 0x2E, 0x60, /* STR R6, [R5] */
445 /* copy u32FlashResult to R3 for return */
447 0xDF, 0xF8, 0x08, 0x50, /* LDR.W R5, ??u32FlashResult */
448 0x2D, 0x68, /* LDR R5, [R5] */
449 /* Breakpoint here */
450 0x00, 0xBE, /* BKPT #0 */
452 /* The following address pointers assume, that the code is running from */
453 /* SRAM basic-address + 8.These address pointers will be patched, if a */
454 /* different start address in RAM is used (e.g. for Flash type 2)! */
455 /* Default SRAM basic-address is 0x20000000. */
456 0x00, 0x00, 0x00, 0x20, /* u32DummyRead address in RAM (0x20000000) */
457 0x04, 0x00, 0x00, 0x20 /* u32FlashResult address in RAM (0x20000004) */
460 LOG_INFO("Fujitsu MB9[A/B]FXXX: FLASH Write ...");
462 /* disable HW watchdog */
463 retval
= target_write_u32(target
, 0x40011C00, 0x1ACCE551);
464 if (retval
!= ERROR_OK
)
467 retval
= target_write_u32(target
, 0x40011C00, 0xE5331AAE);
468 if (retval
!= ERROR_OK
)
471 retval
= target_write_u32(target
, 0x40011008, 0x00000000);
472 if (retval
!= ERROR_OK
)
475 count
= count
/ 2; /* number bytes -> number halfwords */
477 /* check code alignment */
479 LOG_WARNING("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
480 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
483 /* allocate working area and variables with flash programming code */
484 if (target_alloc_working_area(target
, sizeof(fm3_flash_write_code
) + 8,
485 &write_algorithm
) != ERROR_OK
) {
486 LOG_WARNING("no working area available, can't do block memory writes");
487 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
490 retval
= target_write_buffer(target
, write_algorithm
->address
+ 8,
491 sizeof(fm3_flash_write_code
), fm3_flash_write_code
);
492 if (retval
!= ERROR_OK
)
495 /* Patching 'local variable address' */
496 /* Algorithm: u32DummyRead: */
497 retval
= target_write_u32(target
, (write_algorithm
->address
+ 8)
498 + sizeof(fm3_flash_write_code
) - 8, (write_algorithm
->address
));
499 if (retval
!= ERROR_OK
)
501 /* Algorithm: u32FlashResult: */
502 retval
= target_write_u32(target
, (write_algorithm
->address
+ 8)
503 + sizeof(fm3_flash_write_code
) - 4, (write_algorithm
->address
) + 4);
504 if (retval
!= ERROR_OK
)
510 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
) {
512 if (buffer_size
<= 256) {
513 /* free working area, write algorithm already allocated */
514 target_free_working_area(target
, write_algorithm
);
516 LOG_WARNING("No large enough working area available, can't do block memory writes");
517 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
521 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
522 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
524 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
); /* source start address */
525 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* target start address */
526 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* number of halfwords to program */
527 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
); /* Flash Sequence address 1 */
528 init_reg_param(®_params
[4], "r4", 32, PARAM_OUT
); /* Flash Sequence address 1 */
529 init_reg_param(®_params
[5], "r5", 32, PARAM_IN
); /* result */
531 /* write code buffer and use Flash programming code within fm3 */
532 /* Set breakpoint to 0 with time-out of 1000 ms */
534 uint32_t thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
536 retval
= target_write_buffer(target
, source
->address
, thisrun_count
* 2, buffer
);
537 if (retval
!= ERROR_OK
)
540 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
541 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
542 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
543 buf_set_u32(reg_params
[3].value
, 0, 32, u32FlashSeqAddress1
);
544 buf_set_u32(reg_params
[4].value
, 0, 32, u32FlashSeqAddress2
);
546 retval
= target_run_algorithm(target
, 0, NULL
, 6, reg_params
,
547 (write_algorithm
->address
+ 8), 0, 1000, &armv7m_info
);
548 if (retval
!= ERROR_OK
) {
549 LOG_ERROR("Error executing fm3 Flash programming algorithm");
550 retval
= ERROR_FLASH_OPERATION_FAILED
;
554 if (buf_get_u32(reg_params
[5].value
, 0, 32) != ERROR_OK
) {
555 LOG_ERROR("Fujitsu MB9[A/B]FXXX: Flash programming ERROR (Timeout) -> Reg R3: %" PRIx32
,
556 buf_get_u32(reg_params
[5].value
, 0, 32));
557 retval
= ERROR_FLASH_OPERATION_FAILED
;
561 buffer
+= thisrun_count
* 2;
562 address
+= thisrun_count
* 2;
563 count
-= thisrun_count
;
566 target_free_working_area(target
, source
);
567 target_free_working_area(target
, write_algorithm
);
569 destroy_reg_param(®_params
[0]);
570 destroy_reg_param(®_params
[1]);
571 destroy_reg_param(®_params
[2]);
572 destroy_reg_param(®_params
[3]);
573 destroy_reg_param(®_params
[4]);
574 destroy_reg_param(®_params
[5]);
579 static int fm3_probe(struct flash_bank
*bank
)
581 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
584 if (bank
->target
->state
!= TARGET_HALTED
) {
585 LOG_ERROR("Target not halted");
586 return ERROR_TARGET_NOT_HALTED
;
590 -- page-- start -- blocksize - mpu - totalFlash --
593 page2 0x08000 96k ___ fxx3 128k Flash
594 page3 0x20000 128k ___ fxx4 256k Flash
595 page4 0x40000 128k ___ fxx5 384k Flash
596 page5 0x60000 128k ___ fxx6 512k Flash
597 -----------------------
599 page7 0xa0000 128k ___ fxx7 256k Flash
601 page9 0xe0000 128k ___ fxx8 256k Flash
604 num_pages
= 10; /* max number of Flash pages for malloc */
605 fm3_info
->probed
= 0;
607 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_pages
);
608 bank
->base
= 0x00000000;
609 bank
->size
= 32 * 1024; /* bytes */
611 bank
->sectors
[0].offset
= 0;
612 bank
->sectors
[0].size
= 16 * 1024;
613 bank
->sectors
[0].is_erased
= -1;
614 bank
->sectors
[0].is_protected
= -1;
616 bank
->sectors
[1].offset
= 0x4000;
617 bank
->sectors
[1].size
= 16 * 1024;
618 bank
->sectors
[1].is_erased
= -1;
619 bank
->sectors
[1].is_protected
= -1;
621 if ((fm3_info
->variant
== mb9bfxx1
)
622 || (fm3_info
->variant
== mb9afxx1
)) {
624 bank
->size
= 64 * 1024; /* bytes */
625 bank
->num_sectors
= num_pages
;
627 bank
->sectors
[2].offset
= 0x8000;
628 bank
->sectors
[2].size
= 32 * 1024;
629 bank
->sectors
[2].is_erased
= -1;
630 bank
->sectors
[2].is_protected
= -1;
633 if ((fm3_info
->variant
== mb9bfxx2
)
634 || (fm3_info
->variant
== mb9bfxx4
)
635 || (fm3_info
->variant
== mb9bfxx5
)
636 || (fm3_info
->variant
== mb9bfxx6
)
637 || (fm3_info
->variant
== mb9bfxx7
)
638 || (fm3_info
->variant
== mb9bfxx8
)
639 || (fm3_info
->variant
== mb9afxx2
)
640 || (fm3_info
->variant
== mb9afxx4
)
641 || (fm3_info
->variant
== mb9afxx5
)
642 || (fm3_info
->variant
== mb9afxx6
)
643 || (fm3_info
->variant
== mb9afxx7
)
644 || (fm3_info
->variant
== mb9afxx8
)) {
646 bank
->size
= 128 * 1024; /* bytes */
647 bank
->num_sectors
= num_pages
;
649 bank
->sectors
[2].offset
= 0x8000;
650 bank
->sectors
[2].size
= 96 * 1024;
651 bank
->sectors
[2].is_erased
= -1;
652 bank
->sectors
[2].is_protected
= -1;
655 if ((fm3_info
->variant
== mb9bfxx4
)
656 || (fm3_info
->variant
== mb9bfxx5
)
657 || (fm3_info
->variant
== mb9bfxx6
)
658 || (fm3_info
->variant
== mb9bfxx7
)
659 || (fm3_info
->variant
== mb9bfxx8
)
660 || (fm3_info
->variant
== mb9afxx4
)
661 || (fm3_info
->variant
== mb9afxx5
)
662 || (fm3_info
->variant
== mb9afxx6
)
663 || (fm3_info
->variant
== mb9afxx7
)
664 || (fm3_info
->variant
== mb9afxx8
)) {
666 bank
->size
= 256 * 1024; /* bytes */
667 bank
->num_sectors
= num_pages
;
669 bank
->sectors
[3].offset
= 0x20000;
670 bank
->sectors
[3].size
= 128 * 1024;
671 bank
->sectors
[3].is_erased
= -1;
672 bank
->sectors
[3].is_protected
= -1;
675 if ((fm3_info
->variant
== mb9bfxx5
)
676 || (fm3_info
->variant
== mb9bfxx6
)
677 || (fm3_info
->variant
== mb9bfxx7
)
678 || (fm3_info
->variant
== mb9bfxx8
)
679 || (fm3_info
->variant
== mb9afxx5
)
680 || (fm3_info
->variant
== mb9afxx6
)
681 || (fm3_info
->variant
== mb9afxx7
)
682 || (fm3_info
->variant
== mb9afxx8
)) {
684 bank
->size
= 384 * 1024; /* bytes */
685 bank
->num_sectors
= num_pages
;
687 bank
->sectors
[4].offset
= 0x40000;
688 bank
->sectors
[4].size
= 128 * 1024;
689 bank
->sectors
[4].is_erased
= -1;
690 bank
->sectors
[4].is_protected
= -1;
693 if ((fm3_info
->variant
== mb9bfxx6
)
694 || (fm3_info
->variant
== mb9bfxx7
)
695 || (fm3_info
->variant
== mb9bfxx8
)
696 || (fm3_info
->variant
== mb9afxx6
)
697 || (fm3_info
->variant
== mb9afxx7
)
698 || (fm3_info
->variant
== mb9afxx8
)) {
700 bank
->size
= 512 * 1024; /* bytes */
701 bank
->num_sectors
= num_pages
;
703 bank
->sectors
[5].offset
= 0x60000;
704 bank
->sectors
[5].size
= 128 * 1024;
705 bank
->sectors
[5].is_erased
= -1;
706 bank
->sectors
[5].is_protected
= -1;
709 if ((fm3_info
->variant
== mb9bfxx7
)
710 || (fm3_info
->variant
== mb9bfxx8
)
711 || (fm3_info
->variant
== mb9afxx7
)
712 || (fm3_info
->variant
== mb9afxx8
)) {
714 bank
->size
= 768 * 1024; /* bytes */
715 bank
->num_sectors
= num_pages
;
717 bank
->sectors
[6].offset
= 0x80000;
718 bank
->sectors
[6].size
= 128 * 1024;
719 bank
->sectors
[6].is_erased
= -1;
720 bank
->sectors
[6].is_protected
= -1;
722 bank
->sectors
[7].offset
= 0xa0000;
723 bank
->sectors
[7].size
= 128 * 1024;
724 bank
->sectors
[7].is_erased
= -1;
725 bank
->sectors
[7].is_protected
= -1;
728 if ((fm3_info
->variant
== mb9bfxx8
)
729 || (fm3_info
->variant
== mb9afxx8
)) {
731 bank
->size
= 1024 * 1024; /* bytes */
732 bank
->num_sectors
= num_pages
;
734 bank
->sectors
[8].offset
= 0xc0000;
735 bank
->sectors
[8].size
= 128 * 1024;
736 bank
->sectors
[8].is_erased
= -1;
737 bank
->sectors
[8].is_protected
= -1;
739 bank
->sectors
[9].offset
= 0xe0000;
740 bank
->sectors
[9].size
= 128 * 1024;
741 bank
->sectors
[9].is_erased
= -1;
742 bank
->sectors
[9].is_protected
= -1;
745 fm3_info
->probed
= 1;
750 static int fm3_auto_probe(struct flash_bank
*bank
)
752 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
753 if (fm3_info
->probed
)
755 return fm3_probe(bank
);
759 static int fm3_chip_erase(struct flash_bank
*bank
)
761 struct target
*target
= bank
->target
;
762 struct fm3_flash_bank
*fm3_info2
= bank
->driver_priv
;
763 int retval
= ERROR_OK
;
764 uint32_t u32DummyRead
;
765 uint32_t u32FlashType
;
766 uint32_t u32FlashSeqAddress1
;
767 uint32_t u32FlashSeqAddress2
;
769 u32FlashType
= (uint32_t) fm3_info2
->flashtype
;
771 if (u32FlashType
== fm3_flash_type1
) {
772 LOG_INFO("*** Erasing mb9bfxxx type");
773 u32FlashSeqAddress1
= 0x00001550;
774 u32FlashSeqAddress2
= 0x00000AA8;
775 } else if (u32FlashType
== fm3_flash_type2
) {
776 LOG_INFO("*** Erasing mb9afxxx type");
777 u32FlashSeqAddress1
= 0x00000AA8;
778 u32FlashSeqAddress2
= 0x00000554;
780 LOG_ERROR("Flash/Device type unknown!");
781 return ERROR_FLASH_OPERATION_FAILED
;
784 if (target
->state
!= TARGET_HALTED
) {
785 LOG_ERROR("Target not halted");
786 return ERROR_TARGET_NOT_HALTED
;
789 LOG_INFO("Fujitsu MB9[A/B]xxx: Chip Erase ... (may take several seconds)");
791 /* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash access) */
792 retval
= target_write_u32(target
, 0x40000000, 0x0001);
793 if (retval
!= ERROR_OK
)
796 /* dummy read of FASZR */
797 retval
= target_read_u32(target
, 0x40000000, &u32DummyRead
);
798 if (retval
!= ERROR_OK
)
801 /* Flash unlock sequence */
802 retval
= target_write_u16(target
, u32FlashSeqAddress1
, 0x00AA);
803 if (retval
!= ERROR_OK
)
806 retval
= target_write_u16(target
, u32FlashSeqAddress2
, 0x0055);
807 if (retval
!= ERROR_OK
)
810 retval
= target_write_u16(target
, u32FlashSeqAddress1
, 0x0080);
811 if (retval
!= ERROR_OK
)
814 retval
= target_write_u16(target
, u32FlashSeqAddress1
, 0x00AA);
815 if (retval
!= ERROR_OK
)
818 retval
= target_write_u16(target
, u32FlashSeqAddress2
, 0x0055);
819 if (retval
!= ERROR_OK
)
822 /* Chip Erase command (0x0010) */
823 retval
= target_write_u16(target
, u32FlashSeqAddress1
, 0x0010);
824 if (retval
!= ERROR_OK
)
827 retval
= fm3_busy_wait(target
, u32FlashSeqAddress2
, 20000); /* 20s timeout */
828 if (retval
!= ERROR_OK
)
831 /* FASZR = 0x02, Re-enables CPU Run Mode (32-bit Flash access) */
832 retval
= target_write_u32(target
, 0x40000000, 0x0002);
833 if (retval
!= ERROR_OK
)
836 retval
= target_read_u32(target
, 0x40000000, &u32DummyRead
); /* dummy read of FASZR */
841 COMMAND_HANDLER(fm3_handle_chip_erase_command
)
846 return ERROR_COMMAND_SYNTAX_ERROR
;
848 struct flash_bank
*bank
;
849 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
850 if (ERROR_OK
!= retval
)
853 if (fm3_chip_erase(bank
) == ERROR_OK
) {
854 /* set all sectors as erased */
855 for (i
= 0; i
< bank
->num_sectors
; i
++)
856 bank
->sectors
[i
].is_erased
= 1;
858 command_print(CMD_CTX
, "fm3 chip erase complete");
860 command_print(CMD_CTX
, "fm3 chip erase failed");
866 static const struct command_registration fm3_exec_command_handlers
[] = {
868 .name
= "chip_erase",
870 .handler
= fm3_handle_chip_erase_command
,
871 .mode
= COMMAND_EXEC
,
872 .help
= "Erase entire Flash device.",
874 COMMAND_REGISTRATION_DONE
877 static const struct command_registration fm3_command_handlers
[] = {
881 .help
= "fm3 Flash command group",
883 .chain
= fm3_exec_command_handlers
,
885 COMMAND_REGISTRATION_DONE
888 struct flash_driver fm3_flash
= {
890 .commands
= fm3_command_handlers
,
891 .flash_bank_command
= fm3_flash_bank_command
,
893 .write
= fm3_write_block
,
895 .auto_probe
= fm3_auto_probe
,
896 .erase_check
= default_flash_blank_check
,
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)