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

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)