1 /***************************************************************************
2 * Copyright (C) 2011 by Marc Willam, Holger Wech *
3 * openOCD.fseu(AT)de.fujitsu.com *
4 * Copyright (C) 2011 Ronny Strutz *
6 * Copyright (C) 2013 Nemui Trinomius *
7 * nemuisan_kawausogasuki@live.jp *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
21 ***************************************************************************/
28 #include <helper/binarybuffer.h>
29 #include <target/algorithm.h>
30 #include <target/armv7m.h>
32 #define FLASH_DQ6 0x40 /* Data toggle flag bit (TOGG) position */
33 #define FLASH_DQ5 0x20 /* Time limit exceeding flag bit (TLOV) position */
36 MB9BFXX1
, /* Flash Type '1' */
45 MB9AFXX1
, /* Flash Type '2' */
56 FM3_NO_FLASH_TYPE
= 0,
61 struct fm3_flash_bank
{
62 enum fm3_variant variant
;
63 enum fm3_flash_type flashtype
;
67 FLASH_BANK_COMMAND_HANDLER(fm3_flash_bank_command
)
69 struct fm3_flash_bank
*fm3_info
;
72 return ERROR_COMMAND_SYNTAX_ERROR
;
74 fm3_info
= malloc(sizeof(struct fm3_flash_bank
));
75 bank
->driver_priv
= fm3_info
;
78 if (strcmp(CMD_ARGV
[5], "mb9bfxx1.cpu") == 0) {
79 fm3_info
->variant
= MB9BFXX1
;
80 fm3_info
->flashtype
= FM3_FLASH_TYPE1
;
81 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx2.cpu") == 0) {
82 fm3_info
->variant
= MB9BFXX2
;
83 fm3_info
->flashtype
= FM3_FLASH_TYPE1
;
84 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx3.cpu") == 0) {
85 fm3_info
->variant
= MB9BFXX3
;
86 fm3_info
->flashtype
= FM3_FLASH_TYPE1
;
87 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx4.cpu") == 0) {
88 fm3_info
->variant
= MB9BFXX4
;
89 fm3_info
->flashtype
= FM3_FLASH_TYPE1
;
90 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx5.cpu") == 0) {
91 fm3_info
->variant
= MB9BFXX5
;
92 fm3_info
->flashtype
= FM3_FLASH_TYPE1
;
93 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx6.cpu") == 0) {
94 fm3_info
->variant
= MB9BFXX6
;
95 fm3_info
->flashtype
= FM3_FLASH_TYPE1
;
96 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx7.cpu") == 0) {
97 fm3_info
->variant
= MB9BFXX7
;
98 fm3_info
->flashtype
= FM3_FLASH_TYPE1
;
99 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx8.cpu") == 0) {
100 fm3_info
->variant
= MB9BFXX8
;
101 fm3_info
->flashtype
= FM3_FLASH_TYPE1
;
102 } else if (strcmp(CMD_ARGV
[5], "mb9afxx1.cpu") == 0) { /* Flash type '2' */
103 fm3_info
->variant
= MB9AFXX1
;
104 fm3_info
->flashtype
= FM3_FLASH_TYPE2
;
105 } else if (strcmp(CMD_ARGV
[5], "mb9afxx2.cpu") == 0) {
106 fm3_info
->variant
= MB9AFXX2
;
107 fm3_info
->flashtype
= FM3_FLASH_TYPE2
;
108 } else if (strcmp(CMD_ARGV
[5], "mb9afxx3.cpu") == 0) {
109 fm3_info
->variant
= MB9AFXX3
;
110 fm3_info
->flashtype
= FM3_FLASH_TYPE2
;
111 } else if (strcmp(CMD_ARGV
[5], "mb9afxx4.cpu") == 0) {
112 fm3_info
->variant
= MB9AFXX4
;
113 fm3_info
->flashtype
= FM3_FLASH_TYPE2
;
114 } else if (strcmp(CMD_ARGV
[5], "mb9afxx5.cpu") == 0) {
115 fm3_info
->variant
= MB9AFXX5
;
116 fm3_info
->flashtype
= FM3_FLASH_TYPE2
;
117 } else if (strcmp(CMD_ARGV
[5], "mb9afxx6.cpu") == 0) {
118 fm3_info
->variant
= MB9AFXX6
;
119 fm3_info
->flashtype
= FM3_FLASH_TYPE2
;
120 } else if (strcmp(CMD_ARGV
[5], "mb9afxx7.cpu") == 0) {
121 fm3_info
->variant
= MB9AFXX7
;
122 fm3_info
->flashtype
= FM3_FLASH_TYPE2
;
123 } else if (strcmp(CMD_ARGV
[5], "mb9afxx8.cpu") == 0) {
124 fm3_info
->variant
= MB9AFXX8
;
125 fm3_info
->flashtype
= FM3_FLASH_TYPE2
;
128 /* unknown Flash type */
130 LOG_ERROR("unknown fm3 variant: %s", CMD_ARGV
[5]);
132 return ERROR_FLASH_BANK_INVALID
;
135 fm3_info
->probed
= false;
140 /* Data polling algorithm */
141 static int fm3_busy_wait(struct target
*target
, uint32_t offset
, int timeout_ms
)
143 int retval
= ERROR_OK
;
144 uint8_t state1
, state2
;
147 /* While(1) loop exit via "break" and "return" on error */
149 /* dummy-read - see flash manual */
150 retval
= target_read_u8(target
, offset
, &state1
);
151 if (retval
!= ERROR_OK
)
155 retval
= target_read_u8(target
, offset
, &state1
);
156 if (retval
!= ERROR_OK
)
160 retval
= target_read_u8(target
, offset
, &state2
);
161 if (retval
!= ERROR_OK
)
164 /* Flash command finished via polled data equal? */
165 if ((state1
& FLASH_DQ6
) == (state2
& FLASH_DQ6
))
168 else if (state1
& FLASH_DQ5
) {
169 /* Retry data polling */
172 retval
= target_read_u8(target
, offset
, &state1
);
173 if (retval
!= ERROR_OK
)
177 retval
= target_read_u8(target
, offset
, &state2
);
178 if (retval
!= ERROR_OK
)
181 /* Flash command finished via polled data equal? */
182 if ((state1
& FLASH_DQ6
) != (state2
& FLASH_DQ6
))
183 return ERROR_FLASH_OPERATION_FAILED
;
191 /* Polling time exceeded? */
192 if (ms
> timeout_ms
) {
193 LOG_ERROR("Polling data reading timed out!");
194 return ERROR_FLASH_OPERATION_FAILED
;
198 if (retval
== ERROR_OK
)
199 LOG_DEBUG("fm3_busy_wait(%" PRIx32
") needs about %d ms", offset
, ms
);
204 static int fm3_erase(struct flash_bank
*bank
, unsigned int first
,
207 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
208 struct target
*target
= bank
->target
;
209 int retval
= ERROR_OK
;
210 uint32_t u32_dummy_read
;
212 uint32_t u32_flash_type
;
213 uint32_t u32_flash_seq_address1
;
214 uint32_t u32_flash_seq_address2
;
216 struct working_area
*write_algorithm
;
217 struct reg_param reg_params
[3];
218 struct armv7m_algorithm armv7m_info
;
220 u32_flash_type
= (uint32_t) fm3_info
->flashtype
;
222 if (u32_flash_type
== FM3_FLASH_TYPE1
) {
223 u32_flash_seq_address1
= 0x00001550;
224 u32_flash_seq_address2
= 0x00000AA8;
225 } else if (u32_flash_type
== FM3_FLASH_TYPE2
) {
226 u32_flash_seq_address1
= 0x00000AA8;
227 u32_flash_seq_address2
= 0x00000554;
229 LOG_ERROR("Flash/Device type unknown!");
230 return ERROR_FLASH_OPERATION_FAILED
;
233 if (target
->state
!= TARGET_HALTED
) {
234 LOG_ERROR("Target not halted");
235 return ERROR_TARGET_NOT_HALTED
;
238 /* RAMCODE used for fm3 Flash sector erase: */
239 /* R0 keeps Flash Sequence address 1 (u32FlashSeq1) */
240 /* R1 keeps Flash Sequence address 2 (u32FlashSeq2) */
241 /* R2 keeps Flash Offset address (ofs) */
242 static const uint8_t fm3_flash_erase_sector_code
[] = {
243 /* *(uint16_t*)u32FlashSeq1 = 0xAA; */
244 0xAA, 0x24, /* MOVS R4, #0xAA */
245 0x04, 0x80, /* STRH R4, [R0, #0] */
246 /* *(uint16_t*)u32FlashSeq2 = 0x55; */
247 0x55, 0x23, /* MOVS R3, #0x55 */
248 0x0B, 0x80, /* STRH R3, [R1, #0] */
249 /* *(uint16_t*)u32FlashSeq1 = 0x80; */
250 0x80, 0x25, /* MOVS R5, #0x80 */
251 0x05, 0x80, /* STRH R5, [R0, #0] */
252 /* *(uint16_t*)u32FlashSeq1 = 0xAA; */
253 0x04, 0x80, /* STRH R4, [R0, #0] */
254 /* *(uint16_t*)u32FlashSeq2 = 0x55; */
255 0x0B, 0x80, /* STRH R3, [R1, #0] */
256 /* Sector_Erase Command (0x30) */
257 /* *(uint16_t*)ofs = 0x30; */
258 0x30, 0x20, /* MOVS R0, #0x30 */
259 0x10, 0x80, /* STRH R0, [R2, #0] */
261 0x00, 0xBE, /* BKPT #0 */
264 LOG_INFO("Fujitsu MB9[A/B]FXXX: Sector Erase ... (%u to %u)", first
, last
);
266 /* disable HW watchdog */
267 retval
= target_write_u32(target
, 0x40011C00, 0x1ACCE551);
268 if (retval
!= ERROR_OK
)
271 retval
= target_write_u32(target
, 0x40011C00, 0xE5331AAE);
272 if (retval
!= ERROR_OK
)
275 retval
= target_write_u32(target
, 0x40011008, 0x00000000);
276 if (retval
!= ERROR_OK
)
279 /* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash access) */
280 retval
= target_write_u32(target
, 0x40000000, 0x0001);
281 if (retval
!= ERROR_OK
)
284 /* dummy read of FASZR */
285 retval
= target_read_u32(target
, 0x40000000, &u32_dummy_read
);
286 if (retval
!= ERROR_OK
)
289 /* allocate working area with flash sector erase code */
290 if (target_alloc_working_area(target
, sizeof(fm3_flash_erase_sector_code
),
291 &write_algorithm
) != ERROR_OK
) {
292 LOG_WARNING("no working area available, can't do block memory writes");
293 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
295 retval
= target_write_buffer(target
, write_algorithm
->address
,
296 sizeof(fm3_flash_erase_sector_code
), fm3_flash_erase_sector_code
);
297 if (retval
!= ERROR_OK
)
300 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
301 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
303 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
); /* u32_flash_seq_address1 */
304 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* u32_flash_seq_address2 */
305 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* offset */
307 /* write code buffer and use Flash sector erase code within fm3 */
308 for (unsigned int sector
= first
; sector
<= last
; sector
++) {
309 uint32_t offset
= bank
->sectors
[sector
].offset
;
311 for (odd
= 0; odd
< 2 ; odd
++) {
315 buf_set_u32(reg_params
[0].value
, 0, 32, u32_flash_seq_address1
);
316 buf_set_u32(reg_params
[1].value
, 0, 32, u32_flash_seq_address2
);
317 buf_set_u32(reg_params
[2].value
, 0, 32, offset
);
319 retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
,
320 write_algorithm
->address
, 0, 100000, &armv7m_info
);
321 if (retval
!= ERROR_OK
) {
322 LOG_ERROR("Error executing flash erase programming algorithm");
323 retval
= ERROR_FLASH_OPERATION_FAILED
;
327 retval
= fm3_busy_wait(target
, offset
, 500);
328 if (retval
!= ERROR_OK
)
331 bank
->sectors
[sector
].is_erased
= 1;
334 target_free_working_area(target
, write_algorithm
);
335 destroy_reg_param(®_params
[0]);
336 destroy_reg_param(®_params
[1]);
337 destroy_reg_param(®_params
[2]);
339 /* FASZR = 0x02, Enables CPU Run Mode (32-bit Flash access) */
340 retval
= target_write_u32(target
, 0x40000000, 0x0002);
341 if (retval
!= ERROR_OK
)
344 retval
= target_read_u32(target
, 0x40000000, &u32_dummy_read
); /* dummy read of FASZR */
349 static int fm3_write_block(struct flash_bank
*bank
, const uint8_t *buffer
,
350 uint32_t offset
, uint32_t count
)
352 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
353 struct target
*target
= bank
->target
;
354 uint32_t buffer_size
= 2048; /* Default minimum value */
355 struct working_area
*write_algorithm
;
356 struct working_area
*source
;
357 uint32_t address
= bank
->base
+ offset
;
358 struct reg_param reg_params
[6];
359 struct armv7m_algorithm armv7m_info
;
360 int retval
= ERROR_OK
;
361 uint32_t u32_flash_type
;
362 uint32_t u32_flash_seq_address1
;
363 uint32_t u32_flash_seq_address2
;
365 /* Increase buffer_size if needed */
366 if (buffer_size
< (target
->working_area_size
/ 2))
367 buffer_size
= (target
->working_area_size
/ 2);
369 u32_flash_type
= (uint32_t) fm3_info
->flashtype
;
371 if (u32_flash_type
== FM3_FLASH_TYPE1
) {
372 u32_flash_seq_address1
= 0x00001550;
373 u32_flash_seq_address2
= 0x00000AA8;
374 } else if (u32_flash_type
== FM3_FLASH_TYPE2
) {
375 u32_flash_seq_address1
= 0x00000AA8;
376 u32_flash_seq_address2
= 0x00000554;
378 LOG_ERROR("Flash/Device type unknown!");
379 return ERROR_FLASH_OPERATION_FAILED
;
382 /* RAMCODE used for fm3 Flash programming: */
383 /* R0 keeps source start address (u32Source) */
384 /* R1 keeps target start address (u32Target) */
385 /* R2 keeps number of halfwords to write (u32Count) */
386 /* R3 keeps Flash Sequence address 1 (u32FlashSeq1) */
387 /* R4 keeps Flash Sequence address 2 (u32FlashSeq2) */
388 /* R5 returns result value (u32FlashResult) */
390 static const uint8_t fm3_flash_write_code
[] = {
391 /* fm3_FLASH_IF->FASZ &= 0xFFFD; */
392 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
393 0x2D, 0x68, /* LDR R5, [R5] */
394 0x4F, 0xF6, 0xFD, 0x76, /* MOVW R6, #0xFFFD */
395 0x35, 0x40, /* ANDS R5, R5, R6 */
396 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
397 0x35, 0x60, /* STR R5, [R6] */
398 /* fm3_FLASH_IF->FASZ |= 1; */
399 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
400 0x2D, 0x68, /* LDR R5, [R3] */
401 0x55, 0xF0, 0x01, 0x05, /* ORRS.W R5, R5, #1 */
402 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
403 0x35, 0x60, /* STR R5, [R6] */
404 /* u32_dummy_read = fm3_FLASH_IF->FASZ; */
405 0x28, 0x4D, /* LDR.N R5, ??u32_dummy_read */
406 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
407 0x36, 0x68, /* LDR R6, [R6] */
408 0x2E, 0x60, /* STR R6, [R5] */
409 /* u32FlashResult = FLASH_WRITE_NO_RESULT */
410 0x26, 0x4D, /* LDR.N R5, ??u32FlashResult */
411 0x00, 0x26, /* MOVS R6, #0 */
412 0x2E, 0x60, /* STR R6, [R5] */
413 /* while ((u32Count > 0 ) */
414 /* && (u32FlashResult */
415 /* == FLASH_WRITE_NO_RESULT)) */
416 0x01, 0x2A, /* L0: CMP R2, #1 */
417 0x2C, 0xDB, /* BLT.N L1 */
418 0x24, 0x4D, /* LDR.N R5, ??u32FlashResult */
419 0x2D, 0x68, /* LDR R5, [R5] */
420 0x00, 0x2D, /* CMP R5, #0 */
421 0x28, 0xD1, /* BNE.N L1 */
422 /* *u32FlashSeq1 = FLASH_WRITE_1; */
423 0xAA, 0x25, /* MOVS R5, #0xAA */
424 0x1D, 0x60, /* STR R5, [R3] */
425 /* *u32FlashSeq2 = FLASH_WRITE_2; */
426 0x55, 0x25, /* MOVS R5, #0x55 */
427 0x25, 0x60, /* STR R5, [R4] */
428 /* *u32FlashSeq1 = FLASH_WRITE_3; */
429 0xA0, 0x25, /* MOVS R5, #0xA0 */
430 0x1D, 0x60, /* STRH R5, [R3] */
431 /* *(volatile uint16_t*)u32Target */
432 /* = *(volatile uint16_t*)u32Source; */
433 0x05, 0x88, /* LDRH R5, [R0] */
434 0x0D, 0x80, /* STRH R5, [R1] */
435 /* while (u32FlashResult */
436 /* == FLASH_WRITE_NO_RESTULT) */
437 0x1E, 0x4D, /* L2: LDR.N R5, ??u32FlashResult */
438 0x2D, 0x68, /* LDR R5, [R5] */
439 0x00, 0x2D, /* CMP R5, #0 */
440 0x11, 0xD1, /* BNE.N L3 */
441 /* if ((*(volatile uint16_t*)u32Target */
442 /* & FLASH_DQ5) == FLASH_DQ5) */
443 0x0D, 0x88, /* LDRH R5, [R1] */
444 0xAD, 0x06, /* LSLS R5, R5, #0x1A */
445 0x02, 0xD5, /* BPL.N L4 */
446 /* u32FlashResult = FLASH_WRITE_TIMEOUT */
447 0x1A, 0x4D, /* LDR.N R5, ??u32FlashResult */
448 0x02, 0x26, /* MOVS R6, #2 */
449 0x2E, 0x60, /* STR R6, [R5] */
450 /* if ((*(volatile uint16_t *)u32Target */
452 /* == (*(volatile uint16_t*)u32Source */
454 0x0D, 0x88, /* L4: LDRH R5, [R1] */
455 0x15, 0xF0, 0x80, 0x05, /* ANDS.W R5, R5, #0x80 */
456 0x06, 0x88, /* LDRH R6, [R0] */
457 0x16, 0xF0, 0x80, 0x06, /* ANDS.W R6, R6, #0x80 */
458 0xB5, 0x42, /* CMP R5, R6 */
459 0xED, 0xD1, /* BNE.N L2 */
460 /* u32FlashResult = FLASH_WRITE_OKAY */
461 0x15, 0x4D, /* LDR.N R5, ??u32FlashResult */
462 0x01, 0x26, /* MOVS R6, #1 */
463 0x2E, 0x60, /* STR R6, [R5] */
464 0xE9, 0xE7, /* B.N L2 */
465 /* if (u32FlashResult */
466 /* != FLASH_WRITE_TIMEOUT) */
467 0x13, 0x4D, /* LDR.N R5, ??u32FlashResult */
468 0x2D, 0x68, /* LDR R5, [R5] */
469 0x02, 0x2D, /* CMP R5, #2 */
470 0x02, 0xD0, /* BEQ.N L5 */
471 /* u32FlashResult = FLASH_WRITE_NO_RESULT */
472 0x11, 0x4D, /* LDR.N R5, ??u32FlashResult */
473 0x00, 0x26, /* MOVS R6, #0 */
474 0x2E, 0x60, /* STR R6, [R5] */
476 0x52, 0x1E, /* L5: SUBS R2, R2, #1 */
477 /* u32Source += 2; */
478 0x80, 0x1C, /* ADDS R0, R0, #2 */
479 /* u32Target += 2; */
480 0x89, 0x1C, /* ADDS R1, R1, #2 */
481 0xD0, 0xE7, /* B.N L0 */
482 /* fm3_FLASH_IF->FASZ &= 0xFFFE; */
483 0x5F, 0xF0, 0x80, 0x45, /* L1: MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
484 0x2D, 0x68, /* LDR R5, [R5] */
485 0x4F, 0xF6, 0xFE, 0x76, /* MOVW R6, #0xFFFE */
486 0x35, 0x40, /* ANDS R5, R5, R6 */
487 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
488 0x35, 0x60, /* STR R5, [R6] */
489 /* fm3_FLASH_IF->FASZ |= 2; */
490 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
491 0x2D, 0x68, /* LDR R5, [R5] */
492 0x55, 0xF0, 0x02, 0x05, /* ORRS.W R5, R5, #2 */
493 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
494 0x35, 0x60, /* STR R5, [R6] */
495 /* u32_dummy_read = fm3_FLASH_IF->FASZ; */
496 0x04, 0x4D, /* LDR.N R5, ??u32_dummy_read */
497 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
498 0x36, 0x68, /* LDR R6, [R6] */
499 0x2E, 0x60, /* STR R6, [R5] */
500 /* copy u32FlashResult to R3 for return */
502 0xDF, 0xF8, 0x08, 0x50, /* LDR.W R5, ??u32FlashResult */
503 0x2D, 0x68, /* LDR R5, [R5] */
504 /* Breakpoint here */
505 0x00, 0xBE, /* BKPT #0 */
507 /* The following address pointers assume, that the code is running from */
508 /* SRAM basic-address + 8.These address pointers will be patched, if a */
509 /* different start address in RAM is used (e.g. for Flash type 2)! */
510 /* Default SRAM basic-address is 0x20000000. */
511 0x00, 0x00, 0x00, 0x20, /* u32_dummy_read address in RAM (0x20000000) */
512 0x04, 0x00, 0x00, 0x20 /* u32FlashResult address in RAM (0x20000004) */
515 LOG_INFO("Fujitsu MB9[A/B]FXXX: FLASH Write ...");
517 /* disable HW watchdog */
518 retval
= target_write_u32(target
, 0x40011C00, 0x1ACCE551);
519 if (retval
!= ERROR_OK
)
522 retval
= target_write_u32(target
, 0x40011C00, 0xE5331AAE);
523 if (retval
!= ERROR_OK
)
526 retval
= target_write_u32(target
, 0x40011008, 0x00000000);
527 if (retval
!= ERROR_OK
)
530 count
= count
/ 2; /* number bytes -> number halfwords */
532 /* check code alignment */
534 LOG_WARNING("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
535 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
538 /* allocate working area and variables with flash programming code */
539 if (target_alloc_working_area(target
, sizeof(fm3_flash_write_code
) + 8,
540 &write_algorithm
) != ERROR_OK
) {
541 LOG_WARNING("no working area available, can't do block memory writes");
542 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
545 retval
= target_write_buffer(target
, write_algorithm
->address
+ 8,
546 sizeof(fm3_flash_write_code
), fm3_flash_write_code
);
547 if (retval
!= ERROR_OK
)
550 /* Patching 'local variable address' */
551 /* Algorithm: u32_dummy_read: */
552 retval
= target_write_u32(target
, (write_algorithm
->address
+ 8)
553 + sizeof(fm3_flash_write_code
) - 8, (write_algorithm
->address
));
554 if (retval
!= ERROR_OK
)
556 /* Algorithm: u32FlashResult: */
557 retval
= target_write_u32(target
, (write_algorithm
->address
+ 8)
558 + sizeof(fm3_flash_write_code
) - 4, (write_algorithm
->address
) + 4);
559 if (retval
!= ERROR_OK
)
565 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
) {
567 if (buffer_size
<= 256) {
568 /* free working area, write algorithm already allocated */
569 target_free_working_area(target
, write_algorithm
);
571 LOG_WARNING("No large enough working area available, can't do block memory writes");
572 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
576 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
577 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
579 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
); /* source start address */
580 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* target start address */
581 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* number of halfwords to program */
582 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
); /* Flash Sequence address 1 */
583 init_reg_param(®_params
[4], "r4", 32, PARAM_OUT
); /* Flash Sequence address 1 */
584 init_reg_param(®_params
[5], "r5", 32, PARAM_IN
); /* result */
586 /* write code buffer and use Flash programming code within fm3 */
587 /* Set breakpoint to 0 with time-out of 1000 ms */
589 uint32_t thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
591 retval
= target_write_buffer(target
, source
->address
, thisrun_count
* 2, buffer
);
592 if (retval
!= ERROR_OK
)
595 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
596 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
597 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
598 buf_set_u32(reg_params
[3].value
, 0, 32, u32_flash_seq_address1
);
599 buf_set_u32(reg_params
[4].value
, 0, 32, u32_flash_seq_address2
);
601 retval
= target_run_algorithm(target
, 0, NULL
, 6, reg_params
,
602 (write_algorithm
->address
+ 8), 0, 1000, &armv7m_info
);
603 if (retval
!= ERROR_OK
) {
604 LOG_ERROR("Error executing fm3 Flash programming algorithm");
605 retval
= ERROR_FLASH_OPERATION_FAILED
;
609 if (buf_get_u32(reg_params
[5].value
, 0, 32) != ERROR_OK
) {
610 LOG_ERROR("Fujitsu MB9[A/B]FXXX: Flash programming ERROR (Timeout) -> Reg R3: %" PRIx32
,
611 buf_get_u32(reg_params
[5].value
, 0, 32));
612 retval
= ERROR_FLASH_OPERATION_FAILED
;
616 buffer
+= thisrun_count
* 2;
617 address
+= thisrun_count
* 2;
618 count
-= thisrun_count
;
621 target_free_working_area(target
, source
);
622 target_free_working_area(target
, write_algorithm
);
624 destroy_reg_param(®_params
[0]);
625 destroy_reg_param(®_params
[1]);
626 destroy_reg_param(®_params
[2]);
627 destroy_reg_param(®_params
[3]);
628 destroy_reg_param(®_params
[4]);
629 destroy_reg_param(®_params
[5]);
634 static int fm3_probe(struct flash_bank
*bank
)
636 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
639 if (bank
->target
->state
!= TARGET_HALTED
) {
640 LOG_ERROR("Target not halted");
641 return ERROR_TARGET_NOT_HALTED
;
645 -- page-- start -- blocksize - mpu - totalFlash --
648 page2 0x08000 96k ___ fxx3 128k Flash
649 page3 0x20000 128k ___ fxx4 256k Flash
650 page4 0x40000 128k ___ fxx5 384k Flash
651 page5 0x60000 128k ___ fxx6 512k Flash
652 -----------------------
654 page7 0xa0000 128k ___ fxx7 256k Flash
656 page9 0xe0000 128k ___ fxx8 256k Flash
659 num_pages
= 10; /* max number of Flash pages for malloc */
660 fm3_info
->probed
= false;
662 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_pages
);
663 bank
->base
= 0x00000000;
664 bank
->size
= 32 * 1024; /* bytes */
666 bank
->sectors
[0].offset
= 0;
667 bank
->sectors
[0].size
= 16 * 1024;
668 bank
->sectors
[0].is_erased
= -1;
669 bank
->sectors
[0].is_protected
= -1;
671 bank
->sectors
[1].offset
= 0x4000;
672 bank
->sectors
[1].size
= 16 * 1024;
673 bank
->sectors
[1].is_erased
= -1;
674 bank
->sectors
[1].is_protected
= -1;
676 if ((fm3_info
->variant
== MB9BFXX1
)
677 || (fm3_info
->variant
== MB9AFXX1
)) {
679 bank
->size
= 64 * 1024; /* bytes */
680 bank
->num_sectors
= num_pages
;
682 bank
->sectors
[2].offset
= 0x8000;
683 bank
->sectors
[2].size
= 32 * 1024;
684 bank
->sectors
[2].is_erased
= -1;
685 bank
->sectors
[2].is_protected
= -1;
688 if ((fm3_info
->variant
== MB9BFXX2
)
689 || (fm3_info
->variant
== MB9BFXX4
)
690 || (fm3_info
->variant
== MB9BFXX5
)
691 || (fm3_info
->variant
== MB9BFXX6
)
692 || (fm3_info
->variant
== MB9BFXX7
)
693 || (fm3_info
->variant
== MB9BFXX8
)
694 || (fm3_info
->variant
== MB9AFXX2
)
695 || (fm3_info
->variant
== MB9AFXX4
)
696 || (fm3_info
->variant
== MB9AFXX5
)
697 || (fm3_info
->variant
== MB9AFXX6
)
698 || (fm3_info
->variant
== MB9AFXX7
)
699 || (fm3_info
->variant
== MB9AFXX8
)) {
701 bank
->size
= 128 * 1024; /* bytes */
702 bank
->num_sectors
= num_pages
;
704 bank
->sectors
[2].offset
= 0x8000;
705 bank
->sectors
[2].size
= 96 * 1024;
706 bank
->sectors
[2].is_erased
= -1;
707 bank
->sectors
[2].is_protected
= -1;
710 if ((fm3_info
->variant
== MB9BFXX4
)
711 || (fm3_info
->variant
== MB9BFXX5
)
712 || (fm3_info
->variant
== MB9BFXX6
)
713 || (fm3_info
->variant
== MB9BFXX7
)
714 || (fm3_info
->variant
== MB9BFXX8
)
715 || (fm3_info
->variant
== MB9AFXX4
)
716 || (fm3_info
->variant
== MB9AFXX5
)
717 || (fm3_info
->variant
== MB9AFXX6
)
718 || (fm3_info
->variant
== MB9AFXX7
)
719 || (fm3_info
->variant
== MB9AFXX8
)) {
721 bank
->size
= 256 * 1024; /* bytes */
722 bank
->num_sectors
= num_pages
;
724 bank
->sectors
[3].offset
= 0x20000;
725 bank
->sectors
[3].size
= 128 * 1024;
726 bank
->sectors
[3].is_erased
= -1;
727 bank
->sectors
[3].is_protected
= -1;
730 if ((fm3_info
->variant
== MB9BFXX5
)
731 || (fm3_info
->variant
== MB9BFXX6
)
732 || (fm3_info
->variant
== MB9BFXX7
)
733 || (fm3_info
->variant
== MB9BFXX8
)
734 || (fm3_info
->variant
== MB9AFXX5
)
735 || (fm3_info
->variant
== MB9AFXX6
)
736 || (fm3_info
->variant
== MB9AFXX7
)
737 || (fm3_info
->variant
== MB9AFXX8
)) {
739 bank
->size
= 384 * 1024; /* bytes */
740 bank
->num_sectors
= num_pages
;
742 bank
->sectors
[4].offset
= 0x40000;
743 bank
->sectors
[4].size
= 128 * 1024;
744 bank
->sectors
[4].is_erased
= -1;
745 bank
->sectors
[4].is_protected
= -1;
748 if ((fm3_info
->variant
== MB9BFXX6
)
749 || (fm3_info
->variant
== MB9BFXX7
)
750 || (fm3_info
->variant
== MB9BFXX8
)
751 || (fm3_info
->variant
== MB9AFXX6
)
752 || (fm3_info
->variant
== MB9AFXX7
)
753 || (fm3_info
->variant
== MB9AFXX8
)) {
755 bank
->size
= 512 * 1024; /* bytes */
756 bank
->num_sectors
= num_pages
;
758 bank
->sectors
[5].offset
= 0x60000;
759 bank
->sectors
[5].size
= 128 * 1024;
760 bank
->sectors
[5].is_erased
= -1;
761 bank
->sectors
[5].is_protected
= -1;
764 if ((fm3_info
->variant
== MB9BFXX7
)
765 || (fm3_info
->variant
== MB9BFXX8
)
766 || (fm3_info
->variant
== MB9AFXX7
)
767 || (fm3_info
->variant
== MB9AFXX8
)) {
769 bank
->size
= 768 * 1024; /* bytes */
770 bank
->num_sectors
= num_pages
;
772 bank
->sectors
[6].offset
= 0x80000;
773 bank
->sectors
[6].size
= 128 * 1024;
774 bank
->sectors
[6].is_erased
= -1;
775 bank
->sectors
[6].is_protected
= -1;
777 bank
->sectors
[7].offset
= 0xa0000;
778 bank
->sectors
[7].size
= 128 * 1024;
779 bank
->sectors
[7].is_erased
= -1;
780 bank
->sectors
[7].is_protected
= -1;
783 if ((fm3_info
->variant
== MB9BFXX8
)
784 || (fm3_info
->variant
== MB9AFXX8
)) {
786 bank
->size
= 1024 * 1024; /* bytes */
787 bank
->num_sectors
= num_pages
;
789 bank
->sectors
[8].offset
= 0xc0000;
790 bank
->sectors
[8].size
= 128 * 1024;
791 bank
->sectors
[8].is_erased
= -1;
792 bank
->sectors
[8].is_protected
= -1;
794 bank
->sectors
[9].offset
= 0xe0000;
795 bank
->sectors
[9].size
= 128 * 1024;
796 bank
->sectors
[9].is_erased
= -1;
797 bank
->sectors
[9].is_protected
= -1;
800 fm3_info
->probed
= true;
805 static int fm3_auto_probe(struct flash_bank
*bank
)
807 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
808 if (fm3_info
->probed
)
810 return fm3_probe(bank
);
814 static int fm3_chip_erase(struct flash_bank
*bank
)
816 struct target
*target
= bank
->target
;
817 struct fm3_flash_bank
*fm3_info2
= bank
->driver_priv
;
818 int retval
= ERROR_OK
;
819 uint32_t u32_dummy_read
;
820 uint32_t u32_flash_type
;
821 uint32_t u32_flash_seq_address1
;
822 uint32_t u32_flash_seq_address2
;
824 struct working_area
*write_algorithm
;
825 struct reg_param reg_params
[3];
826 struct armv7m_algorithm armv7m_info
;
828 u32_flash_type
= (uint32_t) fm3_info2
->flashtype
;
830 if (u32_flash_type
== FM3_FLASH_TYPE1
) {
831 LOG_INFO("*** Erasing mb9bfxxx type");
832 u32_flash_seq_address1
= 0x00001550;
833 u32_flash_seq_address2
= 0x00000AA8;
834 } else if (u32_flash_type
== FM3_FLASH_TYPE2
) {
835 LOG_INFO("*** Erasing mb9afxxx type");
836 u32_flash_seq_address1
= 0x00000AA8;
837 u32_flash_seq_address2
= 0x00000554;
839 LOG_ERROR("Flash/Device type unknown!");
840 return ERROR_FLASH_OPERATION_FAILED
;
843 if (target
->state
!= TARGET_HALTED
) {
844 LOG_ERROR("Target not halted");
845 return ERROR_TARGET_NOT_HALTED
;
848 /* RAMCODE used for fm3 Flash chip erase: */
849 /* R0 keeps Flash Sequence address 1 (u32FlashSeq1) */
850 /* R1 keeps Flash Sequence address 2 (u32FlashSeq2) */
851 static const uint8_t fm3_flash_erase_chip_code
[] = {
852 /* *(uint16_t*)u32FlashSeq1 = 0xAA; */
853 0xAA, 0x22, /* MOVS R2, #0xAA */
854 0x02, 0x80, /* STRH R2, [R0, #0] */
855 /* *(uint16_t*)u32FlashSeq2 = 0x55; */
856 0x55, 0x23, /* MOVS R3, #0x55 */
857 0x0B, 0x80, /* STRH R3, [R1, #0] */
858 /* *(uint16_t*)u32FlashSeq1 = 0x80; */
859 0x80, 0x24, /* MOVS R4, #0x80 */
860 0x04, 0x80, /* STRH R4, [R0, #0] */
861 /* *(uint16_t*)u32FlashSeq1 = 0xAA; */
862 0x02, 0x80, /* STRH R2, [R0, #0] */
863 /* *(uint16_t*)u32FlashSeq2 = 0x55; */
864 0x0B, 0x80, /* STRH R3, [R1, #0] */
865 /* Chip_Erase Command 0x10 */
866 /* *(uint16_t*)u32FlashSeq1 = 0x10; */
867 0x10, 0x21, /* MOVS R1, #0x10 */
868 0x01, 0x80, /* STRH R1, [R0, #0] */
870 0x00, 0xBE, /* BKPT #0 */
873 LOG_INFO("Fujitsu MB9[A/B]xxx: Chip Erase ... (may take several seconds)");
875 /* disable HW watchdog */
876 retval
= target_write_u32(target
, 0x40011C00, 0x1ACCE551);
877 if (retval
!= ERROR_OK
)
880 retval
= target_write_u32(target
, 0x40011C00, 0xE5331AAE);
881 if (retval
!= ERROR_OK
)
884 retval
= target_write_u32(target
, 0x40011008, 0x00000000);
885 if (retval
!= ERROR_OK
)
888 /* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash access) */
889 retval
= target_write_u32(target
, 0x40000000, 0x0001);
890 if (retval
!= ERROR_OK
)
893 /* dummy read of FASZR */
894 retval
= target_read_u32(target
, 0x40000000, &u32_dummy_read
);
895 if (retval
!= ERROR_OK
)
898 /* allocate working area with flash chip erase code */
899 if (target_alloc_working_area(target
, sizeof(fm3_flash_erase_chip_code
),
900 &write_algorithm
) != ERROR_OK
) {
901 LOG_WARNING("no working area available, can't do block memory writes");
902 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
904 retval
= target_write_buffer(target
, write_algorithm
->address
,
905 sizeof(fm3_flash_erase_chip_code
), fm3_flash_erase_chip_code
);
906 if (retval
!= ERROR_OK
)
909 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
910 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
912 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
); /* u32_flash_seq_address1 */
913 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* u32_flash_seq_address2 */
915 buf_set_u32(reg_params
[0].value
, 0, 32, u32_flash_seq_address1
);
916 buf_set_u32(reg_params
[1].value
, 0, 32, u32_flash_seq_address2
);
918 retval
= target_run_algorithm(target
, 0, NULL
, 2, reg_params
,
919 write_algorithm
->address
, 0, 100000, &armv7m_info
);
920 if (retval
!= ERROR_OK
) {
921 LOG_ERROR("Error executing flash erase programming algorithm");
922 retval
= ERROR_FLASH_OPERATION_FAILED
;
926 target_free_working_area(target
, write_algorithm
);
928 destroy_reg_param(®_params
[0]);
929 destroy_reg_param(®_params
[1]);
931 retval
= fm3_busy_wait(target
, u32_flash_seq_address2
, 20000); /* 20s timeout */
932 if (retval
!= ERROR_OK
)
935 /* FASZR = 0x02, Re-enables CPU Run Mode (32-bit Flash access) */
936 retval
= target_write_u32(target
, 0x40000000, 0x0002);
937 if (retval
!= ERROR_OK
)
940 retval
= target_read_u32(target
, 0x40000000, &u32_dummy_read
); /* dummy read of FASZR */
945 COMMAND_HANDLER(fm3_handle_chip_erase_command
)
948 return ERROR_COMMAND_SYNTAX_ERROR
;
950 struct flash_bank
*bank
;
951 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
952 if (retval
!= ERROR_OK
)
955 if (fm3_chip_erase(bank
) == ERROR_OK
) {
956 /* set all sectors as erased */
957 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++)
958 bank
->sectors
[i
].is_erased
= 1;
960 command_print(CMD
, "fm3 chip erase complete");
962 command_print(CMD
, "fm3 chip erase failed");
968 static const struct command_registration fm3_exec_command_handlers
[] = {
970 .name
= "chip_erase",
972 .handler
= fm3_handle_chip_erase_command
,
973 .mode
= COMMAND_EXEC
,
974 .help
= "Erase entire Flash device.",
976 COMMAND_REGISTRATION_DONE
979 static const struct command_registration fm3_command_handlers
[] = {
983 .help
= "fm3 Flash command group",
985 .chain
= fm3_exec_command_handlers
,
987 COMMAND_REGISTRATION_DONE
990 const struct flash_driver fm3_flash
= {
992 .commands
= fm3_command_handlers
,
993 .flash_bank_command
= fm3_flash_bank_command
,
995 .write
= fm3_write_block
,
997 .auto_probe
= fm3_auto_probe
,
998 .erase_check
= default_flash_blank_check
,
999 .free_driver_priv
= default_flash_free_driver_priv
,
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)