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

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)