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 6734
130 const char *partname
;
307 static char * StellarisClassname
[5] =
316 /***************************************************************************
317 * openocd command interface *
318 ***************************************************************************/
320 /* flash_bank stellaris <base> <size> 0 0 <target#>
322 FLASH_BANK_COMMAND_HANDLER(stellaris_flash_bank_command
)
324 struct stellaris_flash_bank
*stellaris_info
;
328 LOG_WARNING("incomplete flash_bank stellaris configuration");
329 return ERROR_FLASH_BANK_INVALID
;
332 stellaris_info
= calloc(sizeof(struct stellaris_flash_bank
), 1);
334 bank
->driver_priv
= stellaris_info
;
336 stellaris_info
->target_name
= "Unknown target";
338 /* part wasn't probed for info yet */
339 stellaris_info
->did1
= 0;
341 /* TODO Specify the main crystal speed in kHz using an optional
342 * argument; ditto, the speed of an external oscillator used
343 * instead of a crystal. Avoid programming flash using IOSC.
348 static int get_stellaris_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
350 int printed
, device_class
;
351 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
353 if (stellaris_info
->did1
== 0)
354 return ERROR_FLASH_BANK_NOT_PROBED
;
356 /* Read main and master clock freqency register */
357 stellaris_read_clock_info(bank
);
359 if (DID0_VER(stellaris_info
->did0
) > 0)
361 device_class
= (stellaris_info
->did0
>> 16) & 0xFF;
367 printed
= snprintf(buf
,
369 "\nTI/LMI Stellaris information: Chip is "
370 "class %i (%s) %s rev %c%i\n",
372 StellarisClassname
[device_class
],
373 stellaris_info
->target_name
,
374 (int)('A' + ((stellaris_info
->did0
>> 8) & 0xFF)),
375 (int)((stellaris_info
->did0
) & 0xFF));
379 printed
= snprintf(buf
,
381 "did1: 0x%8.8" PRIx32
", arch: 0x%4.4" PRIx32
382 ", eproc: %s, ramsize: %ik, flashsize: %ik\n",
383 stellaris_info
->did1
,
384 stellaris_info
->did1
,
386 (int)((1 + ((stellaris_info
->dc0
>> 16) & 0xFFFF))/4),
387 (int)((1 + (stellaris_info
->dc0
& 0xFFFF))*2));
391 printed
= snprintf(buf
,
393 "master clock: %ikHz%s, "
394 "rcc is 0x%" PRIx32
", rcc2 is 0x%" PRIx32
"\n",
395 (int)(stellaris_info
->mck_freq
/ 1000),
396 stellaris_info
->mck_desc
,
398 stellaris_info
->rcc2
);
402 if (stellaris_info
->num_lockbits
> 0)
404 printed
= snprintf(buf
,
406 "pagesize: %" PRIi32
", pages: %d, "
407 "lockbits: %i, pages per lockbit: %i\n",
408 stellaris_info
->pagesize
,
409 (unsigned) stellaris_info
->num_pages
,
410 stellaris_info
->num_lockbits
,
411 (unsigned) stellaris_info
->pages_in_lockregion
);
418 /***************************************************************************
419 * chip identification and status *
420 ***************************************************************************/
422 /* Set the flash timimg register to match current clocking */
423 static void stellaris_set_flash_timing(struct flash_bank
*bank
)
425 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
426 struct target
*target
= bank
->target
;
427 uint32_t usecrl
= (stellaris_info
->mck_freq
/1000000ul-1);
429 LOG_DEBUG("usecrl = %i",(int)(usecrl
));
430 target_write_u32(target
, SCB_BASE
| USECRL
, usecrl
);
433 static const unsigned rcc_xtal
[32] = {
434 [0x00] = 1000000, /* no pll */
435 [0x01] = 1843200, /* no pll */
436 [0x02] = 2000000, /* no pll */
437 [0x03] = 2457600, /* no pll */
441 [0x06] = 4000000, /* usb */
445 [0x09] = 5000000, /* usb */
447 [0x0b] = 6000000, /* (reset) usb */
451 [0x0e] = 8000000, /* usb */
454 /* parts before DustDevil use just 4 bits for xtal spec */
456 [0x10] = 10000000, /* usb */
457 [0x11] = 12000000, /* usb */
462 [0x15] = 16000000, /* usb */
466 /** Read clock configuration and set stellaris_info->usec_clocks. */
467 static void stellaris_read_clock_info(struct flash_bank
*bank
)
469 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
470 struct target
*target
= bank
->target
;
471 uint32_t rcc
, rcc2
, pllcfg
, sysdiv
, usesysdiv
, bypass
, oscsrc
;
473 unsigned long mainfreq
;
475 target_read_u32(target
, SCB_BASE
| RCC
, &rcc
);
476 LOG_DEBUG("Stellaris RCC %" PRIx32
"", rcc
);
478 target_read_u32(target
, SCB_BASE
| RCC2
, &rcc2
);
479 LOG_DEBUG("Stellaris RCC2 %" PRIx32
"", rcc
);
481 target_read_u32(target
, SCB_BASE
| PLLCFG
, &pllcfg
);
482 LOG_DEBUG("Stellaris PLLCFG %" PRIx32
"", pllcfg
);
484 stellaris_info
->rcc
= rcc
;
485 stellaris_info
->rcc
= rcc2
;
487 sysdiv
= (rcc
>> 23) & 0xF;
488 usesysdiv
= (rcc
>> 22) & 0x1;
489 bypass
= (rcc
>> 11) & 0x1;
490 oscsrc
= (rcc
>> 4) & 0x3;
491 xtal
= (rcc
>> 6) & stellaris_info
->xtal_mask
;
493 /* NOTE: post-Sandstorm parts have RCC2 which may override
494 * parts of RCC ... with more sysdiv options, option for
495 * 32768 Hz mainfreq, PLL controls. On Sandstorm it reads
496 * as zero, so the "use RCC2" flag is always clear.
498 if (rcc2
& (1 << 31)) {
499 sysdiv
= (rcc2
>> 23) & 0x3F;
500 bypass
= (rcc2
>> 11) & 0x1;
501 oscsrc
= (rcc2
>> 4) & 0x7;
503 /* FIXME Tempest parts have an additional lsb for
504 * fractional sysdiv (200 MHz / 2.5 == 80 MHz)
508 stellaris_info
->mck_desc
= "";
513 mainfreq
= rcc_xtal
[xtal
];
516 mainfreq
= stellaris_info
->iosc_freq
;
517 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
520 mainfreq
= stellaris_info
->iosc_freq
/ 4;
521 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
523 case 3: /* lowspeed */
524 /* Sandstorm doesn't have this 30K +/- 30% osc */
526 stellaris_info
->mck_desc
= " (±30%)";
528 case 8: /* hibernation osc */
529 /* not all parts support hibernation */
533 default: /* NOTREACHED */
538 /* PLL is used if it's not bypassed; its output is 200 MHz
539 * even when it runs at 400 MHz (adds divide-by-two stage).
542 mainfreq
= 200000000;
545 stellaris_info
->mck_freq
= mainfreq
/(1 + sysdiv
);
547 stellaris_info
->mck_freq
= mainfreq
;
550 /* Read device id register, main clock frequency register and fill in driver info structure */
551 static int stellaris_read_part_info(struct flash_bank
*bank
)
553 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
554 struct target
*target
= bank
->target
;
555 uint32_t did0
, did1
, ver
, fam
;
558 /* Read and parse chip identification register */
559 target_read_u32(target
, SCB_BASE
| DID0
, &did0
);
560 target_read_u32(target
, SCB_BASE
| DID1
, &did1
);
561 target_read_u32(target
, SCB_BASE
| DC0
, &stellaris_info
->dc0
);
562 target_read_u32(target
, SCB_BASE
| DC1
, &stellaris_info
->dc1
);
563 LOG_DEBUG("did0 0x%" PRIx32
", did1 0x%" PRIx32
", dc0 0x%" PRIx32
", dc1 0x%" PRIx32
"",
564 did0
, did1
, stellaris_info
->dc0
, stellaris_info
->dc1
);
567 if ((ver
!= 0) && (ver
!= 1))
569 LOG_WARNING("Unknown did0 version, cannot identify target");
570 return ERROR_FLASH_OPERATION_FAILED
;
575 LOG_WARNING("Cannot identify target as a Stellaris");
576 return ERROR_FLASH_OPERATION_FAILED
;
580 fam
= (did1
>> 24) & 0xF;
581 if (((ver
!= 0) && (ver
!= 1)) || (fam
!= 0))
583 LOG_WARNING("Unknown did1 version/family.");
584 return ERROR_FLASH_OPERATION_FAILED
;
587 /* For Sandstorm, Fury, DustDevil: current data sheets say IOSC
588 * is 12 MHz, but some older parts have 15 MHz. A few data sheets
589 * even give _both_ numbers! We'll use current numbers; IOSC is
590 * always approximate.
592 * For Tempest: IOSC is calibrated, 16 MHz
594 stellaris_info
->iosc_freq
= 12000000;
595 stellaris_info
->iosc_desc
= " (±30%)";
596 stellaris_info
->xtal_mask
= 0x0f;
598 switch ((did0
>> 28) & 0x7) {
599 case 0: /* Sandstorm */
601 * Current (2009-August) parts seem to be rev C2 and use 12 MHz.
602 * Parts before rev C0 used 15 MHz; some C0 parts use 15 MHz
603 * (LM3S618), but some other C0 parts are 12 MHz (LM3S811).
605 if (((did0
>> 8) & 0xff) < 2) {
606 stellaris_info
->iosc_freq
= 15000000;
607 stellaris_info
->iosc_desc
= " (±50%)";
611 switch ((did0
>> 16) & 0xff) {
614 case 4: /* Tempest */
615 stellaris_info
->iosc_freq
= 16000000; /* +/- 1% */
616 stellaris_info
->iosc_desc
= " (±1%)";
618 case 3: /* DustDevil */
619 stellaris_info
->xtal_mask
= 0x1f;
622 LOG_WARNING("Unknown did0 class");
626 LOG_WARNING("Unknown did0 version");
630 for (i
= 0; StellarisParts
[i
].partno
; i
++)
632 if (StellarisParts
[i
].partno
== ((did1
>> 16) & 0xFFFF))
636 stellaris_info
->target_name
= StellarisParts
[i
].partname
;
638 stellaris_info
->did0
= did0
;
639 stellaris_info
->did1
= did1
;
641 stellaris_info
->num_lockbits
= 1 + (stellaris_info
->dc0
& 0xFFFF);
642 stellaris_info
->num_pages
= 2 *(1 + (stellaris_info
->dc0
& 0xFFFF));
643 stellaris_info
->pagesize
= 1024;
644 stellaris_info
->pages_in_lockregion
= 2;
646 /* REVISIT for at least Tempest parts, read NVMSTAT.FWB too.
647 * That exposes a 32-word Flash Write Buffer ... enabling
648 * writes of more than one word at a time.
654 /***************************************************************************
656 ***************************************************************************/
658 static int stellaris_protect_check(struct flash_bank
*bank
)
660 struct stellaris_flash_bank
*stellaris
= bank
->driver_priv
;
661 int status
= ERROR_OK
;
665 if (stellaris
->did1
== 0)
666 return ERROR_FLASH_BANK_NOT_PROBED
;
668 for (i
= 0; i
< (unsigned) bank
->num_sectors
; i
++)
669 bank
->sectors
[i
].is_protected
= -1;
671 /* Read each Flash Memory Protection Program Enable (FMPPE) register
672 * to report any pages that we can't write. Ignore the Read Enable
675 for (i
= 0, page
= 0;
676 i
< DIV_ROUND_UP(stellaris
->num_lockbits
, 32u);
680 status
= target_read_u32(bank
->target
,
681 SCB_BASE
+ (i
? (FMPPE0
+ 4 * i
) : FMPPE
),
683 LOG_DEBUG("FMPPE%d = %#8.8x (status %d)", i
,
684 (unsigned) lockbits
, status
);
685 if (status
!= ERROR_OK
)
688 for (unsigned j
= 0; j
< 32; j
++) {
691 for (k
= 0; k
< stellaris
->pages_in_lockregion
; k
++) {
692 if (page
>= (unsigned) bank
->num_sectors
)
694 bank
->sectors
[page
++].is_protected
=
695 !(lockbits
& (1 << j
));
704 static int stellaris_erase(struct flash_bank
*bank
, int first
, int last
)
707 uint32_t flash_fmc
, flash_cris
;
708 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
709 struct target
*target
= bank
->target
;
711 if (bank
->target
->state
!= TARGET_HALTED
)
713 LOG_ERROR("Target not halted");
714 return ERROR_TARGET_NOT_HALTED
;
717 if (stellaris_info
->did1
== 0)
718 return ERROR_FLASH_BANK_NOT_PROBED
;
720 if ((first
< 0) || (last
< first
) || (last
>= (int)stellaris_info
->num_pages
))
722 return ERROR_FLASH_SECTOR_INVALID
;
725 if ((first
== 0) && (last
== ((int)stellaris_info
->num_pages
-1)))
727 return stellaris_mass_erase(bank
);
730 /* Refresh flash controller timing */
731 stellaris_read_clock_info(bank
);
732 stellaris_set_flash_timing(bank
);
734 /* Clear and disable flash programming interrupts */
735 target_write_u32(target
, FLASH_CIM
, 0);
736 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
738 /* REVISIT this clobbers state set by any halted firmware ...
739 * it might want to process those IRQs.
742 for (banknr
= first
; banknr
<= last
; banknr
++)
744 /* Address is first word in page */
745 target_write_u32(target
, FLASH_FMA
, banknr
* stellaris_info
->pagesize
);
746 /* Write erase command */
747 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_ERASE
);
748 /* Wait until erase complete */
751 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
753 while (flash_fmc
& FMC_ERASE
);
755 /* Check acess violations */
756 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
757 if (flash_cris
& (AMASK
))
759 LOG_WARNING("Error erasing flash page %i, flash_cris 0x%" PRIx32
"", banknr
, flash_cris
);
760 target_write_u32(target
, FLASH_CRIS
, 0);
761 return ERROR_FLASH_OPERATION_FAILED
;
764 bank
->sectors
[banknr
].is_erased
= 1;
770 static int stellaris_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
772 uint32_t fmppe
, flash_fmc
, flash_cris
;
775 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
776 struct target
*target
= bank
->target
;
778 if (bank
->target
->state
!= TARGET_HALTED
)
780 LOG_ERROR("Target not halted");
781 return ERROR_TARGET_NOT_HALTED
;
786 LOG_ERROR("Hardware doesn't support page-level unprotect. "
787 "Try the 'recover' command.");
788 return ERROR_INVALID_ARGUMENTS
;
791 if (stellaris_info
->did1
== 0)
792 return ERROR_FLASH_BANK_NOT_PROBED
;
794 /* lockregions are 2 pages ... must protect [even..odd] */
795 if ((first
< 0) || (first
& 1)
796 || (last
< first
) || !(last
& 1)
797 || (last
>= 2 * stellaris_info
->num_lockbits
))
799 LOG_ERROR("Can't protect unaligned or out-of-range pages.");
800 return ERROR_FLASH_SECTOR_INVALID
;
803 /* Refresh flash controller timing */
804 stellaris_read_clock_info(bank
);
805 stellaris_set_flash_timing(bank
);
807 /* convert from pages to lockregions */
811 /* FIXME this assumes single FMPPE, for a max of 64K of flash!!
812 * Current parts can be much bigger.
815 LOG_ERROR("No support yet for protection > 64K");
816 return ERROR_FLASH_OPERATION_FAILED
;
819 target_read_u32(target
, SCB_BASE
| FMPPE
, &fmppe
);
821 for (lockregion
= first
; lockregion
<= last
; lockregion
++)
822 fmppe
&= ~(1 << lockregion
);
824 /* Clear and disable flash programming interrupts */
825 target_write_u32(target
, FLASH_CIM
, 0);
826 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
828 /* REVISIT this clobbers state set by any halted firmware ...
829 * it might want to process those IRQs.
832 LOG_DEBUG("fmppe 0x%" PRIx32
"",fmppe
);
833 target_write_u32(target
, SCB_BASE
| FMPPE
, fmppe
);
836 target_write_u32(target
, FLASH_FMA
, 1);
838 /* Write commit command */
839 /* REVISIT safety check, since this cannot be undone
840 * except by the "Recover a locked device" procedure.
841 * REVISIT DustDevil-A0 parts have an erratum making FMPPE commits
842 * inadvisable ... it makes future mass erase operations fail.
844 LOG_WARNING("Flash protection cannot be removed once committed, commit is NOT executed !");
845 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
847 /* Wait until erase complete */
850 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
852 while (flash_fmc
& FMC_COMT
);
854 /* Check acess violations */
855 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
856 if (flash_cris
& (AMASK
))
858 LOG_WARNING("Error setting flash page protection, flash_cris 0x%" PRIx32
"", flash_cris
);
859 target_write_u32(target
, FLASH_CRIS
, 0);
860 return ERROR_FLASH_OPERATION_FAILED
;
866 /* see contib/loaders/flash/stellaris.s for src */
868 static const uint8_t stellaris_write_code
[] =
873 r1 = destination address
874 r2 = bytecount (in) - endaddr (work)
877 r3 = pFLASH_CTRL_BASE
883 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
884 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
885 0x01,0x25, /* movs r5, 1 */
886 0x00,0x26, /* movs r6, #0 */
888 0x19,0x60, /* str r1, [r3, #0] */
889 0x87,0x59, /* ldr r7, [r0, r6] */
890 0x5F,0x60, /* str r7, [r3, #4] */
891 0x9C,0x60, /* str r4, [r3, #8] */
893 0x9F,0x68, /* ldr r7, [r3, #8] */
894 0x2F,0x42, /* tst r7, r5 */
895 0xFC,0xD1, /* bne waitloop */
896 0x04,0x31, /* adds r1, r1, #4 */
897 0x04,0x36, /* adds r6, r6, #4 */
898 0x96,0x42, /* cmp r6, r2 */
899 0xF4,0xD1, /* bne mainloop */
900 0x00,0xBE, /* bkpt #0 */
901 /* pFLASH_CTRL_BASE: */
902 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
904 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
907 static int stellaris_write_block(struct flash_bank
*bank
,
908 uint8_t *buffer
, uint32_t offset
, uint32_t wcount
)
910 struct target
*target
= bank
->target
;
911 uint32_t buffer_size
= 16384;
912 struct working_area
*source
;
913 struct working_area
*write_algorithm
;
914 uint32_t address
= bank
->base
+ offset
;
915 struct reg_param reg_params
[3];
916 struct armv7m_algorithm armv7m_info
;
917 int retval
= ERROR_OK
;
919 /* power of two, and multiple of word size */
920 static const unsigned buf_min
= 128;
922 /* for small buffers it's faster not to download an algorithm */
923 if (wcount
* 4 < buf_min
)
924 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
926 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" wcount=%08" PRIx32
"",
927 bank
, buffer
, offset
, wcount
);
929 /* flash write code */
930 if (target_alloc_working_area(target
, sizeof(stellaris_write_code
), &write_algorithm
) != ERROR_OK
)
932 LOG_DEBUG("no working area for block memory writes");
933 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
936 /* plus a buffer big enough for this data */
937 if (wcount
* 4 < buffer_size
)
938 buffer_size
= wcount
* 4;
941 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
)
944 if (buffer_size
<= buf_min
)
946 target_free_working_area(target
, write_algorithm
);
947 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
949 LOG_DEBUG("retry target_alloc_working_area(%s, size=%u)",
950 target_name(target
), (unsigned) buffer_size
);
953 retval
= target_write_buffer(target
, write_algorithm
->address
,
954 sizeof(stellaris_write_code
),
955 (uint8_t *) stellaris_write_code
);
957 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
958 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
960 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
961 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
962 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
966 uint32_t thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
968 target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
970 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
971 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
972 buf_set_u32(reg_params
[2].value
, 0, 32, 4*thisrun_count
);
973 LOG_DEBUG("Algorithm flash write %u words to 0x%" PRIx32
975 (unsigned) thisrun_count
, address
,
976 (unsigned) (wcount
- thisrun_count
));
977 retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
,
978 write_algorithm
->address
,
980 10000, &armv7m_info
);
981 if (retval
!= ERROR_OK
)
983 LOG_ERROR("error %d executing stellaris "
984 "flash write algorithm",
986 retval
= ERROR_FLASH_OPERATION_FAILED
;
990 buffer
+= thisrun_count
* 4;
991 address
+= thisrun_count
* 4;
992 wcount
-= thisrun_count
;
995 /* REVISIT we could speed up writing multi-section images by
996 * not freeing the initialized write_algorithm this way.
999 target_free_working_area(target
, write_algorithm
);
1000 target_free_working_area(target
, source
);
1002 destroy_reg_param(®_params
[0]);
1003 destroy_reg_param(®_params
[1]);
1004 destroy_reg_param(®_params
[2]);
1009 static int stellaris_write(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
1011 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
1012 struct target
*target
= bank
->target
;
1013 uint32_t address
= offset
;
1014 uint32_t flash_cris
, flash_fmc
;
1015 uint32_t words_remaining
= (count
/ 4);
1016 uint32_t bytes_remaining
= (count
& 0x00000003);
1017 uint32_t bytes_written
= 0;
1020 if (bank
->target
->state
!= TARGET_HALTED
)
1022 LOG_ERROR("Target not halted");
1023 return ERROR_TARGET_NOT_HALTED
;
1026 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" count=%08" PRIx32
"",
1027 bank
, buffer
, offset
, count
);
1029 if (stellaris_info
->did1
== 0)
1030 return ERROR_FLASH_BANK_NOT_PROBED
;
1034 LOG_WARNING("offset size must be word aligned");
1035 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
1038 if (offset
+ count
> bank
->size
)
1039 return ERROR_FLASH_DST_OUT_OF_BANK
;
1041 /* Refresh flash controller timing */
1042 stellaris_read_clock_info(bank
);
1043 stellaris_set_flash_timing(bank
);
1045 /* Clear and disable flash programming interrupts */
1046 target_write_u32(target
, FLASH_CIM
, 0);
1047 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
1049 /* REVISIT this clobbers state set by any halted firmware ...
1050 * it might want to process those IRQs.
1053 /* multiple words to be programmed? */
1054 if (words_remaining
> 0)
1056 /* try using a block write */
1057 retval
= stellaris_write_block(bank
, buffer
, offset
,
1059 if (retval
!= ERROR_OK
)
1061 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
1063 LOG_DEBUG("writing flash word-at-a-time");
1065 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
1067 /* if an error occured, we examine the reason, and quit */
1068 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
1070 LOG_ERROR("flash writing failed with CRIS: 0x%" PRIx32
"", flash_cris
);
1071 return ERROR_FLASH_OPERATION_FAILED
;
1076 buffer
+= words_remaining
* 4;
1077 address
+= words_remaining
* 4;
1078 words_remaining
= 0;
1082 while (words_remaining
> 0)
1084 if (!(address
& 0xff))
1085 LOG_DEBUG("0x%" PRIx32
"", address
);
1087 /* Program one word */
1088 target_write_u32(target
, FLASH_FMA
, address
);
1089 target_write_buffer(target
, FLASH_FMD
, 4, buffer
);
1090 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
1091 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1092 /* Wait until write complete */
1095 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1096 } while (flash_fmc
& FMC_WRITE
);
1103 if (bytes_remaining
)
1105 uint8_t last_word
[4] = {0xff, 0xff, 0xff, 0xff};
1108 while (bytes_remaining
> 0)
1110 last_word
[i
++] = *(buffer
+ bytes_written
);
1115 if (!(address
& 0xff))
1116 LOG_DEBUG("0x%" PRIx32
"", address
);
1118 /* Program one word */
1119 target_write_u32(target
, FLASH_FMA
, address
);
1120 target_write_buffer(target
, FLASH_FMD
, 4, last_word
);
1121 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
1122 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1123 /* Wait until write complete */
1126 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1127 } while (flash_fmc
& FMC_WRITE
);
1130 /* Check access violations */
1131 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
1132 if (flash_cris
& (AMASK
))
1134 LOG_DEBUG("flash_cris 0x%" PRIx32
"", flash_cris
);
1135 return ERROR_FLASH_OPERATION_FAILED
;
1140 static int stellaris_probe(struct flash_bank
*bank
)
1142 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
1145 /* If this is a stellaris chip, it has flash; probe() is just
1146 * to figure out how much is present. Only do it once.
1148 if (stellaris_info
->did1
!= 0)
1151 /* stellaris_read_part_info() already handled error checking and
1152 * reporting. Note that it doesn't write, so we don't care about
1153 * whether the target is halted or not.
1155 retval
= stellaris_read_part_info(bank
);
1156 if (retval
!= ERROR_OK
)
1161 free(bank
->sectors
);
1162 bank
->sectors
= NULL
;
1165 /* provide this for the benefit of the NOR flash framework */
1166 bank
->size
= 1024 * stellaris_info
->num_pages
;
1167 bank
->num_sectors
= stellaris_info
->num_pages
;
1168 bank
->sectors
= calloc(bank
->num_sectors
, sizeof(struct flash_sector
));
1169 for (int i
= 0; i
< bank
->num_sectors
; i
++)
1171 bank
->sectors
[i
].offset
= i
* stellaris_info
->pagesize
;
1172 bank
->sectors
[i
].size
= stellaris_info
->pagesize
;
1173 bank
->sectors
[i
].is_erased
= -1;
1174 bank
->sectors
[i
].is_protected
= -1;
1180 static int stellaris_mass_erase(struct flash_bank
*bank
)
1182 struct target
*target
= NULL
;
1183 struct stellaris_flash_bank
*stellaris_info
= NULL
;
1186 stellaris_info
= bank
->driver_priv
;
1187 target
= bank
->target
;
1189 if (target
->state
!= TARGET_HALTED
)
1191 LOG_ERROR("Target not halted");
1192 return ERROR_TARGET_NOT_HALTED
;
1195 if (stellaris_info
->did1
== 0)
1196 return ERROR_FLASH_BANK_NOT_PROBED
;
1198 /* Refresh flash controller timing */
1199 stellaris_read_clock_info(bank
);
1200 stellaris_set_flash_timing(bank
);
1202 /* Clear and disable flash programming interrupts */
1203 target_write_u32(target
, FLASH_CIM
, 0);
1204 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
1206 /* REVISIT this clobbers state set by any halted firmware ...
1207 * it might want to process those IRQs.
1210 target_write_u32(target
, FLASH_FMA
, 0);
1211 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1212 /* Wait until erase complete */
1215 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1217 while (flash_fmc
& FMC_MERASE
);
1219 /* if device has > 128k, then second erase cycle is needed
1220 * this is only valid for older devices, but will not hurt */
1221 if (stellaris_info
->num_pages
* stellaris_info
->pagesize
> 0x20000)
1223 target_write_u32(target
, FLASH_FMA
, 0x20000);
1224 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1225 /* Wait until erase complete */
1228 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1230 while (flash_fmc
& FMC_MERASE
);
1236 COMMAND_HANDLER(stellaris_handle_mass_erase_command
)
1242 command_print(CMD_CTX
, "stellaris mass_erase <bank>");
1246 struct flash_bank
*bank
;
1247 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1248 if (ERROR_OK
!= retval
)
1251 if (stellaris_mass_erase(bank
) == ERROR_OK
)
1253 /* set all sectors as erased */
1254 for (i
= 0; i
< bank
->num_sectors
; i
++)
1256 bank
->sectors
[i
].is_erased
= 1;
1259 command_print(CMD_CTX
, "stellaris mass erase complete");
1263 command_print(CMD_CTX
, "stellaris mass erase failed");
1270 * Perform the Stellaris "Recovering a 'Locked' Device procedure.
1271 * This performs a mass erase and then restores all nonvolatile registers
1272 * (including USER_* registers and flash lock bits) to their defaults.
1273 * Accordingly, flash can be reprogrammed, and JTAG can be used.
1275 * NOTE that DustDevil parts (at least rev A0 silicon) have errata which
1276 * can affect this operation if flash protection has been enabled.
1278 COMMAND_HANDLER(stellaris_handle_recover_command
)
1280 struct flash_bank
*bank
;
1283 retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1284 if (retval
!= ERROR_OK
)
1287 /* REVISIT ... it may be worth sanity checking that the AP is
1288 * inactive before we start. ARM documents that switching a DP's
1289 * mode while it's active can cause fault modes that need a power
1294 if (!(jtag_get_reset_config() & RESET_HAS_SRST
)) {
1295 LOG_ERROR("Can't recover Stellaris flash without SRST");
1298 jtag_add_reset(0, 1);
1300 for (int i
= 0; i
< 5; i
++) {
1301 retval
= dap_to_swd(bank
->target
);
1302 if (retval
!= ERROR_OK
)
1305 retval
= dap_to_jtag(bank
->target
);
1306 if (retval
!= ERROR_OK
)
1310 /* de-assert SRST */
1311 jtag_add_reset(0, 0);
1312 retval
= jtag_execute_queue();
1314 /* wait 400+ msec ... OK, "1+ second" is simpler */
1317 /* USER INTERVENTION required for the power cycle
1318 * Restarting OpenOCD is likely needed because of mode switching.
1320 LOG_INFO("USER ACTION: "
1321 "power cycle Stellaris chip, then restart OpenOCD.");
1327 static const struct command_registration stellaris_exec_command_handlers
[] = {
1329 .name
= "mass_erase",
1330 .handler
= stellaris_handle_mass_erase_command
,
1331 .mode
= COMMAND_EXEC
,
1333 .help
= "erase entire device",
1337 .handler
= stellaris_handle_recover_command
,
1338 .mode
= COMMAND_EXEC
,
1340 .help
= "recover (and erase) locked device",
1342 COMMAND_REGISTRATION_DONE
1344 static const struct command_registration stellaris_command_handlers
[] = {
1346 .name
= "stellaris",
1347 .mode
= COMMAND_EXEC
,
1348 .help
= "Stellaris flash command group",
1349 .chain
= stellaris_exec_command_handlers
,
1351 COMMAND_REGISTRATION_DONE
1354 struct flash_driver stellaris_flash
= {
1355 .name
= "stellaris",
1356 .commands
= stellaris_command_handlers
,
1357 .flash_bank_command
= stellaris_flash_bank_command
,
1358 .erase
= stellaris_erase
,
1359 .protect
= stellaris_protect
,
1360 .write
= stellaris_write
,
1361 .read
= default_flash_read
,
1362 .probe
= stellaris_probe
,
1363 .auto_probe
= stellaris_probe
,
1364 .erase_check
= default_flash_mem_blank_check
,
1365 .protect_check
= stellaris_protect_check
,
1366 .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)