86ec455a12f9fa1a7d6521437e163579568afd23
[fw/openocd] / src / flash / nor / str9x.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /***************************************************************************
4  *   Copyright (C) 2005 by Dominic Rath                                    *
5  *   Dominic.Rath@gmx.de                                                   *
6  *                                                                         *
7  *   Copyright (C) 2008 by Spencer Oliver                                  *
8  *   spen@spen-soft.co.uk                                                  *
9  *
10  *   Copyright (C) 2008 by Oyvind Harboe                                   *
11  *   oyvind.harboe@zylin.com                                               *
12  ***************************************************************************/
13
14 #ifdef HAVE_CONFIG_H
15 #include "config.h"
16 #endif
17
18 #include "imp.h"
19 #include <target/arm966e.h>
20 #include <target/algorithm.h>
21
22 /* Flash registers */
23
24 #define FLASH_BBSR              0x54000000              /* Boot Bank Size Register                */
25 #define FLASH_NBBSR             0x54000004              /* Non-Boot Bank Size Register            */
26 #define FLASH_BBADR             0x5400000C              /* Boot Bank Base Address Register        */
27 #define FLASH_NBBADR    0x54000010              /* Non-Boot Bank Base Address Register    */
28 #define FLASH_CR                0x54000018              /* Control Register                       */
29 #define FLASH_SR                0x5400001C              /* Status Register                        */
30 #define FLASH_BCE5ADDR  0x54000020              /* BC Fifth Entry Target Address Register */
31
32 struct str9x_flash_bank {
33         uint32_t *sector_bits;
34         int variant;
35         int bank1;
36 };
37
38 enum str9x_status_codes {
39         STR9X_CMD_SUCCESS = 0,
40         STR9X_INVALID_COMMAND = 1,
41         STR9X_SRC_ADDR_ERROR = 2,
42         STR9X_DST_ADDR_ERROR = 3,
43         STR9X_SRC_ADDR_NOT_MAPPED = 4,
44         STR9X_DST_ADDR_NOT_MAPPED = 5,
45         STR9X_COUNT_ERROR = 6,
46         STR9X_INVALID_SECTOR = 7,
47         STR9X_SECTOR_NOT_BLANK = 8,
48         STR9X_SECTOR_NOT_PREPARED = 9,
49         STR9X_COMPARE_ERROR = 10,
50         STR9X_BUSY = 11
51 };
52
53 static uint32_t bank1start = 0x00080000;
54
55 static int str9x_build_block_list(struct flash_bank *bank)
56 {
57         struct str9x_flash_bank *str9x_info = bank->driver_priv;
58
59         int i;
60         unsigned int num_sectors;
61         int b0_sectors = 0, b1_sectors = 0;
62         uint32_t offset = 0;
63
64         /* set if we have large flash str9 */
65         str9x_info->variant = 0;
66         str9x_info->bank1 = 0;
67
68         switch (bank->size) {
69                 case (256 * 1024):
70                         b0_sectors = 4;
71                         break;
72                 case (512 * 1024):
73                         b0_sectors = 8;
74                         break;
75                 case (1024 * 1024):
76                         bank1start = 0x00100000;
77                         str9x_info->variant = 1;
78                         b0_sectors = 16;
79                         break;
80                 case (2048 * 1024):
81                         bank1start = 0x00200000;
82                         str9x_info->variant = 1;
83                         b0_sectors = 32;
84                         break;
85                 case (128 * 1024):
86                         str9x_info->variant = 1;
87                         str9x_info->bank1 = 1;
88                         b1_sectors = 8;
89                         bank1start = bank->base;
90                         break;
91                 case (32 * 1024):
92                         str9x_info->bank1 = 1;
93                         b1_sectors = 4;
94                         bank1start = bank->base;
95                         break;
96                 default:
97                         LOG_ERROR("BUG: unknown bank->size encountered");
98                         exit(-1);
99         }
100
101         num_sectors = b0_sectors + b1_sectors;
102
103         bank->num_sectors = num_sectors;
104         bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
105         str9x_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);
106
107         num_sectors = 0;
108
109         for (i = 0; i < b0_sectors; i++) {
110                 bank->sectors[num_sectors].offset = offset;
111                 bank->sectors[num_sectors].size = 0x10000;
112                 offset += bank->sectors[i].size;
113                 bank->sectors[num_sectors].is_erased = -1;
114                 bank->sectors[num_sectors].is_protected = 1;
115                 str9x_info->sector_bits[num_sectors++] = (1 << i);
116         }
117
118         for (i = 0; i < b1_sectors; i++) {
119                 bank->sectors[num_sectors].offset = offset;
120                 bank->sectors[num_sectors].size = str9x_info->variant == 0 ? 0x2000 : 0x4000;
121                 offset += bank->sectors[i].size;
122                 bank->sectors[num_sectors].is_erased = -1;
123                 bank->sectors[num_sectors].is_protected = 1;
124                 if (str9x_info->variant)
125                         str9x_info->sector_bits[num_sectors++] = (1 << i);
126                 else
127                         str9x_info->sector_bits[num_sectors++] = (1 << (i + 8));
128         }
129
130         return ERROR_OK;
131 }
132
133 /* flash bank str9x <base> <size> 0 0 <target#>
134  */
135 FLASH_BANK_COMMAND_HANDLER(str9x_flash_bank_command)
136 {
137         struct str9x_flash_bank *str9x_info;
138
139         if (CMD_ARGC < 6)
140                 return ERROR_COMMAND_SYNTAX_ERROR;
141
142         str9x_info = malloc(sizeof(struct str9x_flash_bank));
143         bank->driver_priv = str9x_info;
144
145         str9x_build_block_list(bank);
146
147         return ERROR_OK;
148 }
149
150 static int str9x_protect_check(struct flash_bank *bank)
151 {
152         int retval;
153         struct str9x_flash_bank *str9x_info = bank->driver_priv;
154         struct target *target = bank->target;
155
156         uint32_t adr;
157         uint32_t status = 0;
158         uint16_t hstatus = 0;
159
160         if (bank->target->state != TARGET_HALTED) {
161                 LOG_ERROR("Target not halted");
162                 return ERROR_TARGET_NOT_HALTED;
163         }
164
165         /* read level one protection */
166
167         if (str9x_info->variant) {
168                 if (str9x_info->bank1) {
169                         adr = bank1start + 0x18;
170                         retval = target_write_u16(target, adr, 0x90);
171                         if (retval != ERROR_OK)
172                                 return retval;
173                         retval = target_read_u16(target, adr, &hstatus);
174                         if (retval != ERROR_OK)
175                                 return retval;
176                         status = hstatus;
177                 } else {
178                         adr = bank1start + 0x14;
179                         retval = target_write_u16(target, adr, 0x90);
180                         if (retval != ERROR_OK)
181                                 return retval;
182                         retval = target_read_u32(target, adr, &status);
183                         if (retval != ERROR_OK)
184                                 return retval;
185                 }
186         } else {
187                 adr = bank1start + 0x10;
188                 retval = target_write_u16(target, adr, 0x90);
189                 if (retval != ERROR_OK)
190                         return retval;
191                 retval = target_read_u16(target, adr, &hstatus);
192                 if (retval != ERROR_OK)
193                         return retval;
194                 status = hstatus;
195         }
196
197         /* read array command */
198         retval = target_write_u16(target, adr, 0xFF);
199         if (retval != ERROR_OK)
200                 return retval;
201
202         for (unsigned int i = 0; i < bank->num_sectors; i++) {
203                 if (status & str9x_info->sector_bits[i])
204                         bank->sectors[i].is_protected = 1;
205                 else
206                         bank->sectors[i].is_protected = 0;
207         }
208
209         return ERROR_OK;
210 }
211
212 static int str9x_erase(struct flash_bank *bank, unsigned int first,
213                 unsigned int last)
214 {
215         struct target *target = bank->target;
216         uint32_t adr;
217         uint8_t status;
218         uint8_t erase_cmd;
219         int total_timeout;
220
221         if (bank->target->state != TARGET_HALTED) {
222                 LOG_ERROR("Target not halted");
223                 return ERROR_TARGET_NOT_HALTED;
224         }
225
226         /* Check if we can erase whole bank */
227         if ((first == 0) && (last == (bank->num_sectors - 1))) {
228                 /* Optimize to run erase bank command instead of sector */
229                 erase_cmd = 0x80;
230                 /* Add timeout duration since erase bank takes more time */
231                 total_timeout = 1000 * bank->num_sectors;
232         } else {
233                 /* Erase sector command */
234                 erase_cmd = 0x20;
235                 total_timeout = 1000;
236         }
237
238         /* this is so the compiler can *know* */
239         assert(total_timeout > 0);
240
241         for (unsigned int i = first; i <= last; i++) {
242                 int retval;
243                 adr = bank->base + bank->sectors[i].offset;
244
245                 /* erase sectors or block */
246                 retval = target_write_u16(target, adr, erase_cmd);
247                 if (retval != ERROR_OK)
248                         return retval;
249                 retval = target_write_u16(target, adr, 0xD0);
250                 if (retval != ERROR_OK)
251                         return retval;
252
253                 /* get status */
254                 retval = target_write_u16(target, adr, 0x70);
255                 if (retval != ERROR_OK)
256                         return retval;
257
258                 int timeout;
259                 for (timeout = 0; timeout < total_timeout; timeout++) {
260                         retval = target_read_u8(target, adr, &status);
261                         if (retval != ERROR_OK)
262                                 return retval;
263                         if (status & 0x80)
264                                 break;
265                         alive_sleep(1);
266                 }
267                 if (timeout == total_timeout) {
268                         LOG_ERROR("erase timed out");
269                         return ERROR_FAIL;
270                 }
271
272                 /* clear status, also clear read array */
273                 retval = target_write_u16(target, adr, 0x50);
274                 if (retval != ERROR_OK)
275                         return retval;
276
277                 /* read array command */
278                 retval = target_write_u16(target, adr, 0xFF);
279                 if (retval != ERROR_OK)
280                         return retval;
281
282                 if (status & 0x22) {
283                         LOG_ERROR("error erasing flash bank, status: 0x%x", status);
284                         return ERROR_FLASH_OPERATION_FAILED;
285                 }
286
287                 /* If we ran erase bank command, we are finished */
288                 if (erase_cmd == 0x80)
289                         break;
290         }
291
292         return ERROR_OK;
293 }
294
295 static int str9x_protect(struct flash_bank *bank, int set, unsigned int first,
296                 unsigned int last)
297 {
298         struct target *target = bank->target;
299         uint32_t adr;
300         uint8_t status;
301
302         if (bank->target->state != TARGET_HALTED) {
303                 LOG_ERROR("Target not halted");
304                 return ERROR_TARGET_NOT_HALTED;
305         }
306
307         for (unsigned int i = first; i <= last; i++) {
308                 /* Level One Protection */
309
310                 adr = bank->base + bank->sectors[i].offset;
311
312                 target_write_u16(target, adr, 0x60);
313                 if (set)
314                         target_write_u16(target, adr, 0x01);
315                 else
316                         target_write_u16(target, adr, 0xD0);
317
318                 /* query status */
319                 target_read_u8(target, adr, &status);
320
321                 /* clear status, also clear read array */
322                 target_write_u16(target, adr, 0x50);
323
324                 /* read array command */
325                 target_write_u16(target, adr, 0xFF);
326         }
327
328         return ERROR_OK;
329 }
330
331 static int str9x_write_block(struct flash_bank *bank,
332                 const uint8_t *buffer, uint32_t offset, uint32_t count)
333 {
334         struct target *target = bank->target;
335         uint32_t buffer_size = 32768;
336         struct working_area *write_algorithm;
337         struct working_area *source;
338         uint32_t address = bank->base + offset;
339         struct reg_param reg_params[4];
340         struct arm_algorithm arm_algo;
341         int retval = ERROR_OK;
342
343         /* see contrib/loaders/flash/str9x.s for src */
344
345         static const uint32_t str9x_flash_write_code[] = {
346                                         /* write:                               */
347                 0xe3c14003,     /*      bic     r4, r1, #3              */
348                 0xe3a03040,     /*      mov     r3, #0x40               */
349                 0xe1c430b0,     /*      strh r3, [r4, #0]       */
350                 0xe0d030b2,     /*      ldrh r3, [r0], #2       */
351                 0xe0c130b2,     /*      strh r3, [r1], #2       */
352                 0xe3a03070,     /*      mov r3, #0x70           */
353                 0xe1c430b0,     /*      strh r3, [r4, #0]       */
354                                         /* busy:                                */
355                 0xe5d43000,     /*      ldrb r3, [r4, #0]       */
356                 0xe3130080,     /*      tst r3, #0x80           */
357                 0x0afffffc,     /*      beq busy                        */
358                 0xe3a05050,     /*      mov     r5, #0x50               */
359                 0xe1c450b0,     /*      strh r5, [r4, #0]       */
360                 0xe3a050ff,     /*      mov     r5, #0xFF               */
361                 0xe1c450b0,     /*      strh r5, [r4, #0]       */
362                 0xe3130012,     /*      tst     r3, #0x12               */
363                 0x1a000001,     /*      bne exit                        */
364                 0xe2522001,     /*      subs r2, r2, #1         */
365                 0x1affffed,     /*      bne write                       */
366                                         /* exit:                                */
367                 0xe1200070,     /*      bkpt #0                         */
368         };
369
370         /* flash write code */
371         if (target_alloc_working_area(target, sizeof(str9x_flash_write_code),
372                         &write_algorithm) != ERROR_OK) {
373                 LOG_WARNING("no working area available, can't do block memory writes");
374                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
375         }
376
377         uint8_t code[sizeof(str9x_flash_write_code)];
378         target_buffer_set_u32_array(target, code, ARRAY_SIZE(str9x_flash_write_code),
379                         str9x_flash_write_code);
380         target_write_buffer(target, write_algorithm->address, sizeof(code), code);
381
382         /* memory buffer */
383         while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
384                 buffer_size /= 2;
385                 if (buffer_size <= 256) {
386                         /* we already allocated the writing code, but failed to get a
387                          * buffer, free the algorithm */
388                         target_free_working_area(target, write_algorithm);
389
390                         LOG_WARNING("no large enough working area available, can't do block memory writes");
391                         return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
392                 }
393         }
394
395         arm_algo.common_magic = ARM_COMMON_MAGIC;
396         arm_algo.core_mode = ARM_MODE_SVC;
397         arm_algo.core_state = ARM_STATE_ARM;
398
399         init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
400         init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
401         init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
402         init_reg_param(&reg_params[3], "r3", 32, PARAM_IN);
403
404         while (count > 0) {
405                 uint32_t thisrun_count = (count > (buffer_size / 2)) ? (buffer_size / 2) : count;
406
407                 target_write_buffer(target, source->address, thisrun_count * 2, buffer);
408
409                 buf_set_u32(reg_params[0].value, 0, 32, source->address);
410                 buf_set_u32(reg_params[1].value, 0, 32, address);
411                 buf_set_u32(reg_params[2].value, 0, 32, thisrun_count);
412
413                 retval = target_run_algorithm(target, 0, NULL, 4, reg_params,
414                                 write_algorithm->address,
415                                 0, 10000, &arm_algo);
416                 if (retval != ERROR_OK) {
417                         LOG_ERROR("error executing str9x flash write algorithm");
418                         retval = ERROR_FLASH_OPERATION_FAILED;
419                         break;
420                 }
421
422                 if (buf_get_u32(reg_params[3].value, 0, 32) != 0x80) {
423                         retval = ERROR_FLASH_OPERATION_FAILED;
424                         break;
425                 }
426
427                 buffer += thisrun_count * 2;
428                 address += thisrun_count * 2;
429                 count -= thisrun_count;
430         }
431
432         target_free_working_area(target, source);
433         target_free_working_area(target, write_algorithm);
434
435         destroy_reg_param(&reg_params[0]);
436         destroy_reg_param(&reg_params[1]);
437         destroy_reg_param(&reg_params[2]);
438         destroy_reg_param(&reg_params[3]);
439
440         return retval;
441 }
442
443 static int str9x_write(struct flash_bank *bank,
444                 const uint8_t *buffer, uint32_t offset, uint32_t count)
445 {
446         struct target *target = bank->target;
447         uint32_t words_remaining = (count / 2);
448         uint32_t bytes_remaining = (count & 0x00000001);
449         uint32_t address = bank->base + offset;
450         uint32_t bytes_written = 0;
451         uint8_t status;
452         int retval;
453         uint32_t check_address = offset;
454         uint32_t bank_adr;
455
456         if (bank->target->state != TARGET_HALTED) {
457                 LOG_ERROR("Target not halted");
458                 return ERROR_TARGET_NOT_HALTED;
459         }
460
461         if (offset & 0x1) {
462                 LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset);
463                 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
464         }
465
466         for (unsigned int i = 0; i < bank->num_sectors; i++) {
467                 uint32_t sec_start = bank->sectors[i].offset;
468                 uint32_t sec_end = sec_start + bank->sectors[i].size;
469
470                 /* check if destination falls within the current sector */
471                 if ((check_address >= sec_start) && (check_address < sec_end)) {
472                         /* check if destination ends in the current sector */
473                         if (offset + count < sec_end)
474                                 check_address = offset + count;
475                         else
476                                 check_address = sec_end;
477                 }
478         }
479
480         if (check_address != offset + count)
481                 return ERROR_FLASH_DST_OUT_OF_BANK;
482
483         /* multiple half words (2-byte) to be programmed? */
484         if (words_remaining > 0) {
485                 /* try using a block write */
486                 retval = str9x_write_block(bank, buffer, offset, words_remaining);
487                 if (retval != ERROR_OK) {
488                         if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
489                                 /* if block write failed (no sufficient working area),
490                                  * we use normal (slow) single dword accesses */
491                                 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
492                         } else if (retval == ERROR_FLASH_OPERATION_FAILED) {
493                                 LOG_ERROR("flash writing failed");
494                                 return ERROR_FLASH_OPERATION_FAILED;
495                         }
496                 } else {
497                         buffer += words_remaining * 2;
498                         address += words_remaining * 2;
499                         words_remaining = 0;
500                 }
501         }
502
503         while (words_remaining > 0) {
504                 bank_adr = address & ~0x03;
505
506                 /* write data command */
507                 target_write_u16(target, bank_adr, 0x40);
508                 target_write_memory(target, address, 2, 1, buffer + bytes_written);
509
510                 /* get status command */
511                 target_write_u16(target, bank_adr, 0x70);
512
513                 int timeout;
514                 for (timeout = 0; timeout < 1000; timeout++) {
515                         target_read_u8(target, bank_adr, &status);
516                         if (status & 0x80)
517                                 break;
518                         alive_sleep(1);
519                 }
520                 if (timeout == 1000) {
521                         LOG_ERROR("write timed out");
522                         return ERROR_FAIL;
523                 }
524
525                 /* clear status reg and read array */
526                 target_write_u16(target, bank_adr, 0x50);
527                 target_write_u16(target, bank_adr, 0xFF);
528
529                 if (status & 0x10)
530                         return ERROR_FLASH_OPERATION_FAILED;
531                 else if (status & 0x02)
532                         return ERROR_FLASH_OPERATION_FAILED;
533
534                 bytes_written += 2;
535                 words_remaining--;
536                 address += 2;
537         }
538
539         if (bytes_remaining) {
540                 uint8_t last_halfword[2] = {0xff, 0xff};
541
542                 /* copy the last remaining bytes into the write buffer */
543                 memcpy(last_halfword, buffer+bytes_written, bytes_remaining);
544
545                 bank_adr = address & ~0x03;
546
547                 /* write data command */
548                 target_write_u16(target, bank_adr, 0x40);
549                 target_write_memory(target, address, 2, 1, last_halfword);
550
551                 /* query status command */
552                 target_write_u16(target, bank_adr, 0x70);
553
554                 int timeout;
555                 for (timeout = 0; timeout < 1000; timeout++) {
556                         target_read_u8(target, bank_adr, &status);
557                         if (status & 0x80)
558                                 break;
559                         alive_sleep(1);
560                 }
561                 if (timeout == 1000) {
562                         LOG_ERROR("write timed out");
563                         return ERROR_FAIL;
564                 }
565
566                 /* clear status reg and read array */
567                 target_write_u16(target, bank_adr, 0x50);
568                 target_write_u16(target, bank_adr, 0xFF);
569
570                 if (status & 0x10)
571                         return ERROR_FLASH_OPERATION_FAILED;
572                 else if (status & 0x02)
573                         return ERROR_FLASH_OPERATION_FAILED;
574         }
575
576         return ERROR_OK;
577 }
578
579 static int str9x_probe(struct flash_bank *bank)
580 {
581         return ERROR_OK;
582 }
583
584 #if 0
585 COMMAND_HANDLER(str9x_handle_part_id_command)
586 {
587         return ERROR_OK;
588 }
589 #endif
590
591 COMMAND_HANDLER(str9x_handle_flash_config_command)
592 {
593         struct target *target = NULL;
594
595         if (CMD_ARGC < 5)
596                 return ERROR_COMMAND_SYNTAX_ERROR;
597
598         struct flash_bank *bank;
599         int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
600         if (retval != ERROR_OK)
601                 return retval;
602
603         uint32_t bbsr, nbbsr, bbadr, nbbadr;
604         COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], bbsr);
605         COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], nbbsr);
606         COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], bbadr);
607         COMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], nbbadr);
608
609         target = bank->target;
610
611         if (bank->target->state != TARGET_HALTED) {
612                 LOG_ERROR("Target not halted");
613                 return ERROR_TARGET_NOT_HALTED;
614         }
615
616         /* config flash controller */
617         target_write_u32(target, FLASH_BBSR, bbsr);
618         target_write_u32(target, FLASH_NBBSR, nbbsr);
619         target_write_u32(target, FLASH_BBADR, bbadr >> 2);
620         target_write_u32(target, FLASH_NBBADR, nbbadr >> 2);
621
622         /* set bit 18 instruction TCM order as per flash programming manual */
623         arm966e_write_cp15(target, 62, 0x40000);
624
625         /* enable flash bank 1 */
626         target_write_u32(target, FLASH_CR, 0x18);
627         return ERROR_OK;
628 }
629
630 static const struct command_registration str9x_config_command_handlers[] = {
631         {
632                 .name = "flash_config",
633                 .handler = str9x_handle_flash_config_command,
634                 .mode = COMMAND_EXEC,
635                 .help = "Configure str9x flash controller, prior to "
636                         "programming the flash.",
637                 .usage = "bank_id BBSR NBBSR BBADR NBBADR",
638         },
639         COMMAND_REGISTRATION_DONE
640 };
641
642 static const struct command_registration str9x_command_handlers[] = {
643         {
644                 .name = "str9x",
645                 .mode = COMMAND_ANY,
646                 .help = "str9x flash command group",
647                 .usage = "",
648                 .chain = str9x_config_command_handlers,
649         },
650         COMMAND_REGISTRATION_DONE
651 };
652
653 const struct flash_driver str9x_flash = {
654         .name = "str9x",
655         .commands = str9x_command_handlers,
656         .flash_bank_command = str9x_flash_bank_command,
657         .erase = str9x_erase,
658         .protect = str9x_protect,
659         .write = str9x_write,
660         .read = default_flash_read,
661         .probe = str9x_probe,
662         .auto_probe = str9x_probe,
663         .erase_check = default_flash_blank_check,
664         .protect_check = str9x_protect_check,
665         .free_driver_priv = default_flash_free_driver_priv,
666 };