From: Stephan Baerwolf Date: Sun, 31 Mar 2013 22:17:32 +0000 (+0200) Subject: BUGFIX: spminterface: use eicall to call "___bootloader__do_spm__ptr" if flash>128kib X-Git-Tag: v0.96~3 X-Git-Url: http://git.linex4red.de/pub/USBaspLoader.git/commitdiff_plain/96ad347f6a816a3520dea91ace4629ea29d2e08f?ds=inline BUGFIX: spminterface: use eicall to call "___bootloader__do_spm__ptr" if flash>128kib Signed-off-by: Stephan Baerwolf --- diff --git a/firmware/spminterface.h b/firmware/spminterface.h index 016afda..d569cd3 100644 --- a/firmware/spminterface.h +++ b/firmware/spminterface.h @@ -178,104 +178,234 @@ ret #else #define __do_spm_Ex __do_spm_Ex_ #endif - -#define __do_spm_Ex_(flash_wordaddress, spmcrval, dataword, ___bootloader__do_spm__ptr) \ -({ \ - asm volatile ( \ - "push r0\n\t" \ - "push r1\n\t" \ - \ - "mov r13, %B[flashaddress]\n\t" \ - "mov r12, %A[flashaddress]\n\t" \ - "mov r11, %C[flashaddress]\n\t" \ - \ - /* also load the spmcrval */ \ - "mov r18, %[spmcrval]\n\t" \ - \ - \ - "mov r1, %B[data]\n\t" \ - "mov r0, %A[data]\n\t" \ - \ - /* finally call the bootloader-function */ \ - "icall\n\t" \ - \ - /* \ - * bootloader__do_spm should change spmcrval (r18) to \ - * "((1<>24)&0xff), \ - [magicC] "M" ((HAVE_SPMINTEREFACE_MAGICVALUE>>16)&0xff), \ - [magicB] "M" ((HAVE_SPMINTEREFACE_MAGICVALUE>> 8)&0xff), \ - [magicA] "M" ((HAVE_SPMINTEREFACE_MAGICVALUE>> 0)&0xff) \ - : "r0","r1","r11","r12","r13","r18","r20","r21","r22","r23" \ - ); \ -}) +#if (defined(EIND) && ((FLASHEND)>131071)) + /* + * Huge flash version using eicall (and EIND) + */ + #define __do_spm_Ex_(flash_wordaddress, spmcrval, dataword, ___bootloader__do_spm__ptr) \ + ({ \ + asm volatile ( \ + "push r0\n\t" \ + "push r1\n\t" \ + \ + "mov r13, %B[flashaddress]\n\t" \ + "mov r12, %A[flashaddress]\n\t" \ + "mov r11, %C[flashaddress]\n\t" \ + \ + /* prepare the EIND for following eicall */ \ + "in r18, %[eind]\n\t" \ + "push r18\n\t" \ + "ldi r18, %[spmfuncaddrEIND]\n\t" \ + "out %[eind], r18\n\t" \ + \ + /* also load the spmcrval */ \ + "mov r18, %[spmcrval]\n\t" \ + \ + \ + "mov r1, %B[data]\n\t" \ + "mov r0, %A[data]\n\t" \ + \ + /* finally call the bootloader-function */ \ + "eicall\n\t" \ + "pop r1\n\t" \ + "out %[eind], r1\n\t" \ + \ + /* \ + * bootloader__do_spm should change spmcrval (r18) to \ + * "((1<>16)), \ + [eind] "I" (_SFR_IO_ADDR(EIND)), \ + [spmcrval] "r" (spmcrval), \ + [data] "r" (dataword), \ + [spmret] "M" ((1<>16)), \ + [eind] "I" (_SFR_IO_ADDR(EIND)), \ + [spmcrval] "r" (spmcrval), \ + [data] "r" (dataword), \ + [spmret] "M" ((1<>24)&0xff), \ + [magicC] "M" ((HAVE_SPMINTEREFACE_MAGICVALUE>>16)&0xff), \ + [magicB] "M" ((HAVE_SPMINTEREFACE_MAGICVALUE>> 8)&0xff), \ + [magicA] "M" ((HAVE_SPMINTEREFACE_MAGICVALUE>> 0)&0xff) \ + : "r0","r1","r11","r12","r13","r18","r20","r21","r22","r23" \ + ); \ + }) + + +#else + /* + * Normal version for devices with <=128KiB flash (using icall) + */ + #if ((FLASHEND)>131071) + #error "Using inappropriate code for device with more than 128kib flash" + #endif + + #define __do_spm_Ex_(flash_wordaddress, spmcrval, dataword, ___bootloader__do_spm__ptr) \ + ({ \ + asm volatile ( \ + "push r0\n\t" \ + "push r1\n\t" \ + \ + "mov r13, %B[flashaddress]\n\t" \ + "mov r12, %A[flashaddress]\n\t" \ + "mov r11, %C[flashaddress]\n\t" \ + \ + /* also load the spmcrval */ \ + "mov r18, %[spmcrval]\n\t" \ + \ + \ + "mov r1, %B[data]\n\t" \ + "mov r0, %A[data]\n\t" \ + \ + /* finally call the bootloader-function */ \ + "icall\n\t" \ + \ + /* \ + * bootloader__do_spm should change spmcrval (r18) to \ + * "((1<>24)&0xff), \ + [magicC] "M" ((HAVE_SPMINTEREFACE_MAGICVALUE>>16)&0xff), \ + [magicB] "M" ((HAVE_SPMINTEREFACE_MAGICVALUE>> 8)&0xff), \ + [magicA] "M" ((HAVE_SPMINTEREFACE_MAGICVALUE>> 0)&0xff) \ + : "r0","r1","r11","r12","r13","r18","r20","r21","r22","r23" \ + ); \ + }) +#endif #if (!(defined(BOOTLOADER_ADDRESS))) || (defined(NEW_BOOTLOADER_ADDRESS)) void do_spm(const uint32_t flash_byteaddress, const uint8_t spmcrval, const uint16_t dataword) {