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

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)