Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

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 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 i;
00093     int j;
00094     int isr_groups_32;
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 #elif defined(__CORTEX_M0PLUS)
00100     isr_groups_32 = 1;
00101 #else
00102     isr_groups_32 = ((SCnSCB->ICTR & SCnSCB_ICTR_INTLINESNUM_Msk) >> SCnSCB_ICTR_INTLINESNUM_Pos) + 1;
00103 #endif
00104 
00105     for (i = 0; i < isr_groups_32; i++) {
00106         NVIC->ICER[i] = 0xFFFFFFFF;
00107         NVIC->ICPR[i] = 0xFFFFFFFF;
00108         for (j = 0; j < 8; j++) {
00109 #if defined(__CORTEX_M23) || defined(__CORTEX_M33)
00110             NVIC->IPR[i * 8 + j] = 0x00000000;
00111 #else
00112             NVIC->IP[i * 8 + j] = 0x00000000;
00113 #endif
00114         }
00115     }
00116 }
00117 
00118 static void powerdown_scb(uint32_t vtor)
00119 {
00120     int i;
00121 
00122     // SCB->CPUID   - Read only CPU ID register
00123     SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk | SCB_ICSR_PENDSTCLR_Msk;
00124     SCB->VTOR = vtor;
00125     SCB->AIRCR = 0x05FA | 0x0000;
00126     SCB->SCR = 0x00000000;
00127     // SCB->CCR     - Implementation defined value
00128     int num_pri_reg; // Number of priority registers
00129 #if defined(__CORTEX_M0PLUS) || defined(__CORTEX_M23)
00130     num_pri_reg = 2;
00131 #else
00132     num_pri_reg = 12;
00133 #endif
00134     for (i = 0; i < num_pri_reg; i++) {
00135 #if defined(__CORTEX_M7) || defined(__CORTEX_M23) || defined(__CORTEX_M33)
00136         SCB->SHPR[i] = 0x00;
00137 #else
00138         SCB->SHP[i] = 0x00;
00139 #endif
00140     }
00141     SCB->SHCSR = 0x00000000;
00142 #if defined(__CORTEX_M23) || defined(__CORTEX_M0PLUS)
00143 #else
00144     SCB->CFSR = 0xFFFFFFFF;
00145     SCB->HFSR = SCB_HFSR_DEBUGEVT_Msk | SCB_HFSR_FORCED_Msk | SCB_HFSR_VECTTBL_Msk;
00146     SCB->DFSR = SCB_DFSR_EXTERNAL_Msk | SCB_DFSR_VCATCH_Msk |
00147                 SCB_DFSR_DWTTRAP_Msk | SCB_DFSR_BKPT_Msk | SCB_DFSR_HALTED_Msk;
00148 #endif
00149     // SCB->MMFAR   - Implementation defined value
00150     // SCB->BFAR    - Implementation defined value
00151     // SCB->AFSR    - Implementation defined value
00152     // SCB->PFR     - Read only processor feature register
00153     // SCB->DFR     - Read only debug feature registers
00154     // SCB->ADR     - Read only auxiliary feature registers
00155     // SCB->MMFR    - Read only memory model feature registers
00156     // SCB->ISAR    - Read only instruction set attribute registers
00157     // SCB->CPACR   - Implementation defined value
00158 }
00159 
00160 #if defined (__CC_ARM)
00161 
00162 __asm static void start_new_application(void *sp, void *pc)
00163 {
00164     MOVS R2, #0
00165     MSR CONTROL, R2         // Switch to main stack
00166     MOV SP, R0
00167     MSR PRIMASK, R2         // Enable interrupts
00168     BX R1
00169 }
00170 
00171 #elif defined (__GNUC__) || defined (__ICCARM__)
00172 
00173 void start_new_application(void *sp, void *pc)
00174 {
00175     __asm volatile(
00176         "movs   r2, #0      \n"
00177         "msr    control, r2 \n" // Switch to main stack
00178         "mov    sp, %0      \n"
00179         "msr    primask, r2 \n" // Enable interrupts
00180         "bx     %1          \n"
00181         :
00182         : "l"(sp), "l"(pc)
00183         : "r2", "cc", "memory"
00184     );
00185 }
00186 
00187 #else
00188 
00189 #error "Unsupported toolchain"
00190 
00191 #endif
00192 
00193 #endif
00194 
00195 #endif /* MBED_APPLICATION_SUPPORT */