1 /***********************************************************************************************************************
2  * Copyright [2020-2023] Renesas Electronics Corporation and/or its affiliates.  All Rights Reserved.
3  *
4  * This software and documentation are supplied by Renesas Electronics America Inc. and may only be used with products
5  * of Renesas Electronics Corp. and its affiliates ("Renesas").  No other uses are authorized.  Renesas products are
6  * sold pursuant to Renesas terms and conditions of sale.  Purchasers are solely responsible for the selection and use
7  * of Renesas products and Renesas assumes no liability.  No license, express or implied, to any intellectual property
8  * right is granted by Renesas. This software is protected under all applicable laws, including copyright laws. Renesas
9  * reserves the right to change or discontinue this software and/or this documentation. THE SOFTWARE AND DOCUMENTATION
10  * IS DELIVERED TO YOU "AS IS," AND RENESAS MAKES NO REPRESENTATIONS OR WARRANTIES, AND TO THE FULLEST EXTENT
11  * PERMISSIBLE UNDER APPLICABLE LAW, DISCLAIMS ALL WARRANTIES, WHETHER EXPLICITLY OR IMPLICITLY, INCLUDING WARRANTIES
12  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT, WITH RESPECT TO THE SOFTWARE OR
13  * DOCUMENTATION.  RENESAS SHALL HAVE NO LIABILITY ARISING OUT OF ANY SECURITY VULNERABILITY OR BREACH.  TO THE MAXIMUM
14  * EXTENT PERMITTED BY LAW, IN NO EVENT WILL RENESAS BE LIABLE TO YOU IN CONNECTION WITH THE SOFTWARE OR DOCUMENTATION
15  * (OR ANY PERSON OR ENTITY CLAIMING RIGHTS DERIVED FROM YOU) FOR ANY LOSS, DAMAGES, OR CLAIMS WHATSOEVER, INCLUDING,
16  * WITHOUT LIMITATION, ANY DIRECT, CONSEQUENTIAL, SPECIAL, INDIRECT, PUNITIVE, OR INCIDENTAL DAMAGES; ANY LOST PROFITS,
17  * OTHER ECONOMIC DAMAGE, PROPERTY DAMAGE, OR PERSONAL INJURY; AND EVEN IF RENESAS HAS BEEN ADVISED OF THE POSSIBILITY
18  * OF SUCH LOSS, DAMAGES, CLAIMS OR COSTS.
19  **********************************************************************************************************************/
20 
21 /***********************************************************************************************************************
22  *
23  * Includes
24  **********************************************************************************************************************/
25 #include "bsp_api.h"
26 
27 /***********************************************************************************************************************
28  * Macro definitions
29  **********************************************************************************************************************/
30 #if defined(__ICCARM__)
31  #define WEAK_ERROR_ATTRIBUTE
32  #define WEAK_INIT_ATTRIBUTE
33  #pragma weak fsp_error_log                            = fsp_error_log_internal
34  #pragma weak bsp_init                                 = bsp_init_internal
35 #elif defined(__GNUC__)
36 
37  #define WEAK_ERROR_ATTRIBUTE    __attribute__((weak, alias("fsp_error_log_internal")))
38 
39  #define WEAK_INIT_ATTRIBUTE     __attribute__((weak, alias("bsp_init_internal")))
40 #endif
41 
42 #define FSP_SECTION_VERSION      ".version"
43 
44 /***********************************************************************************************************************
45  * Typedef definitions
46  **********************************************************************************************************************/
47 
48 /***********************************************************************************************************************
49  * Private function prototypes
50  **********************************************************************************************************************/
51 
52 /** Prototype of initialization function called before main.  This prototype sets the weak association of this
53  * function to an internal example implementation. If this function is defined in the application code, the
54  * application code version is used. */
55 
56 void bsp_init(void * p_args) WEAK_INIT_ATTRIBUTE;
57 
58 void bsp_init_internal(void * p_args); /// Default initialization function
59 
60 #if ((1 == BSP_CFG_ERROR_LOG) || (1 == BSP_CFG_ASSERT))
61 
62 /** Prototype of function called before errors are returned in FSP code if BSP_CFG_ERROR_LOG is set to 1.  This
63  * prototype sets the weak association of this function to an internal example implementation. */
64 
65 void fsp_error_log(fsp_err_t err, const char * file, int32_t line) WEAK_ERROR_ATTRIBUTE;
66 
67 void fsp_error_log_internal(fsp_err_t err, const char * file, int32_t line); /// Default error logger function
68 
69 #endif
70 #if BSP_FEATURE_TZ_VERSION == 2 && BSP_TZ_SECURE_BUILD == 1
71 static bool bsp_valid_register_check(uint32_t               register_address,
72                                      uint32_t const * const p_register_table,
73                                      uint32_t               register_table_length);
74 
75 #endif
76 
77 /***********************************************************************************************************************
78  * Exported global variables (to be accessed by other files)
79  **********************************************************************************************************************/
80 
81 /* FSP pack version structure. */
82 static BSP_DONT_REMOVE const fsp_pack_version_t g_fsp_version BSP_PLACE_IN_SECTION (FSP_SECTION_VERSION) =
83 {
84     .version_id_b =
85     {
86         .minor = FSP_VERSION_MINOR,
87         .major = FSP_VERSION_MAJOR,
88         .build = FSP_VERSION_BUILD,
89         .patch = FSP_VERSION_PATCH
90     }
91 };
92 
93 /* Public FSP version name. */
94 static BSP_DONT_REMOVE const uint8_t g_fsp_version_string[] BSP_PLACE_IN_SECTION(FSP_SECTION_VERSION) =
95     FSP_VERSION_STRING;
96 
97 /* Unique FSP version ID. */
98 static BSP_DONT_REMOVE const uint8_t g_fsp_version_build_string[] BSP_PLACE_IN_SECTION(FSP_SECTION_VERSION) =
99     FSP_VERSION_BUILD_STRING;
100 
101 /*******************************************************************************************************************//**
102  * @addtogroup BSP_MCU
103  * @{
104  **********************************************************************************************************************/
105 
106 /***********************************************************************************************************************
107  * Private global variables and functions
108  **********************************************************************************************************************/
109 
110 /*******************************************************************************************************************//**
111  * Get the FSP version based on compile time macros.
112  *
113  * @param[out] p_version        Memory address to return version information to.
114  *
115  * @retval FSP_SUCCESS          Version information stored.
116  * @retval FSP_ERR_ASSERTION    The parameter p_version is NULL.
117  **********************************************************************************************************************/
R_FSP_VersionGet(fsp_pack_version_t * const p_version)118 fsp_err_t R_FSP_VersionGet (fsp_pack_version_t * const p_version)
119 {
120 #if BSP_CFG_PARAM_CHECKING_ENABLE
121 
122     /** Verify parameters are valid */
123     FSP_ASSERT(NULL != p_version);
124 #endif
125 
126     *p_version = g_fsp_version;
127 
128     return FSP_SUCCESS;
129 }
130 
131 #if ((1 == BSP_CFG_ERROR_LOG) || (1 == BSP_CFG_ASSERT))
132 
133 /*******************************************************************************************************************//**
134  * Default error logger function, used only if fsp_error_log is not defined in the user application.
135  *
136  * @param[in]  err     The error code encountered.
137  * @param[in]  file    The file name in which the error code was encountered.
138  * @param[in]  line    The line number at which the error code was encountered.
139  **********************************************************************************************************************/
fsp_error_log_internal(fsp_err_t err,const char * file,int32_t line)140 void fsp_error_log_internal (fsp_err_t err, const char * file, int32_t line)
141 {
142     /** Do nothing. Do not generate any 'unused' warnings. */
143     FSP_PARAMETER_NOT_USED(err);
144     FSP_PARAMETER_NOT_USED(file);
145     FSP_PARAMETER_NOT_USED(line);
146 }
147 
148 #endif
149 
150 #if BSP_FEATURE_TZ_VERSION == 2 && BSP_TZ_SECURE_BUILD == 1
151 
152 /*******************************************************************************************************************//**
153  * Read a secure 8-bit STYPE3 register in the non-secure state.
154  *
155  * @param[in]  p_reg The address of the secure register.
156  *
157  * @return     Value read from the register.
158  **********************************************************************************************************************/
R_BSP_NSC_STYPE3_RegU8Read(uint8_t volatile const * p_reg)159 BSP_CMSE_NONSECURE_ENTRY uint8_t R_BSP_NSC_STYPE3_RegU8Read (uint8_t volatile const * p_reg)
160 {
161     uint8_t volatile * p_reg_s = (uint8_t volatile *) ((uint32_t) p_reg & ~BSP_FEATURE_TZ_NS_OFFSET);
162 
163     /* Table of secure registers that may be read from the non-secure application. */
164     static const uint32_t valid_addresses[] =
165     {
166         (uint32_t) &R_SYSTEM->SCKDIVCR2,
167         (uint32_t) &R_SYSTEM->SCKSCR,
168         (uint32_t) &R_SYSTEM->SPICKDIVCR,
169         (uint32_t) &R_SYSTEM->SPICKCR,
170         (uint32_t) &R_SYSTEM->SCICKDIVCR,
171         (uint32_t) &R_SYSTEM->SCICKCR,
172         (uint32_t) &R_SYSTEM->CANFDCKCR,
173         (uint32_t) &R_SYSTEM->PLLCR,
174         (uint32_t) &R_SYSTEM->PLL2CR,
175         (uint32_t) &R_SYSTEM->MOCOCR,
176         (uint32_t) &R_SYSTEM->OPCCR,
177     };
178 
179     if (bsp_valid_register_check((uint32_t) p_reg_s, valid_addresses,
180                                  sizeof(valid_addresses) / sizeof(valid_addresses[0])))
181     {
182         return *p_reg_s;
183     }
184 
185     /* Generate a trustzone access violation by accessing the non-secure aliased address. */
186     return *((uint8_t volatile *) ((uint32_t) p_reg | BSP_FEATURE_TZ_NS_OFFSET));
187 }
188 
189 /*******************************************************************************************************************//**
190  * Read a secure 16-bit STYPE3 register in the non-secure state.
191  *
192  * @param[in]  p_reg The address of the secure register.
193  *
194  * @return     Value read from the register.
195  **********************************************************************************************************************/
R_BSP_NSC_STYPE3_RegU16Read(uint16_t volatile const * p_reg)196 BSP_CMSE_NONSECURE_ENTRY uint16_t R_BSP_NSC_STYPE3_RegU16Read (uint16_t volatile const * p_reg)
197 {
198     uint16_t volatile * p_reg_s = (uint16_t volatile *) ((uint32_t) p_reg & ~BSP_FEATURE_TZ_NS_OFFSET);
199 
200     /* Table of secure registers that may be read from the non-secure application. */
201     static const uint32_t valid_addresses[] =
202     {
203         (uint32_t) &R_DTC->DTCSTS,
204     };
205 
206     if (bsp_valid_register_check((uint32_t) p_reg_s, valid_addresses,
207                                  sizeof(valid_addresses) / sizeof(valid_addresses[0])))
208     {
209         return *p_reg_s;
210     }
211 
212     /* Generate a trustzone access violation by accessing the non-secure aliased address. */
213     return *((uint16_t volatile *) ((uint32_t) p_reg | BSP_FEATURE_TZ_NS_OFFSET));
214 }
215 
216 /*******************************************************************************************************************//**
217  * Read a secure 32-bit STYPE3 register in the non-secure state.
218  *
219  * @param[in]  p_reg The address of the secure register.
220  *
221  * @return     Value read from the register.
222  **********************************************************************************************************************/
R_BSP_NSC_STYPE3_RegU32Read(uint32_t volatile const * p_reg)223 BSP_CMSE_NONSECURE_ENTRY uint32_t R_BSP_NSC_STYPE3_RegU32Read (uint32_t volatile const * p_reg)
224 {
225     uint32_t volatile * p_reg_s = (uint32_t volatile *) ((uint32_t) p_reg & ~BSP_FEATURE_TZ_NS_OFFSET);
226 
227     /* Table of secure registers that may be read from the non-secure application. */
228     static const uint32_t valid_addresses[] =
229     {
230         (uint32_t) &R_SYSTEM->SCKDIVCR,
231     };
232 
233     if (bsp_valid_register_check((uint32_t) p_reg_s, valid_addresses,
234                                  sizeof(valid_addresses) / sizeof(valid_addresses[0])))
235     {
236         return *p_reg_s;
237     }
238 
239     /* Generate a trustzone access violation by accessing the non-secure aliased address. */
240     return *((uint32_t volatile *) ((uint32_t) p_reg | BSP_FEATURE_TZ_NS_OFFSET));
241 }
242 
243 #endif
244 
245 /** @} (end addtogroup BSP_MCU) */
246 
247 /*******************************************************************************************************************//**
248  * Default initialization function, used only if bsp_init is not defined in the user application.
249  **********************************************************************************************************************/
bsp_init_internal(void * p_args)250 void bsp_init_internal (void * p_args)
251 {
252     /* Do nothing. */
253     FSP_PARAMETER_NOT_USED(p_args);
254 }
255 
256 #if defined(__ARMCC_VERSION)
257 
258 /*******************************************************************************************************************//**
259  * Default implementation of assert for AC6.
260  **********************************************************************************************************************/
261 __attribute__((weak, noreturn))
__aeabi_assert(const char * expr,const char * file,int line)262 void __aeabi_assert (const char * expr, const char * file, int line)
263 {
264     FSP_PARAMETER_NOT_USED(expr);
265     FSP_PARAMETER_NOT_USED(file);
266     FSP_PARAMETER_NOT_USED(line);
267     __BKPT(0);
268     while (1)
269     {
270         /* Do nothing. */
271     }
272 }
273 
274 #elif defined(__GNUC__)
275 
276 /* The default assert implementation for GCC brings in printing/formatting code.  FSP overrides the default assert
277  * behavior to reduce code size. */
278 
279  #if !BSP_CFG_USE_STANDARD_ASSERT
280 
281 /*******************************************************************************************************************//**
282  * Default implementation of assert for GCC.
283  **********************************************************************************************************************/
__assert_func(const char * file,int line,const char * func,const char * expr)284 BSP_WEAK_REFERENCE void __assert_func (const char * file, int line, const char * func, const char * expr)
285 {
286     FSP_PARAMETER_NOT_USED(file);
287     FSP_PARAMETER_NOT_USED(line);
288     FSP_PARAMETER_NOT_USED(func);
289     FSP_PARAMETER_NOT_USED(expr);
290     __BKPT(0);
291     while (1)
292     {
293         /* Do nothing. */
294     }
295 }
296 
297  #endif
298 
299 #endif
300 
301 #if BSP_FEATURE_TZ_VERSION == 2 && BSP_TZ_SECURE_BUILD == 1
302 
303 /*******************************************************************************************************************//**
304  * Check if a register address should be accessible by the non-secure application.
305  **********************************************************************************************************************/
bsp_valid_register_check(uint32_t register_address,uint32_t const * const p_register_table,uint32_t register_table_length)306 static bool bsp_valid_register_check (uint32_t               register_address,
307                                       uint32_t const * const p_register_table,
308                                       uint32_t               register_table_length)
309 {
310     bool valid = false;
311 
312     /* Check if the given address is valid. */
313     for (uint32_t i = 0; i < register_table_length; i++)
314     {
315         if (p_register_table[i] == register_address)
316         {
317             valid = true;
318             break;
319         }
320     }
321 
322     return valid;
323 }
324 
325 #endif
326