add Fujitsu FM3 Family flash support
[openocd.git] / src / flash / nor / fm3.c
1 /***************************************************************************
2 * Copyright (C) 2011 by Marc Willam, Holger Wech *
3 * m.willam@gmx.eu *
4 * Copyright (C) 2011 Ronny Strutz *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
20 ***************************************************************************/
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "imp.h"
26 #include <helper/binarybuffer.h>
27 #include <target/algorithm.h>
28 #include <target/armv7m.h>
29
30 #define FLASH_DQ6 0x00000040 /* Data toggle flag bit (TOGG) position */
31 #define FLASH_DQ5 0x00000020 /* Time limit exceeding flag bit (TLOV) position */
32
33 enum fm3_variant
34 {
35 mb9bfxx1,
36 mb9bfxx2,
37 mb9bfxx3,
38 mb9bfxx4,
39 mb9bfxx5,
40 mb9bfxx6
41 };
42
43 struct fm3_flash_bank
44 {
45 struct working_area *write_algorithm;
46 enum fm3_variant variant;
47 int probed;
48 };
49
50 FLASH_BANK_COMMAND_HANDLER(fm3_flash_bank_command)
51 {
52 struct fm3_flash_bank *fm3_info;
53
54 if (CMD_ARGC < 6)
55 {
56 LOG_WARNING("incomplete flash_bank fm3 configuration");
57 return ERROR_FLASH_BANK_INVALID;
58 }
59
60 LOG_INFO("******HWE* FLASH CMD Parameter %s", CMD_ARGV[5]);
61
62 fm3_info = malloc(sizeof(struct fm3_flash_bank));
63 bank->driver_priv = fm3_info;
64
65 if (strcmp(CMD_ARGV[5], "mb9bfxx1.cpu") == 0)
66 {
67 fm3_info->variant = mb9bfxx1;
68 }
69 else if (strcmp(CMD_ARGV[5], "mb9bfxx2.cpu") == 0)
70 {
71 fm3_info->variant = mb9bfxx2;
72 }
73 else if (strcmp(CMD_ARGV[5], "mb9bfxx3.cpu") == 0)
74 {
75 fm3_info->variant = mb9bfxx3;
76 }
77 else if (strcmp(CMD_ARGV[5], "mb9bfxx4.cpu") == 0)
78 {
79 fm3_info->variant = mb9bfxx4;
80 }
81 else if (strcmp(CMD_ARGV[5], "mb9bfxx5.cpu") == 0)
82 {
83 fm3_info->variant = mb9bfxx5;
84 }
85 else if (strcmp(CMD_ARGV[5], "mb9bfxx6.cpu") == 0)
86 {
87 fm3_info->variant = mb9bfxx6;
88 LOG_INFO("******HWE* fm3 Variant set to: mb9bfxx6");
89 }
90 else
91 {
92 LOG_ERROR("unknown fm3 variant: %s", CMD_ARGV[5]);
93 free(fm3_info);
94 return ERROR_FLASH_BANK_INVALID;
95 }
96
97 fm3_info->write_algorithm = NULL;
98 fm3_info->probed = 0;
99
100 return ERROR_OK;
101 }
102
103 static int fm3_busy_wait(struct target *target, uint32_t offset, int timeout_ms)
104 {
105 int retval = ERROR_OK;
106 uint16_t state1, state2;
107 int ms = 0;
108
109 while(1) {
110 target_read_u16(target, offset, &state1); /* dummy-read - see flash manual */
111 target_read_u16(target, offset, &state1);
112 target_read_u16(target, offset, &state2);
113
114 if ( (state1 & FLASH_DQ6) == (state2 & FLASH_DQ6) ) {
115 break;
116 }
117 else if (state1 & FLASH_DQ5) {
118 target_read_u16(target, offset, &state1);
119 target_read_u16(target, offset, &state2);
120 if ( (state1 & FLASH_DQ6) != (state2 & FLASH_DQ6) )
121 retval = ERROR_FLASH_OPERATION_FAILED;
122 break;
123 }
124 usleep(1000);
125 ++ms;
126
127 if (ms > timeout_ms) {
128 LOG_ERROR("toggle bit reading timed out!");
129 retval = ERROR_FLASH_OPERATION_FAILED;
130 break;
131 }
132 }
133
134 if (retval == ERROR_OK)
135 LOG_DEBUG("fm3_busy_wait(%x) needs about %d ms", offset, ms);
136
137 return retval;
138 }
139
140 static int fm3_erase(struct flash_bank *bank, int first, int last)
141 {
142 struct target *target = bank->target;
143 int retval = ERROR_OK;
144 uint32_t u32DummyRead;
145 int sector, odd;
146
147 if (target->state != TARGET_HALTED) {
148 LOG_ERROR("Target not halted");
149 return ERROR_TARGET_NOT_HALTED;
150 }
151
152 LOG_INFO("Fujitsu MB9Bxxx: Sector Erase ... (%d to %d)", first, last);
153
154 target_write_u32(target, 0x40000000, 0x0001); /* FASZR = 0x01, Enables CPU Programming Mode */
155 target_read_u32(target, 0x40000000, &u32DummyRead); /* dummy read of FASZR */
156
157 for (sector = first ; sector <= last ; sector++) {
158 uint32_t offset = bank->sectors[sector].offset;
159
160 for (odd = 0; odd < 2 ; odd++) {
161
162 if (odd)
163 offset += 4;
164
165 target_write_u16(target, 0x1550, 0x00AA);
166 target_write_u16(target, 0x0AA8, 0x0055);
167 target_write_u16(target, 0x1550, 0x0080);
168 target_write_u16(target, 0x1550, 0x00AA);
169 target_write_u16(target, 0x0AA8, 0x0055);
170 target_write_u16(target, offset, 0x0030);
171
172 retval = fm3_busy_wait(target, offset, 500);
173
174 if (retval != ERROR_OK)
175 break;
176 }
177 bank->sectors[sector].is_erased = 1;
178 }
179
180 target_write_u32(target, 0x40000000, 0x0002);
181 target_read_u32(target, 0x40000000, &u32DummyRead); /* dummy read of FASZR */
182
183 return retval;
184 }
185
186 static int fm3_write_block(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
187 {
188 struct fm3_flash_bank *fm3_info = bank->driver_priv;
189 struct target *target = bank->target;
190 uint32_t buffer_size = 8192;
191 struct working_area *source;
192 uint32_t address = bank->base + offset;
193 struct reg_param reg_params[4];
194 struct armv7m_algorithm armv7m_info;
195 int retval = ERROR_OK;
196
197 /* RAMCODE used for fm3 Flash programming: */
198 /* R0 keeps source start address (u32Source) */
199 /* R1 keeps target start address (u32Target) */
200 /* R2 keeps number of halfwords to write (u32Count) */
201 /* R3 returns result value (u32FlashResult) */
202
203 const uint8_t fm3_flash_write_code[] = {
204 /* fm3_FLASH_IF->FASZ &= 0xFFFD; */
205 0x00, 0xBF, /* NOP */
206 0x5F, 0xF0, 0x80, 0x43, /* MOVS.W R3, #(fm3_FLASH_IF->FASZ) */
207 0x1B, 0x68, /* LDR R3, [R3] */
208 0x4F, 0xF6, 0xFD, 0x74, /* MOVW R4, #0xFFFD */
209 0x23, 0x40, /* ANDS R3, R3, R4 */
210 0x5F, 0xF0, 0x80, 0x44, /* MOVS.W R4, #(fm3_FLASH_IF->FASZ) */
211 0x23, 0x60, /* STR R3, [R4] */
212 /* fm3_FLASH_IF->FASZ |= 1; */
213 0x5F, 0xF0, 0x80, 0x43, /* MOVS.W R3, #(fm3_FLASH_IF->FASZ) */
214 0x1B, 0x68, /* LDR R3, [R3] */
215 0x53, 0xF0, 0x01, 0x03, /* ORRS.W R3, R3, #1 */
216 0x5F, 0xF0, 0x80, 0x44, /* MOVS.W R4, #(fm3_FLASH_IF->FASZ) */
217 0x23, 0x60, /* STR R3, [R4] */
218 /* u32DummyRead = fm3_FLASH_IF->FASZ; */
219 0x2B, 0x4B, /* LDR.N R3, ??u32DummyRead */
220 0x5F, 0xF0, 0x80, 0x44, /* MOVS.W R4, #(fm3_FLASH_IF->FASZ) */
221 0x24, 0x68, /* LDR R4, [R4] */
222 0x1C, 0x60, /* STR R4, [R3] */
223 /* u32FlashResult = FLASH_WRITE_NO_RESULT */
224 0x2A, 0x4B, /* LDR.N R3, ??u32FlashResult */
225 0x00, 0x24, /* MOVS R4, #0 */
226 0x1C, 0x60, /* STR R4, [R3] */
227 /* while ((u32Count > 0 ) && (u32FlashResult */
228 /* == FLASH_WRITE_NO_RESULT)) */
229 0x01, 0x2A, /* L0: CMP R2, #1 */
230 0x32, 0xDB, /* BLT.N L1 */
231 0x27, 0x4B, /* LDR.N R3, ??u32FlashResult */
232 0x1B, 0x68, /* LDR R3, [R3] */
233 0x00, 0x2B, /* CMP R3, #0 */
234 0x2E, 0xD1, /* BNE.N L1 */
235 /* *(FLASH_SEQ_1550) = FLASH_WRITE_1; */
236 0x41, 0xF2, 0x50, 0x53, /* MOVW R3, #0x1550 */
237 0xAA, 0x24, /* MOVS R4. #0xAA */
238 0x1C, 0x80, /* STRH R4, [R3] */
239 /* *(FLASH_SEQ_0AA8) = FLASH_WRITE_2; */
240 0x40, 0xF6, 0xA8, 0x23, /* MOVW R3, #0x0AA8 */
241 0x55, 0x24, /* MOVS R4. #0x55 */
242 0x1C, 0x80, /* STRH R4, [R3] */
243 /* *(FLASH_SEQ_1550) = FLASH_WRITE_3; */
244 0x41, 0xF2, 0x50, 0x53, /* MOVW R3, #0x1550 */
245 0xA0, 0x24, /* MOVS R4. #0xA0 */
246 0x1C, 0x80, /* STRH R4, [R3] */
247 /* *(volatile uint16_t*)u32Target */
248 /* = *(volatile uint16_t*)u32Source; */
249 0x03, 0x88, /* LDRH R3, [R0] */
250 0x0B, 0x80, /* STRH R3, [R1] */
251 /* while (u32FlashResult == FLASH_WRITE_NO_RESTULT) */
252 0x1E, 0x4B, /* L2: LDR.N R3, ??u32FlashResult */
253 0x1B, 0x68, /* LDR R3, [R3] */
254 0x00, 0x2B, /* CMP R3, #0 */
255 0x11, 0xD1, /* BNE.N L3 */
256 /* if ((*(volatile uint16_t*)u32Target & FLASH_DQ5) */
257 /* == FLASH_DQ5) */
258 0x0B, 0x88, /* LDRH R3, [R1] */
259 0x9B, 0x06, /* LSLS R3, R3, #0x1A */
260 0x02, 0xD5, /* BPL.N L4 */
261 /* u32FlashResult = FLASH_WRITE_TIMEOUT */
262 0x1B, 0x4B, /* LDR.N R3, ??u32FlashResult */
263 0x02, 0x24, /* MOVS R4, #2 */
264 0x1C, 0x60, /* STR R4, [R3] */
265 /* if ((*(volatile uint16_t *)u32Target & FLASH_DQ7) */
266 /* == (*(volatile uint16_t*)u32Source & FLASH_DQ7)) */
267 0x0B, 0x88, /* L4: LDRH R3, [R1] */
268 0x13, 0xF0, 0x80, 0x03, /* ANDS.W R3, R3, #0x80 */
269 0x04, 0x88, /* LDRH R4, [R0] */
270 0x14, 0xF0, 0x80, 0x04, /* ANDS.W R4, R4, #0x80 */
271 0xA3, 0x42, /* CMP R3, R4 */
272 0xED, 0xD1, /* BNE.N L2 */
273 /* u32FlashResult = FLASH_WRITE_OKAY */
274 0x15, 0x4B, /* LDR.N R3, ??u32FlashResult */
275 0x01, 0x24, /* MOVS R4, #1 */
276 0x1C, 0x60, /* STR R4, [R3] */
277 0xE9, 0xE7, /* B.N L2 */
278 /* if (u32FlashResult != FLASH_WRITE_TIMEOUT) */
279 0x13, 0x4B, /* LDR.N R3, ??u32FlashResult */
280 0x1B, 0x68, /* LDR R3, [R3] */
281 0x02, 0x2B, /* CMP R3, #2 */
282 0x02, 0xD0, /* BEQ.N L5 */
283 /* u32FlashResult = FLASH_WRITE_NO_RESULT */
284 0x11, 0x4B, /* LDR.N R3, ??u32FlashResult */
285 0x00, 0x24, /* MOVS R4, #0 */
286 0x1C, 0x60, /* STR R4, [R3] */
287 /* u32Count--; */
288 0x52, 0x1E, /* L5: SUBS R2, R2, #1 */
289 /* u32Source += 2; */
290 0x80, 0x1C, /* ADDS R0, R0, #2 */
291 /* u32Target += 2; */
292 0x89, 0x1C, /* ADDS R1, R1, #2 */
293 0xCA, 0xE7, /* B.N L0 */
294 /* fm3_FLASH_IF->FASZ &= 0xFFFE; */
295 0x5F, 0xF0, 0x80, 0x43, /* L1: MOVS.W R3, #(fm3_FLASH_IF->FASZ) */
296 0x1B, 0x68, /* LDR R3, [R3] */
297 0x4F, 0xF6, 0xFE, 0x74, /* MOVW R4, #0xFFFE */
298 0x23, 0x40, /* ANDS R3, R3, R4 */
299 0x5F, 0xF0, 0x80, 0x44, /* MOVS.W R4, #(fm3_FLASH_IF->FASZ) */
300 0x23, 0x60, /* STR R3, [R4] */
301 /* fm3_FLASH_IF->FASZ |= 2; */
302 0x5F, 0xF0, 0x80, 0x43, /* MOVS.W R3, #(fm3_FLASH_IF->FASZ) */
303 0x1B, 0x68, /* LDR R3, [R3] */
304 0x53, 0xF0, 0x02, 0x03, /* ORRS.W R3, R3, #2 */
305 0x5F, 0xF0, 0x80, 0x44, /* MOVS.W R4, #(fm3_FLASH_IF->FASZ) */
306 0x23, 0x60, /* STR R4, [R3] */
307 /* u32DummyRead = fm3_FLASH_IF->FASZ; */
308 0x04, 0x4B, /* LDR.N R3, ??u32DummyRead */
309 0x5F, 0xF0, 0x80, 0x44, /* MOVS.W R4, #(fm3_FLASH_IF->FASZ) */
310 0x24, 0x68, /* LDR R4, [R4] */
311 0x1C, 0x60, /* STR R4, [R3] */
312 /* copy u32FlashResult to R3 for return value */
313 0xDF, 0xF8, 0x0C, 0x30, /* LDR.W R3, ??u32FlashResult */
314 0x1B, 0x68, /* LDR R3, [R3] */
315 /* Breakpoint here */
316 0x00, 0xBE, /* Breakpoint #0 */
317 0x00, 0x00, /* alignment padding bytes */
318 0x00, 0x80, 0xFF, 0x1F, /* u32DummyRead address in RAM (0x1FFF8000) */
319 0x04, 0x80, 0xFF, 0x1F /* u32FlashResult address in RAM (0x1FFF8004) */
320 };
321
322 LOG_INFO("Fujitsu MB9B500: FLASH Write ...");
323
324 /* disable HW watchdog */
325 target_write_u32(target, 0x40011C00, 0x1ACCE551);
326 target_write_u32(target, 0x40011C00, 0xE5331AAE);
327 target_write_u32(target, 0x40011008, 0x00000000);
328
329 count = count / 2; /* number bytes -> number halfwords */
330
331 /* check code alignment */
332 if (offset & 0x1)
333 {
334 LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset);
335 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
336 }
337
338 /* allocate working area with flash programming code */
339 if (target_alloc_working_area(target, sizeof(fm3_flash_write_code),
340 &fm3_info->write_algorithm) != ERROR_OK)
341 {
342 LOG_WARNING("no working area available, can't do block memory writes");
343 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
344 }
345
346 retval = target_write_buffer(target, fm3_info->write_algorithm->address,
347 sizeof(fm3_flash_write_code), fm3_flash_write_code);
348 if (retval != ERROR_OK)
349 return retval;
350
351 /* memory buffer */
352 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
353 {
354 buffer_size /= 2;
355 if (buffer_size <= 256)
356 {
357 /* free working area, if write algorithm already allocated */
358 if (fm3_info->write_algorithm)
359 {
360 target_free_working_area(target, fm3_info->write_algorithm);
361 }
362
363 LOG_WARNING("no large enough working area available, can't do block memory writes");
364 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
365 }
366 }
367
368 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
369 armv7m_info.core_mode = ARMV7M_MODE_ANY;
370
371 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT); // source start address
372 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); // target start address
373 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); // number of halfwords to program
374 init_reg_param(&reg_params[3], "r3", 32, PARAM_IN); // result
375
376 /* write code buffer and use Flash programming code within fm3 */
377 /* Set breakpoint to 0 with time-out of 1000 ms */
378 while (count > 0)
379 {
380 uint32_t thisrun_count = (count > (buffer_size / 2)) ? (buffer_size / 2) : count;
381
382 /* for some reason the first 8 byte of code are corrupt when target_run_algorithm() returns */
383 /* need some more investigation on this */
384 retval = target_write_buffer(target,
385 fm3_info->write_algorithm->address, 8, fm3_flash_write_code);
386 if (retval != ERROR_OK)
387 return retval;
388
389
390 retval = target_write_buffer(target,
391 source->address, thisrun_count * 2, buffer);
392 if (retval != ERROR_OK)
393 break;
394
395 buf_set_u32(reg_params[0].value, 0, 32, source->address);
396 buf_set_u32(reg_params[1].value, 0, 32, address);
397 buf_set_u32(reg_params[2].value, 0, 32, thisrun_count);
398
399
400 retval = target_run_algorithm(target, 0, NULL, 4, reg_params,
401 fm3_info->write_algorithm->address, 0, 1000, &armv7m_info);
402 if (retval != ERROR_OK)
403 {
404 LOG_ERROR("error executing fm3 Flash programming algorithm");
405 retval = ERROR_FLASH_OPERATION_FAILED;
406 break;
407 }
408
409 #if 0
410 /* debug the corrupted 8 bytes */
411 unsigned char buf[256];
412 retval = target_read_buffer(target, fm3_info->write_algorithm->address, 256, buf);
413 if (retval != ERROR_OK)
414 printf("cannot read buffer\n");
415 unsigned int i;
416 for ( i = 0; i < sizeof(fm3_flash_write_code); i++)
417 if (buf[i] != fm3_flash_write_code[i])
418 printf("broken: %d %02x != %02x\n", i, buf[i], fm3_flash_write_code[i]);
419 #endif
420
421 if (buf_get_u32(reg_params[3].value, 0, 32) != ERROR_OK)
422 {
423 LOG_ERROR("Fujitsu MB9B500: FLASH programming ERROR (Timeout) -> Reg R3: %x",
424 buf_get_u32(reg_params[3].value, 0, 32));
425 retval = ERROR_FLASH_OPERATION_FAILED;
426 break;
427 }
428
429 buffer += thisrun_count * 2;
430 address += thisrun_count * 2;
431 count -= thisrun_count;
432 }
433
434 target_free_working_area(target, source);
435 target_free_working_area(target, fm3_info->write_algorithm);
436
437 destroy_reg_param(&reg_params[0]);
438 destroy_reg_param(&reg_params[1]);
439 destroy_reg_param(&reg_params[2]);
440 destroy_reg_param(&reg_params[3]);
441
442 return retval;
443 }
444
445 static int fm3_probe(struct flash_bank *bank)
446 {
447 struct fm3_flash_bank *fm3_info = bank->driver_priv;
448 uint16_t num_pages;
449
450 if (bank->target->state != TARGET_HALTED)
451 {
452 LOG_ERROR("Target not halted");
453 return ERROR_TARGET_NOT_HALTED;
454 }
455
456 num_pages = 6; /* max number of Flash pages for malloc */
457 fm3_info->probed = 0;
458
459 bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
460 bank->base = 0x00000000;
461 num_pages = 2; /* start with smallest Flash pages number */
462 bank->size = 32 * 1024; /* bytes */
463
464 bank->sectors[0].offset = 0;
465 bank->sectors[0].size = 16 * 1024;
466 bank->sectors[0].is_erased = -1;
467 bank->sectors[0].is_protected = -1;
468
469 bank->sectors[1].offset = 0x4000;
470 bank->sectors[1].size = 16 * 1024;
471 bank->sectors[1].is_erased = -1;
472 bank->sectors[1].is_protected = -1;
473
474 if (fm3_info->variant == mb9bfxx1)
475 {
476 num_pages = 3;
477 bank->size = 64 * 1024; /* bytes */
478 bank->num_sectors = num_pages;
479
480 bank->sectors[2].offset = 0x8000;
481 bank->sectors[2].size = 32 * 1024;
482 bank->sectors[2].is_erased = -1;
483 bank->sectors[2].is_protected = -1;
484 }
485
486 if ( (fm3_info->variant == mb9bfxx2)
487 || (fm3_info->variant == mb9bfxx4)
488 || (fm3_info->variant == mb9bfxx5)
489 || (fm3_info->variant == mb9bfxx6))
490 {
491 num_pages = 3;
492 bank->size = 128 * 1024; // bytes
493 bank->num_sectors = num_pages;
494
495 bank->sectors[2].offset = 0x8000;
496 bank->sectors[2].size = 96 * 1024;
497 bank->sectors[2].is_erased = -1;
498 bank->sectors[2].is_protected = -1;
499 }
500
501 if ( (fm3_info->variant == mb9bfxx4)
502 || (fm3_info->variant == mb9bfxx5)
503 || (fm3_info->variant == mb9bfxx6))
504 {
505 num_pages = 4;
506 bank->size = 256 * 1024; // bytes
507 bank->num_sectors = num_pages;
508
509 bank->sectors[3].offset = 0x20000;
510 bank->sectors[3].size = 128 * 1024;
511 bank->sectors[3].is_erased = -1;
512 bank->sectors[3].is_protected = -1;
513 }
514
515 if ( (fm3_info->variant == mb9bfxx5)
516 || (fm3_info->variant == mb9bfxx6))
517 {
518 num_pages = 5;
519 bank->size = 384 * 1024; // bytes
520 bank->num_sectors = num_pages;
521
522 bank->sectors[4].offset = 0x40000;
523 bank->sectors[4].size = 128 * 1024;
524 bank->sectors[4].is_erased = -1;
525 bank->sectors[4].is_protected = -1;
526 }
527
528 if (fm3_info->variant == mb9bfxx6)
529 {
530 num_pages = 6;
531 bank->size = 512 * 1024; // bytes
532 bank->num_sectors = num_pages;
533
534 bank->sectors[5].offset = 0x60000;
535 bank->sectors[5].size = 128 * 1024;
536 bank->sectors[5].is_erased = -1;
537 bank->sectors[5].is_protected = -1;
538 }
539
540 fm3_info->probed = 1;
541
542 return ERROR_OK;
543 }
544
545 static int fm3_auto_probe(struct flash_bank *bank)
546 {
547 struct fm3_flash_bank *fm3_info = bank->driver_priv;
548 if (fm3_info->probed)
549 return ERROR_OK;
550 return fm3_probe(bank);
551 }
552
553 static int fm3_info(struct flash_bank *bank, char *buf, int buf_size)
554 {
555 snprintf(buf, buf_size, "Fujitsu fm3 Device does not support Chip-ID (Type unknown)");
556 return ERROR_OK;
557 }
558
559 static int fm3_chip_erase(struct flash_bank *bank)
560 {
561 struct target *target = bank->target;
562 int retval = ERROR_OK;
563 uint32_t u32DummyRead;
564
565 if (target->state != TARGET_HALTED)
566 {
567 LOG_ERROR("Target not halted");
568 return ERROR_TARGET_NOT_HALTED;
569 }
570
571 LOG_INFO("Fujitsu MB9Bxxx: Chip Erase ... (may take several seconds)");
572
573 /* Implement Flash chip erase (mass erase) completely on host */
574 target_write_u32(target, 0x40000000, 0x0001); /* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash access) */
575 target_read_u32(target, 0x40000000, &u32DummyRead); /* dummy read of FASZR */
576
577 target_write_u16(target, 0x00001550, 0x00AA); /* Flash unlock sequence */
578 target_write_u16(target, 0x00000AA8, 0x0055);
579 target_write_u16(target, 0x00001550, 0x0080);
580 target_write_u16(target, 0x00001550, 0x00AA);
581 target_write_u16(target, 0x00000AA8, 0x0055);
582 target_write_u16(target, 0x00001550, 0x0010); /* Chip Erase command */
583
584 retval = fm3_busy_wait(target, 0xAA8, 20000);
585
586 target_write_u32(target, 0x40000000, 0x0002);
587 target_read_u32(target, 0x40000000, &u32DummyRead); /* dummy read of FASZR */
588
589 return retval;
590 }
591
592 COMMAND_HANDLER(fm3_handle_chip_erase_command)
593 {
594 int i;
595
596 if (CMD_ARGC < 1)
597 {
598 command_print(CMD_CTX, "fm3 chip_erase <bank>");
599 return ERROR_OK;
600 }
601
602 struct flash_bank *bank;
603 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
604 if (ERROR_OK != retval)
605 return retval;
606
607 if (fm3_chip_erase(bank) == ERROR_OK)
608 {
609 /* set all sectors as erased */
610 for (i = 0; i < bank->num_sectors; i++)
611 bank->sectors[i].is_erased = 1;
612
613 command_print(CMD_CTX, "fm3 chip erase complete");
614 }
615 else
616 {
617 command_print(CMD_CTX, "fm3 chip erase failed");
618 }
619
620 return ERROR_OK;
621 }
622
623 static const struct command_registration fm3_exec_command_handlers[] = {
624 {
625 .name = "chip_erase",
626 .handler = fm3_handle_chip_erase_command,
627 .mode = COMMAND_EXEC,
628 .usage = "bank_id",
629 .help = "Erase entire Flash device.",
630 },
631 COMMAND_REGISTRATION_DONE
632 };
633
634 static const struct command_registration fm3_command_handlers[] = {
635 {
636 .name = "fm3",
637 .mode = COMMAND_ANY,
638 .help = "fm3 Flash command group",
639 .chain = fm3_exec_command_handlers,
640 },
641 COMMAND_REGISTRATION_DONE
642 };
643
644 struct flash_driver fm3_flash = {
645 .name = "fm3",
646 .commands = fm3_command_handlers,
647 .flash_bank_command = fm3_flash_bank_command,
648 .erase = fm3_erase,
649 .write = fm3_write_block,
650 .probe = fm3_probe,
651 .auto_probe = fm3_auto_probe,
652 .erase_check = default_flash_mem_blank_check,
653 .info = fm3_info,
654 };

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)