@@ -55,6 +55,9 @@ LOG_MODULE_REGISTER(LOG_DOMAIN);
55
55
* the serie, there is a discontinuty between bank1 and bank2.
56
56
*/
57
57
#define DISCONTINUOUS_BANKS (REAL_FLASH_SIZE_KB < STM32H7_SERIES_MAX_FLASH_KB)
58
+ #define NUMBER_OF_BANKS 2
59
+ #else
60
+ #define NUMBER_OF_BANKS 1
58
61
#endif
59
62
60
63
struct flash_stm32_sector_t {
@@ -129,6 +132,25 @@ static __unused int write_optsr(const struct device *dev, uint32_t mask, uint32_
129
132
return write_opt (dev , mask , value , cur , true);
130
133
}
131
134
135
+ static __unused int write_optwp (const struct device * dev , uint32_t mask , uint32_t value ,
136
+ uint32_t bank )
137
+ {
138
+ FLASH_TypeDef * regs = FLASH_STM32_REGS (dev );
139
+ uintptr_t cur = (uintptr_t )regs + offsetof(FLASH_TypeDef , WPSN_CUR1 );
140
+
141
+ if (bank >= NUMBER_OF_BANKS ) {
142
+ return - EINVAL ;
143
+ }
144
+
145
+ #ifdef DUAL_BANK
146
+ if (bank == 1 ) {
147
+ cur = (uintptr_t )regs + offsetof(FLASH_TypeDef , WPSN_CUR2 );
148
+ }
149
+ #endif /* DUAL_BANK */
150
+
151
+ return write_opt (dev , mask , value , cur , false);
152
+ }
153
+
132
154
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION )
133
155
uint8_t flash_stm32_get_rdp_level (const struct device * dev )
134
156
{
@@ -143,6 +165,83 @@ void flash_stm32_set_rdp_level(const struct device *dev, uint8_t level)
143
165
}
144
166
#endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */
145
167
168
+ #if defined(CONFIG_FLASH_STM32_WRITE_PROTECT )
169
+
170
+ #define WP_MSK FLASH_WPSN_WRPSN_Msk
171
+ #define WP_POS FLASH_WPSN_WRPSN_Pos
172
+
173
+ int flash_stm32_update_wp_sectors (const struct device * dev , uint64_t changed_sectors ,
174
+ uint64_t protected_sectors )
175
+ {
176
+ /* All banks share the same sector mask. */
177
+ const uint64_t bank_mask = WP_MSK >> WP_POS ;
178
+ const uint32_t sectors_per_bank = __builtin_popcount (WP_MSK );
179
+ uint64_t sectors_mask = 0 ;
180
+ uint32_t protected_sectors_reg ;
181
+ uint32_t changed_sectors_reg ;
182
+ int ret , ret2 = 0 ;
183
+ bool commit = false;
184
+
185
+ for (int i = 0 ; i < NUMBER_OF_BANKS ; i ++ ) {
186
+ sectors_mask |= bank_mask << (sectors_per_bank * i );
187
+ }
188
+
189
+ if ((changed_sectors & sectors_mask ) != changed_sectors ) {
190
+ return - EINVAL ;
191
+ }
192
+
193
+ for (int i = 0 ; i < NUMBER_OF_BANKS ; i ++ ) {
194
+ /* Prepare protected and changed masks per bank. */
195
+ protected_sectors_reg = (protected_sectors >> sectors_per_bank * i ) & bank_mask ;
196
+ changed_sectors_reg = (changed_sectors >> sectors_per_bank * i ) & bank_mask ;
197
+
198
+ if (changed_sectors_reg == 0 ) {
199
+ continue ;
200
+ }
201
+ changed_sectors_reg <<= WP_POS ;
202
+ protected_sectors_reg <<= WP_POS ;
203
+ /* Sector is protected when bit == 0. Flip protected_sectors bits */
204
+ protected_sectors_reg = ~protected_sectors_reg ;
205
+
206
+ ret = write_optwp (dev , changed_sectors_reg , protected_sectors_reg , i );
207
+ /* Option byte was successfully changed if the return value is greater than 0. */
208
+ if (ret > 0 ) {
209
+ commit = true;
210
+ } else if (ret < 0 ) {
211
+ /* Do not continue changing WP on error. */
212
+ ret2 = ret ;
213
+ break ;
214
+ }
215
+ }
216
+
217
+ if (commit ) {
218
+ ret = commit_optb (dev );
219
+ /* Make sure to return the first error. */
220
+ if (ret < 0 && ret2 == 0 ) {
221
+ ret2 = ret ;
222
+ }
223
+ }
224
+
225
+ return ret2 ;
226
+ }
227
+
228
+ int flash_stm32_get_wp_sectors (const struct device * dev , uint64_t * protected_sectors )
229
+ {
230
+ FLASH_TypeDef * regs = FLASH_STM32_REGS (dev );
231
+
232
+ * protected_sectors = (~regs -> WPSN_CUR1 & WP_MSK ) >> WP_POS ;
233
+ #ifdef DUAL_BANK
234
+ /* Available only for STM32H7x */
235
+ uint64_t proctected_sectors_2 =
236
+ (~regs -> WPSN_CUR2 & WP_MSK ) >> WP_POS ;
237
+ const uint32_t sectors_per_bank = __builtin_popcount (WP_MSK );
238
+ * protected_sectors |= proctected_sectors_2 << sectors_per_bank ;
239
+ #endif /* DUAL_BANK */
240
+
241
+ return 0 ;
242
+ }
243
+ #endif /* CONFIG_FLASH_STM32_WRITE_PROTECT */
244
+
146
245
int flash_stm32_option_bytes_lock (const struct device * dev , bool enable )
147
246
{
148
247
FLASH_TypeDef * regs = FLASH_STM32_REGS (dev );
0 commit comments