Thanks Petro, You are right, or so it seems, but from what I can tell most of this is working already and since the armv7-m code is common across STM32 as well that should be ok.
But I did tst and try what you said, it is an easy change because we are in thumb mode and the SAMBA bootloader initializes internal SRAM on SAME70. So we make a small trampoline by simply renaming __start() in sam_start.c to arm_boot, and add sam_head.S to implement __start which sets up the initial stack, calls arm_data_initialize and then jumps to arm_boot() In arm_data_initialize we zero bss, copy from flash to ram and we don't need to call arch_clean_dcache because the cache is in write-through mode (write-through simplifies the cache coherency protocol because it doesn't need the modified state - the main memory is always up to date). I use ISB to throw away any pre-fetched instructions and squash the pipeline .. DIffs: In samv7/Makedefs -HEAD_ASRC = +HEAD_ASRC = sam_head.S In samv7/sam_start.c -const uintptr_t g_idle_topstack = HEAP_BASE; +//const uintptr_t g_idle_topstack = HEAP_BASE; -void __start(void) +void arm_boot(void) Copy attached asm file into samv7 directory and rebuild. Anyhow, it boots, but no difference - still get that exception_common with a FLASH address... I will have to dig deeper but do please try the attached and see if it works for you or I missed something... changes are trivial, it is a basic m7 copy flash to ram like the armv7-r Oh yes, related, I was also able to catch an interrupt with symbols: Program received signal SIGINT, Interrupt. up_doirq (irq=3, regs=0x20402534 <g_intstackalloc+1844>) at armv7-m/up_doirq.c:58 58 { (gdb) up #1 0x00400a00 in exception_common () at armv7-m/gnu/up_lazyexception.S:237 237 bl up_doirq /* R0=IRQ, R1=register save (msp) */ (gdb) up Initial frame selected; you cannot go up. (gdb) down #0 up_doirq (irq=3, regs=0x20402534 <g_intstackalloc+1844>) at armv7-m/up_doirq.c:58 58 { (gdb) up_irq in ram but exception_common still in flash, I wonder why we hit that IRQ (Hardfault). Thanks and let me know what you think. Best regards -James On Fri, Dec 9, 2022 at 2:24 AM Petro Karashchenko < petro.karashche...@gmail.com> wrote: > In order to have the possibility to reprogram the whole internal flash you > will need to implement CONFIG_BOOT_COPYTORAM option in sam_start.c and > create a proper linker script. > Maybe even you will need to move the __start routine to the assembly file > because after copying code to RAM you will need to drain the instruction > pipeline before jumping to relocated code and that will require making sure > that start-up is done in position independent code and just to the > relocated code will not use relative offset jumps. > > Best regards, > Petro > > пт, 9 груд. 2022 р. о 12:18 Petro Karashchenko < > petro.karashche...@gmail.com> > пише: > > > Hi, > > > > Finally I was able to take a look here. The case is that armv7-m (and > some > > other ARM versions) do not use arm_head.S and __start entry points are > > implemented in C code and CONFIG_BOOT_COPYTORAM option is not > implemented, > > so code is always executed from internal flash. So when you are trying to > > erase all internal flash you are getting an exception and that is > expected. > > Currently the CONFIG_ARCH_RAMFUNCS only copies functions marked with > > __ramfunc__ attribute. The internal flash access APIs should be in SRAM > > because that is a requirement of flash access, uness IAP is used to > access > > flash. I will try to push the IAP version and remove many of EEFC APIs. > > > > The MCUboot variant works because MCUboot is located at the separate > flash > > partition and erase/reprogram only application slots. I mean that MCUboot > > can't update itself. > > > > Even having CONFIG_ARCH_RAMVECTORS enabled you will not be able to > > reprogram the whole internal flash because of the above. > > > > Best regards, > > Petro > > > > пт, 9 груд. 2022 р. о 07:56 David Sidrane <david.sidr...@nscdg.com> > пише: > > > >> Have you ensured that all the code (and support code, systic etc) is in > >> RAM? > >> > >> Also, Is this an ECCed FLASH? Is the write size correct? We must line > >> cache > >> the writes on some parts in the PX4 bootloader. > >> > >> > >> > https://github.com/PX4/PX4-Autopilot/blob/main/platforms/nuttx/src/bootloader/common/lib/flash_cache.c > >> > >> > >> David > >> -----Original Message----- > >> From: James Dougherty <jafr...@gmail.com> > >> Sent: Friday, December 9, 2022 12:46 AM > >> To: dev@nuttx.apache.org > >> Subject: Re: SAM-E70 progmem - in system programming and RAMFUNCS > >> > >> Thank you Greg, Thank you David! > >> > >> I did check that is correct: > >> > >> arch/arm/src/samv7/sam_start.c - 344:356 > >> > >> /* Copy any necessary code sections from FLASH to RAM. The correct > >> * destination in SRAM is geive by _sramfuncs and _eramfuncs. The > >> * temporary location is in flash after the data initialization code > >> * at _framfuncs. This should be done before sam_clockconfig() is > >> * called (in case it has some dependency on initialized C variables). > >> */ > >> > >> #ifdef CONFIG_ARCH_RAMFUNCS > >> for (src = &_framfuncs, dest = &_sramfuncs; dest < &_eramfuncs; ) > >> { > >> *dest++ = *src++; > >> } > >> #endif > >> > >> Also looks correct - in: same70-xplained/samv7-scripts/flash-sram.ld - > >> 36:113 > >> > >> /* The SAME70Q21 has 2048Kb of FLASH beginning at address 0x0040:0000 > and > >> * 384Kb of SRAM beginining at 0x2040:0000 > >> * > >> * When booting from FLASH, FLASH memory is aliased to address > 0x0000:0000 > >> * where the code expects to begin execution by jumping to the entry > point > >> in > >> * the 0x0400:0000 address range (Assuming that ITCM is not enable). > >> */ > >> > >> MEMORY > >> { > >> flash (rx) : ORIGIN = 0x00400000, LENGTH = 2048K sram (rwx) : ORIGIN = > >> 0x20400000, LENGTH = 384K } > >> > >> OUTPUT_ARCH(arm) > >> EXTERN(_vectors) > >> ENTRY(_stext) > >> > >> SECTIONS > >> { > >> .text : { > >> _stext = ABSOLUTE(.); > >> *(.vectors) > >> *(.text .text.*) > >> *(.fixup) > >> *(.gnu.warning) > >> *(.rodata .rodata.*) > >> *(.gnu.linkonce.t.*) > >> *(.glue_7) > >> *(.glue_7t) > >> *(.got) > >> *(.gcc_except_table) > >> *(.gnu.linkonce.r.*) > >> _etext = ABSOLUTE(.); > >> } > flash > >> > >> .init_section : { > >> _sinit = ABSOLUTE(.); > >> *(.init_array .init_array.*) > >> _einit = ABSOLUTE(.); > >> } > flash > >> > >> .ARM.extab : { > >> *(.ARM.extab*) > >> } > flash > >> > >> __exidx_start = ABSOLUTE(.); > >> .ARM.exidx : { > >> *(.ARM.exidx*) > >> } > flash > >> __exidx_end = ABSOLUTE(.); > >> > >> _eronly = ABSOLUTE(.); > >> > >> .data : { > >> _sdata = ABSOLUTE(.); > >> *(.data .data.*) > >> *(.gnu.linkonce.d.*) > >> CONSTRUCTORS > >> _edata = ABSOLUTE(.); > >> } > sram AT > flash > >> > >> .ramfunc ALIGN(4): { > >> _sramfuncs = ABSOLUTE(.); > >> *(.ramfunc .ramfunc.*) > >> _eramfuncs = ABSOLUTE(.); > >> } > sram AT > flash > >> > >> _framfuncs = LOADADDR(.ramfunc); > >> > >> .bss : { > >> _sbss = ABSOLUTE(.); > >> *(.bss .bss.*) > >> *(.gnu.linkonce.b.*) > >> *(COMMON) > >> _ebss = ABSOLUTE(.); > >> } > sram > >> > >> To David's point, I looked at NVIC since I have CONFIG_ARCH_RAMVECTORS. > >> arm/src/samv7/samv7_irq.c > >> > >> #ifdef CONFIG_ARCH_RAMVECTORS > >> /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based > >> * vector table that requires special initialization. > >> */ > >> > >> up_ramvec_initialize(); > >> #endif > >> > >> arm/src/armv7-m/up_ramvec_initialize.c > >> after we copy the ram vectors: > >> > >> /* Now configure the NVIC to use the new vector table. */ > >> putreg32((uint32_t)g_ram_vectors, NVIC_VECTAB); > >> > >> and after sam_bringup.c > >> > >> printf("NVIC: 0x%08x\n", getreg32(NVIC_VECTAB)); > >> > >> NVIC: 0x20401180 > >> > >> Looks good. > >> > >> And yes, still hitting flash on exception: > >> > >> flash_erasell /dev/mtd0 > >> > >> Whammo - hardfault in openocd monitor: > >> > >> target halted due to debug-request, current mode: Handler HardFault > >> xPSR: 0x81000003 pc: 0x00401114 msp: 0x204025e8 > >> > >> Try to flash the lower 256KB of flash, works like a champ: > >> > >> nsh> sdflash 0x440000 /mnt/sdcard/nuttx.bin / > >> > >> > .............................................................................. > >> > >> > .............................................................................. > >> > .......................................................................... > >> Installed application of size 233692 bytes to program memory [440000h - > >> 4790dch]. > >> nsh> reboot > >> > >> So tomorrow, I will maybe move the image to another location in flash > and > >> hack up the linker script. > >> Also do a detailed read on the errata, Petro mentioned there is some > >> possible chip bug, maybe that is it .. > >> There is some nasty Komodo dragon lurking in there, hissing and snapping > >> at > >> ankles ... SAMV7 doesn't work like an STM32F1/F4/F7 which all work > >> perfectly > >> on this codebase.. could also be a timing issue - 300Mhz core clock and > >> 150Mhz AHB clock, I will try to slow it down and change the flash wait > >> states also ... maybe a bus error is occuring. > >> > >> I will pick this up again tomorrow, any ideas, please share! > >> > >> Thank you for your time and attention to this issue... > >> -James > >> > >> > >> > >> > >> > >> > >> > >> On Thu, Dec 8, 2022 at 7:57 AM Gregory Nutt <spudan...@gmail.com> > wrote: > >> > >> > On 12/8/2022 5:55 AM, David Sidrane wrote: > >> > > Is the NVIC_VTABLE repointed to the RAM vectors? > >> > > >> > The RAM functions are like .bss: There is a storage area of code that > >> > that is copied into RAM only power up. But the symbols associated > >> > with the RAMFUNCs are defined by the linker script to be the address > >> > of the RAM destination, not the address of the FLASH copy-source > storage > >> > area: > >> > > >> > 186 /* Copy any necessary code sections from FLASH to RAM. The > >> correct > >> > 187 * destination in SRAM is geive by _sramfuncs and _eramfuncs. > The > >> > 188 * temporary location is in flash after the data initialization > >> code > >> > 189 * at _framfuncs. This should be done before sam_clockconfig() > is > >> > 190 * called (in case it has some dependency on initialized C > >> > variables). > >> > 191 */ > >> > 192 > >> > 193 #ifdef CONFIG_ARCH_RAMFUNCS > >> > 194 for (src = (const uint32_t *)_framfuncs, > >> > 195 dest = (uint32_t *)_sramfuncs; dest < (uint32_t > *)_eramfuncs; > >> > 196 ) > >> > 197 { > >> > 198 *dest++ = *src++; > >> > 199 } > >> > 200 #endif > >> > > >> > > >> > > >