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

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)