blob: 5ac40024bd9f8395e66ccfed6a6fa206b9785362 [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001/*****************************************************************************
2* Copyright Statement:
3* --------------------
4* This software is protected by Copyright and the information contained
5* herein is confidential. The software may not be copied and the information
6* contained herein may not be used or disclosed except with the written
7* permission of MediaTek Inc. (C) 2006
8*
9* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
10* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
11* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
12* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
13* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
14* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
15* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
16* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
17* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
18* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
19* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
20* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
21*
22* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
23* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
24* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
25* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
26* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
27*
28* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
29* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
30* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
31* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
32* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
33*
34*****************************************************************************/
35
36/*****************************************************************************
37 *
38 * Filename:
39 * ---------
40 * FTL.c
41 *
42 * Project:
43 * --------
44 * Bootloader
45 *
46 * Description:
47 * ------------
48 * Abstraction layer preparing for FTL
49 *
50 * Author:
51 * -------
52 *
53 *
54 *============================================================================
55 * HISTORY
56 * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
57 *------------------------------------------------------------------------------
58 * removed!
59 * removed!
60 * removed!
61 *
62 * removed!
63 * removed!
64 *
65 * removed!
66 * removed!
67 * removed!
68 *
69 * removed!
70 * removed!
71 * removed!
72 *
73 * removed!
74 * removed!
75 * removed!
76 *
77 * removed!
78 * removed!
79 * removed!
80 *
81 * removed!
82 * removed!
83 * removed!
84 *
85 * removed!
86 * removed!
87 * removed!
88 *
89 * removed!
90 * removed!
91 * removed!
92 *
93 * removed!
94 * removed!
95 * removed!
96 *
97 * removed!
98 * removed!
99 * removed!
100 *
101 * removed!
102 * removed!
103 * removed!
104 *------------------------------------------------------------------------------
105 * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
106 *============================================================================
107 ****************************************************************************/
108
109
110#include "kal_general_types.h"
111#include "kal_public_api.h"
112#include "kal_public_defs.h"
113#include "sw_types.h"
114#include "FTL.h"
115
116#if defined(__EMMC_BOOTING__)
117#include "kal_public_api.h" //MSBB change #include "kal_release.h"
118
119static kal_mutexid ftl_lock = NULL;
120kal_uint32 ftl_task_bitmap[(KAL_MAX_NUM_TASKS + 31) /32];
121#endif /* __EMMC_BOOTING__ */
122
123#ifndef __MTK_TARGET__
124
125FTL_FuncTbl ftlFuncTbl =
126{
127 NULL,
128 NULL,
129 NULL,
130 NULL,
131 NULL,
132 NULL,
133 NULL,
134 NULL,
135 NULL,
136 NULL
137};
138
139
140kal_bool FTL_isPollingMode()
141{
142 return KAL_FALSE;
143}
144
145#elif defined(_NAND_FLASH_BOOTING_)
146
147#include "fota_error.h"
148#include "NAND_DAL.h"
149
150#define MAX_SPARE_SIZE (64)
151
152FTL_STATUS_CODE NFB_ERR_2_FTL_ERR(kal_uint32 error)
153{
154 switch(error)
155 {
156 case ERROR_NFB_SUCCESS:
157 case ERROR_NFB_ECC_CORRECTED:
158 return FTL_SUCCESS;
159
160 case ERROR_NFB_READ:
161 return FTL_ERROR_READ_FAILURE;
162
163 case ERROR_NFB_PROGRAM:
164 return FTL_ERROR_WRITE_FAILURE;
165
166 case ERROR_NFB_ERASE:
167 return FTL_ERROR_ERASE_FAILURE;
168
169 case ERROR_NFB_BAD_BLOCK:
170 return FTL_ERROR_BAD_BLOCK;
171
172 }
173 ASSERT(0);
174 return FTL_SUCCESS;
175}
176
177kal_uint32 FTL_GetBlockSize(kal_uint32 block, FTL_OptParam *opt_param)
178{
179 return DAL_GetBlockSize();
180}
181
182kal_uint32 FTL_GetPageSize()
183{
184 return DAL_GetPageSize();
185}
186
187
188FTL_STATUS_CODE FTL_Init(void *pArgv)
189{
190 DAL_init();
191 return FTL_SUCCESS;
192}
193
194FTL_STATUS_CODE FTL_DeInit(void *pArgv)
195{
196 return FTL_SUCCESS;
197}
198
199FTL_STATUS_CODE FTL_ReadPage(kal_uint32 block, kal_uint32 page, kal_uint32 *pBuf, FTL_OptParam *opt_param)
200{
201 kal_int32 status;
202
203 ASSERT(opt_param == NULL || opt_param->bypass_dal == KAL_FALSE);
204
205 status = (opt_param == NULL || !opt_param->is_polling) ? NFB_ReadPhysicalPage(block, page, pBuf)
206 : demp_ReadPhysicalPage(block, page, pBuf);
207
208 if(status > 0)
209 {
210 return FTL_SUCCESS;
211 }
212 return NFB_ERR_2_FTL_ERR(status);
213}
214
215FTL_STATUS_CODE FTL_WritePage(kal_uint32 block, kal_uint32 page, kal_uint32 *pBuf, FTL_OptParam *opt_param)
216{
217 kal_int32 status = NFB_ProgramPhysicalPage(block, page, pBuf, KAL_TRUE);
218 if(status > 0)
219 {
220 return FTL_SUCCESS;
221 }
222 return NFB_ERR_2_FTL_ERR(status);
223}
224
225FTL_STATUS_CODE FTL_CheckGoodBlock(kal_uint32 block, FTL_OptParam *opt_param)
226{
227 kal_uint32 status = NFB_CheckGoodBlock2(block, KAL_TRUE);
228 if(status == 0)
229 return FTL_SUCCESS;
230 return FTL_ERROR_BAD_BLOCK;
231}
232
233FTL_STATUS_CODE FTL_MarkBadBlock(kal_uint32 block, FTL_OptParam *opt_param)
234{
235 kal_uint32 status = NFB_MarkBadBlock(block, KAL_TRUE);
236 return NFB_ERR_2_FTL_ERR(status);
237}
238
239FTL_STATUS_CODE FTL_EraseBlock(kal_uint32 block, FTL_OptParam *opt_param)
240{
241 kal_uint32 status = NFB_ErasePhysicalBlock(block, KAL_TRUE);
242 return NFB_ERR_2_FTL_ERR(status);
243}
244
245
246FTL_FuncTbl ftlFuncTbl =
247{
248 FTL_Init,
249 FTL_DeInit,
250 FTL_ReadPage,
251 NULL,
252 FTL_WritePage,
253 FTL_CheckGoodBlock,
254 FTL_MarkBadBlock,
255 FTL_EraseBlock,
256 FTL_GetBlockSize,
257 FTL_GetPageSize,
258};
259
260kal_bool FTL_isPollingMode()
261{
262 return KAL_FALSE;
263}
264
265#elif defined(__EMMC_BOOTING__)
266
267#include "sd_adap.h"
268#define EMMC_ID MCDEV_SD0
269#define EMMC_SECTOR_SIZE 512
270
271kal_uint32 FTL_emmcGetBlockSize(kal_uint32 block, FTL_OptParam *opt_param);
272kal_uint32 FTL_emmcGetPageSize();
273
274static kal_bool initialized = KAL_FALSE;
275
276FTL_STATUS_CODE EMMC_ERR_2_FTL_ERR(DRV_STATUS_CODE error)
277{
278 switch(error)
279 {
280 case DRV_SUCCESS:
281 return FTL_SUCCESS;
282
283 case DRV_READ_FAILURE:
284 return FTL_ERROR_READ_FAILURE;
285
286 case DRV_WRITE_FAILURE:
287 return FTL_ERROR_WRITE_FAILURE;
288
289 case DRV_ERASE_FAILURE:
290 return FTL_ERROR_ERASE_FAILURE;
291
292 case DRV_ECC_CORRECTED:
293 return FTL_ERROR_ECC_CORRECTED;
294
295 default:
296 return FTL_ERROR_OTHER_ERROR;
297 }
298 ASSERT(0);
299 return FTL_SUCCESS;
300}
301
302
303FTL_STATUS_CODE FTL_emmcInit(void *pArgv)
304{
305 DRV_STATUS_CODE status = DRV_SUCCESS;
306
307 if(!initialized)
308 {
309 status = DRV_SD_Init();
310 if(status == DRV_SUCCESS)
311 {
312 status = DRV_SD_MountDevice(EMMC_ID, 0);
313
314 if(status == DRV_SUCCESS)
315 {
316 initialized = KAL_TRUE;
317 }
318 }
319 }
320
321 ftl_lock = kal_create_mutex("FTL Lock");
322
323 return EMMC_ERR_2_FTL_ERR(status);
324}
325
326FTL_STATUS_CODE FTL_emmcDeInit(void *pArgv)
327{
328 DRV_STATUS_CODE status = DRV_SUCCESS;
329
330 if(initialized)
331 {
332 status = DRV_SD_DeInit();
333 if(status == DRV_SUCCESS)
334 {
335 initialized = KAL_FALSE;
336 }
337 }
338 return EMMC_ERR_2_FTL_ERR(status);
339}
340
341FTL_STATUS_CODE FTL_emmcReadPage(kal_uint32 block, kal_uint32 page, kal_uint32 *pBuf, FTL_OptParam *opt_param)
342{
343 DRV_STATUS_CODE status;
344 kal_uint32 task_idx, sector;
345
346#if !defined(__FUE__) && !defined(__UBL__)
347 if (opt_param->is_polling)
348 {
349 kal_get_my_task_index(&task_idx);
350
351 get_FTL_lock();
352 /* set the corresponding polling bit */
353 ftl_task_bitmap[task_idx >> 5] |= (0x1 << (task_idx & 31));
354 free_FTL_lock();
355 }
356#endif /* !__FUE__ && !__UBL__ */
357
358 sector = (block * FTL_emmcGetBlockSize(0, NULL)) / EMMC_SECTOR_SIZE
359 + (page * FTL_emmcGetPageSize()) / EMMC_SECTOR_SIZE;
360
361 status = DRV_SD_ReadSectors(EMMC_ID, sector, FTL_emmcGetPageSize()/EMMC_SECTOR_SIZE, pBuf, 0);
362
363#if !defined(__FUE__) && !defined(__UBL__)
364 if (opt_param->is_polling)
365 {
366 get_FTL_lock();
367 /* clear the corresponding polling bit */
368 ftl_task_bitmap[task_idx >> 5] &= ~(0x1 << (task_idx & 31));
369 free_FTL_lock();
370 }
371#endif /* !__FUE__ && !__UBL__ */
372
373 return EMMC_ERR_2_FTL_ERR(status);
374}
375
376FTL_STATUS_CODE FTL_emmcWritePage(kal_uint32 block, kal_uint32 page, kal_uint32 *pBuf, FTL_OptParam *opt_param)
377{
378 DRV_STATUS_CODE status;
379
380 kal_uint32 sector = (block * FTL_emmcGetBlockSize(0, NULL))/EMMC_SECTOR_SIZE + (page * FTL_emmcGetPageSize())/EMMC_SECTOR_SIZE;
381
382 status = DRV_SD_WriteSectors(EMMC_ID, sector, FTL_emmcGetPageSize()/EMMC_SECTOR_SIZE, pBuf, 0);
383
384 return EMMC_ERR_2_FTL_ERR(status);
385}
386
387FTL_STATUS_CODE FTL_emmcCheckGoodBlock(kal_uint32 block, FTL_OptParam *opt_param)
388{
389 return FTL_SUCCESS;
390}
391
392FTL_STATUS_CODE FTL_emmcMarkBadBlock(kal_uint32 block, FTL_OptParam *opt_param)
393{
394 return FTL_SUCCESS;
395}
396
397FTL_STATUS_CODE FTL_emmcEraseBlock(kal_uint32 block, FTL_OptParam *opt_param)
398{
399 DRV_STATUS_CODE status = DRV_SUCCESS;
400 kal_uint32 i;
401 kal_uint32 sector = (block * FTL_emmcGetBlockSize(0, NULL)) / EMMC_SECTOR_SIZE;
402 kal_uint32 sectorCount = FTL_emmcGetBlockSize(0, NULL)/EMMC_SECTOR_SIZE;
403 static kal_uint32 dummyBuf[FTL_EMMC_PAGE_SIZE>>2];
404
405 memset(dummyBuf, 0xff, sizeof(dummyBuf));
406 for(i=0; i<sectorCount && status==DRV_SUCCESS; i+=sizeof(dummyBuf)/EMMC_SECTOR_SIZE)
407 {
408 status = DRV_SD_WriteSectors(EMMC_ID, sector+i, sizeof(dummyBuf)/EMMC_SECTOR_SIZE, dummyBuf, 0);
409 }
410
411 if(status != DRV_SUCCESS)
412 {
413 return FTL_ERROR_ERASE_FAILURE;
414 }
415 else
416 {
417 return FTL_SUCCESS;
418 }
419}
420
421kal_uint32 FTL_emmcGetBlockSize(kal_uint32 block, FTL_OptParam *opt_param)
422{
423 return FTL_EMMC_BLOCK_SIZE;
424}
425
426kal_uint32 FTL_emmcGetPageSize()
427{
428 return FTL_EMMC_PAGE_SIZE;
429}
430
431FTL_FuncTbl ftlFuncTbl =
432{
433 FTL_emmcInit,
434 FTL_emmcDeInit,
435 FTL_emmcReadPage,
436 NULL,
437 FTL_emmcWritePage,
438 FTL_emmcCheckGoodBlock,
439 FTL_emmcMarkBadBlock,
440 FTL_emmcEraseBlock,
441 FTL_emmcGetBlockSize,
442 FTL_emmcGetPageSize
443};
444
445kal_bool FTL_isPollingMode()
446{
447 kal_uint32 task_idx;
448 kal_bool is_polling;
449
450 kal_get_my_task_index(&task_idx);
451 is_polling = ((ftl_task_bitmap[task_idx >> 5] & (0x1 << (task_idx & 31))) != 0) ? KAL_TRUE : KAL_FALSE;
452
453 return is_polling;
454}
455
456#else
457
458#ifdef __NOR_FULL_DRIVER__ //BL_TODO
459
460#include <flash_disk.h>
461
462FTL_STATUS_CODE NOR_ERR_2_FTL_ERR(kal_uint32 error)
463{
464 switch(error)
465 {
466 case ERROR_NOR_SUCCESS:
467 return FTL_SUCCESS;
468
469 case ERROR_NOR_READ:
470 return FTL_ERROR_READ_FAILURE;
471
472 case ERROR_NOR_PROGRAM:
473 return FTL_ERROR_WRITE_FAILURE;
474
475 case ERROR_NOR_ERASE:
476 return FTL_ERROR_ERASE_FAILURE;
477
478 }
479 ASSERT(0);
480 return FTL_SUCCESS;
481}
482
483FTL_STATUS_CODE FTL_Init(void *pArgv)
484{
485 kal_int32 status;
486 static kal_bool initialized = KAL_FALSE;
487
488 if(initialized)
489 {
490 return FTL_SUCCESS;
491 }
492
493 status = NOR_init();
494 initialized = KAL_TRUE;
495
496 return NOR_ERR_2_FTL_ERR(status);
497}
498
499FTL_STATUS_CODE FTL_DeInit(void *pArgv)
500{
501 return FTL_SUCCESS;
502}
503
504FTL_STATUS_CODE FTL_ReadPage(kal_uint32 block, kal_uint32 page, kal_uint32 *pBuf, FTL_OptParam *opt_param)
505{
506 kal_int32 status;
507
508 status = NOR_ReadPhysicalPage(block, page, (kal_uint8*)pBuf);
509
510 return NOR_ERR_2_FTL_ERR(status);
511 }
512
513FTL_STATUS_CODE FTL_WritePage(kal_uint32 block, kal_uint32 page, kal_uint32 *pBuf, FTL_OptParam *opt_param)
514{
515 kal_int32 status;
516
517#if defined(__NOR_FULL_DRIVER__)
518
519 status = NOR_ProgramPhysicalPage(block, page, (kal_uint8*)pBuf);
520
521 return NOR_ERR_2_FTL_ERR(status);
522
523#else
524
525 return FTL_ERROR_WRITE_FAILURE;
526
527#endif
528
529 }
530
531FTL_STATUS_CODE FTL_CheckGoodBlock(kal_uint32 block, FTL_OptParam *opt_param)
532{
533 return FTL_SUCCESS;
534}
535
536FTL_STATUS_CODE FTL_MarkBadBlock(kal_uint32 block, FTL_OptParam *opt_param)
537{
538 return FTL_SUCCESS;
539}
540
541FTL_STATUS_CODE FTL_EraseBlock(kal_uint32 block, FTL_OptParam *opt_param)
542{
543 kal_int32 status;
544
545#if defined(__NOR_FULL_DRIVER__)
546
547 status = NOR_ErasePhysicalBlock(block);
548
549 return NOR_ERR_2_FTL_ERR(status);
550
551#else
552
553 return FTL_ERROR_ERASE_FAILURE;
554
555#endif
556
557}
558
559kal_uint32 FTL_GetBlockSize(kal_uint32 block, FTL_OptParam *opt_param)
560{
561 return NOR_BlockSize(block);
562}
563
564kal_uint32 FTL_GetPageSize()
565{
566 return 2048;
567}
568
569kal_uint32 FTL_AddrToBlockPage(kal_uint32 addr, kal_uint32 *pBlock, kal_uint32 *pPage, FTL_OptParam *opt_param)
570{
571 kal_int32 status;
572 kal_uint32 offset;
573
574 ASSERT(pBlock);
575
576 status = NOR_Addr2BlockIndexOffset(addr, pBlock, &offset);
577
578 if(status == ERROR_NOR_SUCCESS)
579 {
580 *pPage = offset / FTL_GetPageSize();
581 return FTL_SUCCESS;
582 }
583
584 return NOR_ERR_2_FTL_ERR(status);
585}
586
587kal_uint32 FTL_BlockPageToAddr(kal_uint32 Block, kal_uint32 Page, kal_uint32 *addr, FTL_OptParam *opt_param)
588{
589 kal_uint32 offset;
590
591 ASSERT(addr);
592
593 offset = Page * FTL_GetPageSize();
594
595 return NOR_BlockIndexOffset2Addr(Block, offset, addr);
596}
597
598
599FTL_FuncTbl ftlFuncTbl =
600{
601 FTL_Init,
602 FTL_DeInit,
603 FTL_ReadPage,
604 NULL,
605 FTL_WritePage,
606 FTL_CheckGoodBlock,
607 FTL_MarkBadBlock,
608 FTL_EraseBlock,
609 FTL_GetBlockSize,
610 FTL_GetPageSize,
611 FTL_AddrToBlockPage,
612 FTL_BlockPageToAddr
613};
614
615kal_bool FTL_isPollingMode()
616{
617 return KAL_FALSE;
618}
619
620#else
621
622
623FTL_STATUS_CODE FTL_Init(void *pArgv)
624{
625 ASSERT(0);
626 return FTL_SUCCESS;
627}
628
629FTL_STATUS_CODE FTL_DeInit(void *pArgv)
630{
631 ASSERT(0);
632 return FTL_SUCCESS;
633}
634
635FTL_STATUS_CODE FTL_ReadPage(kal_uint32 block, kal_uint32 page, kal_uint32 *pBuf, FTL_OptParam *opt_param)
636{
637 ASSERT(0);
638 return FTL_SUCCESS;
639}
640
641FTL_STATUS_CODE FTL_WritePage(kal_uint32 block, kal_uint32 page, kal_uint32 *pBuf, FTL_OptParam *opt_param)
642{
643 ASSERT(0);
644 return FTL_SUCCESS;
645}
646
647FTL_STATUS_CODE FTL_CheckGoodBlock(kal_uint32 block, FTL_OptParam *opt_param)
648{
649 ASSERT(0);
650 return FTL_SUCCESS;
651}
652
653FTL_STATUS_CODE FTL_MarkBadBlock(kal_uint32 block, FTL_OptParam *opt_param)
654{
655 ASSERT(0);
656 return FTL_SUCCESS;
657}
658
659FTL_STATUS_CODE FTL_EraseBlock(kal_uint32 block, FTL_OptParam *opt_param)
660{
661 ASSERT(0);
662 return FTL_SUCCESS;
663}
664
665kal_uint32 FTL_GetBlockSize(kal_uint32 block, FTL_OptParam *opt_param)
666{
667 ASSERT(0);
668 return 0;
669}
670
671kal_uint32 FTL_GetPageSize()
672{
673 ASSERT(0);
674 return 0;
675}
676
677kal_uint32 FTL_AddrToBlockPage(kal_uint32 addr, kal_uint32 *pBlock, kal_uint32 *pPage, FTL_OptParam *opt_param)
678{
679 ASSERT(0);
680 return FTL_SUCCESS;
681}
682
683kal_uint32 FTL_BlockPageToAddr(kal_uint32 Block, kal_uint32 Page, kal_uint32 *addr, FTL_OptParam *opt_param)
684{
685 ASSERT(0);
686 return FTL_SUCCESS;
687}
688
689FTL_FuncTbl ftlFuncTbl =
690{
691 FTL_Init,
692 FTL_DeInit,
693 FTL_ReadPage,
694 NULL,
695 FTL_WritePage,
696 FTL_CheckGoodBlock,
697 FTL_MarkBadBlock,
698 FTL_EraseBlock,
699 FTL_GetBlockSize,
700 FTL_GetPageSize,
701 FTL_AddrToBlockPage,
702 FTL_BlockPageToAddr
703};
704
705kal_bool FTL_isPollingMode()
706{
707 return KAL_FALSE;
708}
709
710#endif /* BL_TODO */
711
712#endif
713