1 /*
2 * Copyright (c) 2019 Linaro Limited
3 * Copyright (c) 2020 STMicroelectronics
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #define LOG_DOMAIN flash_stm32wb
9 #define LOG_LEVEL CONFIG_FLASH_LOG_LEVEL
10 #include <zephyr/logging/log.h>
11 LOG_MODULE_REGISTER(LOG_DOMAIN);
12
13 #include <zephyr/kernel.h>
14 #include <zephyr/device.h>
15 #include <string.h>
16 #include <zephyr/drivers/flash.h>
17 #include <zephyr/init.h>
18 #include <soc.h>
19 #include <zephyr/sys/__assert.h>
20
21 #include "flash_stm32.h"
22 #include "stm32_hsem.h"
23 #if defined(CONFIG_BT)
24 #include "shci.h"
25 #endif
26
27 #define STM32WBX_PAGE_SHIFT 12
28
29 /*
30 * Up to 255 4K pages
31 */
get_page(off_t offset)32 static uint32_t get_page(off_t offset)
33 {
34 return offset >> STM32WBX_PAGE_SHIFT;
35 }
36
flush_cache(FLASH_TypeDef * regs)37 static inline void flush_cache(FLASH_TypeDef *regs)
38 {
39 if (regs->ACR & FLASH_ACR_DCEN) {
40 regs->ACR &= ~FLASH_ACR_DCEN;
41 /* Datasheet: DCRST: Data cache reset
42 * This bit can be written only when the data cache is disabled
43 */
44 regs->ACR |= FLASH_ACR_DCRST;
45 regs->ACR &= ~FLASH_ACR_DCRST;
46 regs->ACR |= FLASH_ACR_DCEN;
47 }
48
49 if (regs->ACR & FLASH_ACR_ICEN) {
50 regs->ACR &= ~FLASH_ACR_ICEN;
51 /* Datasheet: ICRST: Instruction cache reset :
52 * This bit can be written only when the instruction cache
53 * is disabled
54 */
55 regs->ACR |= FLASH_ACR_ICRST;
56 regs->ACR &= ~FLASH_ACR_ICRST;
57 regs->ACR |= FLASH_ACR_ICEN;
58 }
59 }
60
write_dword(const struct device * dev,off_t offset,uint64_t val)61 static int write_dword(const struct device *dev, off_t offset, uint64_t val)
62 {
63 volatile uint32_t *flash = (uint32_t *)(offset + FLASH_STM32_BASE_ADDRESS);
64 FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
65 uint32_t tmp;
66 int ret, rc;
67 uint32_t cpu1_sem_status;
68 uint32_t cpu2_sem_status = 0;
69 uint32_t key;
70
71 /* if the control register is locked, do not fail silently */
72 if (regs->CR & FLASH_CR_LOCK) {
73 return -EIO;
74 }
75
76 /* Check if this double word is erased and value isn't 0.
77 *
78 * It is allowed to write only zeros over an already written dword
79 * See 3.3.8 in reference manual.
80 */
81 if ((flash[0] != 0xFFFFFFFFUL ||
82 flash[1] != 0xFFFFFFFFUL) && val != 0UL) {
83 LOG_ERR("Word at offs %ld not erased", (long)offset);
84 return -EIO;
85 }
86
87 ret = flash_stm32_check_status(dev);
88 if (ret < 0) {
89 return -EIO;
90 }
91
92 /* Implementation of STM32 AN5289, proposed in STM32WB Cube Application
93 * BLE_RfWithFlash
94 * https://github.com/STMicroelectronics/STM32CubeWB/tree/master/Projects/P-NUCLEO-WB55.Nucleo/Applications/BLE/BLE_RfWithFlash
95 */
96
97 do {
98 /**
99 * When the PESD bit mechanism is used by CPU2 to protect its
100 * timing, the PESD bit should be polled here.
101 * If the PESD is set, the CPU1 will be stalled when reading
102 * literals from an ISR that may occur after the flash
103 * processing has been requested but suspended due to the PESD
104 * bit.
105 *
106 * Note: This code is required only when the PESD mechanism is
107 * used to protect the CPU2 timing.
108 * However, keeping that code make it compatible with both
109 * mechanisms.
110 */
111 while (LL_FLASH_IsActiveFlag_OperationSuspended()) {
112 ;
113 }
114
115 /* Enter critical section */
116 key = irq_lock();
117
118 /**
119 * Depending on the application implementation, in case a
120 * multitasking is possible with an OS, it should be checked
121 * here if another task in the application disallowed flash
122 * processing to protect some latency in critical code
123 * execution.
124 * When flash processing is ongoing, the CPU cannot access the
125 * flash anymore.Trying to access the flash during that time
126 * stalls the CPU.
127 * The only way for CPU1 to disallow flash processing is to
128 * take CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID.
129 */
130 cpu1_sem_status = LL_HSEM_GetStatus(HSEM,
131 CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID);
132 if (cpu1_sem_status == 0) {
133 /**
134 * Check now if the CPU2 disallows flash processing to
135 * protect its timing. If the semaphore is locked, the
136 * CPU2 does not allow flash processing
137 *
138 * Note: By default, the CPU2 uses the PESD mechanism
139 * to protect its timing, therefore, it is useless to
140 * get/release the semaphore.
141 *
142 * However, keeping that code make it compatible with
143 * both mechanisms.
144 * The protection by semaphore is enabled on CPU2 side
145 * with the command SHCI_C2_SetFlashActivityControl()
146 *
147 */
148 cpu2_sem_status = LL_HSEM_1StepLock(HSEM,
149 CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID);
150 if (cpu2_sem_status == 0) {
151 /**
152 * When CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID is
153 * taken, it is allowed to only write one
154 * single 64bits data.
155 * When several 64bits data need to be erased,
156 * the application shall first exit from the
157 * critical section and try again.
158 */
159 /* Set the PG bit */
160 regs->CR |= FLASH_CR_PG;
161
162 /* Flush the register write */
163 tmp = regs->CR;
164
165 /* Perform the data write operation at desired
166 * memory address
167 */
168 flash[0] = (uint32_t)val;
169 flash[1] = (uint32_t)(val >> 32);
170
171 /**
172 * Release the semaphore to give the
173 * opportunity to CPU2 to protect its timing
174 * versus the next flash operation by taking
175 * this semaphore.
176 * Note that the CPU2 is polling on this
177 * semaphore so CPU1 shall release it as fast
178 * as possible.
179 * This is why this code is protected by a
180 * critical section.
181 */
182 LL_HSEM_ReleaseLock(HSEM,
183 CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID,
184 0);
185 }
186 }
187
188 /* Exit critical section */
189 irq_unlock(key);
190
191 } while (cpu2_sem_status || cpu1_sem_status);
192
193 /* Wait until the BSY bit is cleared */
194 rc = flash_stm32_wait_flash_idle(dev);
195
196 /* Clear the PG bit */
197 regs->CR &= (~FLASH_CR_PG);
198
199 return rc;
200 }
201
erase_page(const struct device * dev,uint32_t page)202 static int erase_page(const struct device *dev, uint32_t page)
203 {
204 uint32_t cpu1_sem_status;
205 uint32_t cpu2_sem_status = 0;
206 uint32_t key;
207
208 FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
209 int rc;
210
211 /* if the control register is locked, do not fail silently */
212 if (regs->CR & FLASH_CR_LOCK) {
213 return -EIO;
214 }
215
216 /* Check that no Flash memory operation is ongoing */
217 rc = flash_stm32_wait_flash_idle(dev);
218 if (rc < 0) {
219 return rc;
220 }
221
222 /*
223 * If an erase operation in Flash memory also concerns data in the data
224 * or instruction cache, the user has to ensure that these data
225 * are rewritten before they are accessed during code execution.
226 */
227 flush_cache(regs);
228
229 /* Implementation of STM32 AN5289, proposed in STM32WB Cube Application
230 * BLE_RfWithFlash
231 * https://github.com/STMicroelectronics/STM32CubeWB/tree/master/Projects/P-NUCLEO-WB55.Nucleo/Applications/BLE/BLE_RfWithFlash
232 */
233
234 do {
235 /**
236 * When the PESD bit mechanism is used by CPU2 to protect its
237 * timing, the PESD bit should be polled here.
238 * If the PESD is set, the CPU1 will be stalled when reading
239 * literals from an ISR that may occur after the flash
240 * processing has been requested but suspended due to the PESD
241 * bit.
242 *
243 * Note: This code is required only when the PESD mechanism is
244 * used to protect the CPU2 timing.
245 * However, keeping that code make it compatible with both
246 * mechanisms.
247 */
248 while (LL_FLASH_IsActiveFlag_OperationSuspended()) {
249 ;
250 }
251
252 /* Enter critical section */
253 key = irq_lock();
254
255 /**
256 * Depending on the application implementation, in case a
257 * multitasking is possible with an OS, it should be checked
258 * here if another task in the application disallowed flash
259 * processing to protect some latency in critical code
260 * execution.
261 * When flash processing is ongoing, the CPU cannot access the
262 * flash anymore.Trying to access the flash during that time
263 * stalls the CPU.
264 * The only way for CPU1 to disallow flash processing is to
265 * take CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID.
266 */
267 cpu1_sem_status = LL_HSEM_GetStatus(HSEM,
268 CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID);
269 if (cpu1_sem_status == 0) {
270 /**
271 * Check now if the CPU2 disallows flash processing to
272 * protect its timing. If the semaphore is locked, the
273 * CPU2 does not allow flash processing
274 *
275 * Note: By default, the CPU2 uses the PESD mechanism
276 * to protect its timing, therefore, it is useless to
277 * get/release the semaphore.
278 *
279 * However, keeping that code make it compatible with
280 * both mechanisms.
281 * The protection by semaphore is enabled on CPU2 side
282 * with the command SHCI_C2_SetFlashActivityControl()
283 *
284 */
285 cpu2_sem_status = LL_HSEM_1StepLock(HSEM,
286 CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID);
287 if (cpu2_sem_status == 0) {
288 /**
289 * When CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID is
290 * taken, it is allowed to only erase one
291 * sector.
292 * When several sectors need to be erased,
293 * the application shall first exit from the
294 * critical section and try again.
295 */
296 regs->CR |= FLASH_CR_PER;
297 regs->CR &= ~FLASH_CR_PNB_Msk;
298 regs->CR |= page << FLASH_CR_PNB_Pos;
299
300 regs->CR |= FLASH_CR_STRT;
301
302 /**
303 * Release the semaphore to give the
304 * opportunity to CPU2 to protect its timing
305 * versus the next flash operation by taking
306 * this semaphore.
307 * Note that the CPU2 is polling on this
308 * semaphore so CPU1 shall release it as fast
309 * as possible.
310 * This is why this code is protected by a
311 * critical section.
312 */
313 LL_HSEM_ReleaseLock(HSEM,
314 CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID,
315 0);
316 }
317 }
318
319 /* Exit critical section */
320 irq_unlock(key);
321
322 } while (cpu2_sem_status || cpu1_sem_status);
323
324
325 /* Wait for the BSY bit */
326 rc = flash_stm32_wait_flash_idle(dev);
327
328 regs->CR &= ~FLASH_CR_PER;
329
330 return rc;
331 }
332
flash_stm32_block_erase_loop(const struct device * dev,unsigned int offset,unsigned int len)333 int flash_stm32_block_erase_loop(const struct device *dev,
334 unsigned int offset,
335 unsigned int len)
336 {
337 int i, rc = 0;
338
339 #if defined(CONFIG_BT)
340 /**
341 * Notify the CPU2 that some flash erase activity may be executed
342 * On reception of this command, the CPU2 enables the BLE timing
343 * protection versus flash erase processing.
344 * The Erase flash activity will be executed only when the BLE RF is
345 * idle for at least 25ms.
346 * The CPU2 will prevent all flash activity (write or erase) in all
347 * cases when the BL RF Idle is shorter than 25ms.
348 */
349 SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_ON);
350 #endif /* CONFIG_BT */
351
352 i = get_page(offset);
353 for (; i <= get_page(offset + len - 1) ; ++i) {
354 rc = erase_page(dev, i);
355 if (rc < 0) {
356 break;
357 }
358 }
359
360 #if defined(CONFIG_BT)
361 /**
362 * Notify the CPU2 there will be no request anymore to erase the flash
363 * On reception of this command, the CPU2 disables the BLE timing
364 * protection versus flash erase processing
365 */
366 SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_OFF);
367 #endif /* CONFIG_BT */
368
369 return rc;
370 }
371
flash_stm32_write_range(const struct device * dev,unsigned int offset,const void * data,unsigned int len)372 int flash_stm32_write_range(const struct device *dev, unsigned int offset,
373 const void *data, unsigned int len)
374 {
375 int i, rc = 0;
376
377 for (i = 0; i < len; i += 8, offset += 8U) {
378 rc = write_dword(dev, offset,
379 UNALIGNED_GET((const uint64_t *) data + (i >> 3)));
380 if (rc < 0) {
381 return rc;
382 }
383 }
384
385 return rc;
386 }
387
flash_stm32_page_layout(const struct device * dev,const struct flash_pages_layout ** layout,size_t * layout_size)388 void flash_stm32_page_layout(const struct device *dev,
389 const struct flash_pages_layout **layout,
390 size_t *layout_size)
391 {
392 static struct flash_pages_layout stm32wb_flash_layout = {
393 .pages_count = 0,
394 .pages_size = 0,
395 };
396
397 ARG_UNUSED(dev);
398
399 if (stm32wb_flash_layout.pages_count == 0) {
400 stm32wb_flash_layout.pages_count = FLASH_SIZE / FLASH_PAGE_SIZE;
401 stm32wb_flash_layout.pages_size = FLASH_PAGE_SIZE;
402 }
403
404 *layout = &stm32wb_flash_layout;
405 *layout_size = 1;
406 }
407
flash_stm32_check_status(const struct device * dev)408 int flash_stm32_check_status(const struct device *dev)
409 {
410 FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
411 uint32_t error = 0;
412
413 /* Save Flash errors */
414 error = (regs->SR & FLASH_FLAG_SR_ERRORS);
415 error |= (regs->ECCR & FLASH_FLAG_ECCC);
416
417 /* Clear systematic Option and Engineering bits validity error */
418 if (error & FLASH_FLAG_OPTVERR) {
419 regs->SR |= FLASH_FLAG_SR_ERRORS;
420 return 0;
421 }
422
423 if (error) {
424 return -EIO;
425 }
426
427 return 0;
428 }
429