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