cpu.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /***********************************************************************************************************************
  2. * DISCLAIMER
  3. * This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
  4. * other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
  5. * applicable laws, including copyright laws.
  6. * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
  7. * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
  8. * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
  9. * EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
  10. * SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
  11. * SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  12. * Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
  13. * this software. By using this software, you agree to the additional terms and conditions found by accessing the
  14. * following link:
  15. * http://www.renesas.com/disclaimer
  16. *
  17. * Copyright (C) 2016 Renesas Electronics Corporation. All rights reserved.
  18. ***********************************************************************************************************************/
  19. /***********************************************************************************************************************
  20. * File Name : cpu.c
  21. * Description : This module implements CPU specific functions. An example is enabling/disabling interrupts.
  22. ***********************************************************************************************************************/
  23. /**********************************************************************************************************************
  24. * History : DD.MM.YYYY Version Description
  25. * : 01.10.2016 1.00 First Release
  26. * : 15.05.2017 2.00 Changed comments of the PRCR register.
  27. * : 01.07.2018 2.01 Prevent task switching when protection counter is updated.
  28. * : 27.07.2018 2.02 Added the comment to for statement.
  29. * Added processing to control IPL for R_BSP_RegisterProtectEnable function and
  30. * R_BSP_RegisterProtectDisable function.
  31. * : xx.xx.xxxx 2.03 Removed the wrong comment from for statement.
  32. * Added bsp_ram_initialize function.
  33. * Added support for GNUC and ICCRX.
  34. ***********************************************************************************************************************/
  35. /***********************************************************************************************************************
  36. Includes <System Includes> , "Project Includes"
  37. ***********************************************************************************************************************/
  38. /* Platform support. */
  39. #include "platform.h"
  40. /***********************************************************************************************************************
  41. Macro definitions
  42. ***********************************************************************************************************************/
  43. /* Key code for writing PRCR register. */
  44. #define BSP_PRV_PRCR_KEY (0xA500)
  45. /***********************************************************************************************************************
  46. Typedef definitions
  47. ***********************************************************************************************************************/
  48. /***********************************************************************************************************************
  49. Exported global variables (to be accessed by other files)
  50. ***********************************************************************************************************************/
  51. /***********************************************************************************************************************
  52. Private global variables and functions
  53. ***********************************************************************************************************************/
  54. /* Used for holding reference counters for protection bits. */
  55. static volatile uint16_t g_protect_counters[BSP_REG_PROTECT_TOTAL_ITEMS];
  56. /* Masks for setting or clearing the PRCR register. Use -1 for size because PWPR in MPC is used differently. */
  57. static const uint16_t g_prcr_masks[BSP_REG_PROTECT_TOTAL_ITEMS-1] =
  58. {
  59. 0x0001, /* PRC0. */
  60. 0x0002, /* PRC1. */
  61. 0x0008, /* PRC3. */
  62. };
  63. /***********************************************************************************************************************
  64. * Function Name: R_BSP_InterruptsDisable
  65. * Description : Globally disable interrupts.
  66. * Arguments : none
  67. * Return Value : none
  68. ***********************************************************************************************************************/
  69. void R_BSP_InterruptsDisable (void)
  70. {
  71. /* Use the compiler intrinsic function to clear the I flag. */
  72. R_CLRPSW_I();
  73. }
  74. /***********************************************************************************************************************
  75. * Function Name: R_BSP_InterruptsEnable
  76. * Description : Globally enable interrupts.
  77. * Arguments : none
  78. * Return Value : none
  79. ***********************************************************************************************************************/
  80. void R_BSP_InterruptsEnable (void)
  81. {
  82. /* Use the compiler intrinsic function to set the I flag. */
  83. R_SETPSW_I();
  84. }
  85. /***********************************************************************************************************************
  86. * Function Name: R_BSP_CpuInterruptLevelRead
  87. * Description : Reads the processor interrupt priority level.
  88. * Arguments : none
  89. * Return Value : The current processor IPL
  90. ***********************************************************************************************************************/
  91. uint32_t R_BSP_CpuInterruptLevelRead (void)
  92. {
  93. /* Use the compiler intrinsic function to read the CPU IPL. */
  94. uint32_t psw_value;
  95. psw_value = (uint32_t)R_GET_PSW();
  96. psw_value = psw_value & 0x0f000000;
  97. psw_value = psw_value >> 24;
  98. return psw_value;
  99. }
  100. /***********************************************************************************************************************
  101. * Function Name: R_BSP_CpuInterruptLevelWrite
  102. * Description : Writes the processor interrupt priority level.
  103. * Arguments : level -
  104. * The level to set the processor's IPL to.
  105. * Return Value : true -
  106. * The level was set successfully.
  107. * false -
  108. * Invalid level input.
  109. ***********************************************************************************************************************/
  110. bool R_BSP_CpuInterruptLevelWrite (uint32_t level)
  111. {
  112. uint32_t psw_value;
  113. #if (BSP_CFG_PARAM_CHECKING_ENABLE == 1)
  114. /* Check for valid level. */
  115. if (level > BSP_MCU_IPL_MAX)
  116. {
  117. return false;
  118. }
  119. #endif
  120. /* Use the compiler intrinsic function to set the CPU IPL. */
  121. psw_value = level << 24;
  122. psw_value = psw_value | ((uint32_t)R_GET_PSW() & 0xf0ffffff);
  123. R_SET_PSW(psw_value);
  124. return true;
  125. }
  126. /***********************************************************************************************************************
  127. * Function Name: R_BSP_RegisterProtectEnable
  128. * Description : Enables register protection. Registers that are protected cannot be written to. Register protection is
  129. * enabled by using the Protect Register (PRCR) and the MPC's Write-Protect Register (PWPR).
  130. * Arguments : regs_to_unprotect -
  131. * Which registers to disable write protection for. See typedef defines of bsp_reg_protect_t.
  132. * Return Value : none
  133. ***********************************************************************************************************************/
  134. void R_BSP_RegisterProtectEnable (bsp_reg_protect_t regs_to_protect)
  135. {
  136. volatile uint32_t ipl_value;
  137. bool ret;
  138. /* Get the current Processor Interrupt Priority Level (IPL). */
  139. ipl_value = R_BSP_CpuInterruptLevelRead();
  140. /* Set IPL to the maximum value to disable all interrupts,
  141. * so the scheduler can not be scheduled in critical region.
  142. * Note: Please set this macro more than IPR for other FIT module interrupts. */
  143. if (ipl_value < BSP_CFG_FIT_IPL_MAX)
  144. {
  145. ret = R_BSP_CpuInterruptLevelWrite(BSP_CFG_FIT_IPL_MAX);
  146. if (false == ret)
  147. {
  148. /* check return value */
  149. }
  150. }
  151. /* Is it safe to disable write access? */
  152. if (0 != g_protect_counters[regs_to_protect])
  153. {
  154. /* Decrement the protect counter */
  155. g_protect_counters[regs_to_protect]--;
  156. }
  157. /* Is it safe to disable write access? */
  158. if (0 == g_protect_counters[regs_to_protect])
  159. {
  160. if (BSP_REG_PROTECT_MPC != regs_to_protect)
  161. {
  162. /* Enable protection using PRCR register. */
  163. /* When writing to the PRCR register the upper 8-bits must be the correct key. Set lower bits to 0 to
  164. disable writes.
  165. b15:b8 PRKEY - Write 0xA5 to upper byte to enable writing to lower byte
  166. b7:b4 Reserved (set to 0)
  167. b3 PRC3 - Enables writing to the registers related to the LVD: LVCMPCR, LVDLVLR, LVD1CR0, LVD1CR1,
  168. LVD1SR, LVD2CR0, LVD2CR1, LVD2SR.
  169. b2 Reserved (set to 0)
  170. b1 PRC1 - Enables writing to the registers related to operating modes, low power consumption, the
  171. clock generation circuit, and software reset: SYSCR0, SYSCR1, SBYCR, MSTPCRA, MSTPCRB,
  172. MSTPCRC, MSTPCRD, OPCCR, RSTCKCR, DPSBYCR, DPSIER0, DPSIER1, DPSIER2, DPSIER3,
  173. DPSIFR0, DPSIFR1, DPSIFR2, DPSIFR3, DPSIEGR0, DPSIEGR1, DPSIEGR2, DPSIEGR3,
  174. MOSCWTCR, SOSCETCR, MOFCR, HOCOPCR, SWRR.
  175. b0 PRC0 - Enables writing to the registers related to the clock generation circuit: SCKCR, SCKCR2,
  176. SCKCR3, PLLCR, PLLCR2, BCKCR, MOSCCR, SOSCCR, LOCOCR, ILOCOCR, HOCOCR, HOCOCR2, OSTDCR,
  177. OSTDSR.
  178. */
  179. SYSTEM.PRCR.WORD = (uint16_t)((SYSTEM.PRCR.WORD | BSP_PRV_PRCR_KEY) & (~g_prcr_masks[regs_to_protect]));
  180. }
  181. else
  182. {
  183. /* Enable protection for MPC using PWPR register. */
  184. /* Enable writing of PFSWE bit. It could be assumed that the B0WI bit is still cleared from a call to
  185. protection disable function, but it is written here to make sure that the PFSWE bit always gets
  186. cleared. */
  187. MPC.PWPR.BIT.B0WI = 0;
  188. /* Disable writing to PFS registers. */
  189. MPC.PWPR.BIT.PFSWE = 0;
  190. /* Disable writing of PFSWE bit. */
  191. MPC.PWPR.BIT.B0WI = 1;
  192. }
  193. }
  194. /* Restore the IPL. */
  195. if (ipl_value < BSP_CFG_FIT_IPL_MAX)
  196. {
  197. ret = R_BSP_CpuInterruptLevelWrite(ipl_value);
  198. if (false == ret)
  199. {
  200. /* check return value */
  201. }
  202. }
  203. }
  204. /***********************************************************************************************************************
  205. * Function Name: R_BSP_RegisterProtectDisable
  206. * Description : Disables register protection. Registers that are protected cannot be written to. Register protection is
  207. * disabled by using the Protect Register (PRCR) and the MPC's Write-Protect Register (PWPR).
  208. * Arguments : regs_to_unprotect -
  209. * Which registers to disable write protection for. See typedef defines of bsp_reg_protect_t.
  210. * Return Value : none
  211. ***********************************************************************************************************************/
  212. void R_BSP_RegisterProtectDisable (bsp_reg_protect_t regs_to_unprotect)
  213. {
  214. volatile uint32_t ipl_value;
  215. bool ret;
  216. /* Get the current Processor Interrupt Priority Level (IPL). */
  217. ipl_value = R_BSP_CpuInterruptLevelRead();
  218. /* Set IPL to the maximum value to disable all interrupts,
  219. * so the scheduler can not be scheduled in critical region.
  220. * Note: Please set this macro more than IPR for other FIT module interrupts. */
  221. if (ipl_value < BSP_CFG_FIT_IPL_MAX)
  222. {
  223. ret = R_BSP_CpuInterruptLevelWrite(BSP_CFG_FIT_IPL_MAX);
  224. if (false == ret)
  225. {
  226. /* check return value */
  227. }
  228. }
  229. /* If this is first entry then disable protection. */
  230. if (0 == g_protect_counters[regs_to_unprotect])
  231. {
  232. if (BSP_REG_PROTECT_MPC != regs_to_unprotect)
  233. {
  234. /* Enable protection using PRCR register. */
  235. /* When writing to the PRCR register the upper 8-bits must be the correct key. Set lower bits to 1 to
  236. enable writes.
  237. b15:b8 PRKEY - Write 0xA5 to upper byte to enable writing to lower byte
  238. b7:b4 Reserved (set to 0)
  239. b3 PRC3 - Enables writing to the registers related to the LVD: LVCMPCR, LVDLVLR, LVD1CR0, LVD1CR1,
  240. LVD1SR, LVD2CR0, LVD2CR1, LVD2SR.
  241. b2 Reserved (set to 0)
  242. b1 PRC1 - Enables writing to the registers related to operating modes, low power consumption, the
  243. clock generation circuit, and software reset: SYSCR0, SYSCR1, SBYCR, MSTPCRA, MSTPCRB,
  244. MSTPCRC, MSTPCRD, OPCCR, RSTCKCR, DPSBYCR, DPSIER0, DPSIER1, DPSIER2, DPSIER3,
  245. DPSIFR0, DPSIFR1, DPSIFR2, DPSIFR3, DPSIEGR0, DPSIEGR1, DPSIEGR2, DPSIEGR3,
  246. MOSCWTCR, SOSCETCR, MOFCR, HOCOPCR, SWRR.
  247. b0 PRC0 - Enables writing to the registers related to the clock generation circuit: SCKCR, SCKCR2,
  248. SCKCR3, PLLCR, PLLCR2, BCKCR, MOSCCR, SOSCCR, LOCOCR, ILOCOCR, HOCOCR, HOCOCR2, OSTDCR,
  249. OSTDSR.
  250. */
  251. SYSTEM.PRCR.WORD = (uint16_t)((SYSTEM.PRCR.WORD | BSP_PRV_PRCR_KEY) | g_prcr_masks[regs_to_unprotect]);
  252. }
  253. else
  254. {
  255. /* Disable protection for MPC using PWPR register. */
  256. /* Enable writing of PFSWE bit. */
  257. MPC.PWPR.BIT.B0WI = 0;
  258. /* Enable writing to PFS registers. */
  259. MPC.PWPR.BIT.PFSWE = 1;
  260. }
  261. }
  262. /* Increment the protect counter */
  263. g_protect_counters[regs_to_unprotect]++;
  264. /* Restore the IPL. */
  265. if (ipl_value < BSP_CFG_FIT_IPL_MAX)
  266. {
  267. ret = R_BSP_CpuInterruptLevelWrite(ipl_value);
  268. if (false == ret)
  269. {
  270. /* check return value */
  271. }
  272. }
  273. }
  274. /***********************************************************************************************************************
  275. * Function Name: bsp_register_protect_open
  276. * Description : Initializes variables needed for register protection functionality.
  277. * Arguments : none
  278. * Return Value : none
  279. ***********************************************************************************************************************/
  280. void bsp_register_protect_open (void)
  281. {
  282. uint32_t i;
  283. /* Initialize reference counters to 0. */
  284. for (i = 0; i < BSP_REG_PROTECT_TOTAL_ITEMS; i++)
  285. {
  286. g_protect_counters[i] = 0;
  287. }
  288. }
  289. /***********************************************************************************************************************
  290. * Function Name: bsp_ram_initialize
  291. * Description : Initialize ram variable.
  292. * Arguments : none
  293. * Return Value : none
  294. ***********************************************************************************************************************/
  295. void bsp_ram_initialize (void)
  296. {
  297. uint32_t i;
  298. /* Initialize g_bsp_Locks to 0. */
  299. for (i = 0; i < BSP_NUM_LOCKS; i++)
  300. {
  301. g_bsp_Locks[i].lock = 0;
  302. }
  303. }