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

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)