mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mbed_application.c Source File

mbed_application.c

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2017-2017 ARM Limited
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #include <stdlib.h>
00019 #include <stdarg.h>
00020 #include "device.h"
00021 #include "platform/mbed_application.h"
00022 #include "platform/mbed_mpu_mgmt.h"
00023 
00024 #if MBED_APPLICATION_SUPPORT
00025 
00026 #if defined(__CORTEX_A9)
00027 
00028 static void powerdown_gic(void);
00029 
00030 void mbed_start_application(uintptr_t address)
00031 {
00032     __disable_irq();
00033     powerdown_gic();
00034     __enable_irq();
00035     ((void(*)())address)();
00036 }
00037 
00038 static void powerdown_gic()
00039 {
00040     int i;
00041     int j;
00042 
00043     for (i = 0; i < 32; i++) {
00044         GICDistributor->ICENABLER[i] = 0xFFFFFFFF;
00045         GICDistributor->ICPENDR[i] = 0xFFFFFFFF;
00046         if (i < 4) {
00047             GICDistributor->CPENDSGIR[i] = 0xFFFFFFFF;
00048         }
00049         for (j = 0; j < 8; j++) {
00050             GICDistributor->IPRIORITYR[i * 8 + j] = 0x00000000;
00051         }
00052     }
00053 }
00054 
00055 #else
00056 
00057 static void powerdown_nvic(void);
00058 static void powerdown_scb(uint32_t vtor);
00059 static void start_new_application(void *sp, void *pc);
00060 
00061 void mbed_start_application(uintptr_t address)
00062 {
00063     void *sp;
00064     void *pc;
00065 
00066     // Interrupts are re-enabled in start_new_application
00067     __disable_irq();
00068 
00069     SysTick->CTRL = 0x00000000;
00070     powerdown_nvic();
00071     powerdown_scb(address);
00072     mbed_mpu_manager_deinit();
00073 
00074 #ifdef MBED_DEBUG
00075     // Configs to make debugging easier
00076 #ifdef SCnSCB_ACTLR_DISDEFWBUF_Msk
00077     // Disable write buffer to make BusFaults (eg write to ROM via NULL pointer) precise.
00078     // Possible on Cortex-M3 and M4, not on M0, M7 or M33.
00079     // Would be less necessary if ROM was write-protected in MPU to give a
00080     // precise MemManage exception.
00081     SCnSCB->ACTLR |= SCnSCB_ACTLR_DISDEFWBUF_Msk;
00082 #endif
00083 #endif
00084 
00085     sp = *((void **)address + 0);
00086     pc = *((void **)address + 1);
00087     start_new_application(sp, pc);
00088 }
00089 
00090 static void powerdown_nvic()
00091 {
00092     int isr_groups_32;
00093     int i;
00094     int j;
00095 
00096 #if defined(__CORTEX_M23)
00097     // M23 doesn't support ICTR and supports up to 240 external interrupts.
00098     isr_groups_32 = 8;
00099 #else
00100     isr_groups_32 = ((SCnSCB->ICTR & SCnSCB_ICTR_INTLINESNUM_Msk) >> SCnSCB_ICTR_INTLINESNUM_Pos) + 1;
00101 #endif
00102     for (i = 0; i < isr_groups_32; i++) {
00103         NVIC->ICER[i] = 0xFFFFFFFF;
00104         NVIC->ICPR[i] = 0xFFFFFFFF;
00105         for (j = 0; j < 8; j++) {
00106 #if defined(__CORTEX_M23)
00107             NVIC->IPR[i * 8 + j] = 0x00000000;
00108 #else
00109             NVIC->IP[i * 8 + j] = 0x00000000;
00110 #endif
00111         }
00112     }
00113 }
00114 
00115 static void powerdown_scb(uint32_t vtor)
00116 {
00117     int i;
00118 
00119     // SCB->CPUID   - Read only CPU ID register
00120     SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk | SCB_ICSR_PENDSTCLR_Msk;
00121     SCB->VTOR = vtor;
00122     SCB->AIRCR = 0x05FA | 0x0000;
00123     SCB->SCR = 0x00000000;
00124     // SCB->CCR     - Implementation defined value
00125 #if defined(__CORTEX_M23)
00126     for (i = 0; i < 2; i++) {
00127         SCB->SHPR[i] = 0x00;
00128     }
00129 #else
00130     for (i = 0; i < 12; i++) {
00131 #if defined(__CORTEX_M7)
00132         SCB->SHPR[i] = 0x00;
00133 #else
00134         SCB->SHP[i] = 0x00;
00135 #endif
00136     }
00137 #endif
00138     SCB->SHCSR = 0x00000000;
00139 #if defined(__CORTEX_M23)
00140 #else
00141     SCB->CFSR = 0xFFFFFFFF;
00142     SCB->HFSR = SCB_HFSR_DEBUGEVT_Msk | SCB_HFSR_FORCED_Msk | SCB_HFSR_VECTTBL_Msk;
00143     SCB->DFSR = SCB_DFSR_EXTERNAL_Msk | SCB_DFSR_VCATCH_Msk |
00144                 SCB_DFSR_DWTTRAP_Msk | SCB_DFSR_BKPT_Msk | SCB_DFSR_HALTED_Msk;
00145 #endif
00146     // SCB->MMFAR   - Implementation defined value
00147     // SCB->BFAR    - Implementation defined value
00148     // SCB->AFSR    - Implementation defined value
00149     // SCB->PFR     - Read only processor feature register
00150     // SCB->DFR     - Read only debug feature registers
00151     // SCB->ADR     - Read only auxiliary feature registers
00152     // SCB->MMFR    - Read only memory model feature registers
00153     // SCB->ISAR    - Read only instruction set attribute registers
00154     // SCB->CPACR   - Implementation defined value
00155 }
00156 
00157 #if defined (__CC_ARM)
00158 
00159 __asm static void start_new_application(void *sp, void *pc)
00160 {
00161     MOV R2, #0
00162     MSR CONTROL, R2         // Switch to main stack
00163     MOV SP, R0
00164     MSR PRIMASK, R2         // Enable interrupts
00165     BX R1
00166 }
00167 
00168 #elif defined (__GNUC__) || defined (__ICCARM__)
00169 
00170 void start_new_application(void *sp, void *pc)
00171 {
00172     __asm volatile(
00173         "movw   r2, #0      \n" // Fail to compile "mov r2, #0" with ARMC6. Replace with MOVW.
00174         // We needn't "movt r2, #0" immediately following because MOVW
00175         // will zero-extend the 16-bit immediate.
00176         "msr    control, r2 \n" // Switch to main stack
00177         "mov    sp, %0      \n"
00178         "msr    primask, r2 \n" // Enable interrupts
00179         "bx     %1          \n"
00180         :
00181         : "l"(sp), "l"(pc)
00182         : "r2", "cc", "memory"
00183     );
00184 }
00185 
00186 #else
00187 
00188 #error "Unsupported toolchain"
00189 
00190 #endif
00191 
00192 #endif
00193 
00194 #endif /* MBED_APPLICATION_SUPPORT */