00001 /*This file has been prepared for Doxygen automatic documentation generation.*/ 00016 /* Copyright (c) 2009 Atmel Corporation. All rights reserved. 00017 * 00018 * Redistribution and use in source and binary forms, with or without 00019 * modification, are permitted provided that the following conditions are met: 00020 * 00021 * 1. Redistributions of source code must retain the above copyright notice, this 00022 * list of conditions and the following disclaimer. 00023 * 00024 * 2. Redistributions in binary form must reproduce the above copyright notice, 00025 * this list of conditions and the following disclaimer in the documentation 00026 * and/or other materials provided with the distribution. 00027 * 00028 * 3. The name of Atmel may not be used to endorse or promote products derived 00029 * from this software without specific prior written permission. 00030 * 00031 * 4. This software may only be redistributed and used in connection with an Atmel 00032 * AVR product. 00033 * 00034 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 00035 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00036 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 00037 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 00038 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00039 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00040 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00041 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00042 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00043 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 00044 * 00045 */ 00046 00047 #include <avr32/io.h> 00048 #include "board.h" 00049 #include "flashvault.h" 00050 00053 00054 //** 00055 //** Pre-requesites: SSE fuse bit is 0 and SSDE fuse bit is 1 (i.e. Secure State 00056 //** enabled, Secure State debug disabled) or SSE fuse bit is 1 and SSDE fuse bit 00057 //** is 0 (i.e. Secure State enabled, Secure State Debug enabled) 00058 //** 00059 //** This module is a Secure world implementation offering a public API (to 00060 //** toggle led1). 00061 //** 00062 00063 00065 #define SEC_EXE_STATUS_DEFAULT 0x000000AA 00067 #define SEC_EXE_STATUS_INTERRUPTED 0x00000011 00068 00069 //****************************************************************************** 00070 //*** 00071 //*** S E C U R E W O R L D = F L A S H V A U L T 00072 //*** 00073 //****************************************************************************** 00074 // This must be linked @ 0x80000000 if it is to be run upon reset. 00075 .section .reset, "ax", @progbits 00076 00077 .global _start 00078 .type _start, @function 00079 _start: // reset @ == 0x80000000 00080 // Jump to the C runtime startup routine. 00081 // lda.w pc, sec_boot // Use the linker option -mno-relax when using this pseudo-instruction. 00082 rjmp sec_boot 00083 00084 //** 00085 //** Secure State Event Handling table. 00086 //** 00087 .org 0x4 // SSCALL handler entry point 00088 rjmp sec_sscall_handle 00089 .org 0x8 // Exceptions handler entry point 00090 rjmp sec_exceptions_handle 00091 .org 0xc // NMI handler entry point 00092 rjmp sec_nmi_handle 00093 .org 0x10 // BREAKPOINT handler entry point 00094 rjmp sec_bp_handle 00095 .org 0x14 // Interrupts handler entry point 00096 rjmp sec_irq_handle 00097 00098 00099 //** 00100 //** Boot 00101 //** 00102 sec_boot: 00103 // Set the Secure Sections size to 1kB 00104 mov r8, SECURE_FLASH_SIZE 00105 mtsr AVR32_SS_ADRR, r8 00106 mtsr AVR32_SS_ADRF, r8 00107 00108 // Init the Secure State Stack pointer 00109 mov sp, _e_sec_stack 00110 00111 // Init the SS_RAR register to the start address of the zone outside the FlashVault. 00112 mov r8, lo(AVR32_FLASH_ADDRESS+SECURE_FLASH_SIZE) 00113 orh r8, hi(AVR32_FLASH_ADDRESS+SECURE_FLASH_SIZE) 00114 mtsr AVR32_SS_RAR, r8 00115 00116 // Init the SS_RSR register to Secure State Inactive (clear the SS bit of the 00117 // current SR register). 00118 mfsr r8, AVR32_SR 00119 cbr r8, 31 00120 mtsr AVR32_SS_RSR, r8 00121 00122 // Load initialized data having a global lifetime from the data LMA. 00123 lda.w r0, sec_data 00124 lda.w r1, sec_edata 00125 cp r0, r1 00126 brhs sec_idata_load_loop_end 00127 lda.w r2, sec_data_lma 00128 sec_idata_load_loop: 00129 ld.d r4, r2++ 00130 st.d r0++, r4 00131 cp r0, r1 00132 brlo sec_idata_load_loop 00133 sec_idata_load_loop_end: 00134 00135 // Clear uninitialized data having a global lifetime in the blank static storage section. 00136 lda.w r0, sec_bss_start 00137 lda.w r1, sec_bss_end 00138 cp r0, r1 00139 brhs sec_udata_clear_loop_end 00140 mov r2, 0 00141 mov r3, 0 00142 sec_udata_clear_loop: 00143 st.d r0++, r2 00144 cp r0, r1 00145 brlo sec_udata_clear_loop 00146 sec_udata_clear_loop_end: 00147 00148 // Set the execution status of the secure world as default 00149 mov r0, SEC_EXE_STATUS_DEFAULT 00150 mtsr AVR32_SS_STATUS, r0 00151 00152 // Switch to the application outside the FlashVault. 00153 .int INST_RETSS 00154 // Should never reached that point. 00155 00156 00157 //** 00158 //** SSCALL handler 00159 //** R8: public api vector number 00160 //** 00161 sec_sscall_handle: 00162 // Temporary save of r0 before modifying it. 00163 st.w --sp, r0 00164 // Check if we're back from an interrupt handling performed in the application 00165 // outside the FlashVault. 00166 // If so we should resume the secure execution at the point where it was 00167 // interrupted. 00168 mfsr r0, AVR32_SS_STATUS 00169 cp r0, SEC_EXE_STATUS_INTERRUPTED 00170 // Restore r0 00171 ld.w r0, sp++ 00172 breq sec_irq_restore_exe 00173 00174 // We must save all registers on the stack else the application outside the 00175 // FlashVault may fail when it resumes! 00176 pushm r0-r12, lr 00177 00178 // Save SS_RAR and SS_RSR in secure memory before enabling IRQ 00179 mov r0, ss_rar_save 00180 mfsr r1, AVR32_SS_RAR 00181 st.w r0[0], r1 00182 mov r0, ss_rsr_save 00183 mfsr r1, AVR32_SS_RSR 00184 st.w r0[0], r1 00185 // Enable INT0 interrupts. 00186 csrf AVR32_SR_GM 00187 csrf AVR32_SR_I0M 00188 00189 // Make sure R8 holds one of the public api vector number 00190 cp r8, FLASHVAULT_API_TGL_LED1 00191 breq sec_pub_tgl_led1 00192 // Go back to the application outside the FlashVault. 00193 mov r12, FAIL 00194 // Expected fall-back to sec_exit() 00195 00196 //** 00197 //** Common routine to leave the secure mode: 00198 //** Mask interrupts, restore RAR/RSR. Return value in r12 00199 //** Use the following addresses (RAR @0(i.e. in ss_rar_save), RSR @4(i.e. in ss_rsr_save)) 00200 //** Cannot use stack since we need random access when handling interrupts. 00201 //** 00202 sec_exit: 00203 // Disable all interrupts 00204 ssrf AVR32_SR_GM 00205 // Restore RSR 00206 mov r0, ss_rsr_save 00207 ld.w r1, r0[0] 00208 mtsr AVR32_SS_RSR, r1 00209 // Restore RAR 00210 mov r0, ss_rar_save 00211 ld.w r1, r0[0] 00212 sub r1, -2 // Update return address to the instruction after SSCALL 00213 mtsr AVR32_SS_RAR, r1 00214 // We must restore all registers from the stack else the application outside 00215 // the FlashVault may fail when it resumes! 00216 ldm sp++, r0-r12, lr 00217 .int INST_RETSS 00218 00219 00220 //** 00221 //** Restore a previously interrupted secure mode execution: 00222 //** - Set the secure mode execution status back to default 00223 //** - Restore the SR & PC from the secure stack to resume the secure code execution 00224 //** 00225 sec_irq_restore_exe: 00226 // Pop SR and PC to interrupted secure mode application SSCALL from stack. 00227 // Set the secure mode execution status back to default. 00228 mov r0, SEC_EXE_STATUS_DEFAULT 00229 mtsr AVR32_SS_STATUS, r0 00230 // Restore the SR & PC from the secure stack. 00231 // IRQs will then be reenabled due to SR restore. 00232 // What will happen if IRQ is received immediately? Must this be done atomically? 00233 ld.w r0, sp++ 00234 mtsr AVR32_SR, r0 00235 // We must restore all registers from the stack else the secure code application 00236 // will fail when it resumes! 00237 sub sp, 15*4 // Reset the SP to the appropriate position before popping R0-R12, LR. 00238 ldm sp++, r0-r12, lr 00239 sub sp, -1*4 // Reset the SP to the appropriate position before popping SS_RAR. 00240 ld.w pc, sp++ 00241 00242 00243 //** 00244 //** Exceptions handler, NMI handler, breakpoint handler. 00245 //** These are not expected in this appli; so just turn led3 on. 00246 //** 00247 sec_exceptions_handle: 00248 sec_nmi_handle: 00249 sec_bp_handle: 00250 rcall sec_set_led3_on 00251 rjmp $ 00252 00253 00254 //** 00255 //** Interrupts handler: 00256 //** Secure code was interrupted. Save required state on the secure stack, and 00257 //** return to the application outside the FlashVault. Write status info in 00258 //** SS_STATUS allowing the restore of the secure code execution once we get 00259 //** back from the interrupt handling performed outside the FlashVault. 00260 //** 00261 sec_irq_handle: 00262 // We must save all registers on the stack else the secure code application 00263 // will fail when it resumes! 00264 sub sp, 2*4 // Save room for RAR and RSR 00265 pushm r0-r12,lr // Push R0-R12 & LR on the stack 00266 sub sp, -16*4 // Reset the SP to the appropriate position before saving RAR & RSR. 00267 // Put RSR and RAR of the interrupted secure application on the secure stack. 00268 mfsr r0, AVR32_SS_RAR 00269 st.w --sp, r0 00270 mfsr r0, AVR32_SS_RSR 00271 st.w --sp, r0 00272 00273 // Toggle LED2 to provide a visual information that this case occured. 00274 rcall sec_tgl_led2 00275 00276 // Update SS_STATUS with a value indicating that the secure code was interrupted. 00277 mov r0, SEC_EXE_STATUS_INTERRUPTED 00278 mtsr AVR32_SS_STATUS, r0 00279 00280 // Restore the SS_RAR & SS_RSR from the original SSCALL call (these were saved 00281 // in the SSCALL handler in the ss_rar_save & ss_rsr_save variables). 00282 // Note that SS_RAR will then be set to the application outside the FlashVault 00283 // on the SSCALL instruction that was issued to reach the FlashVault API. 00284 mov r0, ss_rar_save 00285 ld.w r1, r0[0] 00286 mtsr AVR32_SS_RAR, r1 00287 mov r0, ss_rsr_save 00288 ld.w r1, r0[0] 00289 mtsr AVR32_SS_RSR, r1 00290 // Return to the application outside the FlashVault to handle the IRQ. 00291 // NOTE: In the world outside the FlashVault, once the IRQ handling is done, 00292 // rete will be executed which will restore execution on the SSCALL instruction 00293 // which will switch execution to the FlashVault in the SSCALL handler sec_sscall_handle(). 00294 .int INST_RETSS 00295 00296 00297 00298 00299 //** 00300 //** Public API: sec_pub_tgl_led1 00301 //** 00302 sec_pub_tgl_led1: 00303 // Set the GPIO bit in the GPER register to enable the GPIO. 00304 mov r10, 1 << (LED1_GPIO & 0x1F) 00305 mov r9, AVR32_GPIO_ADDRESS + 0x200*(LED1_GPIO >> 5) 00306 00307 sec_tgl_led_retss: 00308 // Set the GPIO bit in the GPER register to enable the GPIO. 00309 st.w r9[AVR32_GPIO_GPERS], r10 00310 // Toggle the GPIO bit in the OVR register. 00311 st.w r9[AVR32_GPIO_OVRT], r10 00312 // Set the GPIO bit in ODER register to enable the GPIO output driver for that pin. 00313 st.w r9[AVR32_GPIO_ODERS], r10 00314 // Go back to the application outside the FlashVault. 00315 mov r12, PASS 00316 rjmp sec_exit 00317 00318 00319 //** 00320 //** Private API (not accessible from outside the secure world): 00321 //** sec_set_led2_on, sec_set_led3_on, sec_tgl_led2 00322 //** 00323 sec_set_led2_on: 00324 // Set the GPIO bit in the GPER register to enable the GPIO. 00325 mov r10, 1 << (LED2_GPIO & 0x1F) 00326 mov r9, AVR32_GPIO_ADDRESS + 0x200*(LED2_GPIO >> 5) 00327 00328 sec_set_led_on_retal: 00329 // Set the GPIO bit in the GPER register to enable the GPIO. 00330 st.w r9[AVR32_GPIO_GPERS], r10 00331 // Clear the GPIO bit in the OVR register to drive a low level when in output mode. 00332 st.w r9[AVR32_GPIO_OVRC], r10 00333 // Set the GPIO bit in ODER register to enable the GPIO output driver for that pin. 00334 st.w r9[AVR32_GPIO_ODERS], r10 00335 retal r12 00336 00337 sec_set_led3_on: 00338 // Set the GPIO bit in the GPER register to enable the GPIO. 00339 mov r10, 1 << (LED3_GPIO & 0x1F) 00340 mov r9, AVR32_GPIO_ADDRESS + 0x200*(LED3_GPIO >> 5) 00341 rjmp sec_set_led_on_retal 00342 00343 sec_tgl_led2: 00344 // Set the GPIO bit in the GPER register to enable the GPIO. 00345 mov r10, 1 << (LED2_GPIO & 0x1F) 00346 mov r9, AVR32_GPIO_ADDRESS + 0x200*(LED2_GPIO >> 5) 00347 // Set the GPIO bit in the GPER register to enable the GPIO. 00348 st.w r9[AVR32_GPIO_GPERS], r10 00349 // Toggle the GPIO bit in the OVR register. 00350 st.w r9[AVR32_GPIO_OVRT], r10 00351 // Set the GPIO bit in ODER register to enable the GPIO output driver for that pin. 00352 st.w r9[AVR32_GPIO_ODERS], r10 00353 retal r12 00354 00355 00356 .section .sec_data, "aw", @progbits 00357 00358 .global ss_rar_save 00359 .type ss_rar_save, @object 00360 .org 0x0 00361 ss_rar_save: .word 00362 00363 .global ss_rsr_save 00364 .type ss_rsr_save, @object 00365 // . = . + 4 // equivalent to .org 0x4 00366 .org 0x4 00367 ss_rsr_save: .word 00368