mbed_application.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /* mbed Microcontroller Library
  2. * Copyright (c) 2017-2017 ARM Limited
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <stdlib.h>
  17. #include <stdarg.h>
  18. #include "device.h"
  19. #include "platform/mbed_application.h"
  20. #if MBED_APPLICATION_SUPPORT
  21. #if defined(__CORTEX_A9)
  22. static void powerdown_gic(void);
  23. void mbed_start_application(uintptr_t address)
  24. {
  25. __disable_irq();
  26. powerdown_gic();
  27. __enable_irq();
  28. ((void(*)())address)();
  29. }
  30. static void powerdown_gic()
  31. {
  32. int i;
  33. int j;
  34. for (i = 0; i < 32; i++) {
  35. GICDistributor->ICENABLER[i] = 0xFFFFFFFF;
  36. GICDistributor->ICPENDR[i] = 0xFFFFFFFF;
  37. if (i < 4) {
  38. GICDistributor->CPENDSGIR[i] = 0xFFFFFFFF;
  39. }
  40. for (j = 0; j < 8; j++) {
  41. GICDistributor->IPRIORITYR[i*8+j] = 0x00000000;
  42. }
  43. }
  44. }
  45. #else
  46. static void powerdown_nvic(void);
  47. static void powerdown_scb(uint32_t vtor);
  48. static void start_new_application(void *sp, void *pc);
  49. void mbed_start_application(uintptr_t address)
  50. {
  51. void *sp;
  52. void *pc;
  53. // Interrupts are re-enabled in start_new_application
  54. __disable_irq();
  55. SysTick->CTRL = 0x00000000;
  56. powerdown_nvic();
  57. powerdown_scb(address);
  58. sp = *((void **)address + 0);
  59. pc = *((void **)address + 1);
  60. start_new_application(sp, pc);
  61. }
  62. static void powerdown_nvic()
  63. {
  64. int isr_groups_32;
  65. int i;
  66. int j;
  67. #if defined(__CORTEX_M23)
  68. // M23 doesn't support ICTR and supports up to 240 external interrupts.
  69. isr_groups_32 = 8;
  70. #else
  71. isr_groups_32 = ((SCnSCB->ICTR & SCnSCB_ICTR_INTLINESNUM_Msk) >> SCnSCB_ICTR_INTLINESNUM_Pos) + 1;
  72. #endif
  73. for (i = 0; i < isr_groups_32; i++) {
  74. NVIC->ICER[i] = 0xFFFFFFFF;
  75. NVIC->ICPR[i] = 0xFFFFFFFF;
  76. for (j = 0; j < 8; j++) {
  77. #if defined(__CORTEX_M23)
  78. NVIC->IPR[i * 8 + j] = 0x00000000;
  79. #else
  80. NVIC->IP[i * 8 + j] = 0x00000000;
  81. #endif
  82. }
  83. }
  84. }
  85. static void powerdown_scb(uint32_t vtor)
  86. {
  87. int i;
  88. // SCB->CPUID - Read only CPU ID register
  89. SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk | SCB_ICSR_PENDSTCLR_Msk;
  90. SCB->VTOR = vtor;
  91. SCB->AIRCR = 0x05FA | 0x0000;
  92. SCB->SCR = 0x00000000;
  93. // SCB->CCR - Implementation defined value
  94. #if defined(__CORTEX_M23)
  95. for (i = 0; i < 2; i++) {
  96. SCB->SHPR[i] = 0x00;
  97. }
  98. #else
  99. for (i = 0; i < 12; i++) {
  100. #if defined(__CORTEX_M7)
  101. SCB->SHPR[i] = 0x00;
  102. #else
  103. SCB->SHP[i] = 0x00;
  104. #endif
  105. }
  106. #endif
  107. SCB->SHCSR = 0x00000000;
  108. #if defined(__CORTEX_M23)
  109. #else
  110. SCB->CFSR = 0xFFFFFFFF;
  111. SCB->HFSR = SCB_HFSR_DEBUGEVT_Msk | SCB_HFSR_FORCED_Msk | SCB_HFSR_VECTTBL_Msk;
  112. SCB->DFSR = SCB_DFSR_EXTERNAL_Msk | SCB_DFSR_VCATCH_Msk |
  113. SCB_DFSR_DWTTRAP_Msk | SCB_DFSR_BKPT_Msk | SCB_DFSR_HALTED_Msk;
  114. #endif
  115. // SCB->MMFAR - Implementation defined value
  116. // SCB->BFAR - Implementation defined value
  117. // SCB->AFSR - Implementation defined value
  118. // SCB->PFR - Read only processor feature register
  119. // SCB->DFR - Read only debug feature registers
  120. // SCB->ADR - Read only auxiliary feature registers
  121. // SCB->MMFR - Read only memory model feature registers
  122. // SCB->ISAR - Read only instruction set attribute registers
  123. // SCB->CPACR - Implementation defined value
  124. }
  125. #if defined (__CC_ARM)
  126. __asm static void start_new_application(void *sp, void *pc)
  127. {
  128. MOV R2, #0
  129. MSR CONTROL, R2 // Switch to main stack
  130. MOV SP, R0
  131. MSR PRIMASK, R2 // Enable interrupts
  132. BX R1
  133. }
  134. #elif defined (__GNUC__) || defined (__ICCARM__)
  135. void start_new_application(void *sp, void *pc)
  136. {
  137. __asm volatile(
  138. "movw r2, #0 \n" // Fail to compile "mov r2, #0" with ARMC6. Replace with MOVW.
  139. // We needn't "movt r2, #0" immediately following because MOVW
  140. // will zero-extend the 16-bit immediate.
  141. "msr control, r2 \n" // Switch to main stack
  142. "mov sp, %0 \n"
  143. "msr primask, r2 \n" // Enable interrupts
  144. "bx %1 \n"
  145. :
  146. : "l"(sp), "l"(pc)
  147. : "r2", "cc", "memory"
  148. );
  149. }
  150. #else
  151. #error "Unsupported toolchain"
  152. #endif
  153. #endif
  154. #endif /* MBED_APPLICATION_SUPPORT */