1 /*
2 * Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 
7 /***********************************************************************************************************************
8  * Includes   <System Includes> , "Project Includes"
9  **********************************************************************************************************************/
10 #include "bsp_api.h"
11 
12 /***********************************************************************************************************************
13  * Macro definitions
14  **********************************************************************************************************************/
15 
16 /* Key code for writing PRCR register. */
17 #define BSP_PRV_PRCR_KEY    (0xA500U)
18 
19 /***********************************************************************************************************************
20  * Typedef definitions
21  **********************************************************************************************************************/
22 
23 /***********************************************************************************************************************
24  * Exported global variables (to be accessed by other files)
25  **********************************************************************************************************************/
26 
27 /***********************************************************************************************************************
28  * Private global variables and functions
29  **********************************************************************************************************************/
30 
31 /** Used for holding reference counters for protection bits. */
32 volatile uint16_t g_protect_counters[4] BSP_SECTION_EARLY_INIT;
33 
34 /** Masks for setting or clearing the PRCR register. Use -1 for size because PWPR in MPC is used differently. */
35 static const uint16_t g_prcr_masks[] =
36 {
37     0x0001U,                           /* PRC0. */
38     0x0002U,                           /* PRC1. */
39     0x0008U,                           /* PRC3. */
40     0x0010U,                           /* PRC4. */
41 };
42 
43 /*******************************************************************************************************************//**
44  * @addtogroup BSP_MCU
45  *
46  * @{
47  **********************************************************************************************************************/
48 
49 /*******************************************************************************************************************//**
50  *        Enable register protection. Registers that are protected cannot be written to. Register protection is
51  *          enabled by using the Protect Register (PRCR) and the MPC's Write-Protect Register (PWPR).
52  *
53  * @param[in] regs_to_protect Registers which have write protection enabled.
54  **********************************************************************************************************************/
R_BSP_RegisterProtectEnable(bsp_reg_protect_t regs_to_protect)55 BSP_SECTION_FLASH_GAP void R_BSP_RegisterProtectEnable (bsp_reg_protect_t regs_to_protect)
56 {
57     /** Get/save the current state of interrupts */
58     FSP_CRITICAL_SECTION_DEFINE;
59     FSP_CRITICAL_SECTION_ENTER;
60 
61     /* Is it safe to disable write access? */
62     if (0U != g_protect_counters[regs_to_protect])
63     {
64         /* Decrement the protect counter */
65         g_protect_counters[regs_to_protect]--;
66     }
67 
68     /* Is it safe to disable write access? */
69     if (0U == g_protect_counters[regs_to_protect])
70     {
71         /** Enable protection using PRCR register.
72          *
73          * When writing to the PRCR register the upper 8-bits must be the correct key. Set lower bits to 0 to
74          * disable writes. */
75 #if BSP_TZ_NONSECURE_BUILD && BSP_FEATURE_TZ_VERSION == 2
76         R_SYSTEM->PRCR_NS = ((R_SYSTEM->PRCR_NS | BSP_PRV_PRCR_KEY) & (uint16_t) (~g_prcr_masks[regs_to_protect]));
77 #else
78         R_SYSTEM->PRCR = ((R_SYSTEM->PRCR | BSP_PRV_PRCR_KEY) & (uint16_t) (~g_prcr_masks[regs_to_protect]));
79 #endif
80     }
81 
82     /** Restore the interrupt state */
83     FSP_CRITICAL_SECTION_EXIT;
84 }
85 
86 /*******************************************************************************************************************//**
87  *        Disable register protection. Registers that are protected cannot be written to. Register protection is
88  *          disabled by using the Protect Register (PRCR) and the MPC's Write-Protect Register (PWPR).
89  *
90  * @param[in] regs_to_unprotect Registers which have write protection disabled.
91  **********************************************************************************************************************/
R_BSP_RegisterProtectDisable(bsp_reg_protect_t regs_to_unprotect)92 BSP_SECTION_FLASH_GAP void R_BSP_RegisterProtectDisable (bsp_reg_protect_t regs_to_unprotect)
93 {
94     /** Get/save the current state of interrupts */
95     FSP_CRITICAL_SECTION_DEFINE;
96     FSP_CRITICAL_SECTION_ENTER;
97 
98     /* If this is first entry then disable protection. */
99     if (0U == g_protect_counters[regs_to_unprotect])
100     {
101         /** Disable protection using PRCR register.
102          *
103          * When writing to the PRCR register the upper 8-bits must be the correct key. Set lower bits to 0 to
104          * disable writes. */
105 #if BSP_TZ_NONSECURE_BUILD && BSP_FEATURE_TZ_VERSION == 2
106         R_SYSTEM->PRCR_NS = ((R_SYSTEM->PRCR_NS | BSP_PRV_PRCR_KEY) | g_prcr_masks[regs_to_unprotect]);
107 #else
108         R_SYSTEM->PRCR = ((R_SYSTEM->PRCR | BSP_PRV_PRCR_KEY) | g_prcr_masks[regs_to_unprotect]);
109 #endif
110     }
111 
112     /** Increment the protect counter */
113     g_protect_counters[regs_to_unprotect]++;
114 
115     /** Restore the interrupt state */
116     FSP_CRITICAL_SECTION_EXIT;
117 }
118 
119 /** @} (end addtogroup BSP_MCU) */
120