1 /*
2 * Copyright (c) 2022 Winner Microelectronics Co., Ltd. All rights reserved.
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 /**
17 * @file wm_internal_fls.c
18 *
19 * @brief flash Driver Module
20 *
21 * @author dave
22 *
23 * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
24 */
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include "wm_dbg.h"
29 #include "wm_mem.h"
30 #include "list.h"
31 #include "wm_regs.h"
32 #include "wm_internal_flash.h"
33 #include "wm_flash_map.h"
34
35 static struct tls_inside_fls *inside_fls = NULL;
36
37 /**System parameter, default for 2M flash*/
38 unsigned int TLS_FLASH_PARAM_DEFAULT = (0x81FB000UL);
39 unsigned int TLS_FLASH_PARAM1_ADDR = (0x81FC000UL);
40 unsigned int TLS_FLASH_PARAM2_ADDR = (0x81FD000UL);
41 unsigned int TLS_FLASH_PARAM_RESTORE_ADDR = (0x81FE000UL);
42 unsigned int TLS_FLASH_OTA_FLAG_ADDR = (0x81FF000UL);
43 unsigned int TLS_FLASH_END_ADDR = (0x81FFFFFUL);
44
read_first_value(void)45 static vu32 read_first_value(void)
46 {
47 return M32(RSA_BASE_ADDRESS);
48 }
49
writeEnable(void)50 static void writeEnable(void)
51 {
52 M32(HR_FLASH_CMD_ADDR) = 0x6;
53 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
54 }
55
readRID(void)56 unsigned char readRID(void)
57 {
58 M32(HR_FLASH_CMD_ADDR) = 0x2c09F;
59 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
60 return read_first_value() & 0xFF;
61 }
62
writeBpBit_for_1wreg(char cmp,char bp4,char bp3,char bp2,char bp1,char bp0)63 static void writeBpBit_for_1wreg(char cmp, char bp4, char bp3, char bp2, char bp1, char bp0)
64 {
65 int status = 0;
66 int bpstatus = 0;
67
68 M32(HR_FLASH_CMD_ADDR) = 0x0C005;
69 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
70 status = read_first_value() & 0xFF;
71
72 M32(HR_FLASH_CMD_ADDR) = 0x0C035;
73 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
74 status |= (read_first_value() & 0xFF) << 8;
75
76 /* Write Enable */
77 M32(HR_FLASH_CMD_ADDR) = 0x6;
78 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
79
80 bpstatus = (bp4 << 6) | (bp3 << 5) | (bp2 << 4) | (bp1 << 3) | (bp0 << 2);
81 status = (status & 0xBF83) | bpstatus | (cmp << 14);
82
83 M32(RSA_BASE_ADDRESS) = status;
84 M32(HR_FLASH_CMD_ADDR) = 0x1A001;
85 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
86 }
87
writeBpBit_for_2wreg(char cmp,char bp4,char bp3,char bp2,char bp1,char bp0)88 static void writeBpBit_for_2wreg(char cmp, char bp4, char bp3, char bp2, char bp1, char bp0)
89 {
90 int status = 0;
91 int bpstatus = 0;
92
93 M32(HR_FLASH_CMD_ADDR) = 0x0C005;
94 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
95 status = read_first_value() & 0xFF;
96
97 M32(HR_FLASH_CMD_ADDR) = 0x0C035;
98 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
99 status |= (read_first_value() & 0xFF) << 8;
100
101 /* Write Enable */
102 M32(HR_FLASH_CMD_ADDR) = 0x6;
103 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
104
105 bpstatus = (bp4 << 6) | (bp3 << 5) | (bp2 << 4) | (bp1 << 3) | (bp0 << 2);
106 bpstatus = (status & 0x83) | bpstatus;
107
108 M32(RSA_BASE_ADDRESS) = bpstatus;
109 M32(HR_FLASH_CMD_ADDR) = 0xA001;
110 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
111
112 M32(HR_FLASH_CMD_ADDR) = 0x6;
113 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
114
115 status = ((status>>8) & 0xBF) | (cmp << 6);
116 M32(RSA_BASE_ADDRESS) = status;
117 M32(HR_FLASH_CMD_ADDR) = 0xA031;
118 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
119 }
120
writeESMTBpBit(char cmp,char bp4,char bp3,char bp2,char bp1,char bp0)121 static void writeESMTBpBit(char cmp, char bp4, char bp3, char bp2, char bp1, char bp0)
122 {
123 int status = 0;
124 int bpstatus = 0;
125
126 M32(HR_FLASH_CMD_ADDR) = 0x0C005;
127 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
128 status = read_first_value() & 0xFF;
129 bpstatus = (bp4 << 6) | (bp3 << 5) | (bp2 << 4) | (bp1 << 3) | (bp0 << 2);
130 status = (status & 0x83) | bpstatus;
131
132 /* Write Enable */
133 M32(HR_FLASH_CMD_ADDR) = 0x6;
134 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
135
136 bpstatus = (bp4 << 6) | (bp3 << 5) | (bp2 << 4) | (bp1 << 3) | (bp0 << 2);
137 status = (status & 0x83) | bpstatus | (cmp << 14);
138
139 M32(RSA_BASE_ADDRESS) = status;
140 M32(HR_FLASH_CMD_ADDR) = 0x0A001;
141 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
142
143 M32(HR_FLASH_CMD_ADDR) = 0x0C085;
144 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
145 status = read_first_value() & 0xFF;
146
147 /* Write Enable */
148 M32(HR_FLASH_CMD_ADDR) = 0x6;
149 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
150
151 status = (status & 0xBF) | (cmp << 6);
152 M32(RSA_BASE_ADDRESS) = status;
153 M32(HR_FLASH_CMD_ADDR) = 0x0A0C1;
154 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
155 }
156
flashunlock(void)157 static int flashunlock(void)
158 {
159 switch (readRID()) {
160 case SPIFLASH_MID_GD:
161 case SPIFLASH_MID_TSINGTENG:
162 writeBpBit_for_1wreg(0, 0, 0, 0, 0, 0);
163 break;
164 case SPIFLASH_MID_PUYA:
165 case SPIFLASH_MID_XTX:
166 case SPIFLASH_MID_BOYA:
167 case SPIFLASH_MID_FUDANMICRO:
168 case SPIFLASH_MID_XMC:
169 writeBpBit_for_2wreg(0, 0, 0, 0, 0, 0);
170 break;
171 case SPIFLASH_MID_ESMT:
172 writeESMTBpBit(0, 0, 0, 0, 0, 0);
173 break;
174 default:
175 return -1;
176 }
177 return 0;
178 }
179
flashlock(void)180 static int flashlock(void)
181 {
182 switch (readRID()) {
183 case SPIFLASH_MID_GD:
184 case SPIFLASH_MID_TSINGTENG:
185 writeBpBit_for_1wreg(0, 1, 1, 0, 1, 0);
186 break;
187 case SPIFLASH_MID_PUYA:
188 case SPIFLASH_MID_XTX:
189 case SPIFLASH_MID_BOYA:
190 case SPIFLASH_MID_FUDANMICRO:
191 case SPIFLASH_MID_XMC:
192 writeBpBit_for_2wreg(0, 1, 1, 0, 1, 0);
193 break;
194 case SPIFLASH_MID_ESMT:
195 writeESMTBpBit(0, 1, 1, 0, 1, 0);
196 break;
197 default:
198 return -1; /* do not clear QIO Mode */
199 }
200 return 0;
201 }
202
writeLbBit_for_1wreg(unsigned int val)203 static void writeLbBit_for_1wreg(unsigned int val)
204 {
205 int status = 0;
206
207 M32(HR_FLASH_CMD_ADDR) = 0x0C005;
208 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
209 status = read_first_value() & 0xFF;
210
211 M32(HR_FLASH_CMD_ADDR) = 0x0C035;
212 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
213 status |= (read_first_value() & 0xFF) << 8;
214
215 /* Write Enable */
216 M32(HR_FLASH_CMD_ADDR) = 0x6;
217 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
218
219 status |= (val);
220
221 M32(RSA_BASE_ADDRESS) = status;
222 M32(HR_FLASH_CMD_ADDR) = 0x1A001;
223 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
224 }
225
writeLbBit_for_2wreg(unsigned int val)226 static void writeLbBit_for_2wreg(unsigned int val)
227 {
228 int status = 0;
229
230 M32(HR_FLASH_CMD_ADDR) = 0x0C005;
231 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
232 status = read_first_value() & 0xFF;
233
234 M32(HR_FLASH_CMD_ADDR) = 0x0C035;
235 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
236 status |= (read_first_value() & 0xFF) << 8;
237
238 /* Write Enable */
239 M32(HR_FLASH_CMD_ADDR) = 0x6;
240 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
241
242 status |= (val);
243 status = (status>>8);
244 M32(RSA_BASE_ADDRESS) = status;
245 M32(HR_FLASH_CMD_ADDR) = 0xA031;
246 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
247 }
248
programSR(unsigned int cmd,unsigned long addr,unsigned char * buf,unsigned int sz)249 static int programSR(unsigned int cmd, unsigned long addr, unsigned char *buf, unsigned int sz)
250 {
251 unsigned long base_addr = 0;
252 unsigned int size = 0;
253 unsigned char *buf_tmp = buf;
254 if (sz > INSIDE_FLS_PAGE_SIZE) {
255 sz = INSIDE_FLS_PAGE_SIZE;
256 }
257
258 base_addr = RSA_BASE_ADDRESS;
259 size = sz;
260 while (size) {
261 M32(base_addr) = *((unsigned long *)buf_tmp);
262 base_addr += 4; // 4:byte alignment
263 buf_tmp += 4; // 4:byte alignment
264 size -= 4; // 4:byte alignment
265 }
266
267 writeEnable();
268 M32(HR_FLASH_CMD_ADDR) = cmd | ((sz - 1) << 16); // 16:byte alignment
269 M32(HR_FLASH_ADDR) = (addr & 0x1FFFFFF);
270 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
271
272 return 0;
273 }
274
programPage(unsigned long adr,unsigned long sz,unsigned char * buf)275 static int programPage (unsigned long adr, unsigned long sz, unsigned char *buf)
276 {
277 programSR(0x80009002, adr, buf, sz);
278 return(0);
279 }
280
eraseSR(unsigned int cmd,unsigned long addr)281 static int eraseSR(unsigned int cmd, unsigned long addr)
282 {
283 /* Write Enable */
284 writeEnable();
285 M32(HR_FLASH_CMD_ADDR) = cmd;
286 M32(HR_FLASH_ADDR) = (addr & 0x1FFFFFF);
287 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
288
289 return 0;
290 }
291
eraseSector(unsigned long adr)292 static int eraseSector (unsigned long adr)
293 {
294 eraseSR(0x80000820, adr);
295
296 return (0); // Finished without Errors
297 }
298
299 /* only for w800 c400 flash */
erasePage(unsigned long addr)300 static int erasePage (unsigned long addr)
301 {
302 eraseSR(0x80000881, addr);
303 return (0); // Finished without Errors
304 }
305
getFlashDensity(void)306 static unsigned int getFlashDensity(void)
307 {
308 unsigned char density = 0;
309
310 M32(HR_FLASH_CMD_ADDR) = 0x2c09F;
311 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
312
313 density = ((read_first_value() & 0xFFFFFF) >> 16) & 0xFF;
314 if (density && (density <= 28)) {
315 return (1 << density);
316 }
317
318 return 0;
319 }
320
__readByCMD(unsigned char cmd,unsigned long addr,unsigned char * buf,unsigned long sz)321 int __readByCMD(unsigned char cmd, unsigned long addr, unsigned char *buf, unsigned long sz)
322 {
323 int i = 0;
324 int word = sz / 4; // 4:byte alignment
325 int byte = sz % 4; // 4:byte alignment
326 unsigned char cmd_tmp = cmd;
327 unsigned char *buf_tmp = buf;
328 unsigned long addr_read;
329 if (!(M32(HR_FLASH_CR)&0x1)) { /* non-QIO mode, only single line command can be used */
330 if (cmd_tmp > 0x0B) {
331 cmd_tmp = 0x0B;
332 }
333 }
334
335 switch (cmd_tmp) {
336 case 0x03:
337 M32(HR_FLASH_CMD_ADDR) = 0x8000C003 | (((sz - 1) & 0x3FF) << 16); // 16:byte alignment
338 M32(HR_FLASH_ADDR) = addr & 0x1FFFFFF;
339 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
340 break;
341 case 0x0B:
342 if ((M32(HR_FLASH_CR) & 0x2) == 0x2) {
343 M32(HR_FLASH_CMD_ADDR) = 0xB400C00B | (((sz - 1) & 0x3FF) << 16); // 16:byte alignment
344 } else {
345 M32(HR_FLASH_CMD_ADDR) = 0xBC00C00B | (((sz - 1) & 0x3FF) << 16); // 16:byte alignment
346 }
347 M32(HR_FLASH_ADDR) = addr & 0x1FFFFFF;
348 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
349 break;
350 case 0xBB:
351 M32(HR_FLASH_CMD_ADDR) = 0xE400C0BB | (((sz - 1) & 0x3FF) << 16); // 16:byte alignment
352 M32(HR_FLASH_ADDR) = addr & 0x1FFFFFF;
353 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
354 break;
355
356 case 0xEB:
357 M32(HR_FLASH_CMD_ADDR) = 0xEC00C0EB | (((sz - 1) & 0x3FF) << 16); // 16:byte alignment
358 M32(HR_FLASH_ADDR) = addr & 0x1FFFFFF;
359 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
360 break;
361
362 default:
363 return -1;
364 }
365 addr_read = RSA_BASE_ADDRESS;
366 for (i = 0; i < word; i ++) {
367 M32(buf_tmp) = M32(addr_read);
368 buf_tmp += 4; // 4:byte alignment
369 addr_read += 4; // 4:byte alignment
370 }
371
372 if (byte > 0) {
373 M32(buf_tmp) = M32(addr_read);
374 buf_tmp += 3; // 3:point last byte
375 byte = 4 - byte; // 4:byte alignment
376 while (byte) {
377 *buf_tmp = 0;
378 buf_tmp --;
379 byte --;
380 }
381 }
382 return 0;
383 }
384
385 /**
386 * @brief This function is used to read data from the flash.
387 *
388 * @param[in] cmd 0xEB in QSPI mode; 0x0b in SPI mode.
389 * @param[in] addr is byte offset addr for read from the flash.
390 * @param[in] buf is user for data buffer of flash read
391 * @param[in] len is byte length for read.
392 *
393 * @retval TLS_FLS_STATUS_OK if read sucsess
394 * @retval TLS_FLS_STATUS_EPERM if inside fls does not initialized.
395 *
396 * @note None
397 */
readByCMD(unsigned char cmd,unsigned long addr,unsigned char * buf,unsigned long sz)398 int readByCMD(unsigned char cmd, unsigned long addr, unsigned char *buf, unsigned long sz)
399 {
400 if (inside_fls == NULL) {
401 return TLS_FLS_STATUS_EPERM;
402 }
403
404 tls_os_sem_acquire(inside_fls->fls_lock, 0);
405 __readByCMD(cmd, addr, buf, sz);
406 tls_os_sem_release(inside_fls->fls_lock);
407 return TLS_FLS_STATUS_OK;
408 }
409
flashRead(unsigned long addr,unsigned char * buf,unsigned long sz)410 int flashRead(unsigned long addr, unsigned char *buf, unsigned long sz)
411 {
412 #define INSIDE_FLS_MAX_RD_SIZE (1024)
413
414 unsigned int flash_addr;
415 unsigned int sz_pagenum = 0;
416 unsigned int sz_remain = 0;
417 int i = 0;
418 int page_offset = addr & (INSIDE_FLS_PAGE_SIZE - 1);
419 unsigned char *buf_tmp = buf;
420
421 if ((page_offset == 0)
422 && (((unsigned int)buf_tmp&0x3) == 0)
423 && ((sz&0x3) == 0)) { /* Use 4-bytes aligned and buf must be 4 times, sz must be 4 times */
424 flash_addr = addr;
425 unsigned int max_size = 0;
426 if (sz >= 512) {
427 max_size = INSIDE_FLS_MAX_RD_SIZE;
428 } else {
429 max_size = INSIDE_FLS_PAGE_SIZE;
430 }
431
432 sz_pagenum = sz / max_size;
433 sz_remain = sz % max_size;
434 for (i = 0; i < sz_pagenum; i++) {
435 __readByCMD(0xEB, flash_addr, (unsigned char *)buf_tmp, max_size);
436 buf_tmp += max_size;
437 flash_addr += max_size;
438 }
439
440 if (sz_remain) {
441 __readByCMD(0xEB, flash_addr, (unsigned char *)buf_tmp, sz_remain);
442 }
443 } else {
444 char *cache = tls_mem_alloc(INSIDE_FLS_PAGE_SIZE);
445 if (cache == NULL) {
446 TLS_DBGPRT_ERR("allocate sector cache memory fail!\n");
447 return TLS_FLS_STATUS_ENOMEM;
448 }
449 flash_addr = addr & ~(INSIDE_FLS_PAGE_SIZE - 1);
450 __readByCMD(0xEB, flash_addr, (unsigned char *)cache, INSIDE_FLS_PAGE_SIZE);
451 if (sz > INSIDE_FLS_PAGE_SIZE - page_offset) {
452 MEMCPY(buf_tmp, cache + page_offset, INSIDE_FLS_PAGE_SIZE - page_offset);
453 buf_tmp += INSIDE_FLS_PAGE_SIZE - page_offset;
454 flash_addr += INSIDE_FLS_PAGE_SIZE;
455
456 sz_pagenum = (sz - (INSIDE_FLS_PAGE_SIZE - page_offset)) / INSIDE_FLS_PAGE_SIZE;
457 sz_remain = (sz - (INSIDE_FLS_PAGE_SIZE - page_offset)) % INSIDE_FLS_PAGE_SIZE;
458 for (i = 0; i < sz_pagenum; i++) {
459 __readByCMD(0xEB, flash_addr, (unsigned char *)cache, INSIDE_FLS_PAGE_SIZE);
460 MEMCPY(buf_tmp, cache, INSIDE_FLS_PAGE_SIZE);
461 buf_tmp += INSIDE_FLS_PAGE_SIZE;
462 flash_addr += INSIDE_FLS_PAGE_SIZE;
463 }
464
465 if (sz_remain) {
466 __readByCMD(0xEB, flash_addr, (unsigned char *)cache, sz_remain + (4- sz_remain%4));
467 MEMCPY(buf_tmp, cache, sz_remain);
468 }
469 } else {
470 MEMCPY(buf_tmp, cache + page_offset, sz);
471 }
472 tls_mem_free(cache);
473 }
474
475 return 0;
476 }
477
478 /**
479 * @brief This function is used to unlock flash protect area [0x0~0x2000].
480 *
481 * @param None
482 *
483 * @return 0-success,non-zero-failure
484 *
485 * @note None
486 */
tls_flash_unlock(void)487 int tls_flash_unlock(void)
488 {
489 int ret = 0;
490 if (inside_fls == NULL) {
491 return TLS_FLS_STATUS_EPERM;
492 }
493 tls_os_sem_acquire(inside_fls->fls_lock, 0);
494 ret = flashunlock();
495 tls_os_sem_release(inside_fls->fls_lock);
496
497 return ret;
498 }
499
500 /**
501 * @brief This function is used to lock flash protect area [0x0~0x2000].
502 *
503 * @param None
504 *
505 * @return 0-success,non-zero-failure
506 *
507 * @note None
508 */
tls_flash_lock(void)509 int tls_flash_lock(void)
510 {
511 int ret = 0;
512 if (inside_fls == NULL) {
513 return TLS_FLS_STATUS_EPERM;
514 }
515 tls_os_sem_acquire(inside_fls->fls_lock, 0);
516 ret = flashlock();
517 tls_os_sem_release(inside_fls->fls_lock);
518
519 return ret;
520 }
521
522 /**
523 * @brief This function is used to semaphore protect.
524 *
525 * @param None
526 *
527 * @return None
528 *
529 * @note None
530 */
tls_fls_sem_lock(void)531 void tls_fls_sem_lock(void)
532 {
533 if (inside_fls == NULL) {
534 return;
535 }
536 tls_os_sem_acquire(inside_fls->fls_lock, 0);
537 }
538
539 /**
540 * @brief This function is used to semaphore protect cancel.
541 *
542 * @param None
543 *
544 * @return None
545 *
546 * @note None
547 */
tls_fls_sem_unlock(void)548 void tls_fls_sem_unlock(void)
549 {
550 if (inside_fls == NULL) {
551 return;
552 }
553 tls_os_sem_release(inside_fls->fls_lock);
554 }
555
556 /**
557 * @brief This function is used to read the unique id of the internal flash.
558 *
559 * @param[out] uuid Specified the address to save the uuid, the length must be greater than or equals to 18 bytes.
560 *
561 * @retval TLS_FLS_STATUS_OK if read sucsess
562 * @retval TLS_FLS_STATUS_EIO if read fail
563 *
564 * @note The uuid's length must be greater than or equals to 18 bytes.
565 */
tls_fls_read_unique_id(unsigned char * uuid)566 int tls_fls_read_unique_id(unsigned char *uuid)
567 {
568 unsigned int value = 0;
569 unsigned int addr_read = 0;
570 int i = 0;
571 int len;
572 unsigned char FLASH_BUF[20];
573 unsigned char *addr = &FLASH_BUF[0];
574 int dumy_bytes = 0;
575 int uni_bytes = 0;
576 unsigned char rid;
577 int word;
578 int byte;
579 if (inside_fls == NULL) {
580 return TLS_FLS_STATUS_EPERM;
581 }
582
583 tls_os_sem_acquire(inside_fls->fls_lock, 0);
584 memset(uuid, 0xFF, 18);
585 rid = readRID();
586 switch (rid) {
587 case SPIFLASH_MID_GD:
588 case SPIFLASH_MID_PUYA:
589 case SPIFLASH_MID_TSINGTENG:
590 dumy_bytes = 4;
591 uni_bytes = 16;
592 break;
593 case SPIFLASH_MID_WINBOND:
594 case SPIFLASH_MID_FUDANMICRO:
595 case SPIFLASH_MID_BOYA:
596 case SPIFLASH_MID_XMC:
597 dumy_bytes = 4;
598 uni_bytes = 8;
599 break;
600 case SPIFLASH_MID_ESMT:
601 case SPIFLASH_MID_XTX:
602 default:
603 tls_os_sem_release(inside_fls->fls_lock);
604 return -1;
605 }
606 uuid[0] = rid;
607 uuid[1] = (unsigned char)(uni_bytes & 0xFF);
608 len = dumy_bytes + uni_bytes;
609 word = len/4;
610 byte = len%4;
611
612 value = 0xC04B|((len-1) << 16);
613 M32(HR_FLASH_CMD_ADDR) = value;
614 M32(HR_FLASH_CMD_START) = CMD_START_Msk;
615
616 addr_read = RSA_BASE_ADDRESS;
617 for (i = 0;i < word; i ++) {
618 M32(addr) = M32(addr_read);
619 addr += 4;
620 addr_read += 4;
621 }
622
623 if (byte > 0) {
624 M32(addr) = M32(addr_read);
625 addr += 3; // point last byte
626 while (byte) {
627 *addr = 0;
628 addr --;
629 byte --;
630 }
631 }
632 addr = &FLASH_BUF[0];
633 memcpy(&uuid[2], addr + dumy_bytes, uni_bytes);
634 tls_os_sem_release(inside_fls->fls_lock);
635
636 return 0;
637 }
638
tls_fls_otp_read(u32 addr,u8 * buf,u32 len)639 int tls_fls_otp_read(u32 addr, u8 *buf, u32 len)
640 {
641 int err;
642
643 int word = len/4;
644 int byte = len%4;
645 unsigned long addr_read = 0xBC00C048;
646 volatile unsigned long value;
647 unsigned long addr_offset = 0;
648 unsigned long sz_need = len;
649
650 if (inside_fls == NULL) {
651 TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
652 return TLS_FLS_STATUS_EPERM;
653 }
654 tls_os_sem_acquire(inside_fls->fls_lock, 0);
655
656 if (buf) {
657 addr_offset = addr % 16;
658 sz_need = (addr_offset + len + 16) / 16 * 16;
659 addr = addr / 16 * 16;
660 }
661 M32(HR_FLASH_CMD_ADDR) = addr_read|(((sz_need-1)&0x3FF)<<16);
662 M32(HR_FLASH_ADDR) = (addr&0x1FFFFFF);
663 M32(HR_FLASH_CMD_START) = tls_reg_read32(HR_FLASH_CMD_START) | CMD_START_Msk;
664
665 if (buf) {
666 addr_read = RSA_BASE_ADDRESS + (addr_offset / 4 * 4);
667 int i = (4 - addr_offset % 4) % 4;
668 if (i > len) {
669 byte = len;
670 } else {
671 byte = i;
672 }
673 if (byte) {
674 value = M32(addr_read);
675 memcpy_s(buf, sizeof(buf), ((char *)&value) + 4 - i, byte);
676 addr_read += 4;
677 buf += byte;
678 }
679 word = (len - byte) / 4;
680 for (i = 0;i < word; i ++) {
681 value = M32(addr_read);
682 memcpy_s(buf, sizeof(buf), (char*)&value, 4);
683 buf += 4;
684 addr_read += 4;
685 }
686 byte = (len - byte) % 4;
687 if (byte > 0) {
688 value = M32(addr_read);
689 memcpy_s(buf, sizeof(buf), (char *)&value, byte);
690 }
691 }
692
693 err = TLS_FLS_STATUS_OK;
694 tls_os_sem_release(inside_fls->fls_lock);
695 return err;
696 }
697
tls_fls_otp_write(u32 addr,u8 * buf,u32 len)698 int tls_fls_otp_write(u32 addr, u8 *buf, u32 len)
699 {
700 int ret = 0;
701 unsigned int erasecmd = 0x80000844;
702 unsigned int writecmd = 0x80009042;
703 uint32_t eraseAddr = 0;
704 uint16_t eraseSize = 0;
705 uint16_t pageSize = 0;
706 unsigned char flashid = 0;
707 int l = 0;
708 unsigned char *backbuf = NULL;
709 unsigned long size = 0;
710 unsigned long p = 0;
711 unsigned char *q = NULL;
712
713 if (!buf) {
714 return TLS_FLS_STATUS_EINVAL;
715 }
716 if (inside_fls == NULL) {
717 TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
718 return TLS_FLS_STATUS_EPERM;
719 }
720 eraseSize = inside_fls->OTPWRParam.eraseSize;
721 pageSize = inside_fls->OTPWRParam.pageSize;
722 if (eraseSize == 0 || pageSize == 0) {
723 TLS_DBGPRT_ERR("flash type is not supported!\n");
724 return TLS_FLS_STATUS_ENOSUPPORT;
725 }
726 eraseAddr = addr & ~(eraseSize - 1);
727 if (addr < eraseAddr || len > eraseSize - (addr - eraseAddr)) {
728 return TLS_FLS_STATUS_EINVAL;
729 }
730 TLS_DBGPRT_INFO("addr 0x%x, eraseAddr 0x%x, eraseSize 0x%x, pageSize 0x%x\n", addr, eraseAddr, eraseSize, pageSize);
731 backbuf = tls_mem_alloc(eraseSize);
732 if (!backbuf) {
733 ret = TLS_FLS_STATUS_ENOMEM;
734 goto out;
735 }
736 p = eraseAddr;
737 q = backbuf;
738 size = eraseSize;
739 while (size > 0) {
740 l = size > pageSize ? pageSize : size;
741 if (tls_fls_otp_read(p, q, l) != TLS_FLS_STATUS_OK) {
742 ret = TLS_FLS_STATUS_EPERM;
743 goto out;
744 }
745 q += l;
746 p += l;
747 size -= l;
748 }
749 tls_os_sem_acquire(inside_fls->fls_lock, 0);
750 eraseSR(erasecmd, eraseAddr);
751 memcpy_s(backbuf + (addr - eraseAddr), sizeof(backbuf + (addr - eraseAddr)), buf, len);
752 p = eraseAddr;
753 q = backbuf;
754 size = eraseSize;
755 while (size > 0) {
756 l = size > pageSize ? pageSize : size;
757 programSR(writecmd, p, q, l);
758 q += l;
759 p += l;
760 size -= l;
761 }
762 tls_os_sem_release(inside_fls->fls_lock);
763 out:
764 if (backbuf) {
765 tls_mem_free(backbuf);
766 }
767 return ret;
768 }
769
tls_fls_otp_lock(void)770 int tls_fls_otp_lock(void)
771 {
772 if (inside_fls == NULL) {
773 TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
774 return TLS_FLS_STATUS_EPERM;
775 }
776 tls_os_sem_acquire(inside_fls->fls_lock, 0);
777 switch (inside_fls->flashid) {
778 case SPIFLASH_MID_GD:
779 case SPIFLASH_MID_TSINGTENG:
780 writeLbBit_for_1wreg((1<<10));
781 break;
782 case SPIFLASH_MID_FUDANMICRO:
783 writeLbBit_for_2wreg((1<<10));
784 break;
785 case SPIFLASH_MID_BOYA:
786 case SPIFLASH_MID_XMC:
787 case SPIFLASH_MID_WINBOND:
788 case SPIFLASH_MID_PUYA:
789 writeLbBit_for_2wreg((7<<11));
790 break;
791 case SPIFLASH_MID_XTX:
792 case SPIFLASH_MID_ESMT:
793 default:
794 TLS_DBGPRT_ERR("flash is not supported!\n");
795 return TLS_FLS_STATUS_ENOSUPPORT;
796 }
797 tls_os_sem_release(inside_fls->fls_lock);
798 return 0;
799 }
800
801 /**
802 * @brief This function is used to read data from the flash.
803 *
804 * @param[in] addr is byte offset addr for read from the flash.
805 * @param[in] buf is user for data buffer of flash read
806 * @param[in] len is byte length for read.
807 *
808 * @retval TLS_FLS_STATUS_OK if read sucsess
809 * @retval TLS_FLS_STATUS_EIO if read fail
810 *
811 * @note None
812 */
tls_fls_read(u32 addr,u8 * buf,u32 len)813 int tls_fls_read(u32 addr, u8 *buf, u32 len)
814 {
815 int err;
816
817 if (inside_fls == NULL) {
818 TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
819 return TLS_FLS_STATUS_EPERM;
820 }
821
822 if (((addr & (INSIDE_FLS_BASE_ADDR - 1)) >= inside_fls->density) || (len == 0) || (buf == NULL)) {
823 return TLS_FLS_STATUS_EINVAL;
824 }
825
826 tls_os_sem_acquire(inside_fls->fls_lock, 0);
827
828 flashRead(addr, buf, len);
829
830 err = TLS_FLS_STATUS_OK;
831 tls_os_sem_release(inside_fls->fls_lock);
832 return err;
833 }
834
835 /**
836 * @brief This function is used to write data to the flash.
837 *
838 * @param[in] addr is byte offset addr for write to the flash
839 * @param[in] buf is the data buffer want to write to flash
840 * @param[in] len is the byte length want to write
841 *
842 * @retval TLS_FLS_STATUS_OK if write flash success
843 * @retval TLS_FLS_STATUS_EPERM if flash struct point is null
844 * @retval TLS_FLS_STATUS_ENODRV if flash driver is not installed
845 * @retval TLS_FLS_STATUS_EINVAL if argument is invalid
846 * @retval TLS_FLS_STATUS_EIO if io error
847 *
848 * @note None
849 */
tls_fls_write(u32 addr,u8 * buf,u32 len)850 int tls_fls_write(u32 addr, u8 *buf, u32 len)
851 {
852 u8 *cache;
853 unsigned int secpos;
854 unsigned int secoff;
855 unsigned int secremain;
856 unsigned int i;
857 unsigned int offaddr;
858
859 if (inside_fls == NULL) {
860 TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
861 return TLS_FLS_STATUS_EPERM;
862 }
863
864 if (((addr & (INSIDE_FLS_BASE_ADDR - 1)) >= inside_fls->density) || (len == 0) || (buf == NULL)) {
865 return TLS_FLS_STATUS_EINVAL;
866 }
867
868 tls_os_sem_acquire(inside_fls->fls_lock, 0);
869
870 cache = tls_mem_alloc(INSIDE_FLS_SECTOR_SIZE);
871 if (cache == NULL) {
872 tls_os_sem_release(inside_fls->fls_lock);
873 TLS_DBGPRT_ERR("allocate sector cache memory fail!\n");
874 return TLS_FLS_STATUS_ENOMEM;
875 }
876
877 offaddr = addr & (INSIDE_FLS_BASE_ADDR - 1); // Offset of 0X08000000
878 secpos = offaddr / INSIDE_FLS_SECTOR_SIZE; // Section addr
879 secoff = (offaddr % INSIDE_FLS_SECTOR_SIZE); // Offset in section
880 secremain = INSIDE_FLS_SECTOR_SIZE - secoff; // ����ʣ��ռ��С
881 if (len <= secremain) {
882 secremain = len; // Not bigger with remain size in section
883 }
884
885 flashRead(secpos * INSIDE_FLS_SECTOR_SIZE, cache, INSIDE_FLS_SECTOR_SIZE);
886 while (1) {
887 eraseSector(secpos * INSIDE_FLS_SECTOR_SIZE);
888 for (i = 0; i < secremain; i++) { // ����
889 cache[i + secoff] = buf[i];
890 }
891 for (i = 0; i < (INSIDE_FLS_SECTOR_SIZE / INSIDE_FLS_PAGE_SIZE); i++) {
892 programPage(secpos * INSIDE_FLS_SECTOR_SIZE + i * INSIDE_FLS_PAGE_SIZE, \
893 INSIDE_FLS_PAGE_SIZE, &cache[i * INSIDE_FLS_PAGE_SIZE]); // Write
894 }
895 if (len == secremain) {
896 break; // ������
897 } else { // д��δ����
898 secpos++; // ������ַ��1
899 secoff = 0; // ƫ��λ��Ϊ0
900 buf += secremain; // ָ��ƫ��
901 len -= secremain;
902 if (len > (INSIDE_FLS_SECTOR_SIZE)) {
903 secremain = INSIDE_FLS_SECTOR_SIZE; // ��һ����������д����
904 } else {
905 secremain = len; // Next section will finish
906 flashRead(secpos * INSIDE_FLS_SECTOR_SIZE, cache, INSIDE_FLS_SECTOR_SIZE);
907 }
908 }
909 }
910
911 tls_mem_free(cache);
912 tls_os_sem_release(inside_fls->fls_lock);
913 return TLS_FLS_STATUS_OK;
914 }
915
916 /**
917 * @brief This function is used to write data into the flash without erase.
918 *
919 * @param[in] addr Specifies the starting address to write to
920 * @param[in] buf Pointer to a byte array that is to be written
921 * @param[in] len Specifies the length of the data to be written
922 *
923 * @retval TLS_FLS_STATUS_OK if write flash success
924 * @retval TLS_FLS_STATUS_EPERM if flash struct point is null
925 * @retval TLS_FLS_STATUS_ENODRV if flash driver is not installed
926 * @retval TLS_FLS_STATUS_EINVAL if argument is invalid
927 *
928 * @note Erase action should be excuted by API tls_fls_erase in user layer.
929 */
tls_fls_write_without_erase(u32 addr,u8 * buf,u32 len)930 int tls_fls_write_without_erase(u32 addr, u8 *buf, u32 len)
931 {
932 u8 *cache;
933 unsigned int pagepos;
934 unsigned int pageoff;
935 unsigned int pageremain;
936 unsigned int i;
937 unsigned int offaddr;
938
939 if (inside_fls == NULL) {
940 TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
941 return TLS_FLS_STATUS_EPERM;
942 }
943
944 if (((addr & (INSIDE_FLS_BASE_ADDR - 1)) >= inside_fls->density) || (len == 0) || (buf == NULL)) {
945 return TLS_FLS_STATUS_EINVAL;
946 }
947
948 tls_os_sem_acquire(inside_fls->fls_lock, 0);
949
950 cache = tls_mem_alloc(INSIDE_FLS_PAGE_SIZE);
951 if (cache == NULL) {
952 tls_os_sem_release(inside_fls->fls_lock);
953 TLS_DBGPRT_ERR("allocate page cache memory fail!\n");
954 return TLS_FLS_STATUS_ENOMEM;
955 }
956
957 offaddr = addr & (INSIDE_FLS_BASE_ADDR - 1); // Offset of 0X08000000
958 pagepos = offaddr / INSIDE_FLS_PAGE_SIZE; // Page addr
959 pageoff = (offaddr % INSIDE_FLS_PAGE_SIZE); // Offset in page
960 pageremain = INSIDE_FLS_PAGE_SIZE - pageoff; // size remained in one page
961 if (len <= pageremain) {
962 pageremain = len; // Not bigger with remain size in one page
963 }
964
965 flashRead(pagepos * INSIDE_FLS_PAGE_SIZE, cache, INSIDE_FLS_PAGE_SIZE);
966 while (1) {
967 for (i = 0; i < pageremain; i++) {
968 cache[i + pageoff] = buf[i];
969 }
970
971 programPage(pagepos * INSIDE_FLS_PAGE_SIZE, INSIDE_FLS_PAGE_SIZE, &cache[0]); // Write
972 if (len == pageremain) { // page program over
973 break;
974 } else {
975 pagepos++; // next page
976 pageoff = 0; // page offset set to zero
977 buf += pageremain; // buffer modified
978 len -= pageremain; // len decrease
979 if (len > (INSIDE_FLS_PAGE_SIZE)) {
980 pageremain = INSIDE_FLS_PAGE_SIZE; // size next to write
981 } else {
982 pageremain = len; // last data to write
983 flashRead(pagepos * INSIDE_FLS_PAGE_SIZE, cache, INSIDE_FLS_PAGE_SIZE);
984 }
985 }
986 }
987
988 tls_mem_free(cache);
989 tls_os_sem_release(inside_fls->fls_lock);
990 return TLS_FLS_STATUS_OK;
991 }
992
993 /**
994 * @brief This function is used to erase the appoint sector
995 *
996 * @param[in] sector sector num of the flash, 4K byte a sector
997 *
998 * @retval TLS_FLS_STATUS_OK if read sucsess
999 * @retval other if read fail
1000 *
1001 * @note None
1002 */
tls_fls_erase(u32 sector)1003 int tls_fls_erase(u32 sector)
1004 {
1005 u32 addr;
1006 if (inside_fls == NULL) {
1007 TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
1008 return TLS_FLS_STATUS_EPERM;
1009 }
1010
1011 if (sector >= (inside_fls->density / INSIDE_FLS_SECTOR_SIZE + INSIDE_FLS_BASE_ADDR / INSIDE_FLS_SECTOR_SIZE)) {
1012 TLS_DBGPRT_ERR("the sector to be erase overflow!\n");
1013 return TLS_FLS_STATUS_EINVAL;
1014 }
1015
1016 tls_os_sem_acquire(inside_fls->fls_lock, 0);
1017
1018 addr = sector * INSIDE_FLS_SECTOR_SIZE;
1019
1020 eraseSector(addr);
1021
1022 tls_os_sem_release(inside_fls->fls_lock);
1023
1024 return TLS_FLS_STATUS_OK;
1025 }
1026
1027 static u8 *gsflscache = NULL;
1028 static u32 gsSector = 0;
1029
1030 /**
1031 * @brief This function is used to flush the appoint sector
1032 *
1033 * @param None
1034 *
1035 * @return None
1036 *
1037 * @note None
1038 */
tls_fls_flush_sector(void)1039 static void tls_fls_flush_sector(void)
1040 {
1041 u32 addr;
1042 if (gsSector < (inside_fls->density / INSIDE_FLS_SECTOR_SIZE + INSIDE_FLS_BASE_ADDR / INSIDE_FLS_SECTOR_SIZE)) {
1043 addr = gsSector * INSIDE_FLS_SECTOR_SIZE;
1044
1045 eraseSector(addr);
1046 for (int i = 0; i < INSIDE_FLS_SECTOR_SIZE / INSIDE_FLS_PAGE_SIZE; i++) {
1047 programPage(gsSector * INSIDE_FLS_SECTOR_SIZE +
1048 i * INSIDE_FLS_PAGE_SIZE, INSIDE_FLS_PAGE_SIZE,
1049 &gsflscache[i * INSIDE_FLS_PAGE_SIZE]);
1050 }
1051 }
1052 }
1053
1054 /**
1055 * @brief This function is used to fast write flash initialize
1056 *
1057 * @param None
1058 *
1059 * @retval TLS_FLS_STATUS_OK sucsess
1060 * @retval other fail
1061 *
1062 * @note None
1063 */
tls_fls_fast_write_init(void)1064 int tls_fls_fast_write_init(void)
1065 {
1066 if (inside_fls == NULL) {
1067 TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
1068 return TLS_FLS_STATUS_EPERM;
1069 }
1070 if (gsflscache != NULL) {
1071 TLS_DBGPRT_ERR("tls_fls_fast_write_init installed!\n");
1072 return -1;
1073 }
1074 gsflscache = tls_mem_alloc(INSIDE_FLS_SECTOR_SIZE);
1075 if (gsflscache == NULL) {
1076 TLS_DBGPRT_ERR("tls_fls_fast_write_init malloc err!\n");
1077 return -1;
1078 }
1079 return TLS_FLS_STATUS_OK;
1080 }
1081
1082 /**
1083 * @brief This function is used to destroy fast write flash
1084 *
1085 * @param None
1086 *
1087 * @return None
1088 *
1089 * @note None
1090 */
tls_fls_fast_write_destroy(void)1091 void tls_fls_fast_write_destroy(void)
1092 {
1093 if (gsflscache != NULL) {
1094 if (inside_fls == NULL) {
1095 TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
1096 return;
1097 } else {
1098 tls_os_sem_acquire(inside_fls->fls_lock, 0);
1099 tls_fls_flush_sector();
1100 tls_os_sem_release(inside_fls->fls_lock);
1101 }
1102
1103 tls_mem_free(gsflscache);
1104 gsflscache = NULL;
1105 }
1106 }
1107
1108 /**
1109 * @brief This function is used to fast write data to the flash.
1110 *
1111 * @param[in] addr is byte offset addr for write to the flash
1112 * @param[in] buf is the data buffer want to write to flash
1113 * @param[in] length is the byte length want to write
1114 *
1115 * @retval TLS_FLS_STATUS_OK success
1116 * @retval other fail
1117 *
1118 * @note None
1119 */
tls_fls_fast_write(u32 addr,u8 * buf,u32 length)1120 int tls_fls_fast_write(u32 addr, u8 *buf, u32 length)
1121 {
1122 u32 sector, offset, maxlen, len;
1123
1124 if (inside_fls == NULL) {
1125 TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
1126 return TLS_FLS_STATUS_EPERM;
1127 }
1128 if (((addr & (INSIDE_FLS_BASE_ADDR - 1)) >= inside_fls->density) || (length == 0) || (buf == NULL)) {
1129 return TLS_FLS_STATUS_EINVAL;
1130 }
1131 tls_os_sem_acquire(inside_fls->fls_lock, 0);
1132
1133 sector = addr / INSIDE_FLS_SECTOR_SIZE;
1134 offset = addr % INSIDE_FLS_SECTOR_SIZE;
1135 maxlen = INSIDE_FLS_SECTOR_SIZE;
1136
1137 if ((sector != gsSector) && (gsSector != 0)) {
1138 tls_fls_flush_sector();
1139 }
1140 gsSector = sector;
1141 if (offset > 0) {
1142 maxlen -= offset;
1143 }
1144 while (length > 0) {
1145 len = (length > maxlen) ? maxlen : length;
1146 MEMCPY(gsflscache + offset, buf, len);
1147 if (offset + len >= INSIDE_FLS_SECTOR_SIZE) {
1148 tls_fls_flush_sector();
1149 gsSector++;
1150 }
1151 offset = 0;
1152 maxlen = INSIDE_FLS_SECTOR_SIZE;
1153 buf += len;
1154 length -= len;
1155 }
1156
1157 tls_os_sem_release(inside_fls->fls_lock);
1158
1159 return TLS_FLS_STATUS_OK;
1160 }
1161
1162 /**
1163 * @brief This function is used to erase flash all chip
1164 *
1165 * @param None
1166 *
1167 * @retval TLS_FLS_STATUS_OK sucsess
1168 * @retval other fail
1169 *
1170 * @note None
1171 */
tls_fls_chip_erase(void)1172 int tls_fls_chip_erase(void)
1173 {
1174 int i, j;
1175 u8 *cache;
1176
1177 if (inside_fls == NULL) {
1178 TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
1179 return TLS_FLS_STATUS_EPERM;
1180 }
1181
1182 tls_os_sem_acquire(inside_fls->fls_lock, 0);
1183
1184 cache = tls_mem_alloc(INSIDE_FLS_SECTOR_SIZE);
1185 if (cache == NULL) {
1186 tls_os_sem_release(inside_fls->fls_lock);
1187 TLS_DBGPRT_ERR("allocate sector cache memory fail!\n");
1188 return TLS_FLS_STATUS_ENOMEM;
1189 }
1190
1191 for (i = 0; i < (inside_fls->density - (INSIDE_FLS_SECBOOT_ADDR & 0xFFFFF)) / INSIDE_FLS_SECTOR_SIZE; i ++) {
1192 flashRead(INSIDE_FLS_SECBOOT_ADDR + i * INSIDE_FLS_SECTOR_SIZE, cache, INSIDE_FLS_SECTOR_SIZE);
1193 for (j = 0; j < INSIDE_FLS_SECTOR_SIZE; j++) {
1194 if (cache[j] != 0xFF) {
1195 eraseSector(INSIDE_FLS_SECBOOT_ADDR + i * INSIDE_FLS_SECTOR_SIZE);
1196 break;
1197 }
1198 }
1199 }
1200
1201 tls_mem_free(cache);
1202
1203 tls_os_sem_release(inside_fls->fls_lock);
1204
1205 return TLS_FLS_STATUS_OK;
1206 }
1207
1208 /**
1209 * @brief This function is used to get flash param
1210 *
1211 * @param[in] type the type of the param need to get
1212 * @param[out] param point to addr of out param
1213 *
1214 * @retval TLS_FLS_STATUS_OK sucsess
1215 * @retval other fail
1216 *
1217 * @note None
1218 */
tls_fls_get_param(u8 type,void * param)1219 int tls_fls_get_param(u8 type, void *param)
1220 {
1221 int err;
1222
1223 if (inside_fls == NULL) {
1224 TLS_DBGPRT_ERR("flash driver module not beed installed!\n");
1225 return TLS_FLS_STATUS_EPERM;
1226 }
1227
1228 if (param == NULL) {
1229 return TLS_FLS_STATUS_EINVAL;
1230 }
1231 tls_os_sem_acquire(inside_fls->fls_lock, 0);
1232 err = TLS_FLS_STATUS_OK;
1233 switch (type) {
1234 case TLS_FLS_PARAM_TYPE_ID:
1235 *((u32 *) param) = 0x2013;
1236 break;
1237
1238 case TLS_FLS_PARAM_TYPE_SIZE:
1239 *((u32 *) param) = inside_fls->density;
1240 break;
1241
1242 case TLS_FLS_PARAM_TYPE_PAGE_SIZE:
1243 *((u32 *) param) = INSIDE_FLS_PAGE_SIZE;
1244 break;
1245
1246 case TLS_FLS_PARAM_TYPE_PROG_SIZE:
1247 *((u32 *) param) = INSIDE_FLS_PAGE_SIZE;
1248 break;
1249
1250 case TLS_FLS_PARAM_TYPE_SECTOR_SIZE:
1251 *((u32 *) param) = INSIDE_FLS_SECTOR_SIZE;
1252 break;
1253
1254 default:
1255 TLS_DBGPRT_WARNING("invalid parameter ID!\n");
1256 err = TLS_FLS_STATUS_EINVAL;
1257 break;
1258 }
1259 tls_os_sem_release(inside_fls->fls_lock);
1260 return err;
1261 }
1262
1263 /**
1264 * @brief This function is used to initialize the flash module
1265 *
1266 * @param None
1267 *
1268 * @retval TLS_FLS_STATUS_OK sucsess
1269 * @retval other fail
1270 *
1271 * @note None
1272 */
tls_fls_init(void)1273 int tls_fls_init(void)
1274 {
1275 struct tls_inside_fls *fls;
1276 int err;
1277
1278 if (inside_fls != NULL) {
1279 TLS_DBGPRT_ERR("flash driver module has been installed!\n");
1280 return TLS_FLS_STATUS_EBUSY;
1281 }
1282
1283 fls = (struct tls_inside_fls *) tls_mem_alloc(sizeof(struct tls_inside_fls));
1284 if (fls == NULL) {
1285 TLS_DBGPRT_ERR("allocate @inside_fls fail!\n");
1286 return TLS_FLS_STATUS_ENOMEM;
1287 }
1288
1289 memset_s(fls, sizeof(fls), 0, sizeof(*fls));
1290 err = tls_os_sem_create(&fls->fls_lock, 1);
1291 if (err != TLS_OS_SUCCESS) {
1292 tls_mem_free(fls);
1293 TLS_DBGPRT_ERR("create semaphore @fls_lock fail!\n");
1294 return TLS_FLS_STATUS_ENOMEM;
1295 }
1296 fls->flashid = readRID();
1297 fls->density = getFlashDensity();
1298 fls->OTPWRParam.pageSize = 256;
1299 switch (fls->flashid) {
1300 case SPIFLASH_MID_GD:
1301 fls->OTPWRParam.eraseSize = 1024;
1302 break;
1303 case SPIFLASH_MID_FUDANMICRO:
1304 fls->OTPWRParam.eraseSize = 1024;
1305 if (fls->density <= (1 << 20)) { // 8Mbit
1306 fls->OTPWRParam.eraseSize = 256;
1307 }
1308 break;
1309 case SPIFLASH_MID_TSINGTENG:
1310 case SPIFLASH_MID_BOYA:
1311 case SPIFLASH_MID_XMC:
1312 case SPIFLASH_MID_WINBOND:
1313 fls->OTPWRParam.eraseSize = 256;
1314 break;
1315 case SPIFLASH_MID_PUYA:
1316 fls->OTPWRParam.eraseSize = 512;
1317 break;
1318 case SPIFLASH_MID_XTX:
1319 case SPIFLASH_MID_ESMT:
1320 fls->OTPWRParam.eraseSize = 0; // not support
1321 break;
1322 default:
1323 tls_mem_free(fls);
1324 TLS_DBGPRT_ERR("flash is not supported!\n");
1325 return TLS_FLS_STATUS_ENOSUPPORT;
1326 }
1327
1328 inside_fls = fls;
1329
1330 return TLS_FLS_STATUS_OK;
1331 }
1332
tls_fls_exit(void)1333 int tls_fls_exit(void)
1334 {
1335 TLS_DBGPRT_FLASH_INFO("Not support flash driver module uninstalled!\n");
1336 return TLS_FLS_STATUS_EPERM;
1337 }
1338
1339 /**
1340 * @brief This function is used to initialize system parameter postion by flash density
1341 *
1342 * @param None
1343 *
1344 * @retval None
1345 *
1346 * @note must be called before function tls_param_init
1347 */
tls_fls_sys_param_postion_init(void)1348 void tls_fls_sys_param_postion_init(void)
1349 {
1350 unsigned int density = 0;
1351 int err;
1352 err = tls_fls_get_param(TLS_FLS_PARAM_TYPE_SIZE, (void *)&density);
1353 if (TLS_FLS_STATUS_OK == err) {
1354 TLS_FLASH_END_ADDR = (FLASH_BASE_ADDR|density) - 1;
1355 TLS_FLASH_OTA_FLAG_ADDR = (FLASH_BASE_ADDR|density) - 0x1000;
1356 TLS_FLASH_PARAM_RESTORE_ADDR = (FLASH_BASE_ADDR|density) - 0x2000;
1357 TLS_FLASH_PARAM2_ADDR = (FLASH_BASE_ADDR|density) - 0x3000;
1358 TLS_FLASH_PARAM1_ADDR = (FLASH_BASE_ADDR|density) - 0x4000;
1359 TLS_FLASH_PARAM_DEFAULT = (FLASH_BASE_ADDR|density) - 0x5000;
1360 } else {
1361 TLS_DBGPRT_ERR("system parameter postion use default!\n");
1362 }
1363 }