1 /*
2 // Copyright (C) 2022 Beken Corporation
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <common/bk_include.h>
17 #include <os/os.h>
18 #include "BkDriverFlash.h"
19 #include "bk_flash.h"
20 #include "bk_drv_model.h"
21 #include <common/bk_kernel_err.h>
22 #include "bk_uart.h"
23 #include <os/mem.h>
24 /* Logic partition on flash devices */
25
26 #ifdef CONFIG_SOC_BK7256XX
27 extern const bk_logic_partition_t bk7256_partitions[BK_PARTITION_MAX];
28 #else
29 const bk_logic_partition_t bk7231_partitions[BK_PARTITION_MAX] = {
30 [BK_PARTITION_BOOTLOADER] =
31 {
32 .partition_owner = BK_FLASH_EMBEDDED,
33 .partition_description = "Bootloader",
34 .partition_start_addr = 0x00000000,
35 .partition_length = 0x0F000,
36 .partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_DIS,
37 },
38 [BK_PARTITION_APPLICATION] =
39 {
40 .partition_owner = BK_FLASH_EMBEDDED,
41 .partition_description = "Application",
42 .partition_start_addr = 0x11000,
43 #if CONFIG_SUPPORT_MATTER || CONFIG_FLASH_SIZE_4M
44 .partition_length = 0x1A9000,
45 #else
46 .partition_length = 0x143000,
47 #endif
48 .partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_DIS,
49 },
50 [BK_PARTITION_OTA] =
51 {
52 .partition_owner = BK_FLASH_EMBEDDED,
53 .partition_description = "ota",
54 #if CONFIG_FLASH_SIZE_4M
55 .partition_start_addr = 0x1BA000,
56 .partition_length = 0x1A9000, //1700KB
57 #elif CONFIG_SUPPORT_MATTER
58 .partition_start_addr = 0x1BA000,
59 .partition_length = 0x11000, //68KB
60 #else
61 .partition_start_addr = 0x132000,
62 .partition_length = 0xAE000, //696KB
63 #endif
64 .partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_DIS,
65 },
66 #if CONFIG_SUPPORT_MATTER
67 [BK_PARTITION_MATTER_FLASH] =
68 {
69 .partition_owner = BK_FLASH_EMBEDDED,
70 .partition_description = "Matter",
71 #if CONFIG_FLASH_SIZE_4M
72 .partition_start_addr = 0x363000,
73 #else
74 partition_start_addr = 0x1CB000,
75 #endif
76 .partition_length = 0x15000, //84KB
77 .partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_DIS,
78 },
79 #endif
80 [BK_PARTITION_RF_FIRMWARE] =
81 {
82 .partition_owner = BK_FLASH_EMBEDDED,
83 .partition_description = "RF Firmware",
84 #if (CONFIG_FLASH_SIZE_4M)
85 .partition_start_addr = 0x3FE000,
86 #else
87 .partition_start_addr = 0x1e0000,// bootloader unused space for rf cal+mac related info.
88 #endif
89 .partition_length = 0x1000,
90 .partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_DIS,
91 },
92 [BK_PARTITION_NET_PARAM] =
93 {
94 .partition_owner = BK_FLASH_EMBEDDED,
95 .partition_description = "NET info",
96 #if (CONFIG_FLASH_SIZE_4M)
97 .partition_start_addr = 0x3FF000,
98 #else
99 .partition_start_addr = 0x1e1000,// for net related info
100 #endif
101 .partition_length = 0x1000,
102 .partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_DIS,
103 },
104 };
105 #endif
106
BkFlashPartitionAssert(bk_partition_t inPartition)107 static void BkFlashPartitionAssert(bk_partition_t inPartition)
108 {
109 BK_ASSERT(BK_PARTITION_BOOTLOADER < BK_PARTITION_MAX);
110 }
111
BkFlashPartitionIsValid(bk_partition_t inPartition)112 static uint32_t BkFlashPartitionIsValid(bk_partition_t inPartition)
113 {
114 if ((inPartition >= BK_PARTITION_BOOTLOADER) && (inPartition < BK_PARTITION_MAX))
115 return 1;
116 else
117 return 0;
118 }
119
bk_flash_get_info(bk_partition_t inPartition)120 bk_logic_partition_t *bk_flash_get_info(bk_partition_t inPartition)
121 {
122 bk_logic_partition_t *pt = NULL;
123
124 BkFlashPartitionAssert(inPartition);
125
126 if (BkFlashPartitionIsValid(inPartition)){
127 #if (CONFIG_SOC_BK7256XX)
128 pt = (bk_logic_partition_t *)&bk7256_partitions[inPartition];
129 #else
130 pt = (bk_logic_partition_t *)&bk7231_partitions[inPartition];
131 #endif
132 }
133 else
134 pt = NULL;
135 return pt;
136 }
137
BkFlashInit(void)138 bk_err_t BkFlashInit(void)
139 {
140 return 0;
141 }
142
BkFlashUninit(void)143 bk_err_t BkFlashUninit(void)
144 {
145 return 0;
146 }
147
bk_flash_erase(bk_partition_t inPartition,uint32_t off_set,uint32_t size)148 bk_err_t bk_flash_erase(bk_partition_t inPartition, uint32_t off_set, uint32_t size)
149 {
150 uint32_t i;
151 uint32_t param;
152 UINT32 status;
153 DD_HANDLE flash_hdl;
154 uint32_t start_sector, end_sector;
155 bk_logic_partition_t *partition_info;
156 GLOBAL_INT_DECLARATION();
157
158 partition_info = bk_flash_get_info(inPartition);
159 start_sector = off_set >> 12;
160 end_sector = (off_set + size - 1) >> 12;
161
162 flash_hdl = ddev_open(DD_DEV_TYPE_FLASH, &status, 0);
163 BK_ASSERT(DD_HANDLE_UNVALID != flash_hdl);
164 for (i = start_sector; i <= end_sector; i ++) {
165 param = partition_info->partition_start_addr + (i << 12);
166 GLOBAL_INT_DISABLE();
167 ddev_control(flash_hdl, CMD_FLASH_ERASE_SECTOR, (void *)¶m);
168 GLOBAL_INT_RESTORE();
169 }
170
171 return kNoErr;
172 }
173
bk_flash_write(bk_partition_t inPartition,volatile uint32_t off_set,uint8_t * inBuffer,uint32_t inBufferLength)174 bk_err_t bk_flash_write(bk_partition_t inPartition, volatile uint32_t off_set, uint8_t *inBuffer, uint32_t inBufferLength)
175 {
176 UINT32 status;
177 DD_HANDLE flash_hdl;
178 uint32_t start_addr;
179 bk_logic_partition_t *partition_info;
180 GLOBAL_INT_DECLARATION();
181
182 if (NULL == inBuffer) {
183 os_printf("%s inBuffer=NULL\r\n", __FUNCTION__);
184 return kParamErr;
185 }
186
187 partition_info = bk_flash_get_info(inPartition);
188 if (NULL == partition_info) {
189 os_printf("%s partiion not found\r\n", __FUNCTION__);
190 return kNotFoundErr;
191 }
192
193 start_addr = partition_info->partition_start_addr + off_set;
194
195 flash_hdl = ddev_open(DD_DEV_TYPE_FLASH, &status, 0);
196 if (DD_HANDLE_UNVALID == flash_hdl) {
197 os_printf("%s open failed\r\n", __FUNCTION__);
198 return kOpenErr;
199 }
200
201 GLOBAL_INT_DISABLE();
202 ddev_write(flash_hdl, (char *)inBuffer, inBufferLength, start_addr);
203 GLOBAL_INT_RESTORE();
204
205 return kNoErr;
206 }
207
bk_flash_read(bk_partition_t inPartition,volatile uint32_t off_set,uint8_t * outBuffer,uint32_t inBufferLength)208 bk_err_t bk_flash_read(bk_partition_t inPartition, volatile uint32_t off_set, uint8_t *outBuffer, uint32_t inBufferLength)
209 {
210 UINT32 status;
211 uint32_t start_addr;
212 DD_HANDLE flash_hdl;
213 bk_logic_partition_t *partition_info;
214 GLOBAL_INT_DECLARATION();
215
216 if (NULL == outBuffer) {
217 os_printf("%s outBuffer=NULL\r\n", __FUNCTION__);
218 return kParamErr;
219 }
220
221 partition_info = bk_flash_get_info(inPartition);
222 if (NULL == partition_info) {
223 os_printf("%s partiion not found\r\n", __FUNCTION__);
224 return kNotFoundErr;
225 }
226
227 start_addr = partition_info->partition_start_addr + off_set;
228
229 flash_hdl = ddev_open(DD_DEV_TYPE_FLASH, &status, 0);
230 if (DD_HANDLE_UNVALID == flash_hdl) {
231 os_printf("%s open failed\r\n", __FUNCTION__);
232 return kOpenErr;
233 }
234
235 GLOBAL_INT_DISABLE();
236 ddev_read(flash_hdl, (char *)outBuffer, inBufferLength, start_addr);
237 GLOBAL_INT_RESTORE();
238
239 return kNoErr;
240 }
241
bk_flash_enable_security(PROTECT_TYPE type)242 bk_err_t bk_flash_enable_security(PROTECT_TYPE type)
243 {
244 DD_HANDLE flash_hdl;
245 UINT32 status;
246 uint32_t param = type;
247
248 flash_hdl = ddev_open(DD_DEV_TYPE_FLASH, &status, 0);
249 if (DD_HANDLE_UNVALID == flash_hdl) {
250 os_printf("%s open failed\r\n", __FUNCTION__);
251 return kOpenErr;
252 }
253 ddev_control(flash_hdl, CMD_FLASH_SET_PROTECT, (void *)¶m);
254
255 return kNoErr;
256 }
257
258
bk_flash_get_security(PROTECT_TYPE * protect_flag)259 bk_err_t bk_flash_get_security(PROTECT_TYPE *protect_flag)
260 {
261 DD_HANDLE flash_hdl;
262 UINT32 status;
263 uint32_t param;
264
265 flash_hdl = ddev_open(DD_DEV_TYPE_FLASH, &status, 0);
266 ddev_control(flash_hdl, CMD_FLASH_GET_PROTECT, ¶m);
267 *protect_flag = param;
268
269 return kNoErr;
270 }
271
bk_flash_abs_addr_read(unsigned int off_set,unsigned char * outBuffer,unsigned int size)272 bk_err_t bk_flash_abs_addr_read(unsigned int off_set, unsigned char *outBuffer, unsigned int size)
273 {
274 UINT32 status;
275 DD_HANDLE flash_hdl;
276 GLOBAL_INT_DECLARATION();
277
278 flash_hdl = ddev_open(DD_DEV_TYPE_FLASH, &status, 0);
279
280 GLOBAL_INT_DISABLE();
281 ddev_read(flash_hdl, (char *)outBuffer, size, off_set);
282 GLOBAL_INT_RESTORE();
283
284 return kNoErr;
285 }
286
bk_flash_abs_addr_erase(unsigned int flashOffset,unsigned int size)287 bk_err_t bk_flash_abs_addr_erase(unsigned int flashOffset, unsigned int size)
288 {
289 UINT32 status, i;
290 DD_HANDLE flash_hdl;
291 UINT32 start_sector, end_sector, param;
292 GLOBAL_INT_DECLARATION();
293
294 flash_hdl = ddev_open(DD_DEV_TYPE_FLASH, &status, 0);
295
296 start_sector = flashOffset >> 12;
297 end_sector = (flashOffset + size - 1) >> 12;
298
299 GLOBAL_INT_DISABLE();
300 for (i = start_sector; i <= end_sector; i ++) {
301 param = i << 12;
302 ddev_control(flash_hdl, CMD_FLASH_ERASE_SECTOR, (void *)¶m);
303 }
304 GLOBAL_INT_RESTORE();
305
306 return kNoErr;
307 }
308
bk_flash_abs_addr_write(unsigned int off_set,const unsigned char * inBuffer,unsigned int size,unsigned char eraseflag)309 bk_err_t bk_flash_abs_addr_write(unsigned int off_set, const unsigned char *inBuffer, unsigned int size, unsigned char eraseflag)
310 {
311 UINT32 status;
312 DD_HANDLE flash_hdl;
313 GLOBAL_INT_DECLARATION();
314
315 flash_hdl = ddev_open(DD_DEV_TYPE_FLASH, &status, 0);
316
317 if (eraseflag)
318 bk_flash_abs_addr_erase(off_set, size);
319
320 GLOBAL_INT_DISABLE();
321 ddev_write(flash_hdl, (char *)inBuffer, size, off_set);
322 GLOBAL_INT_RESTORE();
323
324 return kNoErr;
325 }
326
test_flash_write(volatile uint32_t start_addr,uint32_t len)327 bk_err_t test_flash_write(volatile uint32_t start_addr, uint32_t len)
328 {
329 UINT32 status;
330 DD_HANDLE flash_hdl;
331 uint32_t i;
332 u8 buf[256];
333 uint32_t addr = start_addr;
334 uint32_t length = len;
335 uint32_t tmp = addr + length;
336
337 for (i = 0; i < 256; i++)
338 buf[i] = i;
339
340 flash_hdl = ddev_open(DD_DEV_TYPE_FLASH, &status, 0);
341 BK_ASSERT(DD_HANDLE_UNVALID != flash_hdl);
342 for (; addr < tmp; addr += 256) {
343 os_printf("write addr(size:256):%d\r\n", addr);
344 ddev_write(flash_hdl, (char *)buf, 256, addr);
345 }
346
347 return kNoErr;
348 }
test_flash_erase(volatile uint32_t start_addr,uint32_t len)349 bk_err_t test_flash_erase(volatile uint32_t start_addr, uint32_t len)
350 {
351 UINT32 status;
352 DD_HANDLE flash_hdl;
353
354 uint32_t addr = start_addr;
355 uint32_t length = len;
356 uint32_t tmp = addr + length;
357
358 flash_hdl = ddev_open(DD_DEV_TYPE_FLASH, &status, 0);
359 if (DD_HANDLE_UNVALID == flash_hdl) {
360 os_printf("%s open failed\r\n", __FUNCTION__);
361 return kOpenErr;
362 }
363 for (; addr < tmp; addr += 0x1000) {
364 os_printf("erase addr:%d\r\n", addr);
365 ddev_control(flash_hdl, CMD_FLASH_ERASE_SECTOR, (void *)&addr);
366
367 }
368 return kNoErr;
369 }
370
test_flash_read(volatile uint32_t start_addr,uint32_t len)371 bk_err_t test_flash_read(volatile uint32_t start_addr, uint32_t len)
372 {
373 UINT32 status;
374 DD_HANDLE flash_hdl;
375 uint32_t i, j, tmp;
376 u8 buf[256];
377 uint32_t addr = start_addr;
378 uint32_t length = len;
379 tmp = addr + length;
380
381 flash_hdl = ddev_open(DD_DEV_TYPE_FLASH, &status, 0);
382 if (DD_HANDLE_UNVALID == flash_hdl) {
383 os_printf("%s open failed\r\n", __FUNCTION__);
384 return kOpenErr;
385 }
386 for (; addr < tmp; addr += 256) {
387 os_memset(buf, 0, 256);
388 ddev_read(flash_hdl, (char *)buf, 256, addr);
389 os_printf("read addr:%x\r\n", addr);
390 for (i = 0; i < 16; i++) {
391 for (j = 0; j < 16; j++)
392 os_printf("%02x ", buf[i * 16 + j]);
393 os_printf("\r\n");
394 }
395 }
396
397 return kNoErr;
398 }
399
test_flash_read_without_print(volatile uint32_t start_addr,uint32_t len)400 bk_err_t test_flash_read_without_print(volatile uint32_t start_addr, uint32_t len)
401 {
402 UINT32 status;
403 DD_HANDLE flash_hdl;
404 uint32_t tmp;
405 u8 buf[256];
406 uint32_t addr = start_addr;
407 uint32_t length = len;
408 tmp = addr + length;
409
410 flash_hdl = ddev_open(DD_DEV_TYPE_FLASH, &status, 0);
411 if (DD_HANDLE_UNVALID == flash_hdl) {
412 os_printf("%s open failed\r\n", __FUNCTION__);
413 return kOpenErr;
414 }
415 for (; addr < tmp; addr += 256) {
416 os_memset(buf, 0, 256);
417 ddev_read(flash_hdl, (char *)buf, 256, addr);
418 }
419
420 return kNoErr;
421 }
422
test_flash_read_time(volatile uint32_t start_addr,uint32_t len)423 bk_err_t test_flash_read_time(volatile uint32_t start_addr, uint32_t len)
424 {
425 UINT32 status, time_start, time_end;
426 DD_HANDLE flash_hdl;
427 uint32_t tmp;
428 u8 buf[256];
429 uint32_t addr = start_addr;
430 uint32_t length = len;
431
432 tmp = addr + length;
433
434 flash_hdl = ddev_open(DD_DEV_TYPE_FLASH, &status, 0);
435 if (DD_HANDLE_UNVALID == flash_hdl) {
436 os_printf("%s open failed\r\n", __FUNCTION__);
437 return kOpenErr;
438 }
439 beken_time_get_time((beken_time_t *)&time_start);
440 os_printf("read time start:%d\r\n", time_start);
441
442 for (; addr < tmp; addr += 256) {
443 os_memset(buf, 0, 256);
444 ddev_read(flash_hdl, (char *)buf, 256, addr);
445 }
446 beken_time_get_time((beken_time_t *)&time_end);
447 os_printf("read time end:%d\r\n", time_end);
448 os_printf("cost time:%d\r\n", time_end - time_start);
449
450 return kNoErr;
451 }
452
453 static beken_mutex_t hal_flash_mutex;
454
hal_flash_lock(void)455 int hal_flash_lock(void)
456 {
457 rtos_lock_mutex(&hal_flash_mutex);
458 return kNoErr;
459 }
460
hal_flash_unlock(void)461 int hal_flash_unlock(void)
462 {
463 rtos_unlock_mutex(&hal_flash_mutex);
464 return kNoErr;
465 }
466
467
hal_flash_init(void)468 int hal_flash_init(void)
469 {
470 int ret = 0;
471
472 ret = rtos_init_mutex(&hal_flash_mutex);
473 if (ret != 0)
474 return kGeneralErr;
475 return kNoErr;
476 }
477
478 // EOF
479
480