![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466
Diff: mbed-os/targets/TARGET_NUVOTON/TARGET_M2351/device/stddriver_secure.c
- Revision:
- 0:8fdf9a60065b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os/targets/TARGET_NUVOTON/TARGET_M2351/device/stddriver_secure.c Wed Oct 10 00:33:53 2018 +0000 @@ -0,0 +1,254 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017-2018 Nuvoton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <arm_cmse.h> +#include <stdbool.h> +#include "cmsis.h" +#include "partition_M2351.h" +#include "stddriver_secure.h" +#include "mbed_error.h" + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +typedef struct nu_modidx_ns_s { + uint32_t sys_modidx; // Module index defined in SYS + uint32_t clk_modidx; // Module index defined in CLK + uint32_t ns; // 0: secure or undefined, 1: non-secure +} nu_modidx_ns_t; + +/* Placeholder for module index not defined + * + * Not all modules have corresponding SYS/CLK module index. + * Check sys.h/clk.h under StdDriver for non-used value to mean 'NONE'. + */ +#define NU_SYS_MODIDX_UNDEF 0xFFFFFFFFUL +#define NU_CLK_MODIDX_UNDEF 0xFFFFFFFFUL + +/* Table which records security state of module based on partition file. + * + * Some secure modules are not listed here for saving memory: + * 1. Modules are hard-wired to secure. + * 2. Modules belonging to the same PNSSET register are all secure. + * + * check_mod_ns must filter out 'NONE' module index to avoid security issue. + */ +static const nu_modidx_ns_t modidx_ns_tab[] = { + +#if defined(SCU_INIT_PNSSET0_VAL) && SCU_INIT_PNSSET0_VAL + {USBH_RST, USBH_MODULE, SCU_INIT_PNSSET0_VAL & (1 << 9)}, + {SDH0_RST, SDH0_MODULE, SCU_INIT_PNSSET0_VAL & (1 << 13)}, + {NU_SYS_MODIDX_UNDEF, NU_CLK_MODIDX_UNDEF, SCU_INIT_PNSSET0_VAL & (1 << 14)}, + {EBI_RST, EBI_MODULE, SCU_INIT_PNSSET0_VAL & (1 << 16)}, + {PDMA1_RST, PDMA1_MODULE, SCU_INIT_PNSSET0_VAL & (1 << 24)}, +#endif + +#if defined(SCU_INIT_PNSSET1_VAL) && SCU_INIT_PNSSET1_VAL + {CRC_RST, CRC_MODULE, SCU_INIT_PNSSET1_VAL & (1 << 17)}, + {CRPT_RST, CRPT_MODULE, SCU_INIT_PNSSET1_VAL & (1 << 18)}, +#endif + +#if defined(SCU_INIT_PNSSET2_VAL) && SCU_INIT_PNSSET2_VAL + {NU_SYS_MODIDX_UNDEF, RTC_MODULE, SCU_INIT_PNSSET2_VAL & (1 << 1)}, + {EADC_RST, EADC_MODULE, SCU_INIT_PNSSET2_VAL & (1 << 3)}, + {ACMP01_RST, ACMP01_MODULE, SCU_INIT_PNSSET2_VAL & (1 << 5)}, + {NU_SYS_MODIDX_UNDEF, NU_CLK_MODIDX_UNDEF, SCU_INIT_PNSSET2_VAL & (1 << 6)}, + {DAC_RST, DAC_MODULE, SCU_INIT_PNSSET2_VAL & (1 << 7)}, + {I2S0_RST, I2S0_MODULE, SCU_INIT_PNSSET2_VAL & (1 << 8)}, + {OTG_RST, OTG_MODULE, SCU_INIT_PNSSET2_VAL & (1 << 13)}, + {TMR2_RST, TMR2_MODULE, SCU_INIT_PNSSET2_VAL & (1 << 17)}, + {TMR3_RST, TMR3_MODULE, SCU_INIT_PNSSET2_VAL & (1 << 17)}, + {EPWM0_RST, EPWM0_MODULE, SCU_INIT_PNSSET2_VAL & (1 << 24)}, + {EPWM1_RST, EPWM1_MODULE, SCU_INIT_PNSSET2_VAL & (1 << 25)}, + {BPWM0_RST, BPWM0_MODULE, SCU_INIT_PNSSET2_VAL & (1 << 26)}, + {BPWM1_RST, BPWM1_MODULE, SCU_INIT_PNSSET2_VAL & (1 << 27)}, +#endif + +#if defined(SCU_INIT_PNSSET3_VAL) && SCU_INIT_PNSSET3_VAL + {SPI0_RST, SPI0_MODULE, SCU_INIT_PNSSET3_VAL & (1 << 0)}, + {SPI1_RST, SPI1_MODULE, SCU_INIT_PNSSET3_VAL & (1 << 1)}, + {SPI2_RST, SPI1_MODULE, SCU_INIT_PNSSET3_VAL & (1 << 2)}, + {SPI3_RST, SPI3_MODULE, SCU_INIT_PNSSET3_VAL & (1 << 3)}, + {NU_SYS_MODIDX_UNDEF, NU_CLK_MODIDX_UNDEF, SCU_INIT_PNSSET3_VAL & (1 << 4)}, + {SPI5_RST, SPI5_MODULE, SCU_INIT_PNSSET3_VAL & (1 << 5)}, + {UART0_RST, UART0_MODULE, SCU_INIT_PNSSET3_VAL & (1 << 16)}, + {UART1_RST, UART1_MODULE, SCU_INIT_PNSSET3_VAL & (1 << 17)}, + {UART2_RST, UART2_MODULE, SCU_INIT_PNSSET3_VAL & (1 << 18)}, + {UART3_RST, UART3_MODULE, SCU_INIT_PNSSET3_VAL & (1 << 19)}, + {UART4_RST, UART4_MODULE, SCU_INIT_PNSSET3_VAL & (1 << 20)}, + {UART5_RST, UART5_MODULE, SCU_INIT_PNSSET3_VAL & (1 << 21)}, +#endif + +#if defined(SCU_INIT_PNSSET4_VAL) && SCU_INIT_PNSSET4_VAL + {I2C0_RST, I2C0_MODULE, SCU_INIT_PNSSET4_VAL & (1 << 0)}, + {I2C1_RST, I2C1_MODULE, SCU_INIT_PNSSET4_VAL & (1 << 1)}, + {I2C2_RST, I2C2_MODULE, SCU_INIT_PNSSET4_VAL & (1 << 2)}, + {SC0_RST, SC0_MODULE, SCU_INIT_PNSSET4_VAL & (1 << 16)}, + {SC1_RST, SC1_MODULE, SCU_INIT_PNSSET4_VAL & (1 << 17)}, + {SC2_RST, SC2_MODULE, SCU_INIT_PNSSET4_VAL & (1 << 18)}, +#endif + +#if defined(SCU_INIT_PNSSET5_VAL) && SCU_INIT_PNSSET5_VAL + {CAN0_RST, CAN0_MODULE, SCU_INIT_PNSSET5_VAL & (1 << 0)}, + {QEI0_RST, QEI0_MODULE, SCU_INIT_PNSSET5_VAL & (1 << 16)}, + {QEI1_RST, QEI1_MODULE, SCU_INIT_PNSSET5_VAL & (1 << 17)}, + {ECAP0_RST, ECAP0_MODULE, SCU_INIT_PNSSET5_VAL & (1 << 20)}, + {ECAP1_RST, ECAP1_MODULE, SCU_INIT_PNSSET5_VAL & (1 << 21)}, + {DSRC_RST, DSRC_MODULE, SCU_INIT_PNSSET5_VAL & (1 << 23)}, + {NU_SYS_MODIDX_UNDEF, NU_CLK_MODIDX_UNDEF, SCU_INIT_PNSSET5_VAL & (1 << 24)}, + {TRNG_RST, TRNG_MODULE, SCU_INIT_PNSSET5_VAL & (1 << 25)}, +#endif + +#if defined(SCU_INIT_PNSSET6_VAL) && SCU_INIT_PNSSET6_VAL + {USBD_RST, USBD_MODULE, SCU_INIT_PNSSET6_VAL & (1 << 0)}, + {USCI0_RST, USCI0_MODULE, SCU_INIT_PNSSET6_VAL & (1 << 16)}, + {USCI1_RST, USCI1_MODULE, SCU_INIT_PNSSET6_VAL & (1 << 17)}, +#endif + +}; + +#define NU_MODCLASS_SYS 0 +#define NU_MODCLASS_CLK 1 + +/* Check if specified module is non-secure + * + * \param modclass Module class (NU_MODCLASS_SYS/NU_MODCLASS_CLK) + * \param modidx Module index + * + * \return 0 if not non-secure (secure or undefined), or 1 if non-secure + * + * \note Undefined module index is treated as not non-secure. + */ +static bool check_mod_ns(int modclass, uint32_t modidx); + +__NONSECURE_ENTRY +void SYS_ResetModule_S(uint32_t u32ModuleIndex) +{ + /* Guard access to secure module from non-secure domain */ + if (cmse_nonsecure_caller() && + (! check_mod_ns(NU_MODCLASS_SYS, u32ModuleIndex))) { + error("Non-secure domain tries to control secure or undefined module."); + } + + SYS_ResetModule(u32ModuleIndex); +} + +__NONSECURE_ENTRY +void CLK_SetModuleClock_S(uint32_t u32ModuleIndex, uint32_t u32ClkSrc, uint32_t u32ClkDiv) +{ + /* Guard access to secure module from non-secure domain */ + if (cmse_nonsecure_caller() && + (! check_mod_ns(NU_MODCLASS_CLK, u32ModuleIndex))) { + error("Non-secure domain tries to control secure or undefined module."); + } + + CLK_SetModuleClock(u32ModuleIndex, u32ClkSrc, u32ClkDiv); +} + +__NONSECURE_ENTRY +void CLK_EnableModuleClock_S(uint32_t u32ModuleIndex) +{ + /* Guard access to secure module from non-secure domain */ + if (cmse_nonsecure_caller() && + (! check_mod_ns(NU_MODCLASS_CLK, u32ModuleIndex))) { + error("Non-secure domain tries to control secure or undefined module."); + } + + CLK_EnableModuleClock(u32ModuleIndex); +} + +__NONSECURE_ENTRY +void CLK_DisableModuleClock_S(uint32_t u32ModuleIndex) +{ + /* Guard access to secure module from non-secure domain */ + if (cmse_nonsecure_caller() && + (! check_mod_ns(NU_MODCLASS_CLK, u32ModuleIndex))) { + error("Non-secure domain tries to control secure or undefined module."); + } + + CLK_DisableModuleClock(u32ModuleIndex); +} + +__NONSECURE_ENTRY +void SYS_LockReg_S(void) +{ + /* Allow non-secure domain to lock/unlock locked registers without check. + * Guard access to locked registers is done through other related secure functions. */ + SYS_LockReg(); +} + +__NONSECURE_ENTRY +void SYS_UnlockReg_S(void) +{ + /* Allow non-secure domain to lock/unlock locked registers without check. + * Guard access to locked registers is done through other related secure functions. */ + SYS_UnlockReg(); +} + +__NONSECURE_ENTRY +void CLK_Idle_S(void) +{ + CLK_Idle(); +} + +__NONSECURE_ENTRY +void CLK_PowerDown_S(void) +{ + CLK_PowerDown(); +} + +static bool check_mod_ns(int modclass, uint32_t modidx) +{ + const nu_modidx_ns_t *modidx_ns = modidx_ns_tab; + const nu_modidx_ns_t *modidx_ns_end = modidx_ns_tab + sizeof (modidx_ns_tab) / sizeof (modidx_ns_tab[0]); + + if (modclass == NU_MODCLASS_SYS) { + /* The modidx_ns_tab table has 'NONE' module index. + * We must filter it out to avoid security issue. */ + if (modidx == NU_SYS_MODIDX_UNDEF) { + return false; + } + + for (; modidx_ns != modidx_ns_end; modidx_ns ++) { + if (modidx == modidx_ns->sys_modidx) { + if (modidx_ns->ns) { + return true; + } else { + return false; + } + } + } + } else if (modclass == NU_MODCLASS_CLK) { + /* The modidx_ns_tab table has 'NONE' module index. + * We must filter it out to avoid security issue. */ + if (modidx == NU_CLK_MODIDX_UNDEF) { + return false; + } + + for (; modidx_ns != modidx_ns_end; modidx_ns ++) { + if (modidx == modidx_ns->clk_modidx) { + if (modidx_ns->ns) { + return true; + } else { + return false; + } + } + } + } + + return false; +} + +#endif