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

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)