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 */
103 const char * target_name
;
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
;
126 // Autogenerated by contrib/gen-stellaris-part-header.pl
127 // From Stellaris Firmware Development Package revision 8049
130 const char *partname
;
373 static char * StellarisClassname
[7] =
384 /***************************************************************************
385 * openocd command interface *
386 ***************************************************************************/
388 /* flash_bank stellaris <base> <size> 0 0 <target#>
390 FLASH_BANK_COMMAND_HANDLER(stellaris_flash_bank_command
)
392 struct stellaris_flash_bank
*stellaris_info
;
396 LOG_WARNING("incomplete flash_bank stellaris configuration");
397 return ERROR_FLASH_BANK_INVALID
;
400 stellaris_info
= calloc(sizeof(struct stellaris_flash_bank
), 1);
402 bank
->driver_priv
= stellaris_info
;
404 stellaris_info
->target_name
= "Unknown target";
406 /* part wasn't probed for info yet */
407 stellaris_info
->did1
= 0;
409 /* TODO Specify the main crystal speed in kHz using an optional
410 * argument; ditto, the speed of an external oscillator used
411 * instead of a crystal. Avoid programming flash using IOSC.
416 static int get_stellaris_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
418 int printed
, device_class
;
419 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
421 if (stellaris_info
->did1
== 0)
422 return ERROR_FLASH_BANK_NOT_PROBED
;
424 /* Read main and master clock freqency register */
425 stellaris_read_clock_info(bank
);
427 if (DID0_VER(stellaris_info
->did0
) > 0)
429 device_class
= (stellaris_info
->did0
>> 16) & 0xFF;
435 printed
= snprintf(buf
,
437 "\nTI/LMI Stellaris information: Chip is "
438 "class %i (%s) %s rev %c%i\n",
440 StellarisClassname
[device_class
],
441 stellaris_info
->target_name
,
442 (int)('A' + ((stellaris_info
->did0
>> 8) & 0xFF)),
443 (int)((stellaris_info
->did0
) & 0xFF));
447 printed
= snprintf(buf
,
449 "did1: 0x%8.8" PRIx32
", arch: 0x%4.4" PRIx32
450 ", eproc: %s, ramsize: %ik, flashsize: %ik\n",
451 stellaris_info
->did1
,
452 stellaris_info
->did1
,
454 (int)((1 + ((stellaris_info
->dc0
>> 16) & 0xFFFF))/4),
455 (int)((1 + (stellaris_info
->dc0
& 0xFFFF))*2));
459 printed
= snprintf(buf
,
461 "master clock: %ikHz%s, "
462 "rcc is 0x%" PRIx32
", rcc2 is 0x%" PRIx32
"\n",
463 (int)(stellaris_info
->mck_freq
/ 1000),
464 stellaris_info
->mck_desc
,
466 stellaris_info
->rcc2
);
470 if (stellaris_info
->num_lockbits
> 0)
472 printed
= snprintf(buf
,
474 "pagesize: %" PRIi32
", pages: %d, "
475 "lockbits: %i, pages per lockbit: %i\n",
476 stellaris_info
->pagesize
,
477 (unsigned) stellaris_info
->num_pages
,
478 stellaris_info
->num_lockbits
,
479 (unsigned) stellaris_info
->pages_in_lockregion
);
486 /***************************************************************************
487 * chip identification and status *
488 ***************************************************************************/
490 /* Set the flash timimg register to match current clocking */
491 static void stellaris_set_flash_timing(struct flash_bank
*bank
)
493 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
494 struct target
*target
= bank
->target
;
495 uint32_t usecrl
= (stellaris_info
->mck_freq
/1000000ul-1);
497 LOG_DEBUG("usecrl = %i",(int)(usecrl
));
498 target_write_u32(target
, SCB_BASE
| USECRL
, usecrl
);
501 static const unsigned rcc_xtal
[32] = {
502 [0x00] = 1000000, /* no pll */
503 [0x01] = 1843200, /* no pll */
504 [0x02] = 2000000, /* no pll */
505 [0x03] = 2457600, /* no pll */
509 [0x06] = 4000000, /* usb */
513 [0x09] = 5000000, /* usb */
515 [0x0b] = 6000000, /* (reset) usb */
519 [0x0e] = 8000000, /* usb */
522 /* parts before DustDevil use just 4 bits for xtal spec */
524 [0x10] = 10000000, /* usb */
525 [0x11] = 12000000, /* usb */
530 [0x15] = 16000000, /* usb */
534 /** Read clock configuration and set stellaris_info->usec_clocks. */
535 static void stellaris_read_clock_info(struct flash_bank
*bank
)
537 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
538 struct target
*target
= bank
->target
;
539 uint32_t rcc
, rcc2
, pllcfg
, sysdiv
, usesysdiv
, bypass
, oscsrc
;
541 unsigned long mainfreq
;
543 target_read_u32(target
, SCB_BASE
| RCC
, &rcc
);
544 LOG_DEBUG("Stellaris RCC %" PRIx32
"", rcc
);
546 target_read_u32(target
, SCB_BASE
| RCC2
, &rcc2
);
547 LOG_DEBUG("Stellaris RCC2 %" PRIx32
"", rcc
);
549 target_read_u32(target
, SCB_BASE
| PLLCFG
, &pllcfg
);
550 LOG_DEBUG("Stellaris PLLCFG %" PRIx32
"", pllcfg
);
552 stellaris_info
->rcc
= rcc
;
553 stellaris_info
->rcc
= rcc2
;
555 sysdiv
= (rcc
>> 23) & 0xF;
556 usesysdiv
= (rcc
>> 22) & 0x1;
557 bypass
= (rcc
>> 11) & 0x1;
558 oscsrc
= (rcc
>> 4) & 0x3;
559 xtal
= (rcc
>> 6) & stellaris_info
->xtal_mask
;
561 /* NOTE: post-Sandstorm parts have RCC2 which may override
562 * parts of RCC ... with more sysdiv options, option for
563 * 32768 Hz mainfreq, PLL controls. On Sandstorm it reads
564 * as zero, so the "use RCC2" flag is always clear.
566 if (rcc2
& (1 << 31)) {
567 sysdiv
= (rcc2
>> 23) & 0x3F;
568 bypass
= (rcc2
>> 11) & 0x1;
569 oscsrc
= (rcc2
>> 4) & 0x7;
571 /* FIXME Tempest parts have an additional lsb for
572 * fractional sysdiv (200 MHz / 2.5 == 80 MHz)
576 stellaris_info
->mck_desc
= "";
581 mainfreq
= rcc_xtal
[xtal
];
584 mainfreq
= stellaris_info
->iosc_freq
;
585 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
588 mainfreq
= stellaris_info
->iosc_freq
/ 4;
589 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
591 case 3: /* lowspeed */
592 /* Sandstorm doesn't have this 30K +/- 30% osc */
594 stellaris_info
->mck_desc
= " (±30%)";
596 case 8: /* hibernation osc */
597 /* not all parts support hibernation */
601 default: /* NOTREACHED */
606 /* PLL is used if it's not bypassed; its output is 200 MHz
607 * even when it runs at 400 MHz (adds divide-by-two stage).
610 mainfreq
= 200000000;
613 stellaris_info
->mck_freq
= mainfreq
/(1 + sysdiv
);
615 stellaris_info
->mck_freq
= mainfreq
;
618 /* Read device id register, main clock frequency register and fill in driver info structure */
619 static int stellaris_read_part_info(struct flash_bank
*bank
)
621 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
622 struct target
*target
= bank
->target
;
623 uint32_t did0
, did1
, ver
, fam
;
626 /* Read and parse chip identification register */
627 target_read_u32(target
, SCB_BASE
| DID0
, &did0
);
628 target_read_u32(target
, SCB_BASE
| DID1
, &did1
);
629 target_read_u32(target
, SCB_BASE
| DC0
, &stellaris_info
->dc0
);
630 target_read_u32(target
, SCB_BASE
| DC1
, &stellaris_info
->dc1
);
631 LOG_DEBUG("did0 0x%" PRIx32
", did1 0x%" PRIx32
", dc0 0x%" PRIx32
", dc1 0x%" PRIx32
"",
632 did0
, did1
, stellaris_info
->dc0
, stellaris_info
->dc1
);
635 if ((ver
!= 0) && (ver
!= 1))
637 LOG_WARNING("Unknown did0 version, cannot identify target");
638 return ERROR_FLASH_OPERATION_FAILED
;
643 LOG_WARNING("Cannot identify target as a Stellaris");
644 return ERROR_FLASH_OPERATION_FAILED
;
648 fam
= (did1
>> 24) & 0xF;
649 if (((ver
!= 0) && (ver
!= 1)) || (fam
!= 0))
651 LOG_WARNING("Unknown did1 version/family.");
652 return ERROR_FLASH_OPERATION_FAILED
;
655 /* For Sandstorm, Fury, DustDevil: current data sheets say IOSC
656 * is 12 MHz, but some older parts have 15 MHz. A few data sheets
657 * even give _both_ numbers! We'll use current numbers; IOSC is
658 * always approximate.
660 * For Tempest: IOSC is calibrated, 16 MHz
662 stellaris_info
->iosc_freq
= 12000000;
663 stellaris_info
->iosc_desc
= " (±30%)";
664 stellaris_info
->xtal_mask
= 0x0f;
666 switch ((did0
>> 28) & 0x7) {
667 case 0: /* Sandstorm */
669 * Current (2009-August) parts seem to be rev C2 and use 12 MHz.
670 * Parts before rev C0 used 15 MHz; some C0 parts use 15 MHz
671 * (LM3S618), but some other C0 parts are 12 MHz (LM3S811).
673 if (((did0
>> 8) & 0xff) < 2) {
674 stellaris_info
->iosc_freq
= 15000000;
675 stellaris_info
->iosc_desc
= " (±50%)";
679 switch ((did0
>> 16) & 0xff) {
682 case 4: /* Tempest */
683 stellaris_info
->iosc_freq
= 16000000; /* +/- 1% */
684 stellaris_info
->iosc_desc
= " (±1%)";
686 case 3: /* DustDevil */
687 stellaris_info
->xtal_mask
= 0x1f;
690 LOG_WARNING("Unknown did0 class");
694 LOG_WARNING("Unknown did0 version");
698 for (i
= 0; StellarisParts
[i
].partno
; i
++)
700 if (StellarisParts
[i
].partno
== ((did1
>> 16) & 0xFFFF))
704 stellaris_info
->target_name
= StellarisParts
[i
].partname
;
706 stellaris_info
->did0
= did0
;
707 stellaris_info
->did1
= did1
;
709 stellaris_info
->num_lockbits
= 1 + (stellaris_info
->dc0
& 0xFFFF);
710 stellaris_info
->num_pages
= 2 *(1 + (stellaris_info
->dc0
& 0xFFFF));
711 stellaris_info
->pagesize
= 1024;
712 stellaris_info
->pages_in_lockregion
= 2;
714 /* REVISIT for at least Tempest parts, read NVMSTAT.FWB too.
715 * That exposes a 32-word Flash Write Buffer ... enabling
716 * writes of more than one word at a time.
722 /***************************************************************************
724 ***************************************************************************/
726 static int stellaris_protect_check(struct flash_bank
*bank
)
728 struct stellaris_flash_bank
*stellaris
= bank
->driver_priv
;
729 int status
= ERROR_OK
;
733 if (stellaris
->did1
== 0)
734 return ERROR_FLASH_BANK_NOT_PROBED
;
736 for (i
= 0; i
< (unsigned) bank
->num_sectors
; i
++)
737 bank
->sectors
[i
].is_protected
= -1;
739 /* Read each Flash Memory Protection Program Enable (FMPPE) register
740 * to report any pages that we can't write. Ignore the Read Enable
743 for (i
= 0, page
= 0;
744 i
< DIV_ROUND_UP(stellaris
->num_lockbits
, 32u);
748 status
= target_read_u32(bank
->target
,
749 SCB_BASE
+ (i
? (FMPPE0
+ 4 * i
) : FMPPE
),
751 LOG_DEBUG("FMPPE%d = %#8.8x (status %d)", i
,
752 (unsigned) lockbits
, status
);
753 if (status
!= ERROR_OK
)
756 for (unsigned j
= 0; j
< 32; j
++) {
759 for (k
= 0; k
< stellaris
->pages_in_lockregion
; k
++) {
760 if (page
>= (unsigned) bank
->num_sectors
)
762 bank
->sectors
[page
++].is_protected
=
763 !(lockbits
& (1 << j
));
772 static int stellaris_erase(struct flash_bank
*bank
, int first
, int last
)
775 uint32_t flash_fmc
, flash_cris
;
776 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
777 struct target
*target
= bank
->target
;
779 if (bank
->target
->state
!= TARGET_HALTED
)
781 LOG_ERROR("Target not halted");
782 return ERROR_TARGET_NOT_HALTED
;
785 if (stellaris_info
->did1
== 0)
786 return ERROR_FLASH_BANK_NOT_PROBED
;
788 if ((first
< 0) || (last
< first
) || (last
>= (int)stellaris_info
->num_pages
))
790 return ERROR_FLASH_SECTOR_INVALID
;
793 if ((first
== 0) && (last
== ((int)stellaris_info
->num_pages
-1)))
795 return stellaris_mass_erase(bank
);
798 /* Refresh flash controller timing */
799 stellaris_read_clock_info(bank
);
800 stellaris_set_flash_timing(bank
);
802 /* Clear and disable flash programming interrupts */
803 target_write_u32(target
, FLASH_CIM
, 0);
804 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
806 /* REVISIT this clobbers state set by any halted firmware ...
807 * it might want to process those IRQs.
810 for (banknr
= first
; banknr
<= last
; banknr
++)
812 /* Address is first word in page */
813 target_write_u32(target
, FLASH_FMA
, banknr
* stellaris_info
->pagesize
);
814 /* Write erase command */
815 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_ERASE
);
816 /* Wait until erase complete */
819 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
821 while (flash_fmc
& FMC_ERASE
);
823 /* Check acess violations */
824 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
825 if (flash_cris
& (AMASK
))
827 LOG_WARNING("Error erasing flash page %i, flash_cris 0x%" PRIx32
"", banknr
, flash_cris
);
828 target_write_u32(target
, FLASH_CRIS
, 0);
829 return ERROR_FLASH_OPERATION_FAILED
;
832 bank
->sectors
[banknr
].is_erased
= 1;
838 static int stellaris_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
840 uint32_t fmppe
, flash_fmc
, flash_cris
;
843 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
844 struct target
*target
= bank
->target
;
846 if (bank
->target
->state
!= TARGET_HALTED
)
848 LOG_ERROR("Target not halted");
849 return ERROR_TARGET_NOT_HALTED
;
854 LOG_ERROR("Hardware doesn't support page-level unprotect. "
855 "Try the 'recover' command.");
856 return ERROR_INVALID_ARGUMENTS
;
859 if (stellaris_info
->did1
== 0)
860 return ERROR_FLASH_BANK_NOT_PROBED
;
862 /* lockregions are 2 pages ... must protect [even..odd] */
863 if ((first
< 0) || (first
& 1)
864 || (last
< first
) || !(last
& 1)
865 || (last
>= 2 * stellaris_info
->num_lockbits
))
867 LOG_ERROR("Can't protect unaligned or out-of-range pages.");
868 return ERROR_FLASH_SECTOR_INVALID
;
871 /* Refresh flash controller timing */
872 stellaris_read_clock_info(bank
);
873 stellaris_set_flash_timing(bank
);
875 /* convert from pages to lockregions */
879 /* FIXME this assumes single FMPPE, for a max of 64K of flash!!
880 * Current parts can be much bigger.
883 LOG_ERROR("No support yet for protection > 64K");
884 return ERROR_FLASH_OPERATION_FAILED
;
887 target_read_u32(target
, SCB_BASE
| FMPPE
, &fmppe
);
889 for (lockregion
= first
; lockregion
<= last
; lockregion
++)
890 fmppe
&= ~(1 << lockregion
);
892 /* Clear and disable flash programming interrupts */
893 target_write_u32(target
, FLASH_CIM
, 0);
894 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
896 /* REVISIT this clobbers state set by any halted firmware ...
897 * it might want to process those IRQs.
900 LOG_DEBUG("fmppe 0x%" PRIx32
"",fmppe
);
901 target_write_u32(target
, SCB_BASE
| FMPPE
, fmppe
);
904 target_write_u32(target
, FLASH_FMA
, 1);
906 /* Write commit command */
907 /* REVISIT safety check, since this cannot be undone
908 * except by the "Recover a locked device" procedure.
909 * REVISIT DustDevil-A0 parts have an erratum making FMPPE commits
910 * inadvisable ... it makes future mass erase operations fail.
912 LOG_WARNING("Flash protection cannot be removed once committed, commit is NOT executed !");
913 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
915 /* Wait until erase complete */
918 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
920 while (flash_fmc
& FMC_COMT
);
922 /* Check acess violations */
923 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
924 if (flash_cris
& (AMASK
))
926 LOG_WARNING("Error setting flash page protection, flash_cris 0x%" PRIx32
"", flash_cris
);
927 target_write_u32(target
, FLASH_CRIS
, 0);
928 return ERROR_FLASH_OPERATION_FAILED
;
934 /* see contib/loaders/flash/stellaris.s for src */
936 static const uint8_t stellaris_write_code
[] =
941 r1 = destination address
942 r2 = bytecount (in) - endaddr (work)
945 r3 = pFLASH_CTRL_BASE
951 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
952 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
953 0x01,0x25, /* movs r5, 1 */
954 0x00,0x26, /* movs r6, #0 */
956 0x19,0x60, /* str r1, [r3, #0] */
957 0x87,0x59, /* ldr r7, [r0, r6] */
958 0x5F,0x60, /* str r7, [r3, #4] */
959 0x9C,0x60, /* str r4, [r3, #8] */
961 0x9F,0x68, /* ldr r7, [r3, #8] */
962 0x2F,0x42, /* tst r7, r5 */
963 0xFC,0xD1, /* bne waitloop */
964 0x04,0x31, /* adds r1, r1, #4 */
965 0x04,0x36, /* adds r6, r6, #4 */
966 0x96,0x42, /* cmp r6, r2 */
967 0xF4,0xD1, /* bne mainloop */
968 0x00,0xBE, /* bkpt #0 */
969 /* pFLASH_CTRL_BASE: */
970 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
972 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
975 static int stellaris_write_block(struct flash_bank
*bank
,
976 uint8_t *buffer
, uint32_t offset
, uint32_t wcount
)
978 struct target
*target
= bank
->target
;
979 uint32_t buffer_size
= 16384;
980 struct working_area
*source
;
981 struct working_area
*write_algorithm
;
982 uint32_t address
= bank
->base
+ offset
;
983 struct reg_param reg_params
[3];
984 struct armv7m_algorithm armv7m_info
;
985 int retval
= ERROR_OK
;
987 /* power of two, and multiple of word size */
988 static const unsigned buf_min
= 128;
990 /* for small buffers it's faster not to download an algorithm */
991 if (wcount
* 4 < buf_min
)
992 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
994 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" wcount=%08" PRIx32
"",
995 bank
, buffer
, offset
, wcount
);
997 /* flash write code */
998 if (target_alloc_working_area(target
, sizeof(stellaris_write_code
), &write_algorithm
) != ERROR_OK
)
1000 LOG_DEBUG("no working area for block memory writes");
1001 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1004 /* plus a buffer big enough for this data */
1005 if (wcount
* 4 < buffer_size
)
1006 buffer_size
= wcount
* 4;
1009 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
)
1012 if (buffer_size
<= buf_min
)
1014 target_free_working_area(target
, write_algorithm
);
1015 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1017 LOG_DEBUG("retry target_alloc_working_area(%s, size=%u)",
1018 target_name(target
), (unsigned) buffer_size
);
1021 retval
= target_write_buffer(target
, write_algorithm
->address
,
1022 sizeof(stellaris_write_code
),
1023 (uint8_t *) stellaris_write_code
);
1025 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
1026 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
1028 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
1029 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
1030 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
1034 uint32_t thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
1036 target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
1038 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
1039 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
1040 buf_set_u32(reg_params
[2].value
, 0, 32, 4*thisrun_count
);
1041 LOG_DEBUG("Algorithm flash write %u words to 0x%" PRIx32
1043 (unsigned) thisrun_count
, address
,
1044 (unsigned) (wcount
- thisrun_count
));
1045 retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
,
1046 write_algorithm
->address
,
1048 10000, &armv7m_info
);
1049 if (retval
!= ERROR_OK
)
1051 LOG_ERROR("error %d executing stellaris "
1052 "flash write algorithm",
1054 retval
= ERROR_FLASH_OPERATION_FAILED
;
1058 buffer
+= thisrun_count
* 4;
1059 address
+= thisrun_count
* 4;
1060 wcount
-= thisrun_count
;
1063 /* REVISIT we could speed up writing multi-section images by
1064 * not freeing the initialized write_algorithm this way.
1067 target_free_working_area(target
, write_algorithm
);
1068 target_free_working_area(target
, source
);
1070 destroy_reg_param(®_params
[0]);
1071 destroy_reg_param(®_params
[1]);
1072 destroy_reg_param(®_params
[2]);
1077 static int stellaris_write(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
1079 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
1080 struct target
*target
= bank
->target
;
1081 uint32_t address
= offset
;
1082 uint32_t flash_cris
, flash_fmc
;
1083 uint32_t words_remaining
= (count
/ 4);
1084 uint32_t bytes_remaining
= (count
& 0x00000003);
1085 uint32_t bytes_written
= 0;
1088 if (bank
->target
->state
!= TARGET_HALTED
)
1090 LOG_ERROR("Target not halted");
1091 return ERROR_TARGET_NOT_HALTED
;
1094 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" count=%08" PRIx32
"",
1095 bank
, buffer
, offset
, count
);
1097 if (stellaris_info
->did1
== 0)
1098 return ERROR_FLASH_BANK_NOT_PROBED
;
1102 LOG_WARNING("offset size must be word aligned");
1103 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
1106 if (offset
+ count
> bank
->size
)
1107 return ERROR_FLASH_DST_OUT_OF_BANK
;
1109 /* Refresh flash controller timing */
1110 stellaris_read_clock_info(bank
);
1111 stellaris_set_flash_timing(bank
);
1113 /* Clear and disable flash programming interrupts */
1114 target_write_u32(target
, FLASH_CIM
, 0);
1115 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
1117 /* REVISIT this clobbers state set by any halted firmware ...
1118 * it might want to process those IRQs.
1121 /* multiple words to be programmed? */
1122 if (words_remaining
> 0)
1124 /* try using a block write */
1125 retval
= stellaris_write_block(bank
, buffer
, offset
,
1127 if (retval
!= ERROR_OK
)
1129 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
1131 LOG_DEBUG("writing flash word-at-a-time");
1133 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
1135 /* if an error occured, we examine the reason, and quit */
1136 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
1138 LOG_ERROR("flash writing failed with CRIS: 0x%" PRIx32
"", flash_cris
);
1139 return ERROR_FLASH_OPERATION_FAILED
;
1144 buffer
+= words_remaining
* 4;
1145 address
+= words_remaining
* 4;
1146 words_remaining
= 0;
1150 while (words_remaining
> 0)
1152 if (!(address
& 0xff))
1153 LOG_DEBUG("0x%" PRIx32
"", address
);
1155 /* Program one word */
1156 target_write_u32(target
, FLASH_FMA
, address
);
1157 target_write_buffer(target
, FLASH_FMD
, 4, buffer
);
1158 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
1159 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1160 /* Wait until write complete */
1163 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1164 } while (flash_fmc
& FMC_WRITE
);
1171 if (bytes_remaining
)
1173 uint8_t last_word
[4] = {0xff, 0xff, 0xff, 0xff};
1176 while (bytes_remaining
> 0)
1178 last_word
[i
++] = *(buffer
+ bytes_written
);
1183 if (!(address
& 0xff))
1184 LOG_DEBUG("0x%" PRIx32
"", address
);
1186 /* Program one word */
1187 target_write_u32(target
, FLASH_FMA
, address
);
1188 target_write_buffer(target
, FLASH_FMD
, 4, last_word
);
1189 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
1190 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1191 /* Wait until write complete */
1194 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1195 } while (flash_fmc
& FMC_WRITE
);
1198 /* Check access violations */
1199 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
1200 if (flash_cris
& (AMASK
))
1202 LOG_DEBUG("flash_cris 0x%" PRIx32
"", flash_cris
);
1203 return ERROR_FLASH_OPERATION_FAILED
;
1208 static int stellaris_probe(struct flash_bank
*bank
)
1210 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
1213 /* If this is a stellaris chip, it has flash; probe() is just
1214 * to figure out how much is present. Only do it once.
1216 if (stellaris_info
->did1
!= 0)
1219 /* stellaris_read_part_info() already handled error checking and
1220 * reporting. Note that it doesn't write, so we don't care about
1221 * whether the target is halted or not.
1223 retval
= stellaris_read_part_info(bank
);
1224 if (retval
!= ERROR_OK
)
1229 free(bank
->sectors
);
1230 bank
->sectors
= NULL
;
1233 /* provide this for the benefit of the NOR flash framework */
1234 bank
->size
= 1024 * stellaris_info
->num_pages
;
1235 bank
->num_sectors
= stellaris_info
->num_pages
;
1236 bank
->sectors
= calloc(bank
->num_sectors
, sizeof(struct flash_sector
));
1237 for (int i
= 0; i
< bank
->num_sectors
; i
++)
1239 bank
->sectors
[i
].offset
= i
* stellaris_info
->pagesize
;
1240 bank
->sectors
[i
].size
= stellaris_info
->pagesize
;
1241 bank
->sectors
[i
].is_erased
= -1;
1242 bank
->sectors
[i
].is_protected
= -1;
1248 static int stellaris_mass_erase(struct flash_bank
*bank
)
1250 struct target
*target
= NULL
;
1251 struct stellaris_flash_bank
*stellaris_info
= NULL
;
1254 stellaris_info
= bank
->driver_priv
;
1255 target
= bank
->target
;
1257 if (target
->state
!= TARGET_HALTED
)
1259 LOG_ERROR("Target not halted");
1260 return ERROR_TARGET_NOT_HALTED
;
1263 if (stellaris_info
->did1
== 0)
1264 return ERROR_FLASH_BANK_NOT_PROBED
;
1266 /* Refresh flash controller timing */
1267 stellaris_read_clock_info(bank
);
1268 stellaris_set_flash_timing(bank
);
1270 /* Clear and disable flash programming interrupts */
1271 target_write_u32(target
, FLASH_CIM
, 0);
1272 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
1274 /* REVISIT this clobbers state set by any halted firmware ...
1275 * it might want to process those IRQs.
1278 target_write_u32(target
, FLASH_FMA
, 0);
1279 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1280 /* Wait until erase complete */
1283 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1285 while (flash_fmc
& FMC_MERASE
);
1287 /* if device has > 128k, then second erase cycle is needed
1288 * this is only valid for older devices, but will not hurt */
1289 if (stellaris_info
->num_pages
* stellaris_info
->pagesize
> 0x20000)
1291 target_write_u32(target
, FLASH_FMA
, 0x20000);
1292 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1293 /* Wait until erase complete */
1296 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1298 while (flash_fmc
& FMC_MERASE
);
1304 COMMAND_HANDLER(stellaris_handle_mass_erase_command
)
1310 command_print(CMD_CTX
, "stellaris mass_erase <bank>");
1314 struct flash_bank
*bank
;
1315 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1316 if (ERROR_OK
!= retval
)
1319 if (stellaris_mass_erase(bank
) == ERROR_OK
)
1321 /* set all sectors as erased */
1322 for (i
= 0; i
< bank
->num_sectors
; i
++)
1324 bank
->sectors
[i
].is_erased
= 1;
1327 command_print(CMD_CTX
, "stellaris mass erase complete");
1331 command_print(CMD_CTX
, "stellaris mass erase failed");
1338 * Perform the Stellaris "Recovering a 'Locked' Device procedure.
1339 * This performs a mass erase and then restores all nonvolatile registers
1340 * (including USER_* registers and flash lock bits) to their defaults.
1341 * Accordingly, flash can be reprogrammed, and JTAG can be used.
1343 * NOTE that DustDevil parts (at least rev A0 silicon) have errata which
1344 * can affect this operation if flash protection has been enabled.
1346 COMMAND_HANDLER(stellaris_handle_recover_command
)
1348 struct flash_bank
*bank
;
1351 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1352 if (retval
!= ERROR_OK
)
1355 /* REVISIT ... it may be worth sanity checking that the AP is
1356 * inactive before we start. ARM documents that switching a DP's
1357 * mode while it's active can cause fault modes that need a power
1362 if (!(jtag_get_reset_config() & RESET_HAS_SRST
)) {
1363 LOG_ERROR("Can't recover Stellaris flash without SRST");
1366 jtag_add_reset(0, 1);
1368 for (int i
= 0; i
< 5; i
++) {
1369 retval
= dap_to_swd(bank
->target
);
1370 if (retval
!= ERROR_OK
)
1373 retval
= dap_to_jtag(bank
->target
);
1374 if (retval
!= ERROR_OK
)
1378 /* de-assert SRST */
1379 jtag_add_reset(0, 0);
1380 retval
= jtag_execute_queue();
1382 /* wait 400+ msec ... OK, "1+ second" is simpler */
1385 /* USER INTERVENTION required for the power cycle
1386 * Restarting OpenOCD is likely needed because of mode switching.
1388 LOG_INFO("USER ACTION: "
1389 "power cycle Stellaris chip, then restart OpenOCD.");
1395 static const struct command_registration stellaris_exec_command_handlers
[] = {
1397 .name
= "mass_erase",
1398 .handler
= stellaris_handle_mass_erase_command
,
1399 .mode
= COMMAND_EXEC
,
1401 .help
= "erase entire device",
1405 .handler
= stellaris_handle_recover_command
,
1406 .mode
= COMMAND_EXEC
,
1408 .help
= "recover (and erase) locked device",
1410 COMMAND_REGISTRATION_DONE
1412 static const struct command_registration stellaris_command_handlers
[] = {
1414 .name
= "stellaris",
1415 .mode
= COMMAND_EXEC
,
1416 .help
= "Stellaris flash command group",
1417 .chain
= stellaris_exec_command_handlers
,
1419 COMMAND_REGISTRATION_DONE
1422 struct flash_driver stellaris_flash
= {
1423 .name
= "stellaris",
1424 .commands
= stellaris_command_handlers
,
1425 .flash_bank_command
= stellaris_flash_bank_command
,
1426 .erase
= stellaris_erase
,
1427 .protect
= stellaris_protect
,
1428 .write
= stellaris_write
,
1429 .read
= default_flash_read
,
1430 .probe
= stellaris_probe
,
1431 .auto_probe
= stellaris_probe
,
1432 .erase_check
= default_flash_mem_blank_check
,
1433 .protect_check
= stellaris_protect_check
,
1434 .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)