openocd: fix simple cases of Yoda condition
[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 bool 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 = false;
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, unsigned int first,
205 unsigned int last)
206 {
207 struct fm3_flash_bank *fm3_info = bank->driver_priv;
208 struct target *target = bank->target;
209 int retval = ERROR_OK;
210 uint32_t u32_dummy_read;
211 int odd;
212 uint32_t u32_flash_type;
213 uint32_t u32_flash_seq_address1;
214 uint32_t u32_flash_seq_address2;
215
216 struct working_area *write_algorithm;
217 struct reg_param reg_params[3];
218 struct armv7m_algorithm armv7m_info;
219
220 u32_flash_type = (uint32_t) fm3_info->flashtype;
221
222 if (u32_flash_type == FM3_FLASH_TYPE1) {
223 u32_flash_seq_address1 = 0x00001550;
224 u32_flash_seq_address2 = 0x00000AA8;
225 } else if (u32_flash_type == FM3_FLASH_TYPE2) {
226 u32_flash_seq_address1 = 0x00000AA8;
227 u32_flash_seq_address2 = 0x00000554;
228 } else {
229 LOG_ERROR("Flash/Device type unknown!");
230 return ERROR_FLASH_OPERATION_FAILED;
231 }
232
233 if (target->state != TARGET_HALTED) {
234 LOG_ERROR("Target not halted");
235 return ERROR_TARGET_NOT_HALTED;
236 }
237
238 /* RAMCODE used for fm3 Flash sector erase: */
239 /* R0 keeps Flash Sequence address 1 (u32FlashSeq1) */
240 /* R1 keeps Flash Sequence address 2 (u32FlashSeq2) */
241 /* R2 keeps Flash Offset address (ofs) */
242 static const uint8_t fm3_flash_erase_sector_code[] = {
243 /* *(uint16_t*)u32FlashSeq1 = 0xAA; */
244 0xAA, 0x24, /* MOVS R4, #0xAA */
245 0x04, 0x80, /* STRH R4, [R0, #0] */
246 /* *(uint16_t*)u32FlashSeq2 = 0x55; */
247 0x55, 0x23, /* MOVS R3, #0x55 */
248 0x0B, 0x80, /* STRH R3, [R1, #0] */
249 /* *(uint16_t*)u32FlashSeq1 = 0x80; */
250 0x80, 0x25, /* MOVS R5, #0x80 */
251 0x05, 0x80, /* STRH R5, [R0, #0] */
252 /* *(uint16_t*)u32FlashSeq1 = 0xAA; */
253 0x04, 0x80, /* STRH R4, [R0, #0] */
254 /* *(uint16_t*)u32FlashSeq2 = 0x55; */
255 0x0B, 0x80, /* STRH R3, [R1, #0] */
256 /* Sector_Erase Command (0x30) */
257 /* *(uint16_t*)ofs = 0x30; */
258 0x30, 0x20, /* MOVS R0, #0x30 */
259 0x10, 0x80, /* STRH R0, [R2, #0] */
260 /* End Code */
261 0x00, 0xBE, /* BKPT #0 */
262 };
263
264 LOG_INFO("Fujitsu MB9[A/B]FXXX: Sector Erase ... (%u to %u)", first, last);
265
266 /* disable HW watchdog */
267 retval = target_write_u32(target, 0x40011C00, 0x1ACCE551);
268 if (retval != ERROR_OK)
269 return retval;
270
271 retval = target_write_u32(target, 0x40011C00, 0xE5331AAE);
272 if (retval != ERROR_OK)
273 return retval;
274
275 retval = target_write_u32(target, 0x40011008, 0x00000000);
276 if (retval != ERROR_OK)
277 return retval;
278
279 /* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash access) */
280 retval = target_write_u32(target, 0x40000000, 0x0001);
281 if (retval != ERROR_OK)
282 return retval;
283
284 /* dummy read of FASZR */
285 retval = target_read_u32(target, 0x40000000, &u32_dummy_read);
286 if (retval != ERROR_OK)
287 return retval;
288
289 /* allocate working area with flash sector erase code */
290 if (target_alloc_working_area(target, sizeof(fm3_flash_erase_sector_code),
291 &write_algorithm) != ERROR_OK) {
292 LOG_WARNING("no working area available, can't do block memory writes");
293 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
294 }
295 retval = target_write_buffer(target, write_algorithm->address,
296 sizeof(fm3_flash_erase_sector_code), fm3_flash_erase_sector_code);
297 if (retval != ERROR_OK)
298 return retval;
299
300 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
301 armv7m_info.core_mode = ARM_MODE_THREAD;
302
303 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT); /* u32_flash_seq_address1 */
304 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* u32_flash_seq_address2 */
305 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* offset */
306
307 /* write code buffer and use Flash sector erase code within fm3 */
308 for (unsigned int sector = first ; sector <= last ; sector++) {
309 uint32_t offset = bank->sectors[sector].offset;
310
311 for (odd = 0; odd < 2 ; odd++) {
312 if (odd)
313 offset += 4;
314
315 buf_set_u32(reg_params[0].value, 0, 32, u32_flash_seq_address1);
316 buf_set_u32(reg_params[1].value, 0, 32, u32_flash_seq_address2);
317 buf_set_u32(reg_params[2].value, 0, 32, offset);
318
319 retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
320 write_algorithm->address, 0, 100000, &armv7m_info);
321 if (retval != ERROR_OK) {
322 LOG_ERROR("Error executing flash erase programming algorithm");
323 retval = ERROR_FLASH_OPERATION_FAILED;
324 return retval;
325 }
326
327 retval = fm3_busy_wait(target, offset, 500);
328 if (retval != ERROR_OK)
329 return retval;
330 }
331 bank->sectors[sector].is_erased = 1;
332 }
333
334 target_free_working_area(target, write_algorithm);
335 destroy_reg_param(&reg_params[0]);
336 destroy_reg_param(&reg_params[1]);
337 destroy_reg_param(&reg_params[2]);
338
339 /* FASZR = 0x02, Enables CPU Run Mode (32-bit Flash access) */
340 retval = target_write_u32(target, 0x40000000, 0x0002);
341 if (retval != ERROR_OK)
342 return retval;
343
344 retval = target_read_u32(target, 0x40000000, &u32_dummy_read); /* dummy read of FASZR */
345
346 return retval;
347 }
348
349 static int fm3_write_block(struct flash_bank *bank, const uint8_t *buffer,
350 uint32_t offset, uint32_t count)
351 {
352 struct fm3_flash_bank *fm3_info = bank->driver_priv;
353 struct target *target = bank->target;
354 uint32_t buffer_size = 2048; /* Default minimum value */
355 struct working_area *write_algorithm;
356 struct working_area *source;
357 uint32_t address = bank->base + offset;
358 struct reg_param reg_params[6];
359 struct armv7m_algorithm armv7m_info;
360 int retval = ERROR_OK;
361 uint32_t u32_flash_type;
362 uint32_t u32_flash_seq_address1;
363 uint32_t u32_flash_seq_address2;
364
365 /* Increase buffer_size if needed */
366 if (buffer_size < (target->working_area_size / 2))
367 buffer_size = (target->working_area_size / 2);
368
369 u32_flash_type = (uint32_t) fm3_info->flashtype;
370
371 if (u32_flash_type == FM3_FLASH_TYPE1) {
372 u32_flash_seq_address1 = 0x00001550;
373 u32_flash_seq_address2 = 0x00000AA8;
374 } else if (u32_flash_type == FM3_FLASH_TYPE2) {
375 u32_flash_seq_address1 = 0x00000AA8;
376 u32_flash_seq_address2 = 0x00000554;
377 } else {
378 LOG_ERROR("Flash/Device type unknown!");
379 return ERROR_FLASH_OPERATION_FAILED;
380 }
381
382 /* RAMCODE used for fm3 Flash programming: */
383 /* R0 keeps source start address (u32Source) */
384 /* R1 keeps target start address (u32Target) */
385 /* R2 keeps number of halfwords to write (u32Count) */
386 /* R3 keeps Flash Sequence address 1 (u32FlashSeq1) */
387 /* R4 keeps Flash Sequence address 2 (u32FlashSeq2) */
388 /* R5 returns result value (u32FlashResult) */
389
390 static const uint8_t fm3_flash_write_code[] = {
391 /* fm3_FLASH_IF->FASZ &= 0xFFFD; */
392 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
393 0x2D, 0x68, /* LDR R5, [R5] */
394 0x4F, 0xF6, 0xFD, 0x76, /* MOVW R6, #0xFFFD */
395 0x35, 0x40, /* ANDS R5, R5, R6 */
396 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
397 0x35, 0x60, /* STR R5, [R6] */
398 /* fm3_FLASH_IF->FASZ |= 1; */
399 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
400 0x2D, 0x68, /* LDR R5, [R3] */
401 0x55, 0xF0, 0x01, 0x05, /* ORRS.W R5, R5, #1 */
402 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
403 0x35, 0x60, /* STR R5, [R6] */
404 /* u32_dummy_read = fm3_FLASH_IF->FASZ; */
405 0x28, 0x4D, /* LDR.N R5, ??u32_dummy_read */
406 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
407 0x36, 0x68, /* LDR R6, [R6] */
408 0x2E, 0x60, /* STR R6, [R5] */
409 /* u32FlashResult = FLASH_WRITE_NO_RESULT */
410 0x26, 0x4D, /* LDR.N R5, ??u32FlashResult */
411 0x00, 0x26, /* MOVS R6, #0 */
412 0x2E, 0x60, /* STR R6, [R5] */
413 /* while ((u32Count > 0 ) */
414 /* && (u32FlashResult */
415 /* == FLASH_WRITE_NO_RESULT)) */
416 0x01, 0x2A, /* L0: CMP R2, #1 */
417 0x2C, 0xDB, /* BLT.N L1 */
418 0x24, 0x4D, /* LDR.N R5, ??u32FlashResult */
419 0x2D, 0x68, /* LDR R5, [R5] */
420 0x00, 0x2D, /* CMP R5, #0 */
421 0x28, 0xD1, /* BNE.N L1 */
422 /* *u32FlashSeq1 = FLASH_WRITE_1; */
423 0xAA, 0x25, /* MOVS R5, #0xAA */
424 0x1D, 0x60, /* STR R5, [R3] */
425 /* *u32FlashSeq2 = FLASH_WRITE_2; */
426 0x55, 0x25, /* MOVS R5, #0x55 */
427 0x25, 0x60, /* STR R5, [R4] */
428 /* *u32FlashSeq1 = FLASH_WRITE_3; */
429 0xA0, 0x25, /* MOVS R5, #0xA0 */
430 0x1D, 0x60, /* STRH R5, [R3] */
431 /* *(volatile uint16_t*)u32Target */
432 /* = *(volatile uint16_t*)u32Source; */
433 0x05, 0x88, /* LDRH R5, [R0] */
434 0x0D, 0x80, /* STRH R5, [R1] */
435 /* while (u32FlashResult */
436 /* == FLASH_WRITE_NO_RESTULT) */
437 0x1E, 0x4D, /* L2: LDR.N R5, ??u32FlashResult */
438 0x2D, 0x68, /* LDR R5, [R5] */
439 0x00, 0x2D, /* CMP R5, #0 */
440 0x11, 0xD1, /* BNE.N L3 */
441 /* if ((*(volatile uint16_t*)u32Target */
442 /* & FLASH_DQ5) == FLASH_DQ5) */
443 0x0D, 0x88, /* LDRH R5, [R1] */
444 0xAD, 0x06, /* LSLS R5, R5, #0x1A */
445 0x02, 0xD5, /* BPL.N L4 */
446 /* u32FlashResult = FLASH_WRITE_TIMEOUT */
447 0x1A, 0x4D, /* LDR.N R5, ??u32FlashResult */
448 0x02, 0x26, /* MOVS R6, #2 */
449 0x2E, 0x60, /* STR R6, [R5] */
450 /* if ((*(volatile uint16_t *)u32Target */
451 /* & FLASH_DQ7) */
452 /* == (*(volatile uint16_t*)u32Source */
453 /* & FLASH_DQ7)) */
454 0x0D, 0x88, /* L4: LDRH R5, [R1] */
455 0x15, 0xF0, 0x80, 0x05, /* ANDS.W R5, R5, #0x80 */
456 0x06, 0x88, /* LDRH R6, [R0] */
457 0x16, 0xF0, 0x80, 0x06, /* ANDS.W R6, R6, #0x80 */
458 0xB5, 0x42, /* CMP R5, R6 */
459 0xED, 0xD1, /* BNE.N L2 */
460 /* u32FlashResult = FLASH_WRITE_OKAY */
461 0x15, 0x4D, /* LDR.N R5, ??u32FlashResult */
462 0x01, 0x26, /* MOVS R6, #1 */
463 0x2E, 0x60, /* STR R6, [R5] */
464 0xE9, 0xE7, /* B.N L2 */
465 /* if (u32FlashResult */
466 /* != FLASH_WRITE_TIMEOUT) */
467 0x13, 0x4D, /* LDR.N R5, ??u32FlashResult */
468 0x2D, 0x68, /* LDR R5, [R5] */
469 0x02, 0x2D, /* CMP R5, #2 */
470 0x02, 0xD0, /* BEQ.N L5 */
471 /* u32FlashResult = FLASH_WRITE_NO_RESULT */
472 0x11, 0x4D, /* LDR.N R5, ??u32FlashResult */
473 0x00, 0x26, /* MOVS R6, #0 */
474 0x2E, 0x60, /* STR R6, [R5] */
475 /* u32Count--; */
476 0x52, 0x1E, /* L5: SUBS R2, R2, #1 */
477 /* u32Source += 2; */
478 0x80, 0x1C, /* ADDS R0, R0, #2 */
479 /* u32Target += 2; */
480 0x89, 0x1C, /* ADDS R1, R1, #2 */
481 0xD0, 0xE7, /* B.N L0 */
482 /* fm3_FLASH_IF->FASZ &= 0xFFFE; */
483 0x5F, 0xF0, 0x80, 0x45, /* L1: MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
484 0x2D, 0x68, /* LDR R5, [R5] */
485 0x4F, 0xF6, 0xFE, 0x76, /* MOVW R6, #0xFFFE */
486 0x35, 0x40, /* ANDS R5, R5, R6 */
487 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
488 0x35, 0x60, /* STR R5, [R6] */
489 /* fm3_FLASH_IF->FASZ |= 2; */
490 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */
491 0x2D, 0x68, /* LDR R5, [R5] */
492 0x55, 0xF0, 0x02, 0x05, /* ORRS.W R5, R5, #2 */
493 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
494 0x35, 0x60, /* STR R5, [R6] */
495 /* u32_dummy_read = fm3_FLASH_IF->FASZ; */
496 0x04, 0x4D, /* LDR.N R5, ??u32_dummy_read */
497 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */
498 0x36, 0x68, /* LDR R6, [R6] */
499 0x2E, 0x60, /* STR R6, [R5] */
500 /* copy u32FlashResult to R3 for return */
501 /* value */
502 0xDF, 0xF8, 0x08, 0x50, /* LDR.W R5, ??u32FlashResult */
503 0x2D, 0x68, /* LDR R5, [R5] */
504 /* Breakpoint here */
505 0x00, 0xBE, /* BKPT #0 */
506
507 /* The following address pointers assume, that the code is running from */
508 /* SRAM basic-address + 8.These address pointers will be patched, if a */
509 /* different start address in RAM is used (e.g. for Flash type 2)! */
510 /* Default SRAM basic-address is 0x20000000. */
511 0x00, 0x00, 0x00, 0x20, /* u32_dummy_read address in RAM (0x20000000) */
512 0x04, 0x00, 0x00, 0x20 /* u32FlashResult address in RAM (0x20000004) */
513 };
514
515 LOG_INFO("Fujitsu MB9[A/B]FXXX: FLASH Write ...");
516
517 /* disable HW watchdog */
518 retval = target_write_u32(target, 0x40011C00, 0x1ACCE551);
519 if (retval != ERROR_OK)
520 return retval;
521
522 retval = target_write_u32(target, 0x40011C00, 0xE5331AAE);
523 if (retval != ERROR_OK)
524 return retval;
525
526 retval = target_write_u32(target, 0x40011008, 0x00000000);
527 if (retval != ERROR_OK)
528 return retval;
529
530 count = count / 2; /* number bytes -> number halfwords */
531
532 /* check code alignment */
533 if (offset & 0x1) {
534 LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset);
535 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
536 }
537
538 /* allocate working area and variables with flash programming code */
539 if (target_alloc_working_area(target, sizeof(fm3_flash_write_code) + 8,
540 &write_algorithm) != ERROR_OK) {
541 LOG_WARNING("no working area available, can't do block memory writes");
542 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
543 }
544
545 retval = target_write_buffer(target, write_algorithm->address + 8,
546 sizeof(fm3_flash_write_code), fm3_flash_write_code);
547 if (retval != ERROR_OK)
548 return retval;
549
550 /* Patching 'local variable address' */
551 /* Algorithm: u32_dummy_read: */
552 retval = target_write_u32(target, (write_algorithm->address + 8)
553 + sizeof(fm3_flash_write_code) - 8, (write_algorithm->address));
554 if (retval != ERROR_OK)
555 return retval;
556 /* Algorithm: u32FlashResult: */
557 retval = target_write_u32(target, (write_algorithm->address + 8)
558 + sizeof(fm3_flash_write_code) - 4, (write_algorithm->address) + 4);
559 if (retval != ERROR_OK)
560 return retval;
561
562
563
564 /* memory buffer */
565 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) {
566 buffer_size /= 2;
567 if (buffer_size <= 256) {
568 /* free working area, write algorithm already allocated */
569 target_free_working_area(target, write_algorithm);
570
571 LOG_WARNING("No large enough working area available, can't do block memory writes");
572 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
573 }
574 }
575
576 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
577 armv7m_info.core_mode = ARM_MODE_THREAD;
578
579 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT); /* source start address */
580 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* target start address */
581 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* number of halfwords to program */
582 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT); /* Flash Sequence address 1 */
583 init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT); /* Flash Sequence address 1 */
584 init_reg_param(&reg_params[5], "r5", 32, PARAM_IN); /* result */
585
586 /* write code buffer and use Flash programming code within fm3 */
587 /* Set breakpoint to 0 with time-out of 1000 ms */
588 while (count > 0) {
589 uint32_t thisrun_count = (count > (buffer_size / 2)) ? (buffer_size / 2) : count;
590
591 retval = target_write_buffer(target, source->address, thisrun_count * 2, buffer);
592 if (retval != ERROR_OK)
593 break;
594
595 buf_set_u32(reg_params[0].value, 0, 32, source->address);
596 buf_set_u32(reg_params[1].value, 0, 32, address);
597 buf_set_u32(reg_params[2].value, 0, 32, thisrun_count);
598 buf_set_u32(reg_params[3].value, 0, 32, u32_flash_seq_address1);
599 buf_set_u32(reg_params[4].value, 0, 32, u32_flash_seq_address2);
600
601 retval = target_run_algorithm(target, 0, NULL, 6, reg_params,
602 (write_algorithm->address + 8), 0, 1000, &armv7m_info);
603 if (retval != ERROR_OK) {
604 LOG_ERROR("Error executing fm3 Flash programming algorithm");
605 retval = ERROR_FLASH_OPERATION_FAILED;
606 break;
607 }
608
609 if (buf_get_u32(reg_params[5].value, 0, 32) != ERROR_OK) {
610 LOG_ERROR("Fujitsu MB9[A/B]FXXX: Flash programming ERROR (Timeout) -> Reg R3: %" PRIx32,
611 buf_get_u32(reg_params[5].value, 0, 32));
612 retval = ERROR_FLASH_OPERATION_FAILED;
613 break;
614 }
615
616 buffer += thisrun_count * 2;
617 address += thisrun_count * 2;
618 count -= thisrun_count;
619 }
620
621 target_free_working_area(target, source);
622 target_free_working_area(target, write_algorithm);
623
624 destroy_reg_param(&reg_params[0]);
625 destroy_reg_param(&reg_params[1]);
626 destroy_reg_param(&reg_params[2]);
627 destroy_reg_param(&reg_params[3]);
628 destroy_reg_param(&reg_params[4]);
629 destroy_reg_param(&reg_params[5]);
630
631 return retval;
632 }
633
634 static int fm3_probe(struct flash_bank *bank)
635 {
636 struct fm3_flash_bank *fm3_info = bank->driver_priv;
637 uint16_t num_pages;
638
639 if (bank->target->state != TARGET_HALTED) {
640 LOG_ERROR("Target not halted");
641 return ERROR_TARGET_NOT_HALTED;
642 }
643
644 /*
645 -- page-- start -- blocksize - mpu - totalFlash --
646 page0 0x00000 16k
647 page1 0x04000 16k
648 page2 0x08000 96k ___ fxx3 128k Flash
649 page3 0x20000 128k ___ fxx4 256k Flash
650 page4 0x40000 128k ___ fxx5 384k Flash
651 page5 0x60000 128k ___ fxx6 512k Flash
652 -----------------------
653 page6 0x80000 128k
654 page7 0xa0000 128k ___ fxx7 256k Flash
655 page8 0xc0000 128k
656 page9 0xe0000 128k ___ fxx8 256k Flash
657 */
658
659 num_pages = 10; /* max number of Flash pages for malloc */
660 fm3_info->probed = false;
661
662 bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
663 bank->base = 0x00000000;
664 bank->size = 32 * 1024; /* bytes */
665
666 bank->sectors[0].offset = 0;
667 bank->sectors[0].size = 16 * 1024;
668 bank->sectors[0].is_erased = -1;
669 bank->sectors[0].is_protected = -1;
670
671 bank->sectors[1].offset = 0x4000;
672 bank->sectors[1].size = 16 * 1024;
673 bank->sectors[1].is_erased = -1;
674 bank->sectors[1].is_protected = -1;
675
676 if ((fm3_info->variant == MB9BFXX1)
677 || (fm3_info->variant == MB9AFXX1)) {
678 num_pages = 3;
679 bank->size = 64 * 1024; /* bytes */
680 bank->num_sectors = num_pages;
681
682 bank->sectors[2].offset = 0x8000;
683 bank->sectors[2].size = 32 * 1024;
684 bank->sectors[2].is_erased = -1;
685 bank->sectors[2].is_protected = -1;
686 }
687
688 if ((fm3_info->variant == MB9BFXX2)
689 || (fm3_info->variant == MB9BFXX4)
690 || (fm3_info->variant == MB9BFXX5)
691 || (fm3_info->variant == MB9BFXX6)
692 || (fm3_info->variant == MB9BFXX7)
693 || (fm3_info->variant == MB9BFXX8)
694 || (fm3_info->variant == MB9AFXX2)
695 || (fm3_info->variant == MB9AFXX4)
696 || (fm3_info->variant == MB9AFXX5)
697 || (fm3_info->variant == MB9AFXX6)
698 || (fm3_info->variant == MB9AFXX7)
699 || (fm3_info->variant == MB9AFXX8)) {
700 num_pages = 3;
701 bank->size = 128 * 1024; /* bytes */
702 bank->num_sectors = num_pages;
703
704 bank->sectors[2].offset = 0x8000;
705 bank->sectors[2].size = 96 * 1024;
706 bank->sectors[2].is_erased = -1;
707 bank->sectors[2].is_protected = -1;
708 }
709
710 if ((fm3_info->variant == MB9BFXX4)
711 || (fm3_info->variant == MB9BFXX5)
712 || (fm3_info->variant == MB9BFXX6)
713 || (fm3_info->variant == MB9BFXX7)
714 || (fm3_info->variant == MB9BFXX8)
715 || (fm3_info->variant == MB9AFXX4)
716 || (fm3_info->variant == MB9AFXX5)
717 || (fm3_info->variant == MB9AFXX6)
718 || (fm3_info->variant == MB9AFXX7)
719 || (fm3_info->variant == MB9AFXX8)) {
720 num_pages = 4;
721 bank->size = 256 * 1024; /* bytes */
722 bank->num_sectors = num_pages;
723
724 bank->sectors[3].offset = 0x20000;
725 bank->sectors[3].size = 128 * 1024;
726 bank->sectors[3].is_erased = -1;
727 bank->sectors[3].is_protected = -1;
728 }
729
730 if ((fm3_info->variant == MB9BFXX5)
731 || (fm3_info->variant == MB9BFXX6)
732 || (fm3_info->variant == MB9BFXX7)
733 || (fm3_info->variant == MB9BFXX8)
734 || (fm3_info->variant == MB9AFXX5)
735 || (fm3_info->variant == MB9AFXX6)
736 || (fm3_info->variant == MB9AFXX7)
737 || (fm3_info->variant == MB9AFXX8)) {
738 num_pages = 5;
739 bank->size = 384 * 1024; /* bytes */
740 bank->num_sectors = num_pages;
741
742 bank->sectors[4].offset = 0x40000;
743 bank->sectors[4].size = 128 * 1024;
744 bank->sectors[4].is_erased = -1;
745 bank->sectors[4].is_protected = -1;
746 }
747
748 if ((fm3_info->variant == MB9BFXX6)
749 || (fm3_info->variant == MB9BFXX7)
750 || (fm3_info->variant == MB9BFXX8)
751 || (fm3_info->variant == MB9AFXX6)
752 || (fm3_info->variant == MB9AFXX7)
753 || (fm3_info->variant == MB9AFXX8)) {
754 num_pages = 6;
755 bank->size = 512 * 1024; /* bytes */
756 bank->num_sectors = num_pages;
757
758 bank->sectors[5].offset = 0x60000;
759 bank->sectors[5].size = 128 * 1024;
760 bank->sectors[5].is_erased = -1;
761 bank->sectors[5].is_protected = -1;
762 }
763
764 if ((fm3_info->variant == MB9BFXX7)
765 || (fm3_info->variant == MB9BFXX8)
766 || (fm3_info->variant == MB9AFXX7)
767 || (fm3_info->variant == MB9AFXX8)) {
768 num_pages = 8;
769 bank->size = 768 * 1024; /* bytes */
770 bank->num_sectors = num_pages;
771
772 bank->sectors[6].offset = 0x80000;
773 bank->sectors[6].size = 128 * 1024;
774 bank->sectors[6].is_erased = -1;
775 bank->sectors[6].is_protected = -1;
776
777 bank->sectors[7].offset = 0xa0000;
778 bank->sectors[7].size = 128 * 1024;
779 bank->sectors[7].is_erased = -1;
780 bank->sectors[7].is_protected = -1;
781 }
782
783 if ((fm3_info->variant == MB9BFXX8)
784 || (fm3_info->variant == MB9AFXX8)) {
785 num_pages = 10;
786 bank->size = 1024 * 1024; /* bytes */
787 bank->num_sectors = num_pages;
788
789 bank->sectors[8].offset = 0xc0000;
790 bank->sectors[8].size = 128 * 1024;
791 bank->sectors[8].is_erased = -1;
792 bank->sectors[8].is_protected = -1;
793
794 bank->sectors[9].offset = 0xe0000;
795 bank->sectors[9].size = 128 * 1024;
796 bank->sectors[9].is_erased = -1;
797 bank->sectors[9].is_protected = -1;
798 }
799
800 fm3_info->probed = true;
801
802 return ERROR_OK;
803 }
804
805 static int fm3_auto_probe(struct flash_bank *bank)
806 {
807 struct fm3_flash_bank *fm3_info = bank->driver_priv;
808 if (fm3_info->probed)
809 return ERROR_OK;
810 return fm3_probe(bank);
811 }
812
813 /* Chip erase */
814 static int fm3_chip_erase(struct flash_bank *bank)
815 {
816 struct target *target = bank->target;
817 struct fm3_flash_bank *fm3_info2 = bank->driver_priv;
818 int retval = ERROR_OK;
819 uint32_t u32_dummy_read;
820 uint32_t u32_flash_type;
821 uint32_t u32_flash_seq_address1;
822 uint32_t u32_flash_seq_address2;
823
824 struct working_area *write_algorithm;
825 struct reg_param reg_params[3];
826 struct armv7m_algorithm armv7m_info;
827
828 u32_flash_type = (uint32_t) fm3_info2->flashtype;
829
830 if (u32_flash_type == FM3_FLASH_TYPE1) {
831 LOG_INFO("*** Erasing mb9bfxxx type");
832 u32_flash_seq_address1 = 0x00001550;
833 u32_flash_seq_address2 = 0x00000AA8;
834 } else if (u32_flash_type == FM3_FLASH_TYPE2) {
835 LOG_INFO("*** Erasing mb9afxxx type");
836 u32_flash_seq_address1 = 0x00000AA8;
837 u32_flash_seq_address2 = 0x00000554;
838 } else {
839 LOG_ERROR("Flash/Device type unknown!");
840 return ERROR_FLASH_OPERATION_FAILED;
841 }
842
843 if (target->state != TARGET_HALTED) {
844 LOG_ERROR("Target not halted");
845 return ERROR_TARGET_NOT_HALTED;
846 }
847
848 /* RAMCODE used for fm3 Flash chip erase: */
849 /* R0 keeps Flash Sequence address 1 (u32FlashSeq1) */
850 /* R1 keeps Flash Sequence address 2 (u32FlashSeq2) */
851 static const uint8_t fm3_flash_erase_chip_code[] = {
852 /* *(uint16_t*)u32FlashSeq1 = 0xAA; */
853 0xAA, 0x22, /* MOVS R2, #0xAA */
854 0x02, 0x80, /* STRH R2, [R0, #0] */
855 /* *(uint16_t*)u32FlashSeq2 = 0x55; */
856 0x55, 0x23, /* MOVS R3, #0x55 */
857 0x0B, 0x80, /* STRH R3, [R1, #0] */
858 /* *(uint16_t*)u32FlashSeq1 = 0x80; */
859 0x80, 0x24, /* MOVS R4, #0x80 */
860 0x04, 0x80, /* STRH R4, [R0, #0] */
861 /* *(uint16_t*)u32FlashSeq1 = 0xAA; */
862 0x02, 0x80, /* STRH R2, [R0, #0] */
863 /* *(uint16_t*)u32FlashSeq2 = 0x55; */
864 0x0B, 0x80, /* STRH R3, [R1, #0] */
865 /* Chip_Erase Command 0x10 */
866 /* *(uint16_t*)u32FlashSeq1 = 0x10; */
867 0x10, 0x21, /* MOVS R1, #0x10 */
868 0x01, 0x80, /* STRH R1, [R0, #0] */
869 /* End Code */
870 0x00, 0xBE, /* BKPT #0 */
871 };
872
873 LOG_INFO("Fujitsu MB9[A/B]xxx: Chip Erase ... (may take several seconds)");
874
875 /* disable HW watchdog */
876 retval = target_write_u32(target, 0x40011C00, 0x1ACCE551);
877 if (retval != ERROR_OK)
878 return retval;
879
880 retval = target_write_u32(target, 0x40011C00, 0xE5331AAE);
881 if (retval != ERROR_OK)
882 return retval;
883
884 retval = target_write_u32(target, 0x40011008, 0x00000000);
885 if (retval != ERROR_OK)
886 return retval;
887
888 /* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash access) */
889 retval = target_write_u32(target, 0x40000000, 0x0001);
890 if (retval != ERROR_OK)
891 return retval;
892
893 /* dummy read of FASZR */
894 retval = target_read_u32(target, 0x40000000, &u32_dummy_read);
895 if (retval != ERROR_OK)
896 return retval;
897
898 /* allocate working area with flash chip erase code */
899 if (target_alloc_working_area(target, sizeof(fm3_flash_erase_chip_code),
900 &write_algorithm) != ERROR_OK) {
901 LOG_WARNING("no working area available, can't do block memory writes");
902 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
903 }
904 retval = target_write_buffer(target, write_algorithm->address,
905 sizeof(fm3_flash_erase_chip_code), fm3_flash_erase_chip_code);
906 if (retval != ERROR_OK)
907 return retval;
908
909 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
910 armv7m_info.core_mode = ARM_MODE_THREAD;
911
912 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT); /* u32_flash_seq_address1 */
913 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* u32_flash_seq_address2 */
914
915 buf_set_u32(reg_params[0].value, 0, 32, u32_flash_seq_address1);
916 buf_set_u32(reg_params[1].value, 0, 32, u32_flash_seq_address2);
917
918 retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
919 write_algorithm->address, 0, 100000, &armv7m_info);
920 if (retval != ERROR_OK) {
921 LOG_ERROR("Error executing flash erase programming algorithm");
922 retval = ERROR_FLASH_OPERATION_FAILED;
923 return retval;
924 }
925
926 target_free_working_area(target, write_algorithm);
927
928 destroy_reg_param(&reg_params[0]);
929 destroy_reg_param(&reg_params[1]);
930
931 retval = fm3_busy_wait(target, u32_flash_seq_address2, 20000); /* 20s timeout */
932 if (retval != ERROR_OK)
933 return retval;
934
935 /* FASZR = 0x02, Re-enables CPU Run Mode (32-bit Flash access) */
936 retval = target_write_u32(target, 0x40000000, 0x0002);
937 if (retval != ERROR_OK)
938 return retval;
939
940 retval = target_read_u32(target, 0x40000000, &u32_dummy_read); /* dummy read of FASZR */
941
942 return retval;
943 }
944
945 COMMAND_HANDLER(fm3_handle_chip_erase_command)
946 {
947 if (CMD_ARGC < 1)
948 return ERROR_COMMAND_SYNTAX_ERROR;
949
950 struct flash_bank *bank;
951 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
952 if (retval != ERROR_OK)
953 return retval;
954
955 if (fm3_chip_erase(bank) == ERROR_OK) {
956 /* set all sectors as erased */
957 for (unsigned int i = 0; i < bank->num_sectors; i++)
958 bank->sectors[i].is_erased = 1;
959
960 command_print(CMD, "fm3 chip erase complete");
961 } else {
962 command_print(CMD, "fm3 chip erase failed");
963 }
964
965 return ERROR_OK;
966 }
967
968 static const struct command_registration fm3_exec_command_handlers[] = {
969 {
970 .name = "chip_erase",
971 .usage = "<bank>",
972 .handler = fm3_handle_chip_erase_command,
973 .mode = COMMAND_EXEC,
974 .help = "Erase entire Flash device.",
975 },
976 COMMAND_REGISTRATION_DONE
977 };
978
979 static const struct command_registration fm3_command_handlers[] = {
980 {
981 .name = "fm3",
982 .mode = COMMAND_ANY,
983 .help = "fm3 Flash command group",
984 .usage = "",
985 .chain = fm3_exec_command_handlers,
986 },
987 COMMAND_REGISTRATION_DONE
988 };
989
990 const struct flash_driver fm3_flash = {
991 .name = "fm3",
992 .commands = fm3_command_handlers,
993 .flash_bank_command = fm3_flash_bank_command,
994 .erase = fm3_erase,
995 .write = fm3_write_block,
996 .probe = fm3_probe,
997 .auto_probe = fm3_auto_probe,
998 .erase_check = default_flash_blank_check,
999 .free_driver_priv = default_flash_free_driver_priv,
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)