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 + CONFIG_FLASH_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