1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2011 by Marc Willam, Holger Wech *
5 * openOCD.fseu(AT)de.fujitsu.com *
6 * Copyright (C) 2011 Ronny Strutz *
8 * Copyright (C) 2013 Nemui Trinomius *
9 * nemuisan_kawausogasuki@live.jp *
10 ***************************************************************************/
17 #include <helper/binarybuffer.h>
18 #include <target/algorithm.h>
19 #include <target/armv7m.h>
21 #define FLASH_DQ6 0x40 /* Data toggle flag bit (TOGG) position */
22 #define FLASH_DQ5 0x20 /* Time limit exceeding flag bit (TLOV) position */
25 MB9BFXX1
, /* Flash Type '1' */
34 MB9AFXX1
, /* Flash Type '2' */
45 FM3_NO_FLASH_TYPE
= 0,
50 struct fm3_flash_bank
{
51 enum fm3_variant variant
;
52 enum fm3_flash_type flashtype
;
56 FLASH_BANK_COMMAND_HANDLER(fm3_flash_bank_command
)
58 struct fm3_flash_bank
*fm3_info
;
61 return ERROR_COMMAND_SYNTAX_ERROR
;
63 fm3_info
= malloc(sizeof(struct fm3_flash_bank
));
64 bank
->driver_priv
= fm3_info
;
67 if (strcmp(CMD_ARGV
[5], "mb9bfxx1.cpu") == 0) {
68 fm3_info
->variant
= MB9BFXX1
;
69 fm3_info
->flashtype
= FM3_FLASH_TYPE1
;
70 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx2.cpu") == 0) {
71 fm3_info
->variant
= MB9BFXX2
;
72 fm3_info
->flashtype
= FM3_FLASH_TYPE1
;
73 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx3.cpu") == 0) {
74 fm3_info
->variant
= MB9BFXX3
;
75 fm3_info
->flashtype
= FM3_FLASH_TYPE1
;
76 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx4.cpu") == 0) {
77 fm3_info
->variant
= MB9BFXX4
;
78 fm3_info
->flashtype
= FM3_FLASH_TYPE1
;
79 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx5.cpu") == 0) {
80 fm3_info
->variant
= MB9BFXX5
;
81 fm3_info
->flashtype
= FM3_FLASH_TYPE1
;
82 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx6.cpu") == 0) {
83 fm3_info
->variant
= MB9BFXX6
;
84 fm3_info
->flashtype
= FM3_FLASH_TYPE1
;
85 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx7.cpu") == 0) {
86 fm3_info
->variant
= MB9BFXX7
;
87 fm3_info
->flashtype
= FM3_FLASH_TYPE1
;
88 } else if (strcmp(CMD_ARGV
[5], "mb9bfxx8.cpu") == 0) {
89 fm3_info
->variant
= MB9BFXX8
;
90 fm3_info
->flashtype
= FM3_FLASH_TYPE1
;
91 } else if (strcmp(CMD_ARGV
[5], "mb9afxx1.cpu") == 0) { /* Flash type '2' */
92 fm3_info
->variant
= MB9AFXX1
;
93 fm3_info
->flashtype
= FM3_FLASH_TYPE2
;
94 } else if (strcmp(CMD_ARGV
[5], "mb9afxx2.cpu") == 0) {
95 fm3_info
->variant
= MB9AFXX2
;
96 fm3_info
->flashtype
= FM3_FLASH_TYPE2
;
97 } else if (strcmp(CMD_ARGV
[5], "mb9afxx3.cpu") == 0) {
98 fm3_info
->variant
= MB9AFXX3
;
99 fm3_info
->flashtype
= FM3_FLASH_TYPE2
;
100 } else if (strcmp(CMD_ARGV
[5], "mb9afxx4.cpu") == 0) {
101 fm3_info
->variant
= MB9AFXX4
;
102 fm3_info
->flashtype
= FM3_FLASH_TYPE2
;
103 } else if (strcmp(CMD_ARGV
[5], "mb9afxx5.cpu") == 0) {
104 fm3_info
->variant
= MB9AFXX5
;
105 fm3_info
->flashtype
= FM3_FLASH_TYPE2
;
106 } else if (strcmp(CMD_ARGV
[5], "mb9afxx6.cpu") == 0) {
107 fm3_info
->variant
= MB9AFXX6
;
108 fm3_info
->flashtype
= FM3_FLASH_TYPE2
;
109 } else if (strcmp(CMD_ARGV
[5], "mb9afxx7.cpu") == 0) {
110 fm3_info
->variant
= MB9AFXX7
;
111 fm3_info
->flashtype
= FM3_FLASH_TYPE2
;
112 } else if (strcmp(CMD_ARGV
[5], "mb9afxx8.cpu") == 0) {
113 fm3_info
->variant
= MB9AFXX8
;
114 fm3_info
->flashtype
= FM3_FLASH_TYPE2
;
117 /* unknown Flash type */
119 LOG_ERROR("unknown fm3 variant: %s", CMD_ARGV
[5]);
121 return ERROR_FLASH_BANK_INVALID
;
124 fm3_info
->probed
= false;
129 /* Data polling algorithm */
130 static int fm3_busy_wait(struct target
*target
, uint32_t offset
, int timeout_ms
)
132 int retval
= ERROR_OK
;
133 uint8_t state1
, state2
;
136 /* While(1) loop exit via "break" and "return" on error */
138 /* dummy-read - see flash manual */
139 retval
= target_read_u8(target
, offset
, &state1
);
140 if (retval
!= ERROR_OK
)
144 retval
= target_read_u8(target
, offset
, &state1
);
145 if (retval
!= ERROR_OK
)
149 retval
= target_read_u8(target
, offset
, &state2
);
150 if (retval
!= ERROR_OK
)
153 /* Flash command finished via polled data equal? */
154 if ((state1
& FLASH_DQ6
) == (state2
& FLASH_DQ6
))
157 else if (state1
& FLASH_DQ5
) {
158 /* Retry data polling */
161 retval
= target_read_u8(target
, offset
, &state1
);
162 if (retval
!= ERROR_OK
)
166 retval
= target_read_u8(target
, offset
, &state2
);
167 if (retval
!= ERROR_OK
)
170 /* Flash command finished via polled data equal? */
171 if ((state1
& FLASH_DQ6
) != (state2
& FLASH_DQ6
))
172 return ERROR_FLASH_OPERATION_FAILED
;
180 /* Polling time exceeded? */
181 if (ms
> timeout_ms
) {
182 LOG_ERROR("Polling data reading timed out!");
183 return ERROR_FLASH_OPERATION_FAILED
;
187 if (retval
== ERROR_OK
)
188 LOG_DEBUG("fm3_busy_wait(%" PRIx32
") needs about %d ms", offset
, ms
);
193 static int fm3_erase(struct flash_bank
*bank
, unsigned int first
,
196 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
197 struct target
*target
= bank
->target
;
198 int retval
= ERROR_OK
;
199 uint32_t u32_dummy_read
;
201 uint32_t u32_flash_type
;
202 uint32_t u32_flash_seq_address1
;
203 uint32_t u32_flash_seq_address2
;
205 struct working_area
*write_algorithm
;
206 struct reg_param reg_params
[3];
207 struct armv7m_algorithm armv7m_info
;
209 u32_flash_type
= (uint32_t) fm3_info
->flashtype
;
211 if (u32_flash_type
== FM3_FLASH_TYPE1
) {
212 u32_flash_seq_address1
= 0x00001550;
213 u32_flash_seq_address2
= 0x00000AA8;
214 } else if (u32_flash_type
== FM3_FLASH_TYPE2
) {
215 u32_flash_seq_address1
= 0x00000AA8;
216 u32_flash_seq_address2
= 0x00000554;
218 LOG_ERROR("Flash/Device type unknown!");
219 return ERROR_FLASH_OPERATION_FAILED
;
222 if (target
->state
!= TARGET_HALTED
) {
223 LOG_ERROR("Target not halted");
224 return ERROR_TARGET_NOT_HALTED
;
227 /* RAMCODE used for fm3 Flash sector erase: */
228 /* R0 keeps Flash Sequence address 1 (u32FlashSeq1) */
229 /* R1 keeps Flash Sequence address 2 (u32FlashSeq2) */
230 /* R2 keeps Flash Offset address (ofs) */
231 static const uint8_t fm3_flash_erase_sector_code
[] = {
232 /* *(uint16_t*)u32FlashSeq1 = 0xAA; */
233 0xAA, 0x24, /* MOVS R4, #0xAA */
234 0x04, 0x80, /* STRH R4, [R0, #0] */
235 /* *(uint16_t*)u32FlashSeq2 = 0x55; */
236 0x55, 0x23, /* MOVS R3, #0x55 */
237 0x0B, 0x80, /* STRH R3, [R1, #0] */
238 /* *(uint16_t*)u32FlashSeq1 = 0x80; */
239 0x80, 0x25, /* MOVS R5, #0x80 */
240 0x05, 0x80, /* STRH R5, [R0, #0] */
241 /* *(uint16_t*)u32FlashSeq1 = 0xAA; */
242 0x04, 0x80, /* STRH R4, [R0, #0] */
243 /* *(uint16_t*)u32FlashSeq2 = 0x55; */
244 0x0B, 0x80, /* STRH R3, [R1, #0] */
245 /* Sector_Erase Command (0x30) */
246 /* *(uint16_t*)ofs = 0x30; */
247 0x30, 0x20, /* MOVS R0, #0x30 */
248 0x10, 0x80, /* STRH R0, [R2, #0] */
250 0x00, 0xBE, /* BKPT #0 */
253 LOG_INFO("Fujitsu MB9[A/B]FXXX: Sector Erase ... (%u to %u)", first
, last
);
255 /* disable HW watchdog */
256 retval
= target_write_u32(target
, 0x40011C00, 0x1ACCE551);
257 if (retval
!= ERROR_OK
)
260 retval
= target_write_u32(target
, 0x40011C00, 0xE5331AAE);
261 if (retval
!= ERROR_OK
)
264 retval
= target_write_u32(target
, 0x40011008, 0x00000000);
265 if (retval
!= ERROR_OK
)
268 /* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash access) */
269 retval
= target_write_u32(target
, 0x40000000, 0x0001);
270 if (retval
!= ERROR_OK
)
273 /* dummy read of FASZR */
274 retval
= target_read_u32(target
, 0x40000000, &u32_dummy_read
);
275 if (retval
!= ERROR_OK
)
278 /* allocate working area with flash sector erase code */
279 if (target_alloc_working_area(target
, sizeof(fm3_flash_erase_sector_code
),
280 &write_algorithm
) != ERROR_OK
) {
281 LOG_WARNING("no working area available, can't do block memory writes");
282 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
284 retval
= target_write_buffer(target
, write_algorithm
->address
,
285 sizeof(fm3_flash_erase_sector_code
), fm3_flash_erase_sector_code
);
286 if (retval
!= ERROR_OK
)
289 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
290 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
292 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
); /* u32_flash_seq_address1 */
293 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* u32_flash_seq_address2 */
294 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* offset */
296 /* write code buffer and use Flash sector erase code within fm3 */
297 for (unsigned int sector
= first
; sector
<= last
; sector
++) {
298 uint32_t offset
= bank
->sectors
[sector
].offset
;
300 for (odd
= 0; odd
< 2 ; odd
++) {
304 buf_set_u32(reg_params
[0].value
, 0, 32, u32_flash_seq_address1
);
305 buf_set_u32(reg_params
[1].value
, 0, 32, u32_flash_seq_address2
);
306 buf_set_u32(reg_params
[2].value
, 0, 32, offset
);
308 retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
,
309 write_algorithm
->address
, 0, 100000, &armv7m_info
);
310 if (retval
!= ERROR_OK
) {
311 LOG_ERROR("Error executing flash erase programming algorithm");
312 retval
= ERROR_FLASH_OPERATION_FAILED
;
316 retval
= fm3_busy_wait(target
, offset
, 500);
317 if (retval
!= ERROR_OK
)
322 target_free_working_area(target
, write_algorithm
);
323 destroy_reg_param(®_params
[0]);
324 destroy_reg_param(®_params
[1]);
325 destroy_reg_param(®_params
[2]);
327 /* FASZR = 0x02, Enables CPU Run Mode (32-bit Flash access) */
328 retval
= target_write_u32(target
, 0x40000000, 0x0002);
329 if (retval
!= ERROR_OK
)
332 retval
= target_read_u32(target
, 0x40000000, &u32_dummy_read
); /* dummy read of FASZR */
337 static int fm3_write_block(struct flash_bank
*bank
, const uint8_t *buffer
,
338 uint32_t offset
, uint32_t count
)
340 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
341 struct target
*target
= bank
->target
;
342 uint32_t buffer_size
= 2048; /* Default minimum value */
343 struct working_area
*write_algorithm
;
344 struct working_area
*source
;
345 uint32_t address
= bank
->base
+ offset
;
346 struct reg_param reg_params
[6];
347 struct armv7m_algorithm armv7m_info
;
348 int retval
= ERROR_OK
;
349 uint32_t u32_flash_type
;
350 uint32_t u32_flash_seq_address1
;
351 uint32_t u32_flash_seq_address2
;
353 /* Increase buffer_size if needed */
354 if (buffer_size
< (target
->working_area_size
/ 2))
355 buffer_size
= (target
->working_area_size
/ 2);
357 u32_flash_type
= (uint32_t) fm3_info
->flashtype
;
359 if (u32_flash_type
== FM3_FLASH_TYPE1
) {
360 u32_flash_seq_address1
= 0x00001550;
361 u32_flash_seq_address2
= 0x00000AA8;
362 } else if (u32_flash_type
== FM3_FLASH_TYPE2
) {
363 u32_flash_seq_address1
= 0x00000AA8;
364 u32_flash_seq_address2
= 0x00000554;
366 LOG_ERROR("Flash/Device type unknown!");
367 return ERROR_FLASH_OPERATION_FAILED
;
370 /* RAMCODE used for fm3 Flash programming: */
371 /* R0 keeps source start address (u32Source) */
372 /* R1 keeps target start address (u32Target) */
373 /* R2 keeps number of halfwords to write (u32Count) */
374 /* R3 keeps Flash Sequence address 1 (u32FlashSeq1) */
375 /* R4 keeps Flash Sequence address 2 (u32FlashSeq2) */
376 /* R5 returns result value (u32FlashResult) */
378 static const uint8_t fm3_flash_write_code
[] = {
379 /* fm3_FLASH_IF->FASZ &= 0xFFFD; */
380 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
381 0x2D, 0x68, /* LDR R5, [R5] */
382 0x4F, 0xF6, 0xFD, 0x76, /* MOVW R6, #0xFFFD */
383 0x35, 0x40, /* ANDS R5, R5, R6 */
384 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
385 0x35, 0x60, /* STR R5, [R6] */
386 /* fm3_FLASH_IF->FASZ |= 1; */
387 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
388 0x2D, 0x68, /* LDR R5, [R3] */
389 0x55, 0xF0, 0x01, 0x05, /* ORRS.W R5, R5, #1 */
390 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
391 0x35, 0x60, /* STR R5, [R6] */
392 /* u32_dummy_read = fm3_FLASH_IF->FASZ; */
393 0x28, 0x4D, /* LDR.N R5, ??u32_dummy_read */
394 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
395 0x36, 0x68, /* LDR R6, [R6] */
396 0x2E, 0x60, /* STR R6, [R5] */
397 /* u32FlashResult = FLASH_WRITE_NO_RESULT */
398 0x26, 0x4D, /* LDR.N R5, ??u32FlashResult */
399 0x00, 0x26, /* MOVS R6, #0 */
400 0x2E, 0x60, /* STR R6, [R5] */
401 /* while ((u32Count > 0 ) */
402 /* && (u32FlashResult */
403 /* == FLASH_WRITE_NO_RESULT)) */
404 0x01, 0x2A, /* L0: CMP R2, #1 */
405 0x2C, 0xDB, /* BLT.N L1 */
406 0x24, 0x4D, /* LDR.N R5, ??u32FlashResult */
407 0x2D, 0x68, /* LDR R5, [R5] */
408 0x00, 0x2D, /* CMP R5, #0 */
409 0x28, 0xD1, /* BNE.N L1 */
410 /* *u32FlashSeq1 = FLASH_WRITE_1; */
411 0xAA, 0x25, /* MOVS R5, #0xAA */
412 0x1D, 0x60, /* STR R5, [R3] */
413 /* *u32FlashSeq2 = FLASH_WRITE_2; */
414 0x55, 0x25, /* MOVS R5, #0x55 */
415 0x25, 0x60, /* STR R5, [R4] */
416 /* *u32FlashSeq1 = FLASH_WRITE_3; */
417 0xA0, 0x25, /* MOVS R5, #0xA0 */
418 0x1D, 0x60, /* STRH R5, [R3] */
419 /* *(volatile uint16_t*)u32Target */
420 /* = *(volatile uint16_t*)u32Source; */
421 0x05, 0x88, /* LDRH R5, [R0] */
422 0x0D, 0x80, /* STRH R5, [R1] */
423 /* while (u32FlashResult */
424 /* == FLASH_WRITE_NO_RESTULT) */
425 0x1E, 0x4D, /* L2: LDR.N R5, ??u32FlashResult */
426 0x2D, 0x68, /* LDR R5, [R5] */
427 0x00, 0x2D, /* CMP R5, #0 */
428 0x11, 0xD1, /* BNE.N L3 */
429 /* if ((*(volatile uint16_t*)u32Target */
430 /* & FLASH_DQ5) == FLASH_DQ5) */
431 0x0D, 0x88, /* LDRH R5, [R1] */
432 0xAD, 0x06, /* LSLS R5, R5, #0x1A */
433 0x02, 0xD5, /* BPL.N L4 */
434 /* u32FlashResult = FLASH_WRITE_TIMEOUT */
435 0x1A, 0x4D, /* LDR.N R5, ??u32FlashResult */
436 0x02, 0x26, /* MOVS R6, #2 */
437 0x2E, 0x60, /* STR R6, [R5] */
438 /* if ((*(volatile uint16_t *)u32Target */
440 /* == (*(volatile uint16_t*)u32Source */
442 0x0D, 0x88, /* L4: LDRH R5, [R1] */
443 0x15, 0xF0, 0x80, 0x05, /* ANDS.W R5, R5, #0x80 */
444 0x06, 0x88, /* LDRH R6, [R0] */
445 0x16, 0xF0, 0x80, 0x06, /* ANDS.W R6, R6, #0x80 */
446 0xB5, 0x42, /* CMP R5, R6 */
447 0xED, 0xD1, /* BNE.N L2 */
448 /* u32FlashResult = FLASH_WRITE_OKAY */
449 0x15, 0x4D, /* LDR.N R5, ??u32FlashResult */
450 0x01, 0x26, /* MOVS R6, #1 */
451 0x2E, 0x60, /* STR R6, [R5] */
452 0xE9, 0xE7, /* B.N L2 */
453 /* if (u32FlashResult */
454 /* != FLASH_WRITE_TIMEOUT) */
455 0x13, 0x4D, /* LDR.N R5, ??u32FlashResult */
456 0x2D, 0x68, /* LDR R5, [R5] */
457 0x02, 0x2D, /* CMP R5, #2 */
458 0x02, 0xD0, /* BEQ.N L5 */
459 /* u32FlashResult = FLASH_WRITE_NO_RESULT */
460 0x11, 0x4D, /* LDR.N R5, ??u32FlashResult */
461 0x00, 0x26, /* MOVS R6, #0 */
462 0x2E, 0x60, /* STR R6, [R5] */
464 0x52, 0x1E, /* L5: SUBS R2, R2, #1 */
465 /* u32Source += 2; */
466 0x80, 0x1C, /* ADDS R0, R0, #2 */
467 /* u32Target += 2; */
468 0x89, 0x1C, /* ADDS R1, R1, #2 */
469 0xD0, 0xE7, /* B.N L0 */
470 /* fm3_FLASH_IF->FASZ &= 0xFFFE; */
471 0x5F, 0xF0, 0x80, 0x45, /* L1: MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
472 0x2D, 0x68, /* LDR R5, [R5] */
473 0x4F, 0xF6, 0xFE, 0x76, /* MOVW R6, #0xFFFE */
474 0x35, 0x40, /* ANDS R5, R5, R6 */
475 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
476 0x35, 0x60, /* STR R5, [R6] */
477 /* fm3_FLASH_IF->FASZ |= 2; */
478 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
479 0x2D, 0x68, /* LDR R5, [R5] */
480 0x55, 0xF0, 0x02, 0x05, /* ORRS.W R5, R5, #2 */
481 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
482 0x35, 0x60, /* STR R5, [R6] */
483 /* u32_dummy_read = fm3_FLASH_IF->FASZ; */
484 0x04, 0x4D, /* LDR.N R5, ??u32_dummy_read */
485 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
486 0x36, 0x68, /* LDR R6, [R6] */
487 0x2E, 0x60, /* STR R6, [R5] */
488 /* copy u32FlashResult to R3 for return */
490 0xDF, 0xF8, 0x08, 0x50, /* LDR.W R5, ??u32FlashResult */
491 0x2D, 0x68, /* LDR R5, [R5] */
492 /* Breakpoint here */
493 0x00, 0xBE, /* BKPT #0 */
495 /* The following address pointers assume, that the code is running from */
496 /* SRAM basic-address + 8.These address pointers will be patched, if a */
497 /* different start address in RAM is used (e.g. for Flash type 2)! */
498 /* Default SRAM basic-address is 0x20000000. */
499 0x00, 0x00, 0x00, 0x20, /* u32_dummy_read address in RAM (0x20000000) */
500 0x04, 0x00, 0x00, 0x20 /* u32FlashResult address in RAM (0x20000004) */
503 LOG_INFO("Fujitsu MB9[A/B]FXXX: FLASH Write ...");
505 /* disable HW watchdog */
506 retval
= target_write_u32(target
, 0x40011C00, 0x1ACCE551);
507 if (retval
!= ERROR_OK
)
510 retval
= target_write_u32(target
, 0x40011C00, 0xE5331AAE);
511 if (retval
!= ERROR_OK
)
514 retval
= target_write_u32(target
, 0x40011008, 0x00000000);
515 if (retval
!= ERROR_OK
)
518 count
= count
/ 2; /* number bytes -> number halfwords */
520 /* check code alignment */
522 LOG_WARNING("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
523 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
526 /* allocate working area and variables with flash programming code */
527 if (target_alloc_working_area(target
, sizeof(fm3_flash_write_code
) + 8,
528 &write_algorithm
) != ERROR_OK
) {
529 LOG_WARNING("no working area available, can't do block memory writes");
530 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
533 retval
= target_write_buffer(target
, write_algorithm
->address
+ 8,
534 sizeof(fm3_flash_write_code
), fm3_flash_write_code
);
535 if (retval
!= ERROR_OK
)
538 /* Patching 'local variable address' */
539 /* Algorithm: u32_dummy_read: */
540 retval
= target_write_u32(target
, (write_algorithm
->address
+ 8)
541 + sizeof(fm3_flash_write_code
) - 8, (write_algorithm
->address
));
542 if (retval
!= ERROR_OK
)
544 /* Algorithm: u32FlashResult: */
545 retval
= target_write_u32(target
, (write_algorithm
->address
+ 8)
546 + sizeof(fm3_flash_write_code
) - 4, (write_algorithm
->address
) + 4);
547 if (retval
!= ERROR_OK
)
553 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
) {
555 if (buffer_size
<= 256) {
556 /* free working area, write algorithm already allocated */
557 target_free_working_area(target
, write_algorithm
);
559 LOG_WARNING("No large enough working area available, can't do block memory writes");
560 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
564 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
565 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
567 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
); /* source start address */
568 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* target start address */
569 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* number of halfwords to program */
570 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
); /* Flash Sequence address 1 */
571 init_reg_param(®_params
[4], "r4", 32, PARAM_OUT
); /* Flash Sequence address 1 */
572 init_reg_param(®_params
[5], "r5", 32, PARAM_IN
); /* result */
574 /* write code buffer and use Flash programming code within fm3 */
575 /* Set breakpoint to 0 with time-out of 1000 ms */
577 uint32_t thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
579 retval
= target_write_buffer(target
, source
->address
, thisrun_count
* 2, buffer
);
580 if (retval
!= ERROR_OK
)
583 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
584 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
585 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
586 buf_set_u32(reg_params
[3].value
, 0, 32, u32_flash_seq_address1
);
587 buf_set_u32(reg_params
[4].value
, 0, 32, u32_flash_seq_address2
);
589 retval
= target_run_algorithm(target
, 0, NULL
, 6, reg_params
,
590 (write_algorithm
->address
+ 8), 0, 1000, &armv7m_info
);
591 if (retval
!= ERROR_OK
) {
592 LOG_ERROR("Error executing fm3 Flash programming algorithm");
593 retval
= ERROR_FLASH_OPERATION_FAILED
;
597 if (buf_get_u32(reg_params
[5].value
, 0, 32) != ERROR_OK
) {
598 LOG_ERROR("Fujitsu MB9[A/B]FXXX: Flash programming ERROR (Timeout) -> Reg R3: %" PRIx32
,
599 buf_get_u32(reg_params
[5].value
, 0, 32));
600 retval
= ERROR_FLASH_OPERATION_FAILED
;
604 buffer
+= thisrun_count
* 2;
605 address
+= thisrun_count
* 2;
606 count
-= thisrun_count
;
609 target_free_working_area(target
, source
);
610 target_free_working_area(target
, write_algorithm
);
612 destroy_reg_param(®_params
[0]);
613 destroy_reg_param(®_params
[1]);
614 destroy_reg_param(®_params
[2]);
615 destroy_reg_param(®_params
[3]);
616 destroy_reg_param(®_params
[4]);
617 destroy_reg_param(®_params
[5]);
622 static int fm3_probe(struct flash_bank
*bank
)
624 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
627 if (bank
->target
->state
!= TARGET_HALTED
) {
628 LOG_ERROR("Target not halted");
629 return ERROR_TARGET_NOT_HALTED
;
633 -- page-- start -- blocksize - mpu - totalFlash --
636 page2 0x08000 96k ___ fxx3 128k Flash
637 page3 0x20000 128k ___ fxx4 256k Flash
638 page4 0x40000 128k ___ fxx5 384k Flash
639 page5 0x60000 128k ___ fxx6 512k Flash
640 -----------------------
642 page7 0xa0000 128k ___ fxx7 256k Flash
644 page9 0xe0000 128k ___ fxx8 256k Flash
647 num_pages
= 10; /* max number of Flash pages for malloc */
648 fm3_info
->probed
= false;
650 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_pages
);
651 bank
->base
= 0x00000000;
652 bank
->size
= 32 * 1024; /* bytes */
654 bank
->sectors
[0].offset
= 0;
655 bank
->sectors
[0].size
= 16 * 1024;
656 bank
->sectors
[0].is_erased
= -1;
657 bank
->sectors
[0].is_protected
= -1;
659 bank
->sectors
[1].offset
= 0x4000;
660 bank
->sectors
[1].size
= 16 * 1024;
661 bank
->sectors
[1].is_erased
= -1;
662 bank
->sectors
[1].is_protected
= -1;
664 if ((fm3_info
->variant
== MB9BFXX1
)
665 || (fm3_info
->variant
== MB9AFXX1
)) {
667 bank
->size
= 64 * 1024; /* bytes */
668 bank
->num_sectors
= num_pages
;
670 bank
->sectors
[2].offset
= 0x8000;
671 bank
->sectors
[2].size
= 32 * 1024;
672 bank
->sectors
[2].is_erased
= -1;
673 bank
->sectors
[2].is_protected
= -1;
676 if ((fm3_info
->variant
== MB9BFXX2
)
677 || (fm3_info
->variant
== MB9BFXX4
)
678 || (fm3_info
->variant
== MB9BFXX5
)
679 || (fm3_info
->variant
== MB9BFXX6
)
680 || (fm3_info
->variant
== MB9BFXX7
)
681 || (fm3_info
->variant
== MB9BFXX8
)
682 || (fm3_info
->variant
== MB9AFXX2
)
683 || (fm3_info
->variant
== MB9AFXX4
)
684 || (fm3_info
->variant
== MB9AFXX5
)
685 || (fm3_info
->variant
== MB9AFXX6
)
686 || (fm3_info
->variant
== MB9AFXX7
)
687 || (fm3_info
->variant
== MB9AFXX8
)) {
689 bank
->size
= 128 * 1024; /* bytes */
690 bank
->num_sectors
= num_pages
;
692 bank
->sectors
[2].offset
= 0x8000;
693 bank
->sectors
[2].size
= 96 * 1024;
694 bank
->sectors
[2].is_erased
= -1;
695 bank
->sectors
[2].is_protected
= -1;
698 if ((fm3_info
->variant
== MB9BFXX4
)
699 || (fm3_info
->variant
== MB9BFXX5
)
700 || (fm3_info
->variant
== MB9BFXX6
)
701 || (fm3_info
->variant
== MB9BFXX7
)
702 || (fm3_info
->variant
== MB9BFXX8
)
703 || (fm3_info
->variant
== MB9AFXX4
)
704 || (fm3_info
->variant
== MB9AFXX5
)
705 || (fm3_info
->variant
== MB9AFXX6
)
706 || (fm3_info
->variant
== MB9AFXX7
)
707 || (fm3_info
->variant
== MB9AFXX8
)) {
709 bank
->size
= 256 * 1024; /* bytes */
710 bank
->num_sectors
= num_pages
;
712 bank
->sectors
[3].offset
= 0x20000;
713 bank
->sectors
[3].size
= 128 * 1024;
714 bank
->sectors
[3].is_erased
= -1;
715 bank
->sectors
[3].is_protected
= -1;
718 if ((fm3_info
->variant
== MB9BFXX5
)
719 || (fm3_info
->variant
== MB9BFXX6
)
720 || (fm3_info
->variant
== MB9BFXX7
)
721 || (fm3_info
->variant
== MB9BFXX8
)
722 || (fm3_info
->variant
== MB9AFXX5
)
723 || (fm3_info
->variant
== MB9AFXX6
)
724 || (fm3_info
->variant
== MB9AFXX7
)
725 || (fm3_info
->variant
== MB9AFXX8
)) {
727 bank
->size
= 384 * 1024; /* bytes */
728 bank
->num_sectors
= num_pages
;
730 bank
->sectors
[4].offset
= 0x40000;
731 bank
->sectors
[4].size
= 128 * 1024;
732 bank
->sectors
[4].is_erased
= -1;
733 bank
->sectors
[4].is_protected
= -1;
736 if ((fm3_info
->variant
== MB9BFXX6
)
737 || (fm3_info
->variant
== MB9BFXX7
)
738 || (fm3_info
->variant
== MB9BFXX8
)
739 || (fm3_info
->variant
== MB9AFXX6
)
740 || (fm3_info
->variant
== MB9AFXX7
)
741 || (fm3_info
->variant
== MB9AFXX8
)) {
743 bank
->size
= 512 * 1024; /* bytes */
744 bank
->num_sectors
= num_pages
;
746 bank
->sectors
[5].offset
= 0x60000;
747 bank
->sectors
[5].size
= 128 * 1024;
748 bank
->sectors
[5].is_erased
= -1;
749 bank
->sectors
[5].is_protected
= -1;
752 if ((fm3_info
->variant
== MB9BFXX7
)
753 || (fm3_info
->variant
== MB9BFXX8
)
754 || (fm3_info
->variant
== MB9AFXX7
)
755 || (fm3_info
->variant
== MB9AFXX8
)) {
757 bank
->size
= 768 * 1024; /* bytes */
758 bank
->num_sectors
= num_pages
;
760 bank
->sectors
[6].offset
= 0x80000;
761 bank
->sectors
[6].size
= 128 * 1024;
762 bank
->sectors
[6].is_erased
= -1;
763 bank
->sectors
[6].is_protected
= -1;
765 bank
->sectors
[7].offset
= 0xa0000;
766 bank
->sectors
[7].size
= 128 * 1024;
767 bank
->sectors
[7].is_erased
= -1;
768 bank
->sectors
[7].is_protected
= -1;
771 if ((fm3_info
->variant
== MB9BFXX8
)
772 || (fm3_info
->variant
== MB9AFXX8
)) {
774 bank
->size
= 1024 * 1024; /* bytes */
775 bank
->num_sectors
= num_pages
;
777 bank
->sectors
[8].offset
= 0xc0000;
778 bank
->sectors
[8].size
= 128 * 1024;
779 bank
->sectors
[8].is_erased
= -1;
780 bank
->sectors
[8].is_protected
= -1;
782 bank
->sectors
[9].offset
= 0xe0000;
783 bank
->sectors
[9].size
= 128 * 1024;
784 bank
->sectors
[9].is_erased
= -1;
785 bank
->sectors
[9].is_protected
= -1;
788 fm3_info
->probed
= true;
793 static int fm3_auto_probe(struct flash_bank
*bank
)
795 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
796 if (fm3_info
->probed
)
798 return fm3_probe(bank
);
802 static int fm3_chip_erase(struct flash_bank
*bank
)
804 struct target
*target
= bank
->target
;
805 struct fm3_flash_bank
*fm3_info2
= bank
->driver_priv
;
806 int retval
= ERROR_OK
;
807 uint32_t u32_dummy_read
;
808 uint32_t u32_flash_type
;
809 uint32_t u32_flash_seq_address1
;
810 uint32_t u32_flash_seq_address2
;
812 struct working_area
*write_algorithm
;
813 struct reg_param reg_params
[3];
814 struct armv7m_algorithm armv7m_info
;
816 u32_flash_type
= (uint32_t) fm3_info2
->flashtype
;
818 if (u32_flash_type
== FM3_FLASH_TYPE1
) {
819 LOG_INFO("*** Erasing mb9bfxxx type");
820 u32_flash_seq_address1
= 0x00001550;
821 u32_flash_seq_address2
= 0x00000AA8;
822 } else if (u32_flash_type
== FM3_FLASH_TYPE2
) {
823 LOG_INFO("*** Erasing mb9afxxx type");
824 u32_flash_seq_address1
= 0x00000AA8;
825 u32_flash_seq_address2
= 0x00000554;
827 LOG_ERROR("Flash/Device type unknown!");
828 return ERROR_FLASH_OPERATION_FAILED
;
831 if (target
->state
!= TARGET_HALTED
) {
832 LOG_ERROR("Target not halted");
833 return ERROR_TARGET_NOT_HALTED
;
836 /* RAMCODE used for fm3 Flash chip erase: */
837 /* R0 keeps Flash Sequence address 1 (u32FlashSeq1) */
838 /* R1 keeps Flash Sequence address 2 (u32FlashSeq2) */
839 static const uint8_t fm3_flash_erase_chip_code
[] = {
840 /* *(uint16_t*)u32FlashSeq1 = 0xAA; */
841 0xAA, 0x22, /* MOVS R2, #0xAA */
842 0x02, 0x80, /* STRH R2, [R0, #0] */
843 /* *(uint16_t*)u32FlashSeq2 = 0x55; */
844 0x55, 0x23, /* MOVS R3, #0x55 */
845 0x0B, 0x80, /* STRH R3, [R1, #0] */
846 /* *(uint16_t*)u32FlashSeq1 = 0x80; */
847 0x80, 0x24, /* MOVS R4, #0x80 */
848 0x04, 0x80, /* STRH R4, [R0, #0] */
849 /* *(uint16_t*)u32FlashSeq1 = 0xAA; */
850 0x02, 0x80, /* STRH R2, [R0, #0] */
851 /* *(uint16_t*)u32FlashSeq2 = 0x55; */
852 0x0B, 0x80, /* STRH R3, [R1, #0] */
853 /* Chip_Erase Command 0x10 */
854 /* *(uint16_t*)u32FlashSeq1 = 0x10; */
855 0x10, 0x21, /* MOVS R1, #0x10 */
856 0x01, 0x80, /* STRH R1, [R0, #0] */
858 0x00, 0xBE, /* BKPT #0 */
861 LOG_INFO("Fujitsu MB9[A/B]xxx: Chip Erase ... (may take several seconds)");
863 /* disable HW watchdog */
864 retval
= target_write_u32(target
, 0x40011C00, 0x1ACCE551);
865 if (retval
!= ERROR_OK
)
868 retval
= target_write_u32(target
, 0x40011C00, 0xE5331AAE);
869 if (retval
!= ERROR_OK
)
872 retval
= target_write_u32(target
, 0x40011008, 0x00000000);
873 if (retval
!= ERROR_OK
)
876 /* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash access) */
877 retval
= target_write_u32(target
, 0x40000000, 0x0001);
878 if (retval
!= ERROR_OK
)
881 /* dummy read of FASZR */
882 retval
= target_read_u32(target
, 0x40000000, &u32_dummy_read
);
883 if (retval
!= ERROR_OK
)
886 /* allocate working area with flash chip erase code */
887 if (target_alloc_working_area(target
, sizeof(fm3_flash_erase_chip_code
),
888 &write_algorithm
) != ERROR_OK
) {
889 LOG_WARNING("no working area available, can't do block memory writes");
890 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
892 retval
= target_write_buffer(target
, write_algorithm
->address
,
893 sizeof(fm3_flash_erase_chip_code
), fm3_flash_erase_chip_code
);
894 if (retval
!= ERROR_OK
)
897 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
898 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
900 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
); /* u32_flash_seq_address1 */
901 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* u32_flash_seq_address2 */
903 buf_set_u32(reg_params
[0].value
, 0, 32, u32_flash_seq_address1
);
904 buf_set_u32(reg_params
[1].value
, 0, 32, u32_flash_seq_address2
);
906 retval
= target_run_algorithm(target
, 0, NULL
, 2, reg_params
,
907 write_algorithm
->address
, 0, 100000, &armv7m_info
);
908 if (retval
!= ERROR_OK
) {
909 LOG_ERROR("Error executing flash erase programming algorithm");
910 retval
= ERROR_FLASH_OPERATION_FAILED
;
914 target_free_working_area(target
, write_algorithm
);
916 destroy_reg_param(®_params
[0]);
917 destroy_reg_param(®_params
[1]);
919 retval
= fm3_busy_wait(target
, u32_flash_seq_address2
, 20000); /* 20s timeout */
920 if (retval
!= ERROR_OK
)
923 /* FASZR = 0x02, Re-enables CPU Run Mode (32-bit Flash access) */
924 retval
= target_write_u32(target
, 0x40000000, 0x0002);
925 if (retval
!= ERROR_OK
)
928 retval
= target_read_u32(target
, 0x40000000, &u32_dummy_read
); /* dummy read of FASZR */
933 COMMAND_HANDLER(fm3_handle_chip_erase_command
)
936 return ERROR_COMMAND_SYNTAX_ERROR
;
938 struct flash_bank
*bank
;
939 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
940 if (retval
!= ERROR_OK
)
943 if (fm3_chip_erase(bank
) == ERROR_OK
) {
944 command_print(CMD
, "fm3 chip erase complete");
946 command_print(CMD
, "fm3 chip erase failed");
952 static const struct command_registration fm3_exec_command_handlers
[] = {
954 .name
= "chip_erase",
956 .handler
= fm3_handle_chip_erase_command
,
957 .mode
= COMMAND_EXEC
,
958 .help
= "Erase entire Flash device.",
960 COMMAND_REGISTRATION_DONE
963 static const struct command_registration fm3_command_handlers
[] = {
967 .help
= "fm3 Flash command group",
969 .chain
= fm3_exec_command_handlers
,
971 COMMAND_REGISTRATION_DONE
974 const struct flash_driver fm3_flash
= {
976 .commands
= fm3_command_handlers
,
977 .flash_bank_command
= fm3_flash_bank_command
,
979 .write
= fm3_write_block
,
981 .auto_probe
= fm3_auto_probe
,
982 .erase_check
= default_flash_blank_check
,
983 .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)