1 /***************************************************************************
2 * Copyright (C) 2006 by Magnus Lundin *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
24 /***************************************************************************
25 * STELLARIS flash is tested on LM3S811, LM3S6965, LM3s3748, more.
26 ***************************************************************************/
32 #include <target/algorithm.h>
33 #include <target/armv7m.h>
36 #define DID0_VER(did0) ((did0 >> 28)&0x07)
38 /* STELLARIS control registers */
39 #define SCB_BASE 0x400FE000
54 /* "legacy" flash memory protection registers (64KB max) */
58 /* new flash memory protection registers (for more than 64KB) */
59 #define FMPRE0 0x200 /* PRE1 = PRE0 + 4, etc */
60 #define FMPPE0 0x400 /* PPE1 = PPE0 + 4, etc */
64 #define FLASH_CONTROL_BASE 0x400FD000
65 #define FLASH_FMA (FLASH_CONTROL_BASE | 0x000)
66 #define FLASH_FMD (FLASH_CONTROL_BASE | 0x004)
67 #define FLASH_FMC (FLASH_CONTROL_BASE | 0x008)
68 #define FLASH_CRIS (FLASH_CONTROL_BASE | 0x00C)
69 #define FLASH_CIM (FLASH_CONTROL_BASE | 0x010)
70 #define FLASH_MISC (FLASH_CONTROL_BASE | 0x014)
78 /* Flash Controller Command bits */
79 #define FMC_WRKEY (0xA442 << 16)
80 #define FMC_COMT (1 << 3)
81 #define FMC_MERASE (1 << 2)
82 #define FMC_ERASE (1 << 1)
83 #define FMC_WRITE (1 << 0)
85 /* STELLARIS constants */
87 /* values to write in FMA to commit write-"once" values */
88 #define FLASH_FMA_PRE(x) (2 * (x)) /* for FMPPREx */
89 #define FLASH_FMA_PPE(x) (2 * (x) + 1) /* for FMPPPEx */
92 static void stellaris_read_clock_info(struct flash_bank
*bank
);
93 static int stellaris_mass_erase(struct flash_bank
*bank
);
95 struct stellaris_flash_bank
97 /* chip id register */
110 uint32_t pages_in_lockregion
;
113 uint16_t num_lockbits
;
115 /* main clock status */
122 const char *iosc_desc
;
123 const char *mck_desc
;
301 static char * StellarisClassname
[5] =
310 /***************************************************************************
311 * openocd command interface *
312 ***************************************************************************/
314 /* flash_bank stellaris <base> <size> 0 0 <target#>
316 FLASH_BANK_COMMAND_HANDLER(stellaris_flash_bank_command
)
318 struct stellaris_flash_bank
*stellaris_info
;
322 LOG_WARNING("incomplete flash_bank stellaris configuration");
323 return ERROR_FLASH_BANK_INVALID
;
326 stellaris_info
= calloc(sizeof(struct stellaris_flash_bank
), 1);
328 bank
->driver_priv
= stellaris_info
;
330 stellaris_info
->target_name
= "Unknown target";
332 /* part wasn't probed for info yet */
333 stellaris_info
->did1
= 0;
335 /* TODO Specify the main crystal speed in kHz using an optional
336 * argument; ditto, the speed of an external oscillator used
337 * instead of a crystal. Avoid programming flash using IOSC.
342 static int get_stellaris_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
344 int printed
, device_class
;
345 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
347 if (stellaris_info
->did1
== 0)
348 return ERROR_FLASH_BANK_NOT_PROBED
;
350 /* Read main and master clock freqency register */
351 stellaris_read_clock_info(bank
);
353 if (DID0_VER(stellaris_info
->did0
) > 0)
355 device_class
= (stellaris_info
->did0
>> 16) & 0xFF;
361 printed
= snprintf(buf
,
363 "\nTI/LMI Stellaris information: Chip is "
364 "class %i (%s) %s rev %c%i\n",
366 StellarisClassname
[device_class
],
367 stellaris_info
->target_name
,
368 (int)('A' + ((stellaris_info
->did0
>> 8) & 0xFF)),
369 (int)((stellaris_info
->did0
) & 0xFF));
373 printed
= snprintf(buf
,
375 "did1: 0x%8.8" PRIx32
", arch: 0x%4.4" PRIx32
376 ", eproc: %s, ramsize: %ik, flashsize: %ik\n",
377 stellaris_info
->did1
,
378 stellaris_info
->did1
,
380 (int)((1 + ((stellaris_info
->dc0
>> 16) & 0xFFFF))/4),
381 (int)((1 + (stellaris_info
->dc0
& 0xFFFF))*2));
385 printed
= snprintf(buf
,
387 "master clock: %ikHz%s, "
388 "rcc is 0x%" PRIx32
", rcc2 is 0x%" PRIx32
"\n",
389 (int)(stellaris_info
->mck_freq
/ 1000),
390 stellaris_info
->mck_desc
,
392 stellaris_info
->rcc2
);
396 if (stellaris_info
->num_lockbits
> 0)
398 printed
= snprintf(buf
,
400 "pagesize: %" PRIi32
", pages: %d, "
401 "lockbits: %i, pages per lockbit: %i\n",
402 stellaris_info
->pagesize
,
403 (unsigned) stellaris_info
->num_pages
,
404 stellaris_info
->num_lockbits
,
405 (unsigned) stellaris_info
->pages_in_lockregion
);
412 /***************************************************************************
413 * chip identification and status *
414 ***************************************************************************/
416 /* Set the flash timimg register to match current clocking */
417 static void stellaris_set_flash_timing(struct flash_bank
*bank
)
419 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
420 struct target
*target
= bank
->target
;
421 uint32_t usecrl
= (stellaris_info
->mck_freq
/1000000ul-1);
423 LOG_DEBUG("usecrl = %i",(int)(usecrl
));
424 target_write_u32(target
, SCB_BASE
| USECRL
, usecrl
);
427 static const unsigned rcc_xtal
[32] = {
428 [0x00] = 1000000, /* no pll */
429 [0x01] = 1843200, /* no pll */
430 [0x02] = 2000000, /* no pll */
431 [0x03] = 2457600, /* no pll */
435 [0x06] = 4000000, /* usb */
439 [0x09] = 5000000, /* usb */
441 [0x0b] = 6000000, /* (reset) usb */
445 [0x0e] = 8000000, /* usb */
448 /* parts before DustDevil use just 4 bits for xtal spec */
450 [0x10] = 10000000, /* usb */
451 [0x11] = 12000000, /* usb */
456 [0x15] = 16000000, /* usb */
460 /** Read clock configuration and set stellaris_info->usec_clocks. */
461 static void stellaris_read_clock_info(struct flash_bank
*bank
)
463 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
464 struct target
*target
= bank
->target
;
465 uint32_t rcc
, rcc2
, pllcfg
, sysdiv
, usesysdiv
, bypass
, oscsrc
;
467 unsigned long mainfreq
;
469 target_read_u32(target
, SCB_BASE
| RCC
, &rcc
);
470 LOG_DEBUG("Stellaris RCC %" PRIx32
"", rcc
);
472 target_read_u32(target
, SCB_BASE
| RCC2
, &rcc2
);
473 LOG_DEBUG("Stellaris RCC2 %" PRIx32
"", rcc
);
475 target_read_u32(target
, SCB_BASE
| PLLCFG
, &pllcfg
);
476 LOG_DEBUG("Stellaris PLLCFG %" PRIx32
"", pllcfg
);
478 stellaris_info
->rcc
= rcc
;
479 stellaris_info
->rcc
= rcc2
;
481 sysdiv
= (rcc
>> 23) & 0xF;
482 usesysdiv
= (rcc
>> 22) & 0x1;
483 bypass
= (rcc
>> 11) & 0x1;
484 oscsrc
= (rcc
>> 4) & 0x3;
485 xtal
= (rcc
>> 6) & stellaris_info
->xtal_mask
;
487 /* NOTE: post-Sandstorm parts have RCC2 which may override
488 * parts of RCC ... with more sysdiv options, option for
489 * 32768 Hz mainfreq, PLL controls. On Sandstorm it reads
490 * as zero, so the "use RCC2" flag is always clear.
492 if (rcc2
& (1 << 31)) {
493 sysdiv
= (rcc2
>> 23) & 0x3F;
494 bypass
= (rcc2
>> 11) & 0x1;
495 oscsrc
= (rcc2
>> 4) & 0x7;
497 /* FIXME Tempest parts have an additional lsb for
498 * fractional sysdiv (200 MHz / 2.5 == 80 MHz)
502 stellaris_info
->mck_desc
= "";
507 mainfreq
= rcc_xtal
[xtal
];
510 mainfreq
= stellaris_info
->iosc_freq
;
511 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
514 mainfreq
= stellaris_info
->iosc_freq
/ 4;
515 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
517 case 3: /* lowspeed */
518 /* Sandstorm doesn't have this 30K +/- 30% osc */
520 stellaris_info
->mck_desc
= " (±30%)";
522 case 8: /* hibernation osc */
523 /* not all parts support hibernation */
527 default: /* NOTREACHED */
532 /* PLL is used if it's not bypassed; its output is 200 MHz
533 * even when it runs at 400 MHz (adds divide-by-two stage).
536 mainfreq
= 200000000;
539 stellaris_info
->mck_freq
= mainfreq
/(1 + sysdiv
);
541 stellaris_info
->mck_freq
= mainfreq
;
544 /* Read device id register, main clock frequency register and fill in driver info structure */
545 static int stellaris_read_part_info(struct flash_bank
*bank
)
547 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
548 struct target
*target
= bank
->target
;
549 uint32_t did0
, did1
, ver
, fam
;
552 /* Read and parse chip identification register */
553 target_read_u32(target
, SCB_BASE
| DID0
, &did0
);
554 target_read_u32(target
, SCB_BASE
| DID1
, &did1
);
555 target_read_u32(target
, SCB_BASE
| DC0
, &stellaris_info
->dc0
);
556 target_read_u32(target
, SCB_BASE
| DC1
, &stellaris_info
->dc1
);
557 LOG_DEBUG("did0 0x%" PRIx32
", did1 0x%" PRIx32
", dc0 0x%" PRIx32
", dc1 0x%" PRIx32
"",
558 did0
, did1
, stellaris_info
->dc0
, stellaris_info
->dc1
);
561 if ((ver
!= 0) && (ver
!= 1))
563 LOG_WARNING("Unknown did0 version, cannot identify target");
564 return ERROR_FLASH_OPERATION_FAILED
;
569 LOG_WARNING("Cannot identify target as a Stellaris");
570 return ERROR_FLASH_OPERATION_FAILED
;
574 fam
= (did1
>> 24) & 0xF;
575 if (((ver
!= 0) && (ver
!= 1)) || (fam
!= 0))
577 LOG_WARNING("Unknown did1 version/family.");
578 return ERROR_FLASH_OPERATION_FAILED
;
581 /* For Sandstorm, Fury, DustDevil: current data sheets say IOSC
582 * is 12 MHz, but some older parts have 15 MHz. A few data sheets
583 * even give _both_ numbers! We'll use current numbers; IOSC is
584 * always approximate.
586 * For Tempest: IOSC is calibrated, 16 MHz
588 stellaris_info
->iosc_freq
= 12000000;
589 stellaris_info
->iosc_desc
= " (±30%)";
590 stellaris_info
->xtal_mask
= 0x0f;
592 switch ((did0
>> 28) & 0x7) {
593 case 0: /* Sandstorm */
595 * Current (2009-August) parts seem to be rev C2 and use 12 MHz.
596 * Parts before rev C0 used 15 MHz; some C0 parts use 15 MHz
597 * (LM3S618), but some other C0 parts are 12 MHz (LM3S811).
599 if (((did0
>> 8) & 0xff) < 2) {
600 stellaris_info
->iosc_freq
= 15000000;
601 stellaris_info
->iosc_desc
= " (±50%)";
605 switch ((did0
>> 16) & 0xff) {
608 case 4: /* Tempest */
609 stellaris_info
->iosc_freq
= 16000000; /* +/- 1% */
610 stellaris_info
->iosc_desc
= " (±1%)";
612 case 3: /* DustDevil */
613 stellaris_info
->xtal_mask
= 0x1f;
616 LOG_WARNING("Unknown did0 class");
620 LOG_WARNING("Unknown did0 version");
624 for (i
= 0; StellarisParts
[i
].partno
; i
++)
626 if (StellarisParts
[i
].partno
== ((did1
>> 16) & 0xFFFF))
630 stellaris_info
->target_name
= StellarisParts
[i
].partname
;
632 stellaris_info
->did0
= did0
;
633 stellaris_info
->did1
= did1
;
635 stellaris_info
->num_lockbits
= 1 + (stellaris_info
->dc0
& 0xFFFF);
636 stellaris_info
->num_pages
= 2 *(1 + (stellaris_info
->dc0
& 0xFFFF));
637 stellaris_info
->pagesize
= 1024;
638 stellaris_info
->pages_in_lockregion
= 2;
640 /* REVISIT for at least Tempest parts, read NVMSTAT.FWB too.
641 * That exposes a 32-word Flash Write Buffer ... enabling
642 * writes of more than one word at a time.
648 /***************************************************************************
650 ***************************************************************************/
652 static int stellaris_protect_check(struct flash_bank
*bank
)
654 struct stellaris_flash_bank
*stellaris
= bank
->driver_priv
;
655 int status
= ERROR_OK
;
659 if (stellaris
->did1
== 0)
660 return ERROR_FLASH_BANK_NOT_PROBED
;
662 for (i
= 0; i
< (unsigned) bank
->num_sectors
; i
++)
663 bank
->sectors
[i
].is_protected
= -1;
665 /* Read each Flash Memory Protection Program Enable (FMPPE) register
666 * to report any pages that we can't write. Ignore the Read Enable
669 for (i
= 0, page
= 0;
670 i
< DIV_ROUND_UP(stellaris
->num_lockbits
, 32u);
674 status
= target_read_u32(bank
->target
,
675 SCB_BASE
+ (i
? (FMPPE0
+ 4 * i
) : FMPPE
),
677 LOG_DEBUG("FMPPE%d = %#8.8x (status %d)", i
,
678 (unsigned) lockbits
, status
);
679 if (status
!= ERROR_OK
)
682 for (unsigned j
= 0; j
< 32; j
++) {
685 for (k
= 0; k
< stellaris
->pages_in_lockregion
; k
++) {
686 if (page
>= (unsigned) bank
->num_sectors
)
688 bank
->sectors
[page
++].is_protected
=
689 !(lockbits
& (1 << j
));
698 static int stellaris_erase(struct flash_bank
*bank
, int first
, int last
)
701 uint32_t flash_fmc
, flash_cris
;
702 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
703 struct target
*target
= bank
->target
;
705 if (bank
->target
->state
!= TARGET_HALTED
)
707 LOG_ERROR("Target not halted");
708 return ERROR_TARGET_NOT_HALTED
;
711 if (stellaris_info
->did1
== 0)
712 return ERROR_FLASH_BANK_NOT_PROBED
;
714 if ((first
< 0) || (last
< first
) || (last
>= (int)stellaris_info
->num_pages
))
716 return ERROR_FLASH_SECTOR_INVALID
;
719 if ((first
== 0) && (last
== ((int)stellaris_info
->num_pages
-1)))
721 return stellaris_mass_erase(bank
);
724 /* Refresh flash controller timing */
725 stellaris_read_clock_info(bank
);
726 stellaris_set_flash_timing(bank
);
728 /* Clear and disable flash programming interrupts */
729 target_write_u32(target
, FLASH_CIM
, 0);
730 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
732 /* REVISIT this clobbers state set by any halted firmware ...
733 * it might want to process those IRQs.
736 for (banknr
= first
; banknr
<= last
; banknr
++)
738 /* Address is first word in page */
739 target_write_u32(target
, FLASH_FMA
, banknr
* stellaris_info
->pagesize
);
740 /* Write erase command */
741 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_ERASE
);
742 /* Wait until erase complete */
745 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
747 while (flash_fmc
& FMC_ERASE
);
749 /* Check acess violations */
750 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
751 if (flash_cris
& (AMASK
))
753 LOG_WARNING("Error erasing flash page %i, flash_cris 0x%" PRIx32
"", banknr
, flash_cris
);
754 target_write_u32(target
, FLASH_CRIS
, 0);
755 return ERROR_FLASH_OPERATION_FAILED
;
758 bank
->sectors
[banknr
].is_erased
= 1;
764 static int stellaris_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
766 uint32_t fmppe
, flash_fmc
, flash_cris
;
769 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
770 struct target
*target
= bank
->target
;
772 if (bank
->target
->state
!= TARGET_HALTED
)
774 LOG_ERROR("Target not halted");
775 return ERROR_TARGET_NOT_HALTED
;
780 LOG_ERROR("Hardware doesn't suppport page-level unprotect. "
781 "Try the 'recover' command.");
782 return ERROR_INVALID_ARGUMENTS
;
785 if (stellaris_info
->did1
== 0)
786 return ERROR_FLASH_BANK_NOT_PROBED
;
788 /* lockregions are 2 pages ... must protect [even..odd] */
789 if ((first
< 0) || (first
& 1)
790 || (last
< first
) || !(last
& 1)
791 || (last
>= 2 * stellaris_info
->num_lockbits
))
793 LOG_ERROR("Can't protect unaligned or out-of-range pages.");
794 return ERROR_FLASH_SECTOR_INVALID
;
797 /* Refresh flash controller timing */
798 stellaris_read_clock_info(bank
);
799 stellaris_set_flash_timing(bank
);
801 /* convert from pages to lockregions */
805 /* FIXME this assumes single FMPPE, for a max of 64K of flash!!
806 * Current parts can be much bigger.
809 LOG_ERROR("No support yet for protection > 64K");
810 return ERROR_FLASH_OPERATION_FAILED
;
813 target_read_u32(target
, SCB_BASE
| FMPPE
, &fmppe
);
815 for (lockregion
= first
; lockregion
<= last
; lockregion
++)
816 fmppe
&= ~(1 << lockregion
);
818 /* Clear and disable flash programming interrupts */
819 target_write_u32(target
, FLASH_CIM
, 0);
820 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
822 /* REVISIT this clobbers state set by any halted firmware ...
823 * it might want to process those IRQs.
826 LOG_DEBUG("fmppe 0x%" PRIx32
"",fmppe
);
827 target_write_u32(target
, SCB_BASE
| FMPPE
, fmppe
);
830 target_write_u32(target
, FLASH_FMA
, 1);
832 /* Write commit command */
833 /* REVISIT safety check, since this cannot be undone
834 * except by the "Recover a locked device" procedure.
835 * REVISIT DustDevil-A0 parts have an erratum making FMPPE commits
836 * inadvisable ... it makes future mass erase operations fail.
838 LOG_WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
839 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
841 /* Wait until erase complete */
844 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
846 while (flash_fmc
& FMC_COMT
);
848 /* Check acess violations */
849 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
850 if (flash_cris
& (AMASK
))
852 LOG_WARNING("Error setting flash page protection, flash_cris 0x%" PRIx32
"", flash_cris
);
853 target_write_u32(target
, FLASH_CRIS
, 0);
854 return ERROR_FLASH_OPERATION_FAILED
;
860 /* see contib/loaders/flash/stellaris.s for src */
862 static const uint8_t stellaris_write_code
[] =
867 r1 = destination address
868 r2 = bytecount (in) - endaddr (work)
871 r3 = pFLASH_CTRL_BASE
877 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
878 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
879 0x01,0x25, /* movs r5, 1 */
880 0x00,0x26, /* movs r6, #0 */
882 0x19,0x60, /* str r1, [r3, #0] */
883 0x87,0x59, /* ldr r7, [r0, r6] */
884 0x5F,0x60, /* str r7, [r3, #4] */
885 0x9C,0x60, /* str r4, [r3, #8] */
887 0x9F,0x68, /* ldr r7, [r3, #8] */
888 0x2F,0x42, /* tst r7, r5 */
889 0xFC,0xD1, /* bne waitloop */
890 0x04,0x31, /* adds r1, r1, #4 */
891 0x04,0x36, /* adds r6, r6, #4 */
892 0x96,0x42, /* cmp r6, r2 */
893 0xF4,0xD1, /* bne mainloop */
894 0x00,0xBE, /* bkpt #0 */
895 /* pFLASH_CTRL_BASE: */
896 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
898 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
901 static int stellaris_write_block(struct flash_bank
*bank
,
902 uint8_t *buffer
, uint32_t offset
, uint32_t wcount
)
904 struct target
*target
= bank
->target
;
905 uint32_t buffer_size
= 16384;
906 struct working_area
*source
;
907 struct working_area
*write_algorithm
;
908 uint32_t address
= bank
->base
+ offset
;
909 struct reg_param reg_params
[3];
910 struct armv7m_algorithm armv7m_info
;
911 int retval
= ERROR_OK
;
913 /* power of two, and multiple of word size */
914 static const unsigned buf_min
= 128;
916 /* for small buffers it's faster not to download an algorithm */
917 if (wcount
* 4 < buf_min
)
918 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
920 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" wcount=%08" PRIx32
"",
921 bank
, buffer
, offset
, wcount
);
923 /* flash write code */
924 if (target_alloc_working_area(target
, sizeof(stellaris_write_code
), &write_algorithm
) != ERROR_OK
)
926 LOG_DEBUG("no working area for block memory writes");
927 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
930 /* plus a buffer big enough for this data */
931 if (wcount
* 4 < buffer_size
)
932 buffer_size
= wcount
* 4;
935 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
)
938 if (buffer_size
<= buf_min
)
940 target_free_working_area(target
, write_algorithm
);
941 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
943 LOG_DEBUG("retry target_alloc_working_area(%s, size=%u)",
944 target_name(target
), (unsigned) buffer_size
);
947 retval
= target_write_buffer(target
, write_algorithm
->address
,
948 sizeof(stellaris_write_code
),
949 (uint8_t *) stellaris_write_code
);
951 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
952 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
954 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
955 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
956 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
960 uint32_t thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
962 target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
964 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
965 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
966 buf_set_u32(reg_params
[2].value
, 0, 32, 4*thisrun_count
);
967 LOG_DEBUG("Algorithm flash write %u words to 0x%" PRIx32
969 (unsigned) thisrun_count
, address
,
970 (unsigned) (wcount
- thisrun_count
));
971 retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
,
972 write_algorithm
->address
,
974 10000, &armv7m_info
);
975 if (retval
!= ERROR_OK
)
977 LOG_ERROR("error %d executing stellaris "
978 "flash write algorithm",
980 retval
= ERROR_FLASH_OPERATION_FAILED
;
984 buffer
+= thisrun_count
* 4;
985 address
+= thisrun_count
* 4;
986 wcount
-= thisrun_count
;
989 /* REVISIT we could speed up writing multi-section images by
990 * not freeing the initialized write_algorithm this way.
993 target_free_working_area(target
, write_algorithm
);
994 target_free_working_area(target
, source
);
996 destroy_reg_param(®_params
[0]);
997 destroy_reg_param(®_params
[1]);
998 destroy_reg_param(®_params
[2]);
1003 static int stellaris_write(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
1005 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
1006 struct target
*target
= bank
->target
;
1007 uint32_t address
= offset
;
1008 uint32_t flash_cris
, flash_fmc
;
1009 uint32_t words_remaining
= (count
/ 4);
1010 uint32_t bytes_remaining
= (count
& 0x00000003);
1011 uint32_t bytes_written
= 0;
1014 if (bank
->target
->state
!= TARGET_HALTED
)
1016 LOG_ERROR("Target not halted");
1017 return ERROR_TARGET_NOT_HALTED
;
1020 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" count=%08" PRIx32
"",
1021 bank
, buffer
, offset
, count
);
1023 if (stellaris_info
->did1
== 0)
1024 return ERROR_FLASH_BANK_NOT_PROBED
;
1028 LOG_WARNING("offset size must be word aligned");
1029 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
1032 if (offset
+ count
> bank
->size
)
1033 return ERROR_FLASH_DST_OUT_OF_BANK
;
1035 /* Refresh flash controller timing */
1036 stellaris_read_clock_info(bank
);
1037 stellaris_set_flash_timing(bank
);
1039 /* Clear and disable flash programming interrupts */
1040 target_write_u32(target
, FLASH_CIM
, 0);
1041 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
1043 /* REVISIT this clobbers state set by any halted firmware ...
1044 * it might want to process those IRQs.
1047 /* multiple words to be programmed? */
1048 if (words_remaining
> 0)
1050 /* try using a block write */
1051 retval
= stellaris_write_block(bank
, buffer
, offset
,
1053 if (retval
!= ERROR_OK
)
1055 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
1057 LOG_DEBUG("writing flash word-at-a-time");
1059 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
1061 /* if an error occured, we examine the reason, and quit */
1062 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
1064 LOG_ERROR("flash writing failed with CRIS: 0x%" PRIx32
"", flash_cris
);
1065 return ERROR_FLASH_OPERATION_FAILED
;
1070 buffer
+= words_remaining
* 4;
1071 address
+= words_remaining
* 4;
1072 words_remaining
= 0;
1076 while (words_remaining
> 0)
1078 if (!(address
& 0xff))
1079 LOG_DEBUG("0x%" PRIx32
"", address
);
1081 /* Program one word */
1082 target_write_u32(target
, FLASH_FMA
, address
);
1083 target_write_buffer(target
, FLASH_FMD
, 4, buffer
);
1084 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
1085 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1086 /* Wait until write complete */
1089 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1090 } while (flash_fmc
& FMC_WRITE
);
1097 if (bytes_remaining
)
1099 uint8_t last_word
[4] = {0xff, 0xff, 0xff, 0xff};
1102 while (bytes_remaining
> 0)
1104 last_word
[i
++] = *(buffer
+ bytes_written
);
1109 if (!(address
& 0xff))
1110 LOG_DEBUG("0x%" PRIx32
"", address
);
1112 /* Program one word */
1113 target_write_u32(target
, FLASH_FMA
, address
);
1114 target_write_buffer(target
, FLASH_FMD
, 4, last_word
);
1115 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
1116 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1117 /* Wait until write complete */
1120 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1121 } while (flash_fmc
& FMC_WRITE
);
1124 /* Check access violations */
1125 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
1126 if (flash_cris
& (AMASK
))
1128 LOG_DEBUG("flash_cris 0x%" PRIx32
"", flash_cris
);
1129 return ERROR_FLASH_OPERATION_FAILED
;
1134 static int stellaris_probe(struct flash_bank
*bank
)
1136 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
1139 /* If this is a stellaris chip, it has flash; probe() is just
1140 * to figure out how much is present. Only do it once.
1142 if (stellaris_info
->did1
!= 0)
1145 /* stellaris_read_part_info() already handled error checking and
1146 * reporting. Note that it doesn't write, so we don't care about
1147 * whether the target is halted or not.
1149 retval
= stellaris_read_part_info(bank
);
1150 if (retval
!= ERROR_OK
)
1155 free(bank
->sectors
);
1156 bank
->sectors
= NULL
;
1159 /* provide this for the benefit of the NOR flash framework */
1160 bank
->size
= 1024 * stellaris_info
->num_pages
;
1161 bank
->num_sectors
= stellaris_info
->num_pages
;
1162 bank
->sectors
= calloc(bank
->num_sectors
, sizeof(struct flash_sector
));
1163 for (int i
= 0; i
< bank
->num_sectors
; i
++)
1165 bank
->sectors
[i
].offset
= i
* stellaris_info
->pagesize
;
1166 bank
->sectors
[i
].size
= stellaris_info
->pagesize
;
1167 bank
->sectors
[i
].is_erased
= -1;
1168 bank
->sectors
[i
].is_protected
= -1;
1174 static int stellaris_mass_erase(struct flash_bank
*bank
)
1176 struct target
*target
= NULL
;
1177 struct stellaris_flash_bank
*stellaris_info
= NULL
;
1180 stellaris_info
= bank
->driver_priv
;
1181 target
= bank
->target
;
1183 if (target
->state
!= TARGET_HALTED
)
1185 LOG_ERROR("Target not halted");
1186 return ERROR_TARGET_NOT_HALTED
;
1189 if (stellaris_info
->did1
== 0)
1190 return ERROR_FLASH_BANK_NOT_PROBED
;
1192 /* Refresh flash controller timing */
1193 stellaris_read_clock_info(bank
);
1194 stellaris_set_flash_timing(bank
);
1196 /* Clear and disable flash programming interrupts */
1197 target_write_u32(target
, FLASH_CIM
, 0);
1198 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
1200 /* REVISIT this clobbers state set by any halted firmware ...
1201 * it might want to process those IRQs.
1204 target_write_u32(target
, FLASH_FMA
, 0);
1205 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1206 /* Wait until erase complete */
1209 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1211 while (flash_fmc
& FMC_MERASE
);
1213 /* if device has > 128k, then second erase cycle is needed
1214 * this is only valid for older devices, but will not hurt */
1215 if (stellaris_info
->num_pages
* stellaris_info
->pagesize
> 0x20000)
1217 target_write_u32(target
, FLASH_FMA
, 0x20000);
1218 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1219 /* Wait until erase complete */
1222 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1224 while (flash_fmc
& FMC_MERASE
);
1230 COMMAND_HANDLER(stellaris_handle_mass_erase_command
)
1236 command_print(CMD_CTX
, "stellaris mass_erase <bank>");
1240 struct flash_bank
*bank
;
1241 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1242 if (ERROR_OK
!= retval
)
1245 if (stellaris_mass_erase(bank
) == ERROR_OK
)
1247 /* set all sectors as erased */
1248 for (i
= 0; i
< bank
->num_sectors
; i
++)
1250 bank
->sectors
[i
].is_erased
= 1;
1253 command_print(CMD_CTX
, "stellaris mass erase complete");
1257 command_print(CMD_CTX
, "stellaris mass erase failed");
1264 * Perform the Stellaris "Recovering a 'Locked' Device procedure.
1265 * This performs a mass erase and then restores all nonvolatile registers
1266 * (including USER_* registers and flash lock bits) to their defaults.
1267 * Accordingly, flash can be reprogrammed, and JTAG can be used.
1269 * NOTE that DustDevil parts (at least rev A0 silicon) have errata which
1270 * can affect this operation if flash protection has been enabled.
1272 COMMAND_HANDLER(stellaris_handle_recover_command
)
1274 struct flash_bank
*bank
;
1277 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1278 if (retval
!= ERROR_OK
)
1281 /* REVISIT ... it may be worth sanity checking that the AP is
1282 * inactive before we start. ARM documents that switching a DP's
1283 * mode while it's active can cause fault modes that need a power
1288 if (!(jtag_get_reset_config() & RESET_HAS_SRST
)) {
1289 LOG_ERROR("Can't recover Stellaris flash without SRST");
1292 jtag_add_reset(0, 1);
1294 for (int i
= 0; i
< 5; i
++) {
1295 retval
= dap_to_swd(bank
->target
);
1296 if (retval
!= ERROR_OK
)
1299 retval
= dap_to_jtag(bank
->target
);
1300 if (retval
!= ERROR_OK
)
1304 /* de-assert SRST */
1305 jtag_add_reset(0, 0);
1306 retval
= jtag_execute_queue();
1308 /* wait 400+ msec ... OK, "1+ second" is simpler */
1311 /* USER INTERVENTION required for the power cycle
1312 * Restarting OpenOCD is likely needed because of mode switching.
1314 LOG_INFO("USER ACTION: "
1315 "power cycle Stellaris chip, then restart OpenOCD.");
1321 static const struct command_registration stellaris_exec_command_handlers
[] = {
1323 .name
= "mass_erase",
1324 .handler
= stellaris_handle_mass_erase_command
,
1325 .mode
= COMMAND_EXEC
,
1327 .help
= "erase entire device",
1331 .handler
= stellaris_handle_recover_command
,
1332 .mode
= COMMAND_EXEC
,
1334 .help
= "recover (and erase) locked device",
1336 COMMAND_REGISTRATION_DONE
1338 static const struct command_registration stellaris_command_handlers
[] = {
1340 .name
= "stellaris",
1341 .mode
= COMMAND_EXEC
,
1342 .help
= "Stellaris flash command group",
1343 .chain
= stellaris_exec_command_handlers
,
1345 COMMAND_REGISTRATION_DONE
1348 struct flash_driver stellaris_flash
= {
1349 .name
= "stellaris",
1350 .commands
= stellaris_command_handlers
,
1351 .flash_bank_command
= stellaris_flash_bank_command
,
1352 .erase
= stellaris_erase
,
1353 .protect
= stellaris_protect
,
1354 .write
= stellaris_write
,
1355 .read
= default_flash_read
,
1356 .probe
= stellaris_probe
,
1357 .auto_probe
= stellaris_probe
,
1358 .erase_check
= default_flash_mem_blank_check
,
1359 .protect_check
= stellaris_protect_check
,
1360 .info
= get_stellaris_info
,
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)