fm3: fix erase flash fail on using High Level Adapters.
[openocd.git] / src / flash / nor / fm3.c
1 /***************************************************************************
2 * Copyright (C) 2011 by Marc Willam, Holger Wech *
3 * openOCD.fseu(AT)de.fujitsu.com *
4 * Copyright (C) 2011 Ronny Strutz *
5 * *
6 * Copyright (C) 2013 Nemui Trinomius *
7 * nemuisan_kawausogasuki@live.jp *
8 * *
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. *
13 * *
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. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the *
21 * Free Software Foundation, Inc., *
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
23 ***************************************************************************/
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include "imp.h"
30 #include <helper/binarybuffer.h>
31 #include <target/algorithm.h>
32 #include <target/armv7m.h>
33
34 #define FLASH_DQ6 0x40 /* Data toggle flag bit (TOGG) position */
35 #define FLASH_DQ5 0x20 /* Time limit exceeding flag bit (TLOV) position */
36
37 enum fm3_variant {
38 mb9bfxx1, /* Flash Type '1' */
39 mb9bfxx2,
40 mb9bfxx3,
41 mb9bfxx4,
42 mb9bfxx5,
43 mb9bfxx6,
44 mb9bfxx7,
45 mb9bfxx8,
46
47 mb9afxx1, /* Flash Type '2' */
48 mb9afxx2,
49 mb9afxx3,
50 mb9afxx4,
51 mb9afxx5,
52 mb9afxx6,
53 mb9afxx7,
54 mb9afxx8,
55 };
56
57 enum fm3_flash_type {
58 fm3_no_flash_type = 0,
59 fm3_flash_type1 = 1,
60 fm3_flash_type2 = 2
61 };
62
63 struct fm3_flash_bank {
64 enum fm3_variant variant;
65 enum fm3_flash_type flashtype;
66 int probed;
67 };
68
69 FLASH_BANK_COMMAND_HANDLER(fm3_flash_bank_command)
70 {
71 struct fm3_flash_bank *fm3_info;
72
73 if (CMD_ARGC < 6)
74 return ERROR_COMMAND_SYNTAX_ERROR;
75
76 fm3_info = malloc(sizeof(struct fm3_flash_bank));
77 bank->driver_priv = fm3_info;
78
79 /* Flash type '1' */
80 if (strcmp(CMD_ARGV[5], "mb9bfxx1.cpu") == 0) {
81 fm3_info->variant = mb9bfxx1;
82 fm3_info->flashtype = fm3_flash_type1;
83 } else if (strcmp(CMD_ARGV[5], "mb9bfxx2.cpu") == 0) {
84 fm3_info->variant = mb9bfxx2;
85 fm3_info->flashtype = fm3_flash_type1;
86 } else if (strcmp(CMD_ARGV[5], "mb9bfxx3.cpu") == 0) {
87 fm3_info->variant = mb9bfxx3;
88 fm3_info->flashtype = fm3_flash_type1;
89 } else if (strcmp(CMD_ARGV[5], "mb9bfxx4.cpu") == 0) {
90 fm3_info->variant = mb9bfxx4;
91 fm3_info->flashtype = fm3_flash_type1;
92 } else if (strcmp(CMD_ARGV[5], "mb9bfxx5.cpu") == 0) {
93 fm3_info->variant = mb9bfxx5;
94 fm3_info->flashtype = fm3_flash_type1;
95 } else if (strcmp(CMD_ARGV[5], "mb9bfxx6.cpu") == 0) {
96 fm3_info->variant = mb9bfxx6;
97 fm3_info->flashtype = fm3_flash_type1;
98 } else if (strcmp(CMD_ARGV[5], "mb9bfxx7.cpu") == 0) {
99 fm3_info->variant = mb9bfxx7;
100 fm3_info->flashtype = fm3_flash_type1;
101 } else if (strcmp(CMD_ARGV[5], "mb9bfxx8.cpu") == 0) {
102 fm3_info->variant = mb9bfxx8;
103 fm3_info->flashtype = fm3_flash_type1;
104 } else if (strcmp(CMD_ARGV[5], "mb9afxx1.cpu") == 0) { /* Flash type '2' */
105 fm3_info->variant = mb9afxx1;
106 fm3_info->flashtype = fm3_flash_type2;
107 } else if (strcmp(CMD_ARGV[5], "mb9afxx2.cpu") == 0) {
108 fm3_info->variant = mb9afxx2;
109 fm3_info->flashtype = fm3_flash_type2;
110 } else if (strcmp(CMD_ARGV[5], "mb9afxx3.cpu") == 0) {
111 fm3_info->variant = mb9afxx3;
112 fm3_info->flashtype = fm3_flash_type2;
113 } else if (strcmp(CMD_ARGV[5], "mb9afxx4.cpu") == 0) {
114 fm3_info->variant = mb9afxx4;
115 fm3_info->flashtype = fm3_flash_type2;
116 } else if (strcmp(CMD_ARGV[5], "mb9afxx5.cpu") == 0) {
117 fm3_info->variant = mb9afxx5;
118 fm3_info->flashtype = fm3_flash_type2;
119 } else if (strcmp(CMD_ARGV[5], "mb9afxx6.cpu") == 0) {
120 fm3_info->variant = mb9afxx6;
121 fm3_info->flashtype = fm3_flash_type2;
122 } else if (strcmp(CMD_ARGV[5], "mb9afxx7.cpu") == 0) {
123 fm3_info->variant = mb9afxx7;
124 fm3_info->flashtype = fm3_flash_type2;
125 } else if (strcmp(CMD_ARGV[5], "mb9afxx8.cpu") == 0) {
126 fm3_info->variant = mb9afxx8;
127 fm3_info->flashtype = fm3_flash_type2;
128 }
129
130 /* unknown Flash type */
131 else {
132 LOG_ERROR("unknown fm3 variant: %s", CMD_ARGV[5]);
133 free(fm3_info);
134 return ERROR_FLASH_BANK_INVALID;
135 }
136
137 fm3_info->probed = 0;
138
139 return ERROR_OK;
140 }
141
142 /* Data polling algorithm */
143 static int fm3_busy_wait(struct target *target, uint32_t offset, int timeout_ms)
144 {
145 int retval = ERROR_OK;
146 uint8_t state1, state2;
147 int ms = 0;
148
149 /* While(1) loop exit via "break" and "return" on error */
150 while (1) {
151 /* dummy-read - see flash manual */
152 retval = target_read_u8(target, offset, &state1);
153 if (retval != ERROR_OK)
154 return retval;
155
156 /* Data polling 1 */
157 retval = target_read_u8(target, offset, &state1);
158 if (retval != ERROR_OK)
159 return retval;
160
161 /* Data polling 2 */
162 retval = target_read_u8(target, offset, &state2);
163 if (retval != ERROR_OK)
164 return retval;
165
166 /* Flash command finished via polled data equal? */
167 if ((state1 & FLASH_DQ6) == (state2 & FLASH_DQ6))
168 break;
169 /* Timeout Flag? */
170 else if (state1 & FLASH_DQ5) {
171 /* Retry data polling */
172
173 /* Data polling 1 */
174 retval = target_read_u8(target, offset, &state1);
175 if (retval != ERROR_OK)
176 return retval;
177
178 /* Data polling 2 */
179 retval = target_read_u8(target, offset, &state2);
180 if (retval != ERROR_OK)
181 return retval;
182
183 /* Flash command finished via polled data equal? */
184 if ((state1 & FLASH_DQ6) != (state2 & FLASH_DQ6))
185 return ERROR_FLASH_OPERATION_FAILED;
186
187 /* finish anyway */
188 break;
189 }
190 usleep(1000);
191 ++ms;
192
193 /* Polling time exceeded? */
194 if (ms > timeout_ms) {
195 LOG_ERROR("Polling data reading timed out!");
196 return ERROR_FLASH_OPERATION_FAILED;
197 }
198 }
199
200 if (retval == ERROR_OK)
201 LOG_DEBUG("fm3_busy_wait(%" PRIx32 ") needs about %d ms", offset, ms);
202
203 return retval;
204 }
205
206 static int fm3_erase(struct flash_bank *bank, int first, int last)
207 {
208 struct fm3_flash_bank *fm3_info = bank->driver_priv;
209 struct target *target = bank->target;
210 int retval = ERROR_OK;
211 uint32_t u32DummyRead;
212 int sector, odd;
213 uint32_t u32FlashType;
214 uint32_t u32FlashSeqAddress1;
215 uint32_t u32FlashSeqAddress2;
216
217 struct working_area *write_algorithm;
218 struct reg_param reg_params[3];
219 struct armv7m_algorithm armv7m_info;
220
221 u32FlashType = (uint32_t) fm3_info->flashtype;
222
223 if (u32FlashType == fm3_flash_type1) {
224 u32FlashSeqAddress1 = 0x00001550;
225 u32FlashSeqAddress2 = 0x00000AA8;
226 } else if (u32FlashType == fm3_flash_type2) {
227 u32FlashSeqAddress1 = 0x00000AA8;
228 u32FlashSeqAddress2 = 0x00000554;
229 } else {
230 LOG_ERROR("Flash/Device type unknown!");
231 return ERROR_FLASH_OPERATION_FAILED;
232 }
233
234 if (target->state != TARGET_HALTED) {
235 LOG_ERROR("Target not halted");
236 return ERROR_TARGET_NOT_HALTED;
237 }
238
239 /* RAMCODE used for fm3 Flash sector erase: */
240 /* R0 keeps Flash Sequence address 1 (u32FlashSeq1) */
241 /* R1 keeps Flash Sequence address 2 (u32FlashSeq2) */
242 /* R2 keeps Flash Offset address (ofs) */
243 const uint8_t fm3_flash_erase_sector_code[] = {
244 /* *(uint16_t*)u32FlashSeq1 = 0xAA; */
245 0xAA, 0x24, /* MOVS R4, #0xAA */
246 0x04, 0x80, /* STRH R4, [R0, #0] */
247 /* *(uint16_t*)u32FlashSeq2 = 0x55; */
248 0x55, 0x23, /* MOVS R3, #0x55 */
249 0x0B, 0x80, /* STRH R3, [R1, #0] */
250 /* *(uint16_t*)u32FlashSeq1 = 0x80; */
251 0x80, 0x25, /* MOVS R5, #0x80 */
252 0x05, 0x80, /* STRH R5, [R0, #0] */
253 /* *(uint16_t*)u32FlashSeq1 = 0xAA; */
254 0x04, 0x80, /* STRH R4, [R0, #0] */
255 /* *(uint16_t*)u32FlashSeq2 = 0x55; */
256 0x0B, 0x80, /* STRH R3, [R1, #0] */
257 /* Sector_Erase Command (0x30) */
258 /* *(uint16_t*)ofs = 0x30; */
259 0x30, 0x20, /* MOVS R0, #0x30 */
260 0x10, 0x80, /* STRH R0, [R2, #0] */
261 /* End Code */
262 0x00, 0xBE, /* BKPT #0 */
263 };
264
265 LOG_INFO("Fujitsu MB9[A/B]FXXX: Sector Erase ... (%d to %d)", first, last);
266
267 /* disable HW watchdog */
268 retval = target_write_u32(target, 0x40011C00, 0x1ACCE551);
269 if (retval != ERROR_OK)
270 return retval;
271
272 retval = target_write_u32(target, 0x40011C00, 0xE5331AAE);
273 if (retval != ERROR_OK)
274 return retval;
275
276 retval = target_write_u32(target, 0x40011008, 0x00000000);
277 if (retval != ERROR_OK)
278 return retval;
279
280 /* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash acccess) */
281 retval = target_write_u32(target, 0x40000000, 0x0001);
282 if (retval != ERROR_OK)
283 return retval;
284
285 /* dummy read of FASZR */
286 retval = target_read_u32(target, 0x40000000, &u32DummyRead);
287 if (retval != ERROR_OK)
288 return retval;
289
290 /* allocate working area with flash sector erase code */
291 if (target_alloc_working_area(target, sizeof(fm3_flash_erase_sector_code),
292 &write_algorithm) != ERROR_OK) {
293 LOG_WARNING("no working area available, can't do block memory writes");
294 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
295 }
296 retval = target_write_buffer(target, write_algorithm->address,
297 sizeof(fm3_flash_erase_sector_code), fm3_flash_erase_sector_code);
298 if (retval != ERROR_OK)
299 return retval;
300
301 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
302 armv7m_info.core_mode = ARM_MODE_THREAD;
303
304 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT); /* u32FlashSeqAddress1 */
305 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* u32FlashSeqAddress2 */
306 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* offset */
307
308 /* write code buffer and use Flash sector erase code within fm3 */
309 for (sector = first ; sector <= last ; sector++) {
310 uint32_t offset = bank->sectors[sector].offset;
311
312 for (odd = 0; odd < 2 ; odd++) {
313 if (odd)
314 offset += 4;
315
316 buf_set_u32(reg_params[0].value, 0, 32, u32FlashSeqAddress1);
317 buf_set_u32(reg_params[1].value, 0, 32, u32FlashSeqAddress2);
318 buf_set_u32(reg_params[2].value, 0, 32, offset);
319
320 retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
321 write_algorithm->address, 0, 100000, &armv7m_info);
322 if (retval != ERROR_OK) {
323 LOG_ERROR("Error executing flash erase programming algorithm");
324 retval = ERROR_FLASH_OPERATION_FAILED;
325 return retval;
326 }
327
328 retval = fm3_busy_wait(target, offset, 500);
329 if (retval != ERROR_OK)
330 return retval;
331 }
332 bank->sectors[sector].is_erased = 1;
333 }
334
335 target_free_working_area(target, write_algorithm);
336 destroy_reg_param(&reg_params[0]);
337 destroy_reg_param(&reg_params[1]);
338 destroy_reg_param(&reg_params[2]);
339
340 /* FASZR = 0x02, Enables CPU Run Mode (32-bit Flash acccess) */
341 retval = target_write_u32(target, 0x40000000, 0x0002);
342 if (retval != ERROR_OK)
343 return retval;
344
345 retval = target_read_u32(target, 0x40000000, &u32DummyRead); /* dummy read of FASZR */
346
347 return retval;
348 }
349
350 static int fm3_write_block(struct flash_bank *bank, uint8_t *buffer,
351 uint32_t offset, uint32_t count)
352 {
353 struct fm3_flash_bank *fm3_info = bank->driver_priv;
354 struct target *target = bank->target;
355 uint32_t buffer_size = 2048; /* Default minimum value */
356 struct working_area *write_algorithm;
357 struct working_area *source;
358 uint32_t address = bank->base + offset;
359 struct reg_param reg_params[6];
360 struct armv7m_algorithm armv7m_info;
361 int retval = ERROR_OK;
362 uint32_t u32FlashType;
363 uint32_t u32FlashSeqAddress1;
364 uint32_t u32FlashSeqAddress2;
365
366 /* Increase buffer_size if needed */
367 if (buffer_size < (target->working_area_size / 2))
368 buffer_size = (target->working_area_size / 2);
369
370 u32FlashType = (uint32_t) fm3_info->flashtype;
371
372 if (u32FlashType == fm3_flash_type1) {
373 u32FlashSeqAddress1 = 0x00001550;
374 u32FlashSeqAddress2 = 0x00000AA8;
375 } else if (u32FlashType == fm3_flash_type2) {
376 u32FlashSeqAddress1 = 0x00000AA8;
377 u32FlashSeqAddress2 = 0x00000554;
378 } else {
379 LOG_ERROR("Flash/Device type unknown!");
380 return ERROR_FLASH_OPERATION_FAILED;
381 }
382
383 /* RAMCODE used for fm3 Flash programming: */
384 /* R0 keeps source start address (u32Source) */
385 /* R1 keeps target start address (u32Target) */
386 /* R2 keeps number of halfwords to write (u32Count) */
387 /* R3 keeps Flash Sequence address 1 (u32FlashSeq1) */
388 /* R4 keeps Flash Sequence address 2 (u32FlashSeq2) */
389 /* R5 returns result value (u32FlashResult) */
390
391 static const uint8_t fm3_flash_write_code[] = {
392 /* fm3_FLASH_IF->FASZ &= 0xFFFD; */
393 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
394 0x2D, 0x68, /* LDR R5, [R5] */
395 0x4F, 0xF6, 0xFD, 0x76, /* MOVW R6, #0xFFFD */
396 0x35, 0x40, /* ANDS R5, R5, R6 */
397 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
398 0x35, 0x60, /* STR R5, [R6] */
399 /* fm3_FLASH_IF->FASZ |= 1; */
400 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
401 0x2D, 0x68, /* LDR R5, [R3] */
402 0x55, 0xF0, 0x01, 0x05, /* ORRS.W R5, R5, #1 */
403 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
404 0x35, 0x60, /* STR R5, [R6] */
405 /* u32DummyRead = fm3_FLASH_IF->FASZ; */
406 0x28, 0x4D, /* LDR.N R5, ??u32DummyRead */
407 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
408 0x36, 0x68, /* LDR R6, [R6] */
409 0x2E, 0x60, /* STR R6, [R5] */
410 /* u32FlashResult = FLASH_WRITE_NO_RESULT */
411 0x26, 0x4D, /* LDR.N R5, ??u32FlashResult */
412 0x00, 0x26, /* MOVS R6, #0 */
413 0x2E, 0x60, /* STR R6, [R5] */
414 /* while ((u32Count > 0 ) */
415 /* && (u32FlashResult */
416 /* == FLASH_WRITE_NO_RESULT)) */
417 0x01, 0x2A, /* L0: CMP R2, #1 */
418 0x2C, 0xDB, /* BLT.N L1 */
419 0x24, 0x4D, /* LDR.N R5, ??u32FlashResult */
420 0x2D, 0x68, /* LDR R5, [R5] */
421 0x00, 0x2D, /* CMP R5, #0 */
422 0x28, 0xD1, /* BNE.N L1 */
423 /* *u32FlashSeq1 = FLASH_WRITE_1; */
424 0xAA, 0x25, /* MOVS R5, #0xAA */
425 0x1D, 0x60, /* STR R5, [R3] */
426 /* *u32FlashSeq2 = FLASH_WRITE_2; */
427 0x55, 0x25, /* MOVS R5, #0x55 */
428 0x25, 0x60, /* STR R5, [R4] */
429 /* *u32FlashSeq1 = FLASH_WRITE_3; */
430 0xA0, 0x25, /* MOVS R5, #0xA0 */
431 0x1D, 0x60, /* STRH R5, [R3] */
432 /* *(volatile uint16_t*)u32Target */
433 /* = *(volatile uint16_t*)u32Source; */
434 0x05, 0x88, /* LDRH R5, [R0] */
435 0x0D, 0x80, /* STRH R5, [R1] */
436 /* while (u32FlashResult */
437 /* == FLASH_WRITE_NO_RESTULT) */
438 0x1E, 0x4D, /* L2: LDR.N R5, ??u32FlashResult */
439 0x2D, 0x68, /* LDR R5, [R5] */
440 0x00, 0x2D, /* CMP R5, #0 */
441 0x11, 0xD1, /* BNE.N L3 */
442 /* if ((*(volatile uint16_t*)u32Target */
443 /* & FLASH_DQ5) == FLASH_DQ5) */
444 0x0D, 0x88, /* LDRH R5, [R1] */
445 0xAD, 0x06, /* LSLS R5, R5, #0x1A */
446 0x02, 0xD5, /* BPL.N L4 */
447 /* u32FlashResult = FLASH_WRITE_TIMEOUT */
448 0x1A, 0x4D, /* LDR.N R5, ??u32FlashResult */
449 0x02, 0x26, /* MOVS R6, #2 */
450 0x2E, 0x60, /* STR R6, [R5] */
451 /* if ((*(volatile uint16_t *)u32Target */
452 /* & FLASH_DQ7) */
453 /* == (*(volatile uint16_t*)u32Source */
454 /* & FLASH_DQ7)) */
455 0x0D, 0x88, /* L4: LDRH R5, [R1] */
456 0x15, 0xF0, 0x80, 0x05, /* ANDS.W R5, R5, #0x80 */
457 0x06, 0x88, /* LDRH R6, [R0] */
458 0x16, 0xF0, 0x80, 0x06, /* ANDS.W R6, R6, #0x80 */
459 0xB5, 0x42, /* CMP R5, R6 */
460 0xED, 0xD1, /* BNE.N L2 */
461 /* u32FlashResult = FLASH_WRITE_OKAY */
462 0x15, 0x4D, /* LDR.N R5, ??u32FlashResult */
463 0x01, 0x26, /* MOVS R6, #1 */
464 0x2E, 0x60, /* STR R6, [R5] */
465 0xE9, 0xE7, /* B.N L2 */
466 /* if (u32FlashResult */
467 /* != FLASH_WRITE_TIMEOUT) */
468 0x13, 0x4D, /* LDR.N R5, ??u32FlashResult */
469 0x2D, 0x68, /* LDR R5, [R5] */
470 0x02, 0x2D, /* CMP R5, #2 */
471 0x02, 0xD0, /* BEQ.N L5 */
472 /* u32FlashResult = FLASH_WRITE_NO_RESULT */
473 0x11, 0x4D, /* LDR.N R5, ??u32FlashResult */
474 0x00, 0x26, /* MOVS R6, #0 */
475 0x2E, 0x60, /* STR R6, [R5] */
476 /* u32Count--; */
477 0x52, 0x1E, /* L5: SUBS R2, R2, #1 */
478 /* u32Source += 2; */
479 0x80, 0x1C, /* ADDS R0, R0, #2 */
480 /* u32Target += 2; */
481 0x89, 0x1C, /* ADDS R1, R1, #2 */
482 0xD0, 0xE7, /* B.N L0 */
483 /* fm3_FLASH_IF->FASZ &= 0xFFFE; */
484 0x5F, 0xF0, 0x80, 0x45, /* L1: MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
485 0x2D, 0x68, /* LDR R5, [R5] */
486 0x4F, 0xF6, 0xFE, 0x76, /* MOVW R6, #0xFFFE */
487 0x35, 0x40, /* ANDS R5, R5, R6 */
488 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
489 0x35, 0x60, /* STR R5, [R6] */
490 /* fm3_FLASH_IF->FASZ |= 2; */
491 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
492 0x2D, 0x68, /* LDR R5, [R5] */
493 0x55, 0xF0, 0x02, 0x05, /* ORRS.W R5, R5, #2 */
494 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
495 0x35, 0x60, /* STR R5, [R6] */
496 /* u32DummyRead = fm3_FLASH_IF->FASZ; */
497 0x04, 0x4D, /* LDR.N R5, ??u32DummyRead */
498 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
499 0x36, 0x68, /* LDR R6, [R6] */
500 0x2E, 0x60, /* STR R6, [R5] */
501 /* copy u32FlashResult to R3 for return */
502 /* value */
503 0xDF, 0xF8, 0x08, 0x50, /* LDR.W R5, ??u32FlashResult */
504 0x2D, 0x68, /* LDR R5, [R5] */
505 /* Breakpoint here */
506 0x00, 0xBE, /* BKPT #0 */
507
508 /* The following address pointers assume, that the code is running from */
509 /* SRAM basic-address + 8.These address pointers will be patched, if a */
510 /* different start address in RAM is used (e.g. for Flash type 2)! */
511 /* Default SRAM basic-address is 0x20000000. */
512 0x00, 0x00, 0x00, 0x20, /* u32DummyRead address in RAM (0x20000000) */
513 0x04, 0x00, 0x00, 0x20 /* u32FlashResult address in RAM (0x20000004) */
514 };
515
516 LOG_INFO("Fujitsu MB9[A/B]FXXX: FLASH Write ...");
517
518 /* disable HW watchdog */
519 retval = target_write_u32(target, 0x40011C00, 0x1ACCE551);
520 if (retval != ERROR_OK)
521 return retval;
522
523 retval = target_write_u32(target, 0x40011C00, 0xE5331AAE);
524 if (retval != ERROR_OK)
525 return retval;
526
527 retval = target_write_u32(target, 0x40011008, 0x00000000);
528 if (retval != ERROR_OK)
529 return retval;
530
531 count = count / 2; /* number bytes -> number halfwords */
532
533 /* check code alignment */
534 if (offset & 0x1) {
535 LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset);
536 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
537 }
538
539 /* allocate working area and variables with flash programming code */
540 if (target_alloc_working_area(target, sizeof(fm3_flash_write_code) + 8,
541 &write_algorithm) != ERROR_OK) {
542 LOG_WARNING("no working area available, can't do block memory writes");
543 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
544 }
545
546 retval = target_write_buffer(target, write_algorithm->address + 8,
547 sizeof(fm3_flash_write_code), fm3_flash_write_code);
548 if (retval != ERROR_OK)
549 return retval;
550
551 /* Patching 'local variable address' */
552 /* Algorithm: u32DummyRead: */
553 retval = target_write_u32(target, (write_algorithm->address + 8)
554 + sizeof(fm3_flash_write_code) - 8, (write_algorithm->address));
555 if (retval != ERROR_OK)
556 return retval;
557 /* Algorithm: u32FlashResult: */
558 retval = target_write_u32(target, (write_algorithm->address + 8)
559 + sizeof(fm3_flash_write_code) - 4, (write_algorithm->address) + 4);
560 if (retval != ERROR_OK)
561 return retval;
562
563
564
565 /* memory buffer */
566 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) {
567 buffer_size /= 2;
568 if (buffer_size <= 256) {
569 /* free working area, write algorithm already allocated */
570 target_free_working_area(target, write_algorithm);
571
572 LOG_WARNING("No large enough working area available, can't do block memory writes");
573 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
574 }
575 }
576
577 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
578 armv7m_info.core_mode = ARM_MODE_THREAD;
579
580 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT); /* source start address */
581 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* target start address */
582 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* number of halfwords to program */
583 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT); /* Flash Sequence address 1 */
584 init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT); /* Flash Sequence address 1 */
585 init_reg_param(&reg_params[5], "r5", 32, PARAM_IN); /* result */
586
587 /* write code buffer and use Flash programming code within fm3 */
588 /* Set breakpoint to 0 with time-out of 1000 ms */
589 while (count > 0) {
590 uint32_t thisrun_count = (count > (buffer_size / 2)) ? (buffer_size / 2) : count;
591
592 retval = target_write_buffer(target, source->address, thisrun_count * 2, buffer);
593 if (retval != ERROR_OK)
594 break;
595
596 buf_set_u32(reg_params[0].value, 0, 32, source->address);
597 buf_set_u32(reg_params[1].value, 0, 32, address);
598 buf_set_u32(reg_params[2].value, 0, 32, thisrun_count);
599 buf_set_u32(reg_params[3].value, 0, 32, u32FlashSeqAddress1);
600 buf_set_u32(reg_params[4].value, 0, 32, u32FlashSeqAddress2);
601
602 retval = target_run_algorithm(target, 0, NULL, 6, reg_params,
603 (write_algorithm->address + 8), 0, 1000, &armv7m_info);
604 if (retval != ERROR_OK) {
605 LOG_ERROR("Error executing fm3 Flash programming algorithm");
606 retval = ERROR_FLASH_OPERATION_FAILED;
607 break;
608 }
609
610 if (buf_get_u32(reg_params[5].value, 0, 32) != ERROR_OK) {
611 LOG_ERROR("Fujitsu MB9[A/B]FXXX: Flash programming ERROR (Timeout) -> Reg R3: %" PRIx32,
612 buf_get_u32(reg_params[5].value, 0, 32));
613 retval = ERROR_FLASH_OPERATION_FAILED;
614 break;
615 }
616
617 buffer += thisrun_count * 2;
618 address += thisrun_count * 2;
619 count -= thisrun_count;
620 }
621
622 target_free_working_area(target, source);
623 target_free_working_area(target, write_algorithm);
624
625 destroy_reg_param(&reg_params[0]);
626 destroy_reg_param(&reg_params[1]);
627 destroy_reg_param(&reg_params[2]);
628 destroy_reg_param(&reg_params[3]);
629 destroy_reg_param(&reg_params[4]);
630 destroy_reg_param(&reg_params[5]);
631
632 return retval;
633 }
634
635 static int fm3_probe(struct flash_bank *bank)
636 {
637 struct fm3_flash_bank *fm3_info = bank->driver_priv;
638 uint16_t num_pages;
639
640 if (bank->target->state != TARGET_HALTED) {
641 LOG_ERROR("Target not halted");
642 return ERROR_TARGET_NOT_HALTED;
643 }
644
645 /*
646 -- page-- start -- blocksize - mpu - totalFlash --
647 page0 0x00000 16k
648 page1 0x04000 16k
649 page2 0x08000 96k ___ fxx3 128k Flash
650 page3 0x20000 128k ___ fxx4 256k Flash
651 page4 0x40000 128k ___ fxx5 384k Flash
652 page5 0x60000 128k ___ fxx6 512k Flash
653 -----------------------
654 page6 0x80000 128k
655 page7 0xa0000 128k ___ fxx7 256k Flash
656 page8 0xc0000 128k
657 page9 0xe0000 128k ___ fxx8 256k Flash
658 */
659
660 num_pages = 10; /* max number of Flash pages for malloc */
661 fm3_info->probed = 0;
662
663 bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
664 bank->base = 0x00000000;
665 bank->size = 32 * 1024; /* bytes */
666
667 bank->sectors[0].offset = 0;
668 bank->sectors[0].size = 16 * 1024;
669 bank->sectors[0].is_erased = -1;
670 bank->sectors[0].is_protected = -1;
671
672 bank->sectors[1].offset = 0x4000;
673 bank->sectors[1].size = 16 * 1024;
674 bank->sectors[1].is_erased = -1;
675 bank->sectors[1].is_protected = -1;
676
677 if ((fm3_info->variant == mb9bfxx1)
678 || (fm3_info->variant == mb9afxx1)) {
679 num_pages = 3;
680 bank->size = 64 * 1024; /* bytes */
681 bank->num_sectors = num_pages;
682
683 bank->sectors[2].offset = 0x8000;
684 bank->sectors[2].size = 32 * 1024;
685 bank->sectors[2].is_erased = -1;
686 bank->sectors[2].is_protected = -1;
687 }
688
689 if ((fm3_info->variant == mb9bfxx2)
690 || (fm3_info->variant == mb9bfxx4)
691 || (fm3_info->variant == mb9bfxx5)
692 || (fm3_info->variant == mb9bfxx6)
693 || (fm3_info->variant == mb9bfxx7)
694 || (fm3_info->variant == mb9bfxx8)
695 || (fm3_info->variant == mb9afxx2)
696 || (fm3_info->variant == mb9afxx4)
697 || (fm3_info->variant == mb9afxx5)
698 || (fm3_info->variant == mb9afxx6)
699 || (fm3_info->variant == mb9afxx7)
700 || (fm3_info->variant == mb9afxx8)) {
701 num_pages = 3;
702 bank->size = 128 * 1024; /* bytes */
703 bank->num_sectors = num_pages;
704
705 bank->sectors[2].offset = 0x8000;
706 bank->sectors[2].size = 96 * 1024;
707 bank->sectors[2].is_erased = -1;
708 bank->sectors[2].is_protected = -1;
709 }
710
711 if ((fm3_info->variant == mb9bfxx4)
712 || (fm3_info->variant == mb9bfxx5)
713 || (fm3_info->variant == mb9bfxx6)
714 || (fm3_info->variant == mb9bfxx7)
715 || (fm3_info->variant == mb9bfxx8)
716 || (fm3_info->variant == mb9afxx4)
717 || (fm3_info->variant == mb9afxx5)
718 || (fm3_info->variant == mb9afxx6)
719 || (fm3_info->variant == mb9afxx7)
720 || (fm3_info->variant == mb9afxx8)) {
721 num_pages = 4;
722 bank->size = 256 * 1024; /* bytes */
723 bank->num_sectors = num_pages;
724
725 bank->sectors[3].offset = 0x20000;
726 bank->sectors[3].size = 128 * 1024;
727 bank->sectors[3].is_erased = -1;
728 bank->sectors[3].is_protected = -1;
729 }
730
731 if ((fm3_info->variant == mb9bfxx5)
732 || (fm3_info->variant == mb9bfxx6)
733 || (fm3_info->variant == mb9bfxx7)
734 || (fm3_info->variant == mb9bfxx8)
735 || (fm3_info->variant == mb9afxx5)
736 || (fm3_info->variant == mb9afxx6)
737 || (fm3_info->variant == mb9afxx7)
738 || (fm3_info->variant == mb9afxx8)) {
739 num_pages = 5;
740 bank->size = 384 * 1024; /* bytes */
741 bank->num_sectors = num_pages;
742
743 bank->sectors[4].offset = 0x40000;
744 bank->sectors[4].size = 128 * 1024;
745 bank->sectors[4].is_erased = -1;
746 bank->sectors[4].is_protected = -1;
747 }
748
749 if ((fm3_info->variant == mb9bfxx6)
750 || (fm3_info->variant == mb9bfxx7)
751 || (fm3_info->variant == mb9bfxx8)
752 || (fm3_info->variant == mb9afxx6)
753 || (fm3_info->variant == mb9afxx7)
754 || (fm3_info->variant == mb9afxx8)) {
755 num_pages = 6;
756 bank->size = 512 * 1024; /* bytes */
757 bank->num_sectors = num_pages;
758
759 bank->sectors[5].offset = 0x60000;
760 bank->sectors[5].size = 128 * 1024;
761 bank->sectors[5].is_erased = -1;
762 bank->sectors[5].is_protected = -1;
763 }
764
765 if ((fm3_info->variant == mb9bfxx7)
766 || (fm3_info->variant == mb9bfxx8)
767 || (fm3_info->variant == mb9afxx7)
768 || (fm3_info->variant == mb9afxx8)) {
769 num_pages = 8;
770 bank->size = 768 * 1024; /* bytes */
771 bank->num_sectors = num_pages;
772
773 bank->sectors[6].offset = 0x80000;
774 bank->sectors[6].size = 128 * 1024;
775 bank->sectors[6].is_erased = -1;
776 bank->sectors[6].is_protected = -1;
777
778 bank->sectors[7].offset = 0xa0000;
779 bank->sectors[7].size = 128 * 1024;
780 bank->sectors[7].is_erased = -1;
781 bank->sectors[7].is_protected = -1;
782 }
783
784 if ((fm3_info->variant == mb9bfxx8)
785 || (fm3_info->variant == mb9afxx8)) {
786 num_pages = 10;
787 bank->size = 1024 * 1024; /* bytes */
788 bank->num_sectors = num_pages;
789
790 bank->sectors[8].offset = 0xc0000;
791 bank->sectors[8].size = 128 * 1024;
792 bank->sectors[8].is_erased = -1;
793 bank->sectors[8].is_protected = -1;
794
795 bank->sectors[9].offset = 0xe0000;
796 bank->sectors[9].size = 128 * 1024;
797 bank->sectors[9].is_erased = -1;
798 bank->sectors[9].is_protected = -1;
799 }
800
801 fm3_info->probed = 1;
802
803 return ERROR_OK;
804 }
805
806 static int fm3_auto_probe(struct flash_bank *bank)
807 {
808 struct fm3_flash_bank *fm3_info = bank->driver_priv;
809 if (fm3_info->probed)
810 return ERROR_OK;
811 return fm3_probe(bank);
812 }
813
814 /* Chip erase */
815 static int fm3_chip_erase(struct flash_bank *bank)
816 {
817 struct target *target = bank->target;
818 struct fm3_flash_bank *fm3_info2 = bank->driver_priv;
819 int retval = ERROR_OK;
820 uint32_t u32DummyRead;
821 uint32_t u32FlashType;
822 uint32_t u32FlashSeqAddress1;
823 uint32_t u32FlashSeqAddress2;
824
825 struct working_area *write_algorithm;
826 struct reg_param reg_params[3];
827 struct armv7m_algorithm armv7m_info;
828
829 u32FlashType = (uint32_t) fm3_info2->flashtype;
830
831 if (u32FlashType == fm3_flash_type1) {
832 LOG_INFO("*** Erasing mb9bfxxx type");
833 u32FlashSeqAddress1 = 0x00001550;
834 u32FlashSeqAddress2 = 0x00000AA8;
835 } else if (u32FlashType == fm3_flash_type2) {
836 LOG_INFO("*** Erasing mb9afxxx type");
837 u32FlashSeqAddress1 = 0x00000AA8;
838 u32FlashSeqAddress2 = 0x00000554;
839 } else {
840 LOG_ERROR("Flash/Device type unknown!");
841 return ERROR_FLASH_OPERATION_FAILED;
842 }
843
844 if (target->state != TARGET_HALTED) {
845 LOG_ERROR("Target not halted");
846 return ERROR_TARGET_NOT_HALTED;
847 }
848
849 /* RAMCODE used for fm3 Flash chip erase: */
850 /* R0 keeps Flash Sequence address 1 (u32FlashSeq1) */
851 /* R1 keeps Flash Sequence address 2 (u32FlashSeq2) */
852 const uint8_t fm3_flash_erase_chip_code[] = {
853 /* *(uint16_t*)u32FlashSeq1 = 0xAA; */
854 0xAA, 0x22, /* MOVS R2, #0xAA */
855 0x02, 0x80, /* STRH R2, [R0, #0] */
856 /* *(uint16_t*)u32FlashSeq2 = 0x55; */
857 0x55, 0x23, /* MOVS R3, #0x55 */
858 0x0B, 0x80, /* STRH R3, [R1, #0] */
859 /* *(uint16_t*)u32FlashSeq1 = 0x80; */
860 0x80, 0x24, /* MOVS R4, #0x80 */
861 0x04, 0x80, /* STRH R4, [R0, #0] */
862 /* *(uint16_t*)u32FlashSeq1 = 0xAA; */
863 0x02, 0x80, /* STRH R2, [R0, #0] */
864 /* *(uint16_t*)u32FlashSeq2 = 0x55; */
865 0x0B, 0x80, /* STRH R3, [R1, #0] */
866 /* Chip_Erase Command 0x10 */
867 /* *(uint16_t*)u32FlashSeq1 = 0x10; */
868 0x10, 0x21, /* MOVS R1, #0x10 */
869 0x01, 0x80, /* STRH R1, [R0, #0] */
870 /* End Code */
871 0x00, 0xBE, /* BKPT #0 */
872 };
873
874 LOG_INFO("Fujitsu MB9[A/B]xxx: Chip Erase ... (may take several seconds)");
875
876 /* disable HW watchdog */
877 retval = target_write_u32(target, 0x40011C00, 0x1ACCE551);
878 if (retval != ERROR_OK)
879 return retval;
880
881 retval = target_write_u32(target, 0x40011C00, 0xE5331AAE);
882 if (retval != ERROR_OK)
883 return retval;
884
885 retval = target_write_u32(target, 0x40011008, 0x00000000);
886 if (retval != ERROR_OK)
887 return retval;
888
889 /* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash access) */
890 retval = target_write_u32(target, 0x40000000, 0x0001);
891 if (retval != ERROR_OK)
892 return retval;
893
894 /* dummy read of FASZR */
895 retval = target_read_u32(target, 0x40000000, &u32DummyRead);
896 if (retval != ERROR_OK)
897 return retval;
898
899 /* allocate working area with flash chip erase code */
900 if (target_alloc_working_area(target, sizeof(fm3_flash_erase_chip_code),
901 &write_algorithm) != ERROR_OK) {
902 LOG_WARNING("no working area available, can't do block memory writes");
903 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
904 }
905 retval = target_write_buffer(target, write_algorithm->address,
906 sizeof(fm3_flash_erase_chip_code), fm3_flash_erase_chip_code);
907 if (retval != ERROR_OK)
908 return retval;
909
910 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
911 armv7m_info.core_mode = ARM_MODE_THREAD;
912
913 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT); /* u32FlashSeqAddress1 */
914 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* u32FlashSeqAddress2 */
915
916 buf_set_u32(reg_params[0].value, 0, 32, u32FlashSeqAddress1);
917 buf_set_u32(reg_params[1].value, 0, 32, u32FlashSeqAddress2);
918
919 retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
920 write_algorithm->address, 0, 100000, &armv7m_info);
921 if (retval != ERROR_OK) {
922 LOG_ERROR("Error executing flash erase programming algorithm");
923 retval = ERROR_FLASH_OPERATION_FAILED;
924 return retval;
925 }
926
927 target_free_working_area(target, write_algorithm);
928
929 destroy_reg_param(&reg_params[0]);
930 destroy_reg_param(&reg_params[1]);
931
932 retval = fm3_busy_wait(target, u32FlashSeqAddress2, 20000); /* 20s timeout */
933 if (retval != ERROR_OK)
934 return retval;
935
936 /* FASZR = 0x02, Re-enables CPU Run Mode (32-bit Flash access) */
937 retval = target_write_u32(target, 0x40000000, 0x0002);
938 if (retval != ERROR_OK)
939 return retval;
940
941 retval = target_read_u32(target, 0x40000000, &u32DummyRead); /* dummy read of FASZR */
942
943 return retval;
944 }
945
946 COMMAND_HANDLER(fm3_handle_chip_erase_command)
947 {
948 int i;
949
950 if (CMD_ARGC < 1)
951 return ERROR_COMMAND_SYNTAX_ERROR;
952
953 struct flash_bank *bank;
954 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
955 if (ERROR_OK != retval)
956 return retval;
957
958 if (fm3_chip_erase(bank) == ERROR_OK) {
959 /* set all sectors as erased */
960 for (i = 0; i < bank->num_sectors; i++)
961 bank->sectors[i].is_erased = 1;
962
963 command_print(CMD_CTX, "fm3 chip erase complete");
964 } else {
965 command_print(CMD_CTX, "fm3 chip erase failed");
966 }
967
968 return ERROR_OK;
969 }
970
971 static const struct command_registration fm3_exec_command_handlers[] = {
972 {
973 .name = "chip_erase",
974 .usage = "<bank>",
975 .handler = fm3_handle_chip_erase_command,
976 .mode = COMMAND_EXEC,
977 .help = "Erase entire Flash device.",
978 },
979 COMMAND_REGISTRATION_DONE
980 };
981
982 static const struct command_registration fm3_command_handlers[] = {
983 {
984 .name = "fm3",
985 .mode = COMMAND_ANY,
986 .help = "fm3 Flash command group",
987 .usage = "",
988 .chain = fm3_exec_command_handlers,
989 },
990 COMMAND_REGISTRATION_DONE
991 };
992
993 struct flash_driver fm3_flash = {
994 .name = "fm3",
995 .commands = fm3_command_handlers,
996 .flash_bank_command = fm3_flash_bank_command,
997 .erase = fm3_erase,
998 .write = fm3_write_block,
999 .probe = fm3_probe,
1000 .auto_probe = fm3_auto_probe,
1001 .erase_check = default_flash_blank_check,
1002 };

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)