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 is tested on LM3S811, LM3S6965
26 ***************************************************************************/
32 #include "stellaris.h"
33 #include <target/algorithm.h>
34 #include <target/armv7m.h>
37 #define DID0_VER(did0) ((did0 >> 28)&0x07)
39 static void stellaris_read_clock_info(struct flash_bank
*bank
);
40 static int stellaris_mass_erase(struct flash_bank
*bank
);
217 static char * StellarisClassname
[5] =
226 /***************************************************************************
227 * openocd command interface *
228 ***************************************************************************/
230 /* flash_bank stellaris <base> <size> 0 0 <target#>
232 FLASH_BANK_COMMAND_HANDLER(stellaris_flash_bank_command
)
234 struct stellaris_flash_bank
*stellaris_info
;
238 LOG_WARNING("incomplete flash_bank stellaris configuration");
239 return ERROR_FLASH_BANK_INVALID
;
242 stellaris_info
= calloc(sizeof(struct stellaris_flash_bank
), 1);
244 bank
->driver_priv
= stellaris_info
;
246 stellaris_info
->target_name
= "Unknown target";
248 /* part wasn't probed for info yet */
249 stellaris_info
->did1
= 0;
251 /* TODO Specify the main crystal speed in kHz using an optional
252 * argument; ditto, the speed of an external oscillator used
253 * instead of a crystal. Avoid programming flash using IOSC.
258 static int stellaris_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
260 int printed
, device_class
;
261 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
263 if (stellaris_info
->did1
== 0)
264 return ERROR_FLASH_BANK_NOT_PROBED
;
266 /* Read main and master clock freqency register */
267 stellaris_read_clock_info(bank
);
269 if (DID0_VER(stellaris_info
->did0
) > 0)
271 device_class
= (stellaris_info
->did0
>> 16) & 0xFF;
277 printed
= snprintf(buf
,
279 "\nTI/LMI Stellaris information: Chip is "
280 "class %i (%s) %s rev %c%i\n",
282 StellarisClassname
[device_class
],
283 stellaris_info
->target_name
,
284 (int)('A' + ((stellaris_info
->did0
>> 8) & 0xFF)),
285 (int)((stellaris_info
->did0
) & 0xFF));
289 printed
= snprintf(buf
,
291 "did1: 0x%8.8" PRIx32
", arch: 0x%4.4" PRIx32
292 ", eproc: %s, ramsize: %ik, flashsize: %ik\n",
293 stellaris_info
->did1
,
294 stellaris_info
->did1
,
296 (int)((1 + ((stellaris_info
->dc0
>> 16) & 0xFFFF))/4),
297 (int)((1 + (stellaris_info
->dc0
& 0xFFFF))*2));
301 printed
= snprintf(buf
,
303 "master clock: %ikHz%s, "
304 "rcc is 0x%" PRIx32
", rcc2 is 0x%" PRIx32
"\n",
305 (int)(stellaris_info
->mck_freq
/ 1000),
306 stellaris_info
->mck_desc
,
308 stellaris_info
->rcc2
);
312 if (stellaris_info
->num_lockbits
> 0)
314 printed
= snprintf(buf
,
316 "pagesize: %" PRIi32
", pages: %d, "
317 "lockbits: %i, pages per lockbit: %i\n",
318 stellaris_info
->pagesize
,
319 (unsigned) stellaris_info
->num_pages
,
320 stellaris_info
->num_lockbits
,
321 (unsigned) stellaris_info
->pages_in_lockregion
);
328 /***************************************************************************
329 * chip identification and status *
330 ***************************************************************************/
332 /* Set the flash timimg register to match current clocking */
333 static void stellaris_set_flash_timing(struct flash_bank
*bank
)
335 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
336 struct target
*target
= bank
->target
;
337 uint32_t usecrl
= (stellaris_info
->mck_freq
/1000000ul-1);
339 LOG_DEBUG("usecrl = %i",(int)(usecrl
));
340 target_write_u32(target
, SCB_BASE
| USECRL
, usecrl
);
343 static const unsigned rcc_xtal
[32] = {
344 [0x00] = 1000000, /* no pll */
345 [0x01] = 1843200, /* no pll */
346 [0x02] = 2000000, /* no pll */
347 [0x03] = 2457600, /* no pll */
351 [0x06] = 4000000, /* usb */
355 [0x09] = 5000000, /* usb */
357 [0x0b] = 6000000, /* (reset) usb */
361 [0x0e] = 8000000, /* usb */
364 /* parts before DustDevil use just 4 bits for xtal spec */
366 [0x10] = 10000000, /* usb */
367 [0x11] = 12000000, /* usb */
372 [0x15] = 16000000, /* usb */
376 /** Read clock configuration and set stellaris_info->usec_clocks. */
377 static void stellaris_read_clock_info(struct flash_bank
*bank
)
379 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
380 struct target
*target
= bank
->target
;
381 uint32_t rcc
, rcc2
, pllcfg
, sysdiv
, usesysdiv
, bypass
, oscsrc
;
383 unsigned long mainfreq
;
385 target_read_u32(target
, SCB_BASE
| RCC
, &rcc
);
386 LOG_DEBUG("Stellaris RCC %" PRIx32
"", rcc
);
388 target_read_u32(target
, SCB_BASE
| RCC2
, &rcc2
);
389 LOG_DEBUG("Stellaris RCC2 %" PRIx32
"", rcc
);
391 target_read_u32(target
, SCB_BASE
| PLLCFG
, &pllcfg
);
392 LOG_DEBUG("Stellaris PLLCFG %" PRIx32
"", pllcfg
);
394 stellaris_info
->rcc
= rcc
;
395 stellaris_info
->rcc
= rcc2
;
397 sysdiv
= (rcc
>> 23) & 0xF;
398 usesysdiv
= (rcc
>> 22) & 0x1;
399 bypass
= (rcc
>> 11) & 0x1;
400 oscsrc
= (rcc
>> 4) & 0x3;
401 xtal
= (rcc
>> 6) & stellaris_info
->xtal_mask
;
403 /* NOTE: post-Sandstorm parts have RCC2 which may override
404 * parts of RCC ... with more sysdiv options, option for
405 * 32768 Hz mainfreq, PLL controls. On Sandstorm it reads
406 * as zero, so the "use RCC2" flag is always clear.
408 if (rcc2
& (1 << 31)) {
409 sysdiv
= (rcc2
>> 23) & 0x3F;
410 bypass
= (rcc2
>> 11) & 0x1;
411 oscsrc
= (rcc2
>> 4) & 0x7;
413 /* FIXME Tempest parts have an additional lsb for
414 * fractional sysdiv (200 MHz / 2.5 == 80 MHz)
418 stellaris_info
->mck_desc
= "";
423 mainfreq
= rcc_xtal
[xtal
];
426 mainfreq
= stellaris_info
->iosc_freq
;
427 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
430 mainfreq
= stellaris_info
->iosc_freq
/ 4;
431 stellaris_info
->mck_desc
= stellaris_info
->iosc_desc
;
433 case 3: /* lowspeed */
434 /* Sandstorm doesn't have this 30K +/- 30% osc */
436 stellaris_info
->mck_desc
= " (±30%)";
438 case 8: /* hibernation osc */
439 /* not all parts support hibernation */
443 default: /* NOTREACHED */
448 /* PLL is used if it's not bypassed; its output is 200 MHz
449 * even when it runs at 400 MHz (adds divide-by-two stage).
452 mainfreq
= 200000000;
455 stellaris_info
->mck_freq
= mainfreq
/(1 + sysdiv
);
457 stellaris_info
->mck_freq
= mainfreq
;
460 /* Read device id register, main clock frequency register and fill in driver info structure */
461 static int stellaris_read_part_info(struct flash_bank
*bank
)
463 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
464 struct target
*target
= bank
->target
;
465 uint32_t did0
, did1
, ver
, fam
;
468 /* Read and parse chip identification register */
469 target_read_u32(target
, SCB_BASE
| DID0
, &did0
);
470 target_read_u32(target
, SCB_BASE
| DID1
, &did1
);
471 target_read_u32(target
, SCB_BASE
| DC0
, &stellaris_info
->dc0
);
472 target_read_u32(target
, SCB_BASE
| DC1
, &stellaris_info
->dc1
);
473 LOG_DEBUG("did0 0x%" PRIx32
", did1 0x%" PRIx32
", dc0 0x%" PRIx32
", dc1 0x%" PRIx32
"",
474 did0
, did1
, stellaris_info
->dc0
, stellaris_info
->dc1
);
477 if ((ver
!= 0) && (ver
!= 1))
479 LOG_WARNING("Unknown did0 version, cannot identify target");
480 return ERROR_FLASH_OPERATION_FAILED
;
485 LOG_WARNING("Cannot identify target as a Stellaris");
486 return ERROR_FLASH_OPERATION_FAILED
;
490 fam
= (did1
>> 24) & 0xF;
491 if (((ver
!= 0) && (ver
!= 1)) || (fam
!= 0))
493 LOG_WARNING("Unknown did1 version/family.");
494 return ERROR_FLASH_OPERATION_FAILED
;
497 /* For Sandstorm, Fury, DustDevil: current data sheets say IOSC
498 * is 12 MHz, but some older parts have 15 MHz. A few data sheets
499 * even give _both_ numbers! We'll use current numbers; IOSC is
500 * always approximate.
502 * For Tempest: IOSC is calibrated, 16 MHz
504 stellaris_info
->iosc_freq
= 12000000;
505 stellaris_info
->iosc_desc
= " (±30%)";
506 stellaris_info
->xtal_mask
= 0x0f;
508 switch ((did0
>> 28) & 0x7) {
509 case 0: /* Sandstorm */
511 * Current (2009-August) parts seem to be rev C2 and use 12 MHz.
512 * Parts before rev C0 used 15 MHz; some C0 parts use 15 MHz
513 * (LM3S618), but some other C0 parts are 12 MHz (LM3S811).
515 if (((did0
>> 8) & 0xff) < 2) {
516 stellaris_info
->iosc_freq
= 15000000;
517 stellaris_info
->iosc_desc
= " (±50%)";
521 switch ((did0
>> 16) & 0xff) {
524 case 4: /* Tempest */
525 stellaris_info
->iosc_freq
= 16000000; /* +/- 1% */
526 stellaris_info
->iosc_desc
= " (±1%)";
528 case 3: /* DustDevil */
529 stellaris_info
->xtal_mask
= 0x1f;
532 LOG_WARNING("Unknown did0 class");
536 LOG_WARNING("Unknown did0 version");
540 for (i
= 0; StellarisParts
[i
].partno
; i
++)
542 if (StellarisParts
[i
].partno
== ((did1
>> 16) & 0xFFFF))
546 stellaris_info
->target_name
= StellarisParts
[i
].partname
;
548 stellaris_info
->did0
= did0
;
549 stellaris_info
->did1
= did1
;
551 stellaris_info
->num_lockbits
= 1 + (stellaris_info
->dc0
& 0xFFFF);
552 stellaris_info
->num_pages
= 2 *(1 + (stellaris_info
->dc0
& 0xFFFF));
553 stellaris_info
->pagesize
= 1024;
554 stellaris_info
->pages_in_lockregion
= 2;
556 /* REVISIT for at least Tempest parts, read NVMSTAT.FWB too.
557 * That exposes a 32-word Flash Write Buffer ... enabling
558 * writes of more than one word at a time.
564 /***************************************************************************
566 ***************************************************************************/
568 static int stellaris_protect_check(struct flash_bank
*bank
)
570 struct stellaris_flash_bank
*stellaris
= bank
->driver_priv
;
571 int status
= ERROR_OK
;
575 if (stellaris
->did1
== 0)
576 return ERROR_FLASH_BANK_NOT_PROBED
;
578 for (i
= 0; i
< (unsigned) bank
->num_sectors
; i
++)
579 bank
->sectors
[i
].is_protected
= -1;
581 /* Read each Flash Memory Protection Program Enable (FMPPE) register
582 * to report any pages that we can't write. Ignore the Read Enable
585 for (i
= 0, page
= 0;
586 i
< DIV_ROUND_UP(stellaris
->num_lockbits
, 32u);
590 status
= target_read_u32(bank
->target
,
591 SCB_BASE
+ (i
? (FMPPE0
+ 4 * i
) : FMPPE
),
593 LOG_DEBUG("FMPPE%d = %#8.8x (status %d)", i
,
594 (unsigned) lockbits
, status
);
595 if (status
!= ERROR_OK
)
598 for (unsigned j
= 0; j
< 32; j
++) {
601 for (k
= 0; k
< stellaris
->pages_in_lockregion
; k
++) {
602 if (page
>= (unsigned) bank
->num_sectors
)
604 bank
->sectors
[page
++].is_protected
=
605 !(lockbits
& (1 << j
));
614 static int stellaris_erase(struct flash_bank
*bank
, int first
, int last
)
617 uint32_t flash_fmc
, flash_cris
;
618 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
619 struct target
*target
= bank
->target
;
621 if (bank
->target
->state
!= TARGET_HALTED
)
623 LOG_ERROR("Target not halted");
624 return ERROR_TARGET_NOT_HALTED
;
627 if (stellaris_info
->did1
== 0)
628 return ERROR_FLASH_BANK_NOT_PROBED
;
630 if ((first
< 0) || (last
< first
) || (last
>= (int)stellaris_info
->num_pages
))
632 return ERROR_FLASH_SECTOR_INVALID
;
635 if ((first
== 0) && (last
== ((int)stellaris_info
->num_pages
-1)))
637 return stellaris_mass_erase(bank
);
640 /* Refresh flash controller timing */
641 stellaris_read_clock_info(bank
);
642 stellaris_set_flash_timing(bank
);
644 /* Clear and disable flash programming interrupts */
645 target_write_u32(target
, FLASH_CIM
, 0);
646 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
648 /* REVISIT this clobbers state set by any halted firmware ...
649 * it might want to process those IRQs.
652 for (banknr
= first
; banknr
<= last
; banknr
++)
654 /* Address is first word in page */
655 target_write_u32(target
, FLASH_FMA
, banknr
* stellaris_info
->pagesize
);
656 /* Write erase command */
657 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_ERASE
);
658 /* Wait until erase complete */
661 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
663 while (flash_fmc
& FMC_ERASE
);
665 /* Check acess violations */
666 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
667 if (flash_cris
& (AMASK
))
669 LOG_WARNING("Error erasing flash page %i, flash_cris 0x%" PRIx32
"", banknr
, flash_cris
);
670 target_write_u32(target
, FLASH_CRIS
, 0);
671 return ERROR_FLASH_OPERATION_FAILED
;
674 bank
->sectors
[banknr
].is_erased
= 1;
680 static int stellaris_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
682 uint32_t fmppe
, flash_fmc
, flash_cris
;
685 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
686 struct target
*target
= bank
->target
;
688 if (bank
->target
->state
!= TARGET_HALTED
)
690 LOG_ERROR("Target not halted");
691 return ERROR_TARGET_NOT_HALTED
;
696 LOG_ERROR("Can't unprotect write-protected pages.");
697 /* except by the "recover locked device" procedure ... */
698 return ERROR_INVALID_ARGUMENTS
;
701 if (stellaris_info
->did1
== 0)
702 return ERROR_FLASH_BANK_NOT_PROBED
;
704 /* lockregions are 2 pages ... must protect [even..odd] */
705 if ((first
< 0) || (first
& 1)
706 || (last
< first
) || !(last
& 1)
707 || (last
>= 2 * stellaris_info
->num_lockbits
))
709 LOG_ERROR("Can't protect unaligned or out-of-range sectors.");
710 return ERROR_FLASH_SECTOR_INVALID
;
713 /* Refresh flash controller timing */
714 stellaris_read_clock_info(bank
);
715 stellaris_set_flash_timing(bank
);
717 /* convert from pages to lockregions */
721 /* FIXME this assumes single FMPPE, for a max of 64K of flash!!
722 * Current parts can be much bigger.
725 LOG_ERROR("No support yet for protection > 64K");
726 return ERROR_FLASH_OPERATION_FAILED
;
729 target_read_u32(target
, SCB_BASE
| FMPPE
, &fmppe
);
731 for (lockregion
= first
; lockregion
<= last
; lockregion
++)
732 fmppe
&= ~(1 << lockregion
);
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 LOG_DEBUG("fmppe 0x%" PRIx32
"",fmppe
);
743 target_write_u32(target
, SCB_BASE
| FMPPE
, fmppe
);
746 target_write_u32(target
, FLASH_FMA
, 1);
748 /* Write commit command */
749 /* REVISIT safety check, since this cannot be undone
750 * except by the "Recover a locked device" procedure.
751 * REVISIT DustDevil-A0 parts have an erratum making FMPPE commits
752 * inadvisable ... it makes future mass erase operations fail.
754 LOG_WARNING("Flash protection cannot be removed once commited, commit is NOT executed !");
755 /* target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); */
757 /* Wait until erase complete */
760 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
762 while (flash_fmc
& FMC_COMT
);
764 /* Check acess violations */
765 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
766 if (flash_cris
& (AMASK
))
768 LOG_WARNING("Error setting flash page protection, flash_cris 0x%" PRIx32
"", flash_cris
);
769 target_write_u32(target
, FLASH_CRIS
, 0);
770 return ERROR_FLASH_OPERATION_FAILED
;
776 static const uint8_t stellaris_write_code
[] =
781 r1 = destination address
782 r2 = bytecount (in) - endaddr (work)
785 r3 = pFLASH_CTRL_BASE
791 0x07,0x4B, /* ldr r3,pFLASH_CTRL_BASE */
792 0x08,0x4C, /* ldr r4,FLASHWRITECMD */
793 0x01,0x25, /* movs r5, 1 */
794 0x00,0x26, /* movs r6, #0 */
796 0x19,0x60, /* str r1, [r3, #0] */
797 0x87,0x59, /* ldr r7, [r0, r6] */
798 0x5F,0x60, /* str r7, [r3, #4] */
799 0x9C,0x60, /* str r4, [r3, #8] */
801 0x9F,0x68, /* ldr r7, [r3, #8] */
802 0x2F,0x42, /* tst r7, r5 */
803 0xFC,0xD1, /* bne waitloop */
804 0x04,0x31, /* adds r1, r1, #4 */
805 0x04,0x36, /* adds r6, r6, #4 */
806 0x96,0x42, /* cmp r6, r2 */
807 0xF4,0xD1, /* bne mainloop */
809 0xFE,0xE7, /* b exit */
810 /* pFLASH_CTRL_BASE: */
811 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */
813 0x01,0x00,0x42,0xA4 /* .word 0xA4420001 */
816 static int stellaris_write_block(struct flash_bank
*bank
,
817 uint8_t *buffer
, uint32_t offset
, uint32_t wcount
)
819 struct target
*target
= bank
->target
;
820 uint32_t buffer_size
= 8192;
821 struct working_area
*source
;
822 struct working_area
*write_algorithm
;
823 uint32_t address
= bank
->base
+ offset
;
824 struct reg_param reg_params
[3];
825 struct armv7m_algorithm armv7m_info
;
826 int retval
= ERROR_OK
;
828 /* power of two, and multiple of word size */
829 static const unsigned buf_min
= 128;
831 /* for small buffers it's faster not to download an algorithm */
832 if (wcount
* 4 < buf_min
)
833 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
835 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" wcount=%08" PRIx32
"",
836 bank
, buffer
, offset
, wcount
);
838 /* flash write code */
839 if (target_alloc_working_area(target
, sizeof(stellaris_write_code
), &write_algorithm
) != ERROR_OK
)
841 LOG_DEBUG("no working area for block memory writes");
842 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
845 /* plus a buffer big enough for this data */
846 if (wcount
* 4 < buffer_size
)
847 buffer_size
= wcount
* 4;
850 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
853 if (buffer_size
<= buf_min
)
855 target_free_working_area(target
, write_algorithm
);
856 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
858 LOG_DEBUG("retry target_alloc_working_area(%s, size=%u)",
859 target_name(target
), (unsigned) buffer_size
);
862 retval
= target_write_buffer(target
, write_algorithm
->address
,
863 sizeof(stellaris_write_code
),
864 (uint8_t *) stellaris_write_code
);
866 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
867 armv7m_info
.core_mode
= ARMV7M_MODE_ANY
;
869 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
870 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
871 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
875 uint32_t thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
877 target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
879 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
880 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
881 buf_set_u32(reg_params
[2].value
, 0, 32, 4*thisrun_count
);
882 LOG_DEBUG("Algorithm flash write %u words to 0x%" PRIx32
884 (unsigned) thisrun_count
, address
,
885 (unsigned) (wcount
- thisrun_count
));
886 retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
,
887 write_algorithm
->address
,
888 write_algorithm
->address
+
889 sizeof(stellaris_write_code
) - 10,
890 10000, &armv7m_info
);
891 if (retval
!= ERROR_OK
)
893 LOG_ERROR("error %d executing stellaris "
894 "flash write algorithm",
896 retval
= ERROR_FLASH_OPERATION_FAILED
;
900 buffer
+= thisrun_count
* 4;
901 address
+= thisrun_count
* 4;
902 wcount
-= thisrun_count
;
905 /* REVISIT we could speed up writing multi-section images by
906 * not freeing the initialized write_algorithm this way.
909 target_free_working_area(target
, write_algorithm
);
910 target_free_working_area(target
, source
);
912 destroy_reg_param(®_params
[0]);
913 destroy_reg_param(®_params
[1]);
914 destroy_reg_param(®_params
[2]);
919 static int stellaris_write(struct flash_bank
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
921 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
922 struct target
*target
= bank
->target
;
923 uint32_t address
= offset
;
924 uint32_t flash_cris
, flash_fmc
;
925 uint32_t words_remaining
= (count
/ 4);
926 uint32_t bytes_remaining
= (count
& 0x00000003);
927 uint32_t bytes_written
= 0;
930 if (bank
->target
->state
!= TARGET_HALTED
)
932 LOG_ERROR("Target not halted");
933 return ERROR_TARGET_NOT_HALTED
;
936 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32
" count=%08" PRIx32
"",
937 bank
, buffer
, offset
, count
);
939 if (stellaris_info
->did1
== 0)
940 return ERROR_FLASH_BANK_NOT_PROBED
;
944 LOG_WARNING("offset size must be word aligned");
945 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
948 if (offset
+ count
> bank
->size
)
949 return ERROR_FLASH_DST_OUT_OF_BANK
;
951 /* Refresh flash controller timing */
952 stellaris_read_clock_info(bank
);
953 stellaris_set_flash_timing(bank
);
955 /* Clear and disable flash programming interrupts */
956 target_write_u32(target
, FLASH_CIM
, 0);
957 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
959 /* REVISIT this clobbers state set by any halted firmware ...
960 * it might want to process those IRQs.
963 /* multiple words to be programmed? */
964 if (words_remaining
> 0)
966 /* try using a block write */
967 retval
= stellaris_write_block(bank
, buffer
, offset
,
969 if (retval
!= ERROR_OK
)
971 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
973 LOG_DEBUG("writing flash word-at-a-time");
975 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
977 /* if an error occured, we examine the reason, and quit */
978 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
980 LOG_ERROR("flash writing failed with CRIS: 0x%" PRIx32
"", flash_cris
);
981 return ERROR_FLASH_OPERATION_FAILED
;
986 buffer
+= words_remaining
* 4;
987 address
+= words_remaining
* 4;
992 while (words_remaining
> 0)
994 if (!(address
& 0xff))
995 LOG_DEBUG("0x%" PRIx32
"", address
);
997 /* Program one word */
998 target_write_u32(target
, FLASH_FMA
, address
);
999 target_write_buffer(target
, FLASH_FMD
, 4, buffer
);
1000 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
1001 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1002 /* Wait until write complete */
1005 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1006 } while (flash_fmc
& FMC_WRITE
);
1013 if (bytes_remaining
)
1015 uint8_t last_word
[4] = {0xff, 0xff, 0xff, 0xff};
1018 while (bytes_remaining
> 0)
1020 last_word
[i
++] = *(buffer
+ bytes_written
);
1025 if (!(address
& 0xff))
1026 LOG_DEBUG("0x%" PRIx32
"", address
);
1028 /* Program one word */
1029 target_write_u32(target
, FLASH_FMA
, address
);
1030 target_write_buffer(target
, FLASH_FMD
, 4, last_word
);
1031 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_WRITE
);
1032 /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
1033 /* Wait until write complete */
1036 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1037 } while (flash_fmc
& FMC_WRITE
);
1040 /* Check access violations */
1041 target_read_u32(target
, FLASH_CRIS
, &flash_cris
);
1042 if (flash_cris
& (AMASK
))
1044 LOG_DEBUG("flash_cris 0x%" PRIx32
"", flash_cris
);
1045 return ERROR_FLASH_OPERATION_FAILED
;
1050 static int stellaris_probe(struct flash_bank
*bank
)
1052 struct stellaris_flash_bank
*stellaris_info
= bank
->driver_priv
;
1055 /* If this is a stellaris chip, it has flash; probe() is just
1056 * to figure out how much is present. Only do it once.
1058 if (stellaris_info
->did1
!= 0)
1061 /* stellaris_read_part_info() already handled error checking and
1062 * reporting. Note that it doesn't write, so we don't care about
1063 * whether the target is halted or not.
1065 retval
= stellaris_read_part_info(bank
);
1066 if (retval
!= ERROR_OK
)
1069 /* provide this for the benefit of the NOR flash framework */
1070 bank
->size
= 1024 * stellaris_info
->num_pages
;
1071 bank
->num_sectors
= stellaris_info
->num_pages
;
1072 bank
->sectors
= calloc(bank
->num_sectors
, sizeof(struct flash_sector
));
1073 for (int i
= 0; i
< bank
->num_sectors
; i
++)
1075 bank
->sectors
[i
].offset
= i
* stellaris_info
->pagesize
;
1076 bank
->sectors
[i
].size
= stellaris_info
->pagesize
;
1077 bank
->sectors
[i
].is_erased
= -1;
1078 bank
->sectors
[i
].is_protected
= -1;
1084 static int stellaris_mass_erase(struct flash_bank
*bank
)
1086 struct target
*target
= NULL
;
1087 struct stellaris_flash_bank
*stellaris_info
= NULL
;
1090 stellaris_info
= bank
->driver_priv
;
1091 target
= bank
->target
;
1093 if (target
->state
!= TARGET_HALTED
)
1095 LOG_ERROR("Target not halted");
1096 return ERROR_TARGET_NOT_HALTED
;
1099 if (stellaris_info
->did1
== 0)
1100 return ERROR_FLASH_BANK_NOT_PROBED
;
1102 /* Refresh flash controller timing */
1103 stellaris_read_clock_info(bank
);
1104 stellaris_set_flash_timing(bank
);
1106 /* Clear and disable flash programming interrupts */
1107 target_write_u32(target
, FLASH_CIM
, 0);
1108 target_write_u32(target
, FLASH_MISC
, PMISC
| AMISC
);
1110 /* REVISIT this clobbers state set by any halted firmware ...
1111 * it might want to process those IRQs.
1114 target_write_u32(target
, FLASH_FMA
, 0);
1115 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1116 /* Wait until erase complete */
1119 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1121 while (flash_fmc
& FMC_MERASE
);
1123 /* if device has > 128k, then second erase cycle is needed
1124 * this is only valid for older devices, but will not hurt */
1125 if (stellaris_info
->num_pages
* stellaris_info
->pagesize
> 0x20000)
1127 target_write_u32(target
, FLASH_FMA
, 0x20000);
1128 target_write_u32(target
, FLASH_FMC
, FMC_WRKEY
| FMC_MERASE
);
1129 /* Wait until erase complete */
1132 target_read_u32(target
, FLASH_FMC
, &flash_fmc
);
1134 while (flash_fmc
& FMC_MERASE
);
1140 COMMAND_HANDLER(stellaris_handle_mass_erase_command
)
1146 command_print(CMD_CTX
, "stellaris mass_erase <bank>");
1150 struct flash_bank
*bank
;
1151 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1152 if (ERROR_OK
!= retval
)
1155 if (stellaris_mass_erase(bank
) == ERROR_OK
)
1157 /* set all sectors as erased */
1158 for (i
= 0; i
< bank
->num_sectors
; i
++)
1160 bank
->sectors
[i
].is_erased
= 1;
1163 command_print(CMD_CTX
, "stellaris mass erase complete");
1167 command_print(CMD_CTX
, "stellaris mass erase failed");
1173 static const struct command_registration stellaris_exec_command_handlers
[] = {
1175 .name
= "mass_erase",
1176 .handler
= &stellaris_handle_mass_erase_command
,
1177 .mode
= COMMAND_EXEC
,
1178 .help
= "erase entire device",
1180 COMMAND_REGISTRATION_DONE
1182 static const struct command_registration stellaris_command_handlers
[] = {
1184 .name
= "stellaris",
1185 .mode
= COMMAND_ANY
,
1186 .help
= "Stellaris flash command group",
1187 .chain
= stellaris_exec_command_handlers
,
1189 COMMAND_REGISTRATION_DONE
1192 struct flash_driver stellaris_flash
= {
1193 .name
= "stellaris",
1194 .commands
= stellaris_command_handlers
,
1195 .flash_bank_command
= stellaris_flash_bank_command
,
1196 .erase
= stellaris_erase
,
1197 .protect
= stellaris_protect
,
1198 .write
= stellaris_write
,
1199 .probe
= stellaris_probe
,
1200 .auto_probe
= stellaris_probe
,
1201 .erase_check
= default_flash_mem_blank_check
,
1202 .protect_check
= stellaris_protect_check
,
1203 .info
= 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)