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

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)