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
= 0;
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
, int first
, int last
)
206 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
207 struct target
*target
= bank
->target
;
208 int retval
= ERROR_OK
;
209 uint32_t u32DummyRead
;
211 uint32_t u32FlashType
;
212 uint32_t u32FlashSeqAddress1
;
213 uint32_t u32FlashSeqAddress2
;
215 struct working_area
*write_algorithm
;
216 struct reg_param reg_params
[3];
217 struct armv7m_algorithm armv7m_info
;
219 u32FlashType
= (uint32_t) fm3_info
->flashtype
;
221 if (u32FlashType
== fm3_flash_type1
) {
222 u32FlashSeqAddress1
= 0x00001550;
223 u32FlashSeqAddress2
= 0x00000AA8;
224 } else if (u32FlashType
== fm3_flash_type2
) {
225 u32FlashSeqAddress1
= 0x00000AA8;
226 u32FlashSeqAddress2
= 0x00000554;
228 LOG_ERROR("Flash/Device type unknown!");
229 return ERROR_FLASH_OPERATION_FAILED
;
232 if (target
->state
!= TARGET_HALTED
) {
233 LOG_ERROR("Target not halted");
234 return ERROR_TARGET_NOT_HALTED
;
237 /* RAMCODE used for fm3 Flash sector erase: */
238 /* R0 keeps Flash Sequence address 1 (u32FlashSeq1) */
239 /* R1 keeps Flash Sequence address 2 (u32FlashSeq2) */
240 /* R2 keeps Flash Offset address (ofs) */
241 static const uint8_t fm3_flash_erase_sector_code
[] = {
242 /* *(uint16_t*)u32FlashSeq1 = 0xAA; */
243 0xAA, 0x24, /* MOVS R4, #0xAA */
244 0x04, 0x80, /* STRH R4, [R0, #0] */
245 /* *(uint16_t*)u32FlashSeq2 = 0x55; */
246 0x55, 0x23, /* MOVS R3, #0x55 */
247 0x0B, 0x80, /* STRH R3, [R1, #0] */
248 /* *(uint16_t*)u32FlashSeq1 = 0x80; */
249 0x80, 0x25, /* MOVS R5, #0x80 */
250 0x05, 0x80, /* STRH R5, [R0, #0] */
251 /* *(uint16_t*)u32FlashSeq1 = 0xAA; */
252 0x04, 0x80, /* STRH R4, [R0, #0] */
253 /* *(uint16_t*)u32FlashSeq2 = 0x55; */
254 0x0B, 0x80, /* STRH R3, [R1, #0] */
255 /* Sector_Erase Command (0x30) */
256 /* *(uint16_t*)ofs = 0x30; */
257 0x30, 0x20, /* MOVS R0, #0x30 */
258 0x10, 0x80, /* STRH R0, [R2, #0] */
260 0x00, 0xBE, /* BKPT #0 */
263 LOG_INFO("Fujitsu MB9[A/B]FXXX: Sector Erase ... (%d to %d)", first
, last
);
265 /* disable HW watchdog */
266 retval
= target_write_u32(target
, 0x40011C00, 0x1ACCE551);
267 if (retval
!= ERROR_OK
)
270 retval
= target_write_u32(target
, 0x40011C00, 0xE5331AAE);
271 if (retval
!= ERROR_OK
)
274 retval
= target_write_u32(target
, 0x40011008, 0x00000000);
275 if (retval
!= ERROR_OK
)
278 /* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash acccess) */
279 retval
= target_write_u32(target
, 0x40000000, 0x0001);
280 if (retval
!= ERROR_OK
)
283 /* dummy read of FASZR */
284 retval
= target_read_u32(target
, 0x40000000, &u32DummyRead
);
285 if (retval
!= ERROR_OK
)
288 /* allocate working area with flash sector erase code */
289 if (target_alloc_working_area(target
, sizeof(fm3_flash_erase_sector_code
),
290 &write_algorithm
) != ERROR_OK
) {
291 LOG_WARNING("no working area available, can't do block memory writes");
292 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
294 retval
= target_write_buffer(target
, write_algorithm
->address
,
295 sizeof(fm3_flash_erase_sector_code
), fm3_flash_erase_sector_code
);
296 if (retval
!= ERROR_OK
)
299 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
300 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
302 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
); /* u32FlashSeqAddress1 */
303 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* u32FlashSeqAddress2 */
304 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* offset */
306 /* write code buffer and use Flash sector erase code within fm3 */
307 for (sector
= first
; sector
<= last
; sector
++) {
308 uint32_t offset
= bank
->sectors
[sector
].offset
;
310 for (odd
= 0; odd
< 2 ; odd
++) {
314 buf_set_u32(reg_params
[0].value
, 0, 32, u32FlashSeqAddress1
);
315 buf_set_u32(reg_params
[1].value
, 0, 32, u32FlashSeqAddress2
);
316 buf_set_u32(reg_params
[2].value
, 0, 32, offset
);
318 retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
,
319 write_algorithm
->address
, 0, 100000, &armv7m_info
);
320 if (retval
!= ERROR_OK
) {
321 LOG_ERROR("Error executing flash erase programming algorithm");
322 retval
= ERROR_FLASH_OPERATION_FAILED
;
326 retval
= fm3_busy_wait(target
, offset
, 500);
327 if (retval
!= ERROR_OK
)
330 bank
->sectors
[sector
].is_erased
= 1;
333 target_free_working_area(target
, write_algorithm
);
334 destroy_reg_param(®_params
[0]);
335 destroy_reg_param(®_params
[1]);
336 destroy_reg_param(®_params
[2]);
338 /* FASZR = 0x02, Enables CPU Run Mode (32-bit Flash acccess) */
339 retval
= target_write_u32(target
, 0x40000000, 0x0002);
340 if (retval
!= ERROR_OK
)
343 retval
= target_read_u32(target
, 0x40000000, &u32DummyRead
); /* dummy read of FASZR */
348 static int fm3_write_block(struct flash_bank
*bank
, const uint8_t *buffer
,
349 uint32_t offset
, uint32_t count
)
351 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
352 struct target
*target
= bank
->target
;
353 uint32_t buffer_size
= 2048; /* Default minimum value */
354 struct working_area
*write_algorithm
;
355 struct working_area
*source
;
356 uint32_t address
= bank
->base
+ offset
;
357 struct reg_param reg_params
[6];
358 struct armv7m_algorithm armv7m_info
;
359 int retval
= ERROR_OK
;
360 uint32_t u32FlashType
;
361 uint32_t u32FlashSeqAddress1
;
362 uint32_t u32FlashSeqAddress2
;
364 /* Increase buffer_size if needed */
365 if (buffer_size
< (target
->working_area_size
/ 2))
366 buffer_size
= (target
->working_area_size
/ 2);
368 u32FlashType
= (uint32_t) fm3_info
->flashtype
;
370 if (u32FlashType
== fm3_flash_type1
) {
371 u32FlashSeqAddress1
= 0x00001550;
372 u32FlashSeqAddress2
= 0x00000AA8;
373 } else if (u32FlashType
== fm3_flash_type2
) {
374 u32FlashSeqAddress1
= 0x00000AA8;
375 u32FlashSeqAddress2
= 0x00000554;
377 LOG_ERROR("Flash/Device type unknown!");
378 return ERROR_FLASH_OPERATION_FAILED
;
381 /* RAMCODE used for fm3 Flash programming: */
382 /* R0 keeps source start address (u32Source) */
383 /* R1 keeps target start address (u32Target) */
384 /* R2 keeps number of halfwords to write (u32Count) */
385 /* R3 keeps Flash Sequence address 1 (u32FlashSeq1) */
386 /* R4 keeps Flash Sequence address 2 (u32FlashSeq2) */
387 /* R5 returns result value (u32FlashResult) */
389 static const uint8_t fm3_flash_write_code
[] = {
390 /* fm3_FLASH_IF->FASZ &= 0xFFFD; */
391 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
392 0x2D, 0x68, /* LDR R5, [R5] */
393 0x4F, 0xF6, 0xFD, 0x76, /* MOVW R6, #0xFFFD */
394 0x35, 0x40, /* ANDS R5, R5, R6 */
395 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
396 0x35, 0x60, /* STR R5, [R6] */
397 /* fm3_FLASH_IF->FASZ |= 1; */
398 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
399 0x2D, 0x68, /* LDR R5, [R3] */
400 0x55, 0xF0, 0x01, 0x05, /* ORRS.W R5, R5, #1 */
401 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
402 0x35, 0x60, /* STR R5, [R6] */
403 /* u32DummyRead = fm3_FLASH_IF->FASZ; */
404 0x28, 0x4D, /* LDR.N R5, ??u32DummyRead */
405 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
406 0x36, 0x68, /* LDR R6, [R6] */
407 0x2E, 0x60, /* STR R6, [R5] */
408 /* u32FlashResult = FLASH_WRITE_NO_RESULT */
409 0x26, 0x4D, /* LDR.N R5, ??u32FlashResult */
410 0x00, 0x26, /* MOVS R6, #0 */
411 0x2E, 0x60, /* STR R6, [R5] */
412 /* while ((u32Count > 0 ) */
413 /* && (u32FlashResult */
414 /* == FLASH_WRITE_NO_RESULT)) */
415 0x01, 0x2A, /* L0: CMP R2, #1 */
416 0x2C, 0xDB, /* BLT.N L1 */
417 0x24, 0x4D, /* LDR.N R5, ??u32FlashResult */
418 0x2D, 0x68, /* LDR R5, [R5] */
419 0x00, 0x2D, /* CMP R5, #0 */
420 0x28, 0xD1, /* BNE.N L1 */
421 /* *u32FlashSeq1 = FLASH_WRITE_1; */
422 0xAA, 0x25, /* MOVS R5, #0xAA */
423 0x1D, 0x60, /* STR R5, [R3] */
424 /* *u32FlashSeq2 = FLASH_WRITE_2; */
425 0x55, 0x25, /* MOVS R5, #0x55 */
426 0x25, 0x60, /* STR R5, [R4] */
427 /* *u32FlashSeq1 = FLASH_WRITE_3; */
428 0xA0, 0x25, /* MOVS R5, #0xA0 */
429 0x1D, 0x60, /* STRH R5, [R3] */
430 /* *(volatile uint16_t*)u32Target */
431 /* = *(volatile uint16_t*)u32Source; */
432 0x05, 0x88, /* LDRH R5, [R0] */
433 0x0D, 0x80, /* STRH R5, [R1] */
434 /* while (u32FlashResult */
435 /* == FLASH_WRITE_NO_RESTULT) */
436 0x1E, 0x4D, /* L2: LDR.N R5, ??u32FlashResult */
437 0x2D, 0x68, /* LDR R5, [R5] */
438 0x00, 0x2D, /* CMP R5, #0 */
439 0x11, 0xD1, /* BNE.N L3 */
440 /* if ((*(volatile uint16_t*)u32Target */
441 /* & FLASH_DQ5) == FLASH_DQ5) */
442 0x0D, 0x88, /* LDRH R5, [R1] */
443 0xAD, 0x06, /* LSLS R5, R5, #0x1A */
444 0x02, 0xD5, /* BPL.N L4 */
445 /* u32FlashResult = FLASH_WRITE_TIMEOUT */
446 0x1A, 0x4D, /* LDR.N R5, ??u32FlashResult */
447 0x02, 0x26, /* MOVS R6, #2 */
448 0x2E, 0x60, /* STR R6, [R5] */
449 /* if ((*(volatile uint16_t *)u32Target */
451 /* == (*(volatile uint16_t*)u32Source */
453 0x0D, 0x88, /* L4: LDRH R5, [R1] */
454 0x15, 0xF0, 0x80, 0x05, /* ANDS.W R5, R5, #0x80 */
455 0x06, 0x88, /* LDRH R6, [R0] */
456 0x16, 0xF0, 0x80, 0x06, /* ANDS.W R6, R6, #0x80 */
457 0xB5, 0x42, /* CMP R5, R6 */
458 0xED, 0xD1, /* BNE.N L2 */
459 /* u32FlashResult = FLASH_WRITE_OKAY */
460 0x15, 0x4D, /* LDR.N R5, ??u32FlashResult */
461 0x01, 0x26, /* MOVS R6, #1 */
462 0x2E, 0x60, /* STR R6, [R5] */
463 0xE9, 0xE7, /* B.N L2 */
464 /* if (u32FlashResult */
465 /* != FLASH_WRITE_TIMEOUT) */
466 0x13, 0x4D, /* LDR.N R5, ??u32FlashResult */
467 0x2D, 0x68, /* LDR R5, [R5] */
468 0x02, 0x2D, /* CMP R5, #2 */
469 0x02, 0xD0, /* BEQ.N L5 */
470 /* u32FlashResult = FLASH_WRITE_NO_RESULT */
471 0x11, 0x4D, /* LDR.N R5, ??u32FlashResult */
472 0x00, 0x26, /* MOVS R6, #0 */
473 0x2E, 0x60, /* STR R6, [R5] */
475 0x52, 0x1E, /* L5: SUBS R2, R2, #1 */
476 /* u32Source += 2; */
477 0x80, 0x1C, /* ADDS R0, R0, #2 */
478 /* u32Target += 2; */
479 0x89, 0x1C, /* ADDS R1, R1, #2 */
480 0xD0, 0xE7, /* B.N L0 */
481 /* fm3_FLASH_IF->FASZ &= 0xFFFE; */
482 0x5F, 0xF0, 0x80, 0x45, /* L1: MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
483 0x2D, 0x68, /* LDR R5, [R5] */
484 0x4F, 0xF6, 0xFE, 0x76, /* MOVW R6, #0xFFFE */
485 0x35, 0x40, /* ANDS R5, R5, R6 */
486 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
487 0x35, 0x60, /* STR R5, [R6] */
488 /* fm3_FLASH_IF->FASZ |= 2; */
489 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
490 0x2D, 0x68, /* LDR R5, [R5] */
491 0x55, 0xF0, 0x02, 0x05, /* ORRS.W R5, R5, #2 */
492 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
493 0x35, 0x60, /* STR R5, [R6] */
494 /* u32DummyRead = fm3_FLASH_IF->FASZ; */
495 0x04, 0x4D, /* LDR.N R5, ??u32DummyRead */
496 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
497 0x36, 0x68, /* LDR R6, [R6] */
498 0x2E, 0x60, /* STR R6, [R5] */
499 /* copy u32FlashResult to R3 for return */
501 0xDF, 0xF8, 0x08, 0x50, /* LDR.W R5, ??u32FlashResult */
502 0x2D, 0x68, /* LDR R5, [R5] */
503 /* Breakpoint here */
504 0x00, 0xBE, /* BKPT #0 */
506 /* The following address pointers assume, that the code is running from */
507 /* SRAM basic-address + 8.These address pointers will be patched, if a */
508 /* different start address in RAM is used (e.g. for Flash type 2)! */
509 /* Default SRAM basic-address is 0x20000000. */
510 0x00, 0x00, 0x00, 0x20, /* u32DummyRead address in RAM (0x20000000) */
511 0x04, 0x00, 0x00, 0x20 /* u32FlashResult address in RAM (0x20000004) */
514 LOG_INFO("Fujitsu MB9[A/B]FXXX: FLASH Write ...");
516 /* disable HW watchdog */
517 retval
= target_write_u32(target
, 0x40011C00, 0x1ACCE551);
518 if (retval
!= ERROR_OK
)
521 retval
= target_write_u32(target
, 0x40011C00, 0xE5331AAE);
522 if (retval
!= ERROR_OK
)
525 retval
= target_write_u32(target
, 0x40011008, 0x00000000);
526 if (retval
!= ERROR_OK
)
529 count
= count
/ 2; /* number bytes -> number halfwords */
531 /* check code alignment */
533 LOG_WARNING("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
534 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
537 /* allocate working area and variables with flash programming code */
538 if (target_alloc_working_area(target
, sizeof(fm3_flash_write_code
) + 8,
539 &write_algorithm
) != ERROR_OK
) {
540 LOG_WARNING("no working area available, can't do block memory writes");
541 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
544 retval
= target_write_buffer(target
, write_algorithm
->address
+ 8,
545 sizeof(fm3_flash_write_code
), fm3_flash_write_code
);
546 if (retval
!= ERROR_OK
)
549 /* Patching 'local variable address' */
550 /* Algorithm: u32DummyRead: */
551 retval
= target_write_u32(target
, (write_algorithm
->address
+ 8)
552 + sizeof(fm3_flash_write_code
) - 8, (write_algorithm
->address
));
553 if (retval
!= ERROR_OK
)
555 /* Algorithm: u32FlashResult: */
556 retval
= target_write_u32(target
, (write_algorithm
->address
+ 8)
557 + sizeof(fm3_flash_write_code
) - 4, (write_algorithm
->address
) + 4);
558 if (retval
!= ERROR_OK
)
564 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
) {
566 if (buffer_size
<= 256) {
567 /* free working area, write algorithm already allocated */
568 target_free_working_area(target
, write_algorithm
);
570 LOG_WARNING("No large enough working area available, can't do block memory writes");
571 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
575 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
576 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
578 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
); /* source start address */
579 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* target start address */
580 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* number of halfwords to program */
581 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
); /* Flash Sequence address 1 */
582 init_reg_param(®_params
[4], "r4", 32, PARAM_OUT
); /* Flash Sequence address 1 */
583 init_reg_param(®_params
[5], "r5", 32, PARAM_IN
); /* result */
585 /* write code buffer and use Flash programming code within fm3 */
586 /* Set breakpoint to 0 with time-out of 1000 ms */
588 uint32_t thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
590 retval
= target_write_buffer(target
, source
->address
, thisrun_count
* 2, buffer
);
591 if (retval
!= ERROR_OK
)
594 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
595 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
596 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
597 buf_set_u32(reg_params
[3].value
, 0, 32, u32FlashSeqAddress1
);
598 buf_set_u32(reg_params
[4].value
, 0, 32, u32FlashSeqAddress2
);
600 retval
= target_run_algorithm(target
, 0, NULL
, 6, reg_params
,
601 (write_algorithm
->address
+ 8), 0, 1000, &armv7m_info
);
602 if (retval
!= ERROR_OK
) {
603 LOG_ERROR("Error executing fm3 Flash programming algorithm");
604 retval
= ERROR_FLASH_OPERATION_FAILED
;
608 if (buf_get_u32(reg_params
[5].value
, 0, 32) != ERROR_OK
) {
609 LOG_ERROR("Fujitsu MB9[A/B]FXXX: Flash programming ERROR (Timeout) -> Reg R3: %" PRIx32
,
610 buf_get_u32(reg_params
[5].value
, 0, 32));
611 retval
= ERROR_FLASH_OPERATION_FAILED
;
615 buffer
+= thisrun_count
* 2;
616 address
+= thisrun_count
* 2;
617 count
-= thisrun_count
;
620 target_free_working_area(target
, source
);
621 target_free_working_area(target
, write_algorithm
);
623 destroy_reg_param(®_params
[0]);
624 destroy_reg_param(®_params
[1]);
625 destroy_reg_param(®_params
[2]);
626 destroy_reg_param(®_params
[3]);
627 destroy_reg_param(®_params
[4]);
628 destroy_reg_param(®_params
[5]);
633 static int fm3_probe(struct flash_bank
*bank
)
635 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
638 if (bank
->target
->state
!= TARGET_HALTED
) {
639 LOG_ERROR("Target not halted");
640 return ERROR_TARGET_NOT_HALTED
;
644 -- page-- start -- blocksize - mpu - totalFlash --
647 page2 0x08000 96k ___ fxx3 128k Flash
648 page3 0x20000 128k ___ fxx4 256k Flash
649 page4 0x40000 128k ___ fxx5 384k Flash
650 page5 0x60000 128k ___ fxx6 512k Flash
651 -----------------------
653 page7 0xa0000 128k ___ fxx7 256k Flash
655 page9 0xe0000 128k ___ fxx8 256k Flash
658 num_pages
= 10; /* max number of Flash pages for malloc */
659 fm3_info
->probed
= 0;
661 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_pages
);
662 bank
->base
= 0x00000000;
663 bank
->size
= 32 * 1024; /* bytes */
665 bank
->sectors
[0].offset
= 0;
666 bank
->sectors
[0].size
= 16 * 1024;
667 bank
->sectors
[0].is_erased
= -1;
668 bank
->sectors
[0].is_protected
= -1;
670 bank
->sectors
[1].offset
= 0x4000;
671 bank
->sectors
[1].size
= 16 * 1024;
672 bank
->sectors
[1].is_erased
= -1;
673 bank
->sectors
[1].is_protected
= -1;
675 if ((fm3_info
->variant
== mb9bfxx1
)
676 || (fm3_info
->variant
== mb9afxx1
)) {
678 bank
->size
= 64 * 1024; /* bytes */
679 bank
->num_sectors
= num_pages
;
681 bank
->sectors
[2].offset
= 0x8000;
682 bank
->sectors
[2].size
= 32 * 1024;
683 bank
->sectors
[2].is_erased
= -1;
684 bank
->sectors
[2].is_protected
= -1;
687 if ((fm3_info
->variant
== mb9bfxx2
)
688 || (fm3_info
->variant
== mb9bfxx4
)
689 || (fm3_info
->variant
== mb9bfxx5
)
690 || (fm3_info
->variant
== mb9bfxx6
)
691 || (fm3_info
->variant
== mb9bfxx7
)
692 || (fm3_info
->variant
== mb9bfxx8
)
693 || (fm3_info
->variant
== mb9afxx2
)
694 || (fm3_info
->variant
== mb9afxx4
)
695 || (fm3_info
->variant
== mb9afxx5
)
696 || (fm3_info
->variant
== mb9afxx6
)
697 || (fm3_info
->variant
== mb9afxx7
)
698 || (fm3_info
->variant
== mb9afxx8
)) {
700 bank
->size
= 128 * 1024; /* bytes */
701 bank
->num_sectors
= num_pages
;
703 bank
->sectors
[2].offset
= 0x8000;
704 bank
->sectors
[2].size
= 96 * 1024;
705 bank
->sectors
[2].is_erased
= -1;
706 bank
->sectors
[2].is_protected
= -1;
709 if ((fm3_info
->variant
== mb9bfxx4
)
710 || (fm3_info
->variant
== mb9bfxx5
)
711 || (fm3_info
->variant
== mb9bfxx6
)
712 || (fm3_info
->variant
== mb9bfxx7
)
713 || (fm3_info
->variant
== mb9bfxx8
)
714 || (fm3_info
->variant
== mb9afxx4
)
715 || (fm3_info
->variant
== mb9afxx5
)
716 || (fm3_info
->variant
== mb9afxx6
)
717 || (fm3_info
->variant
== mb9afxx7
)
718 || (fm3_info
->variant
== mb9afxx8
)) {
720 bank
->size
= 256 * 1024; /* bytes */
721 bank
->num_sectors
= num_pages
;
723 bank
->sectors
[3].offset
= 0x20000;
724 bank
->sectors
[3].size
= 128 * 1024;
725 bank
->sectors
[3].is_erased
= -1;
726 bank
->sectors
[3].is_protected
= -1;
729 if ((fm3_info
->variant
== mb9bfxx5
)
730 || (fm3_info
->variant
== mb9bfxx6
)
731 || (fm3_info
->variant
== mb9bfxx7
)
732 || (fm3_info
->variant
== mb9bfxx8
)
733 || (fm3_info
->variant
== mb9afxx5
)
734 || (fm3_info
->variant
== mb9afxx6
)
735 || (fm3_info
->variant
== mb9afxx7
)
736 || (fm3_info
->variant
== mb9afxx8
)) {
738 bank
->size
= 384 * 1024; /* bytes */
739 bank
->num_sectors
= num_pages
;
741 bank
->sectors
[4].offset
= 0x40000;
742 bank
->sectors
[4].size
= 128 * 1024;
743 bank
->sectors
[4].is_erased
= -1;
744 bank
->sectors
[4].is_protected
= -1;
747 if ((fm3_info
->variant
== mb9bfxx6
)
748 || (fm3_info
->variant
== mb9bfxx7
)
749 || (fm3_info
->variant
== mb9bfxx8
)
750 || (fm3_info
->variant
== mb9afxx6
)
751 || (fm3_info
->variant
== mb9afxx7
)
752 || (fm3_info
->variant
== mb9afxx8
)) {
754 bank
->size
= 512 * 1024; /* bytes */
755 bank
->num_sectors
= num_pages
;
757 bank
->sectors
[5].offset
= 0x60000;
758 bank
->sectors
[5].size
= 128 * 1024;
759 bank
->sectors
[5].is_erased
= -1;
760 bank
->sectors
[5].is_protected
= -1;
763 if ((fm3_info
->variant
== mb9bfxx7
)
764 || (fm3_info
->variant
== mb9bfxx8
)
765 || (fm3_info
->variant
== mb9afxx7
)
766 || (fm3_info
->variant
== mb9afxx8
)) {
768 bank
->size
= 768 * 1024; /* bytes */
769 bank
->num_sectors
= num_pages
;
771 bank
->sectors
[6].offset
= 0x80000;
772 bank
->sectors
[6].size
= 128 * 1024;
773 bank
->sectors
[6].is_erased
= -1;
774 bank
->sectors
[6].is_protected
= -1;
776 bank
->sectors
[7].offset
= 0xa0000;
777 bank
->sectors
[7].size
= 128 * 1024;
778 bank
->sectors
[7].is_erased
= -1;
779 bank
->sectors
[7].is_protected
= -1;
782 if ((fm3_info
->variant
== mb9bfxx8
)
783 || (fm3_info
->variant
== mb9afxx8
)) {
785 bank
->size
= 1024 * 1024; /* bytes */
786 bank
->num_sectors
= num_pages
;
788 bank
->sectors
[8].offset
= 0xc0000;
789 bank
->sectors
[8].size
= 128 * 1024;
790 bank
->sectors
[8].is_erased
= -1;
791 bank
->sectors
[8].is_protected
= -1;
793 bank
->sectors
[9].offset
= 0xe0000;
794 bank
->sectors
[9].size
= 128 * 1024;
795 bank
->sectors
[9].is_erased
= -1;
796 bank
->sectors
[9].is_protected
= -1;
799 fm3_info
->probed
= 1;
804 static int fm3_auto_probe(struct flash_bank
*bank
)
806 struct fm3_flash_bank
*fm3_info
= bank
->driver_priv
;
807 if (fm3_info
->probed
)
809 return fm3_probe(bank
);
813 static int fm3_chip_erase(struct flash_bank
*bank
)
815 struct target
*target
= bank
->target
;
816 struct fm3_flash_bank
*fm3_info2
= bank
->driver_priv
;
817 int retval
= ERROR_OK
;
818 uint32_t u32DummyRead
;
819 uint32_t u32FlashType
;
820 uint32_t u32FlashSeqAddress1
;
821 uint32_t u32FlashSeqAddress2
;
823 struct working_area
*write_algorithm
;
824 struct reg_param reg_params
[3];
825 struct armv7m_algorithm armv7m_info
;
827 u32FlashType
= (uint32_t) fm3_info2
->flashtype
;
829 if (u32FlashType
== fm3_flash_type1
) {
830 LOG_INFO("*** Erasing mb9bfxxx type");
831 u32FlashSeqAddress1
= 0x00001550;
832 u32FlashSeqAddress2
= 0x00000AA8;
833 } else if (u32FlashType
== fm3_flash_type2
) {
834 LOG_INFO("*** Erasing mb9afxxx type");
835 u32FlashSeqAddress1
= 0x00000AA8;
836 u32FlashSeqAddress2
= 0x00000554;
838 LOG_ERROR("Flash/Device type unknown!");
839 return ERROR_FLASH_OPERATION_FAILED
;
842 if (target
->state
!= TARGET_HALTED
) {
843 LOG_ERROR("Target not halted");
844 return ERROR_TARGET_NOT_HALTED
;
847 /* RAMCODE used for fm3 Flash chip erase: */
848 /* R0 keeps Flash Sequence address 1 (u32FlashSeq1) */
849 /* R1 keeps Flash Sequence address 2 (u32FlashSeq2) */
850 static const uint8_t fm3_flash_erase_chip_code
[] = {
851 /* *(uint16_t*)u32FlashSeq1 = 0xAA; */
852 0xAA, 0x22, /* MOVS R2, #0xAA */
853 0x02, 0x80, /* STRH R2, [R0, #0] */
854 /* *(uint16_t*)u32FlashSeq2 = 0x55; */
855 0x55, 0x23, /* MOVS R3, #0x55 */
856 0x0B, 0x80, /* STRH R3, [R1, #0] */
857 /* *(uint16_t*)u32FlashSeq1 = 0x80; */
858 0x80, 0x24, /* MOVS R4, #0x80 */
859 0x04, 0x80, /* STRH R4, [R0, #0] */
860 /* *(uint16_t*)u32FlashSeq1 = 0xAA; */
861 0x02, 0x80, /* STRH R2, [R0, #0] */
862 /* *(uint16_t*)u32FlashSeq2 = 0x55; */
863 0x0B, 0x80, /* STRH R3, [R1, #0] */
864 /* Chip_Erase Command 0x10 */
865 /* *(uint16_t*)u32FlashSeq1 = 0x10; */
866 0x10, 0x21, /* MOVS R1, #0x10 */
867 0x01, 0x80, /* STRH R1, [R0, #0] */
869 0x00, 0xBE, /* BKPT #0 */
872 LOG_INFO("Fujitsu MB9[A/B]xxx: Chip Erase ... (may take several seconds)");
874 /* disable HW watchdog */
875 retval
= target_write_u32(target
, 0x40011C00, 0x1ACCE551);
876 if (retval
!= ERROR_OK
)
879 retval
= target_write_u32(target
, 0x40011C00, 0xE5331AAE);
880 if (retval
!= ERROR_OK
)
883 retval
= target_write_u32(target
, 0x40011008, 0x00000000);
884 if (retval
!= ERROR_OK
)
887 /* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash access) */
888 retval
= target_write_u32(target
, 0x40000000, 0x0001);
889 if (retval
!= ERROR_OK
)
892 /* dummy read of FASZR */
893 retval
= target_read_u32(target
, 0x40000000, &u32DummyRead
);
894 if (retval
!= ERROR_OK
)
897 /* allocate working area with flash chip erase code */
898 if (target_alloc_working_area(target
, sizeof(fm3_flash_erase_chip_code
),
899 &write_algorithm
) != ERROR_OK
) {
900 LOG_WARNING("no working area available, can't do block memory writes");
901 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
903 retval
= target_write_buffer(target
, write_algorithm
->address
,
904 sizeof(fm3_flash_erase_chip_code
), fm3_flash_erase_chip_code
);
905 if (retval
!= ERROR_OK
)
908 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
909 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
911 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
); /* u32FlashSeqAddress1 */
912 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* u32FlashSeqAddress2 */
914 buf_set_u32(reg_params
[0].value
, 0, 32, u32FlashSeqAddress1
);
915 buf_set_u32(reg_params
[1].value
, 0, 32, u32FlashSeqAddress2
);
917 retval
= target_run_algorithm(target
, 0, NULL
, 2, reg_params
,
918 write_algorithm
->address
, 0, 100000, &armv7m_info
);
919 if (retval
!= ERROR_OK
) {
920 LOG_ERROR("Error executing flash erase programming algorithm");
921 retval
= ERROR_FLASH_OPERATION_FAILED
;
925 target_free_working_area(target
, write_algorithm
);
927 destroy_reg_param(®_params
[0]);
928 destroy_reg_param(®_params
[1]);
930 retval
= fm3_busy_wait(target
, u32FlashSeqAddress2
, 20000); /* 20s timeout */
931 if (retval
!= ERROR_OK
)
934 /* FASZR = 0x02, Re-enables CPU Run Mode (32-bit Flash access) */
935 retval
= target_write_u32(target
, 0x40000000, 0x0002);
936 if (retval
!= ERROR_OK
)
939 retval
= target_read_u32(target
, 0x40000000, &u32DummyRead
); /* dummy read of FASZR */
944 COMMAND_HANDLER(fm3_handle_chip_erase_command
)
949 return ERROR_COMMAND_SYNTAX_ERROR
;
951 struct flash_bank
*bank
;
952 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
953 if (ERROR_OK
!= retval
)
956 if (fm3_chip_erase(bank
) == ERROR_OK
) {
957 /* set all sectors as erased */
958 for (i
= 0; i
< bank
->num_sectors
; i
++)
959 bank
->sectors
[i
].is_erased
= 1;
961 command_print(CMD_CTX
, "fm3 chip erase complete");
963 command_print(CMD_CTX
, "fm3 chip erase failed");
969 static const struct command_registration fm3_exec_command_handlers
[] = {
971 .name
= "chip_erase",
973 .handler
= fm3_handle_chip_erase_command
,
974 .mode
= COMMAND_EXEC
,
975 .help
= "Erase entire Flash device.",
977 COMMAND_REGISTRATION_DONE
980 static const struct command_registration fm3_command_handlers
[] = {
984 .help
= "fm3 Flash command group",
986 .chain
= fm3_exec_command_handlers
,
988 COMMAND_REGISTRATION_DONE
991 struct flash_driver fm3_flash
= {
993 .commands
= fm3_command_handlers
,
994 .flash_bank_command
= fm3_flash_bank_command
,
996 .write
= fm3_write_block
,
998 .auto_probe
= fm3_auto_probe
,
999 .erase_check
= default_flash_blank_check
,
1000 .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)