altos: Run self loader when application sets boot addr to 0
authorKeith Packard <keithp@keithp.com>
Sat, 27 Apr 2013 07:20:47 +0000 (00:20 -0700)
committerKeith Packard <keithp@keithp.com>
Wed, 8 May 2013 04:30:26 +0000 (21:30 -0700)
This causes the flash loader startup code to fall into the loader when
the application sets the boot address to zero.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/stm/ao_boot.h
src/stm/ao_boot_chain.c
src/stm/ao_interrupt.c

index 862e8755b27abe1f95993c6e7daa171f2f5aed6c..e0ed4de78cabc9f0a119639ecf51b3fa2ec1de78 100644 (file)
@@ -24,7 +24,8 @@ ao_boot_chain(uint32_t *base);
 void
 ao_boot_check_pin(void);
 
 void
 ao_boot_check_pin(void);
 
-void
+/* Return true to switch to application (if present) */
+int
 ao_boot_check_chain(void);
 
 void
 ao_boot_check_chain(void);
 
 void
index 668f6e6d6813aab8d0b6a8afc3190dcc91f7878a..6a3864a71356ac69c80059f15cf85a6d8b6ba4dd 100644 (file)
@@ -26,7 +26,7 @@ ao_boot_chain(uint32_t *base)
 
        sp = base[0];
        pc = base[1];
 
        sp = base[0];
        pc = base[1];
-       if (0x08000100 <= pc && pc <= 0x08200000) {
+       if (0x08000100 <= pc && pc <= 0x08200000 && (pc & 1) == 1) {
                asm ("mov sp, %0" : : "r" (sp));
                asm ("mov lr, %0" : : "r" (pc));
                asm ("bx lr");
                asm ("mov sp, %0" : : "r" (sp));
                asm ("mov lr, %0" : : "r" (pc));
                asm ("bx lr");
@@ -44,14 +44,17 @@ struct ao_boot {
 
 static struct ao_boot __attribute__ ((section(".boot"))) ao_boot;
        
 
 static struct ao_boot __attribute__ ((section(".boot"))) ao_boot;
        
-void
+int
 ao_boot_check_chain(void)
 {
        if (ao_boot.signal == AO_BOOT_SIGNAL && ao_boot.check == AO_BOOT_CHECK) {
                ao_boot.signal = 0;
                ao_boot.check = 0;
 ao_boot_check_chain(void)
 {
        if (ao_boot.signal == AO_BOOT_SIGNAL && ao_boot.check == AO_BOOT_CHECK) {
                ao_boot.signal = 0;
                ao_boot.check = 0;
+               if (ao_boot.base == 0)
+                       return 0;
                ao_boot_chain(ao_boot.base);
        }
                ao_boot_chain(ao_boot.base);
        }
+       return 1;
 }
 
 void
 }
 
 void
index 4915628590017450b01ea7432406976c0d29afce..969e6a0f7b6a23a7433785f114c76765005509bb 100644 (file)
@@ -42,10 +42,11 @@ const void *stm_interrupt_vector[];
 void start(void)
 {
 #ifdef AO_BOOT_CHAIN
 void start(void)
 {
 #ifdef AO_BOOT_CHAIN
-       ao_boot_check_chain();
-#endif
+       if (ao_boot_check_chain()) {
 #ifdef AO_BOOT_PIN
 #ifdef AO_BOOT_PIN
-       ao_boot_check_pin();
+               ao_boot_check_pin();
+#endif
+       }
 #endif
        /* Set interrupt vector table offset */
        stm_nvic.vto = (uint32_t) &stm_interrupt_vector;
 #endif
        /* Set interrupt vector table offset */
        stm_nvic.vto = (uint32_t) &stm_interrupt_vector;