|
26 | 26 | #include "partition_M2351.h"
|
27 | 27 | #include "hal_secure.h"
|
28 | 28 |
|
29 |
| -/* NOTE: BSP RTC driver judges secure/non-secure RTC by PC. This implementation cannot support non-secure RTC |
30 |
| - * controlled by secure executable. A better way would be that secure/non-secure RTC base is passed |
31 |
| - * to RTC API as an argument like most other APIs. With BSP RTC driver unchanged, we must enforce |
32 |
| - * secure RTC. */ |
| 29 | +/* Secure attribution of RTC |
| 30 | + * |
| 31 | + * We need RTC to be secure for security concern. |
| 32 | + * |
| 33 | + * On M2351, configured to secure |
| 34 | + * On M2354, hard-wired to secure |
| 35 | + */ |
33 | 36 | #if defined(SCU_INIT_PNSSET2_VAL) && (SCU_INIT_PNSSET2_VAL & (1 << 1))
|
34 | 37 | #error("Limited by BSP/RTC, we can only support secure RTC.")
|
35 | 38 | #endif
|
@@ -67,7 +70,7 @@ void rtc_write(time_t t)
|
67 | 70 | *
|
68 | 71 | * NOTE: This dependents on real hardware.
|
69 | 72 | */
|
70 |
| -#define NU_RTCCLK_PER_SEC ((CLK->CLKSEL3 & CLK_CLKSEL3_SC0SEL_Msk) ? __LIRC : __LXT) |
| 73 | +#define NU_RTCCLK_PER_SEC (__LXT) |
71 | 74 |
|
72 | 75 | /* Strategy for implementation of RTC HAL
|
73 | 76 | *
|
@@ -121,52 +124,53 @@ static time_t t_write = 0;
|
121 | 124 | /* Convert date time from H/W RTC to struct TM */
|
122 | 125 | static void rtc_convert_datetime_hwrtc_to_tm(struct tm *datetime_tm, const S_RTC_TIME_DATA_T *datetime_hwrtc);
|
123 | 126 |
|
124 |
| -static const struct nu_modinit_s rtc_modinit = {RTC_0, RTC_MODULE, 0, 0, 0, RTC_IRQn, NULL}; |
| 127 | +static const struct nu_modinit_s rtc_modinit = {RTC_0, RTC_MODULE, CLK_CLKSEL3_RTCSEL_LXT, 0, 0, RTC_IRQn, NULL}; |
125 | 128 |
|
126 |
| -__NONSECURE_ENTRY |
127 |
| -void rtc_init_s(void) |
| 129 | +static void rtc_init_impl(void); |
| 130 | +static void rtc_free_impl(void); |
| 131 | +static int32_t rtc_isenabled_impl(void); |
| 132 | +static int64_t rtc_read_impl(void); |
| 133 | +static void rtc_write_impl(int64_t t); |
| 134 | + |
| 135 | +static void rtc_init_impl(void) |
128 | 136 | {
|
129 |
| - if (rtc_isenabled()) { |
| 137 | + if (rtc_isenabled_impl()) { |
130 | 138 | return;
|
131 | 139 | }
|
132 | 140 |
|
133 | 141 | RTC_Open(NULL);
|
134 | 142 |
|
135 | 143 | /* POSIX time origin (00:00:00 UTC, Thursday, 1 January 1970) */
|
136 |
| - rtc_write(0); |
| 144 | + rtc_write_impl(0); |
137 | 145 | }
|
138 | 146 |
|
139 |
| -__NONSECURE_ENTRY |
140 |
| -void rtc_free_s(void) |
| 147 | +static void rtc_free_impl(void) |
141 | 148 | {
|
142 | 149 | CLK_DisableModuleClock_S(rtc_modinit.clkidx);
|
143 | 150 | }
|
144 | 151 |
|
145 |
| -__NONSECURE_ENTRY |
146 |
| -int32_t rtc_isenabled_s(void) |
| 152 | +static int32_t rtc_isenabled_impl(void) |
147 | 153 | {
|
148 |
| - // NOTE: To access (RTC) registers, clock must be enabled first. |
149 |
| - if (! (CLK->APBCLK0 & CLK_APBCLK0_RTCCKEN_Msk)) { |
150 |
| - // Enable IP clock |
151 |
| - CLK_EnableModuleClock_S(rtc_modinit.clkidx); |
152 |
| - } |
| 154 | + // To access (RTC) registers, clock must be enabled first. |
| 155 | + // For TZ, with RTC being secure, we needn't call the secure gateway versions. |
| 156 | + CLK_EnableModuleClock(rtc_modinit.clkidx); |
| 157 | + CLK_SetModuleClock(rtc_modinit.clkidx, rtc_modinit.clksrc, rtc_modinit.clkdiv); |
153 | 158 |
|
154 | 159 | RTC_T *rtc_base = (RTC_T *) NU_MODBASE(rtc_modinit.modname);
|
155 | 160 |
|
156 | 161 | // NOTE: Check RTC Init Active flag to support crossing reset cycle.
|
157 | 162 | return !! (rtc_base->INIT & RTC_INIT_ACTIVE_Msk);
|
158 | 163 | }
|
159 | 164 |
|
160 |
| -__NONSECURE_ENTRY |
161 |
| -int64_t rtc_read_s(void) |
| 165 | +static int64_t rtc_read_impl(void) |
162 | 166 | {
|
163 | 167 | /* NOTE: After boot, RTC time registers are not synced immediately, about 1 sec latency.
|
164 | 168 | * RTC time got (through RTC_GetDateAndTime()) in this sec would be last-synced and incorrect.
|
165 | 169 | * NUC472/M453: Known issue
|
166 | 170 | * M487: Fixed
|
167 | 171 | */
|
168 |
| - if (! rtc_isenabled()) { |
169 |
| - rtc_init(); |
| 172 | + if (! rtc_isenabled_impl()) { |
| 173 | + rtc_init_impl(); |
170 | 174 | }
|
171 | 175 |
|
172 | 176 | /* Used for intermediary between date time of H/W RTC and POSIX time */
|
@@ -206,11 +210,10 @@ int64_t rtc_read_s(void)
|
206 | 210 | return t_present;
|
207 | 211 | }
|
208 | 212 |
|
209 |
| -__NONSECURE_ENTRY |
210 |
| -void rtc_write_s(int64_t t) |
| 213 | +static void rtc_write_impl(int64_t t) |
211 | 214 | {
|
212 |
| - if (! rtc_isenabled()) { |
213 |
| - rtc_init(); |
| 215 | + if (! rtc_isenabled_impl()) { |
| 216 | + rtc_init_impl(); |
214 | 217 | }
|
215 | 218 |
|
216 | 219 | t_write = t;
|
@@ -255,4 +258,39 @@ static void rtc_convert_datetime_hwrtc_to_tm(struct tm *datetime_tm, const S_RTC
|
255 | 258 | }
|
256 | 259 |
|
257 | 260 | #endif
|
| 261 | + |
| 262 | +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) |
| 263 | + |
| 264 | +__NONSECURE_ENTRY |
| 265 | +void rtc_init_s(void) |
| 266 | +{ |
| 267 | + rtc_init_impl(); |
| 268 | +} |
| 269 | + |
| 270 | +__NONSECURE_ENTRY |
| 271 | +void rtc_free_s(void) |
| 272 | +{ |
| 273 | + rtc_free_impl(); |
| 274 | +} |
| 275 | + |
| 276 | +__NONSECURE_ENTRY |
| 277 | +int32_t rtc_isenabled_s(void) |
| 278 | +{ |
| 279 | + return rtc_isenabled_impl(); |
| 280 | +} |
| 281 | + |
| 282 | +__NONSECURE_ENTRY |
| 283 | +int64_t rtc_read_s(void) |
| 284 | +{ |
| 285 | + return rtc_read_impl(); |
| 286 | +} |
| 287 | + |
| 288 | +__NONSECURE_ENTRY |
| 289 | +void rtc_write_s(int64_t t) |
| 290 | +{ |
| 291 | + rtc_write_impl(t); |
| 292 | +} |
| 293 | + |
| 294 | +#endif |
| 295 | + |
258 | 296 | #endif
|
0 commit comments