99fa02cc33adea14aa43856ee56965f8e98aa59a
[fw/openocd] / 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 };