blob: c7dd8a8526936c6d482a27d07a44420539b8b88f [file] [log] [blame]
yu.dongc33b3072024-08-21 23:14:49 -07001/*****************************************************************************
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 * fota_partial.c
41 *
42 * Project:
43 * --------
44 * Maui_Software
45 *
46 * Description:
47 * ------------
48 * This file implement the function of FOTA firmware update downlaod
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 * removed!
65 *
66 * removed!
67 * removed!
68 * removed!
69 *
70 * removed!
71 * removed!
72 * removed!
73 *
74 * removed!
75 * removed!
76 * removed!
77 *
78 * removed!
79 * removed!
80 * removed!
81 *
82 * removed!
83 * removed!
84 * removed!
85 *
86 * removed!
87 * removed!
88 * removed!
89 *
90 * removed!
91 * removed!
92 * removed!
93 *
94 * removed!
95 * removed!
96 * removed!
97 *
98 * removed!
99 * removed!
100 * removed!
101 *
102 * removed!
103 * removed!
104 * removed!
105 *
106 * removed!
107 * removed!
108 * removed!
109 *
110 * removed!
111 * removed!
112 * removed!
113 *
114 * removed!
115 * removed!
116 * removed!
117 *
118 * removed!
119 * removed!
120 * removed!
121 *
122 * removed!
123 * removed!
124 * removed!
125 *
126 * removed!
127 * removed!
128 * removed!
129 *
130 * removed!
131 * removed!
132 * removed!
133 *
134 * removed!
135 * removed!
136 * removed!
137 *
138 * removed!
139 * removed!
140 * removed!
141 *
142 * removed!
143 * removed!
144 * removed!
145 *
146 * removed!
147 * removed!
148 * removed!
149 *
150 * removed!
151 * removed!
152 * removed!
153 *
154 * removed!
155 * removed!
156 * removed!
157 *
158 * removed!
159 * removed!
160 * removed!
161 *
162 * removed!
163 * removed!
164 * removed!
165 *
166 * removed!
167 * removed!
168 * removed!
169 *
170 * removed!
171 * removed!
172 * removed!
173 *
174 * removed!
175 * removed!
176 * removed!
177 *
178 * removed!
179 * removed!
180 * removed!
181 *
182 * removed!
183 * removed!
184 * removed!
185 *
186 * removed!
187 * removed!
188 * removed!
189 *
190 * removed!
191 * removed!
192 * removed!
193 *
194 *------------------------------------------------------------------------------
195 * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
196 *============================================================================
197 ****************************************************************************/
198/*******************************************
199* Include File
200********************************************/
201#if defined(__FOTA_DM__)
202
203#include "kal_general_types.h"
204#include "kal_debug.h"
205#include <stdio.h>
206#include <stdarg.h>
207#include "fue_err.h"
208#include "fota.h"
209#include "flash_opt.h"
210#include "fat_fs.h"
211#include "custom_fota.h"
212#include "custom_img_config.h"
213#include "fue.h"
214#include "ssf_fue_support.h"
215#include "fue_update_support.h"
216#if defined(__MAUI_BASIC__)
217#include "uart_sw.h"
218#endif /* __MAUI_BASIC__ */
219#if defined(__HP_FOTA__)
220#include "Bitfone_update.h"
221#endif
222
223#include "dcl.h"
224
225#ifdef __EMMC_BOOTING__
226#include "fue_emmc_adapt.h"
227#endif
228
229#define _FUE_PKG_DEBUG_
230
231/*******************************************************************************
232 * Global Function and Structure Definition
233 *******************************************************************************/
234
235FOTA_DATA FOTAData={STATUS_FOTA_NOT_INITIAL};
236
237FOTA_NFB_Update_Control FOTA_Update_Ctrl;
238FOTA_Package_Control_st FOTA_Package_Ctrl;
239
240#pragma arm section zidata = "NONCACHEDZI"
241
242kal_uint32 fota_temp_page_buffer[FOTA_FLASH_MAX_PAGE_SIZE];
243kal_uint32 fota_replace_page_buffer[FOTA_FLASH_MAX_PAGE_SIZE];
244
245#pragma arm section zidata
246
247/*******************************************************************************
248 * Static Function and Structure Definition
249 *******************************************************************************/
250static kal_int32 FOTA_MTD_Read_Buffer(void *Buffer, kal_uint32 read_len);
251
252/* start address of update package reserved area */
253extern const kal_uint32 FOTA_PACKAGE_BASE_ADDRESS;
254
255/* Following functions and data varoables are located in FOTA library */
256extern FUE_ERROR_CODE FUE_InitializeUpdateRecord(kal_uint32 base_blk, kal_uint32 end_blk, \
257 Flash_GAL_st *fgal, dbg_trace_func dbg_trace);
258extern FUE_ERROR_CODE FUE_NFB_Flush_Update_Record(FOTA_Custom_Update_Info* info_buffer, \
259 dbg_trace_func dbg_trace);
260extern FUE_ERROR_CODE FUE_NFB_Get_Update_Record(FOTA_Custom_Update_Info* info_buffer,\
261 dbg_trace_func dbg_trace);
262
263extern FUE_ERROR_CODE FUE_NFB_Allocate_Block(kal_uint32 begin_block, kal_uint32 end_block, \
264 kal_uint32 curr_block, kal_uint32 *alloc_block, \
265 Flash_GAL_st *fgal, IsBlockAvailable_func check_available, \
266 dbg_trace_func dbg_trace);
267
268extern FUE_ERROR_CODE FUE_BlkInfo_Resume_Package_Blocks(FOTA_Package_Control_st *pkg_ctrl, \
269 kal_uint32 *found_blocks, \
270 /*FOTA_Package_Location_st *found_list, \*/
271 FOTA_Package_List_st *found_list,\
272 kal_uint32 *buff_ptr, \
273 kal_uint32 *buff_len, \
274 /*alloc_pkg_blk alloc_blk, \*/
275 dbg_trace_func dbg_trace);
276
277extern kal_bool FUE_NFB_Is_Available_Block(kal_uint32 block_idx, kal_uint32* buff_ptr, Flash_GAL_st *fgal, \
278 dbg_trace_func dbg_trace);
279
280extern FUE_ERROR_CODE FUE_NFB_Replace_Current_Package_Block(FOTA_Package_Control_st *pkg_ctrl,\
281 kal_uint32 *buff_ptr, \
282 dbg_trace_func dbg_trace);
283
284extern FUE_ERROR_CODE FUE_NFB_Mark_Package_Block_Complete(FOTA_Package_Control_st *pkg_ctrl, \
285 FOTA_Package_Info_st *pkg_info, dbg_trace_func dbg_trace);
286
287extern FUE_ERROR_CODE FUE_NFB_Allocate_PackageBlock(FOTA_Package_Control_st *pkg_ctrl, kal_uint32 start_block, \
288 kal_uint32 *alloc_block, dbg_trace_func dbg_trace);
289
290extern FUE_ERROR_CODE FUE_NFB_Create_Package_Block(FOTA_Package_Control_st *pkg_ctrl, kal_uint32 block_index,\
291 kal_uint32 last_block, kal_uint32 replace_block, \
292 kal_bool add_session, dbg_trace_func dbg_trace);
293
294extern FUE_ERROR_CODE FUE_CreateInitialUpdateRecord(FOTA_NFB_Update_Control *update_ctrl, kal_uint32 start_block, \
295 Flash_GAL_st *fgal, dbg_trace_func dbg_trace);
296
297extern FUE_ERROR_CODE FUE_BlkInfo_Is_Package_Block(FOTA_Package_Control_st *pkg_ctrl, kal_uint32 blk_num, dbg_trace_func dbg_trace);
298
299extern FUE_ERROR_CODE FUE_BlkInfo_Is_Update_Block(FOTA_NFB_Update_Control *update_ctrl, kal_uint32 blk_num, dbg_trace_func dbg_trace);
300
301extern kal_uint32 SSF_GetMAUIImageNumber(void);
302
303extern void FUE_Start_Download_State(void);
304
305extern void FUE_Start_Package_Verification_State(void);
306
307extern FOTA_Area_Info_Wrapper_st FOTA_NFB_Area_Info;
308
309/* For update package block management */
310extern FOTA_Package_List_st g_fota_package_blocks[FOTA_PACKAGE_BLOCK_NUMBER];
311extern kal_uint32 FOTA_PKG_BLOCKS;
312
313/* Following functions are located in init.c */
314extern kal_uint32 INT_GetCurrentTime(void);
315
316
317/* the NFI access synchronization is implemented in NAND flash MTD layer */
318#define FOTA_LOCK()
319#define FOTA_UNLOCK()
320
321/* Forward declaration */
322Flash_GAL_st *FOTA_Setup_FGAL(void);
323static kal_int32 FOTA_MTD_Program_Buffer(void *Buffer, kal_uint32 write_len);
324
325kal_int32 FOTA_InitializeUpdateRecord(void);
326
327kal_int32 FOTA_InitializePackageReservoir(void);
328kal_int32 FOTA_FinishPackageBlock(void);
329kal_int32 FOTA_CheckAvailablePackageBlocks(kal_uint32 *available_num);
330kal_int32 FOTA_ClearPackageReservoir(void);
331kal_int32 FOTA_Get_TotalPackageBlock(kal_uint32 *pkg_blks, kal_uint32* pkg_pages);
332kal_int32 FOTA_Get_CurrentPackagePosition(kal_uint32 *curr_blks, kal_uint32* curr_pages);
333kal_int32 FOTA_ProgramPackagePage(void* buff, kal_uint32 *page_size);
334
335kal_int32 FOTA_GetPackageFlashInfo(kal_uint32 *blk_size, kal_uint32 *page_size);
336
337#if defined(__MAUI_BASIC__)
338
339
340#endif /* __MAUI_BASIC__ */
341/*****************************************************************
342Description : dump trace via kal_print function.
343Input :
344Output : None
345******************************************************************/
346kal_char g_char_buff[512];
347void fue_dbg_print(kal_char* fmt, ...)
348{
349 va_list trace_p;
350 va_start(trace_p, fmt);
351 vsprintf(g_char_buff, fmt, trace_p);
352 va_end(trace_p);
353 kal_print(g_char_buff);
354#if defined(__MAUI_BASIC__)
355 if(KAL_FALSE == kal_query_systemInit())
356 {
357 while(!UART_CheckTxBufferEmpty(uart_port1)); /* wait for UART dump complete */
358 }
359#endif
360}
361
362/* ---------------------------------------------------------------------------------
363FUNCTION
364 FOTA_Package_Blk_Address
365DESCRIPTION
366 convert to block aligned address
367PARAMETER
368 NULL
369RETURN
370 INVALOD_DWORD : out of range
371--------------------------------------------------------------------------------- */
372kal_uint32 FOTA_Package_Blk_Address(FOTA_Package_Control_st *pkg_ctrl, kal_uint32 dst_addr)
373{
374 Logical_Flash_info_st info;
375 kal_uint32 blk_idx = 0;
376 kal_uint32 blk_addr = 0;
377 kal_uint32 phy_blk = 0;
378 kal_uint32 curr_blk_num = pkg_ctrl->m_fota_pkg_blocks;
379 Flash_GAL_st *fgal = pkg_ctrl->m_pkg_fgal;
380
381 ASSERT(fgal);
382
383 fgal->query_info(&info);
384 for(blk_idx = 0 ; blk_idx < curr_blk_num ; blk_idx++)
385 {
386 phy_blk = pkg_ctrl->m_fota_pkg_list[blk_idx].m_pkg_block_position;
387 blk_addr += (fgal->block_size(phy_blk)- 2*info.Flash_page_size);
388 if(blk_addr >= dst_addr)
389 break;
390 }
391 if( blk_idx == curr_blk_num )
392 {
393 fue_dbg_print("FOTA_Package_Blk_Idx: address:0x%x is beyond available %dblks!\n\r",
394 dst_addr, curr_blk_num);
395 ASSERT(0);
396 return INVALID_DWORD;
397 }
398 else
399 {
400 if(blk_addr == dst_addr)
401 fue_dbg_print("FOTA_Package_Blk_Idx: address:0x%x is on the bounadry of blk:%d(%d)!\n\r",
402 dst_addr, blk_idx, phy_blk);
403
404 return blk_addr;
405 }
406}
407
408/* ---------------------------------------------------------------------------------
409FUNCTION
410 FOTA_Initialize
411DESCRIPTION
412 FOTA Initialization API
413 1. Initialize data structure and progress initial step
414PARAMETER
415 NULL
416RETURN
417 0: means pass initialization step (ERROR_FOTA_SUCCESS)
418 < 0: means fail
419 ERROR_FOTA_CUSTOMIZATION: wrong customization
420--------------------------------------------------------------------------------- */
421kal_int32 FOTA_Initialize(void)
422{
423 kal_int32 Ret;
424
425 if( STATUS_FOTA_INITIALIZED == FOTAData.Status )
426 {
427 return ERROR_FOTA_SUCCESS;
428 }
429
430 Ret = FOTA_InitializeUpdateRecord();
431 if( (ERROR_FOTA_NO_AVAILABLE_BLOCK == Ret) || (ERROR_FUE_OPERATION_STOP == Ret) ||
432 (ERROR_FUE_OVER_DESIGN == Ret) )
433 return Ret;
434
435 Ret = FOTA_InitializePackageReservoir();
436
437 if(ERROR_FOTA_INVALID_PARAMETER == Ret)
438 {
439 return Ret;
440 }
441 fue_dbg_print("FOTA_Initialize: %d updatable images!\n\r", SSF_GetMAUIImageNumber());
442
443 FOTAData.SpareCurrWriteAddr = 0;
444 FOTAData.SpareNextWriteBlockAddr = 0;
445 FOTAData.SpareCurrReadAddr = 0;
446 FOTAData.SpareNextReadBlockAddr = 0;
447 FOTAData.BufferIndex = 0;
448
449 if((Ret = FOTA_CustomInitialize()) < 0)
450 return Ret;
451 else
452 FOTAData.Status = STATUS_FOTA_INITIALIZED;
453 return ERROR_FOTA_SUCCESS;
454}
455
456/* ---------------------------------------------------------------------------------
457FUNCTION
458 FOTA_WriteData
459DESCRIPTION
460 FOTA write data API
461 1. This function is used to write data to spare image pool
462 2. This API only allow sequentially writing mechanism
463 3. Authentication mechanism is executed during writing
464PARAMETER
465 Length: the length of writing (Unit: Bytes)
466 Buffer: the start address of buffer
467RETURN
468 0: means pass write success (ERROR_FOTA_SUCCESS)
469 < 0: writing action is fail
470 ERROR_FOTA_AUTH_ROMINFO: authentication fail, can't find rom info
471 ERROR_FOTA_AUTH_FATBEGIN: authentication fail, fat begin address is different
472 ERROR_FOTA_AUTH_FATLEN: authentication fail, fat length is different
473 ERROR_FOTA_AUTH_HCHECKSUM: authentication fail, header checksum fail
474 ERROR_FOTA_AUTH_ID: authentication fail, platform id is different
475 ERROR_FOTA_AUTH_VERSION: authentication fail, downgrade is not allowed
476 ERROR_FOTA_AUTH_IMAGELEN: authentication fail, image length too large
477 ERROR_FOTA_AUTH_FAIL: authentication fail before
478 ERROR_FOTA_OVERRANGE: write over the spare image pool range
479 ERROR_FOTA_NOT_INITIALIZED: not call FOTA_Initialize before
480--------------------------------------------------------------------------------- */
481kal_int32 FOTA_WriteData(kal_uint32 Length, void* Buffer)
482{
483 kal_int32 result;
484 kal_uint32 buff_addr = (kal_uint32)Buffer;
485 kal_uint8 *byte_ptr = NULL;
486
487 if (FOTAData.Status == STATUS_FOTA_NOT_INITIAL)
488 return ERROR_FOTA_NOT_INITIALIZED;
489
490 while(Length > 0)
491 {
492 if ((FOTAData.BufferIndex+Length)>=FOTA_BUFFER_SIZE)
493 {
494 /* no data in write buffer and user buffer is 4-byte aligned */
495 if( (FOTAData.BufferIndex == 0) && (0 == (buff_addr & 0x03)) )
496 {
497 result = FOTA_MTD_Program_Buffer((void*)buff_addr, FOTA_BUFFER_SIZE);
498 if (result < 0)
499 return result;
500 buff_addr += FOTA_BUFFER_SIZE;
501 Length -= FOTA_BUFFER_SIZE;
502 }
503 else
504 {
505 if(FOTAData.BufferIndex != FOTA_BUFFER_SIZE)
506 {
507 byte_ptr = (kal_uint8 *)(((kal_uint32)FOTAData.FOTAWriteBuffer) + FOTAData.BufferIndex);
508 //kal_mem_cpy((void*)&FOTAData.FOTABuffer[FOTAData.BufferIndex>>2], Buffer, FOTA_BUFFER_SIZE - FOTAData.BufferIndex);
509 kal_mem_cpy(byte_ptr, (void *)buff_addr, FOTA_BUFFER_SIZE - FOTAData.BufferIndex);
510 buff_addr += (FOTA_BUFFER_SIZE - FOTAData.BufferIndex);
511 Length -= (FOTA_BUFFER_SIZE - FOTAData.BufferIndex);
512 FOTAData.BufferIndex = FOTA_BUFFER_SIZE;
513 }
514 result = FOTA_MTD_Program_Buffer((void*)FOTAData.FOTAWriteBuffer, FOTA_BUFFER_SIZE);
515 if (result < 0)
516 return result;
517 FOTAData.BufferIndex = 0;
518 }
519 }
520 else
521 {
522 byte_ptr = (kal_uint8 *)(((kal_uint32)FOTAData.FOTAWriteBuffer) + FOTAData.BufferIndex);
523 //kal_mem_cpy((void*)&FOTAData.FOTABuffer[FOTAData.BufferIndex/4], Buffer, Length);
524 kal_mem_cpy(byte_ptr, (void *)buff_addr, Length);
525 FOTAData.BufferIndex += Length;
526 buff_addr += Length;
527 Length = 0;
528 }
529 }
530 return ERROR_FOTA_SUCCESS;
531}
532
533/* ---------------------------------------------------------------------------------
534FUNCTION
535 FOTA_ReadData
536DESCRIPTION
537 FOTA read data API
538 1. This function is used to read data from spare image pool
539 2. This API only support sequentially read operation, i.e. from low address to high address
540PARAMETER
541 Length: the length of reading (Unit: Bytes)
542 Buffer: the start address of buffer
543RETURN
544 0: means pass write success (ERROR_FOTA_SUCCESS)
545 < 0: writing action is fail
546 ERROR_FOTA_AUTH_ROMINFO: authentication fail, can't find rom info
547 ERROR_FOTA_AUTH_FATBEGIN: authentication fail, fat begin address is different
548 ERROR_FOTA_AUTH_FATLEN: authentication fail, fat length is different
549 ERROR_FOTA_AUTH_HCHECKSUM: authentication fail, header checksum fail
550 ERROR_FOTA_AUTH_ID: authentication fail, platform id is different
551 ERROR_FOTA_AUTH_VERSION: authentication fail, downgrade is not allowed
552 ERROR_FOTA_AUTH_IMAGELEN: authentication fail, image length too large
553 ERROR_FOTA_AUTH_FAIL: authentication fail before
554 ERROR_FOTA_OVERRANGE: write over the spare image pool range
555 ERROR_FOTA_NOT_INITIALIZED: not call FOTA_Initialize before
556--------------------------------------------------------------------------------- */
557kal_int32 FOTA_ReadData(kal_uint32 Length, void* Buffer)
558{
559 kal_int32 result = ERROR_FOTA_SUCCESS;
560 kal_uint32 buffer_addr = (kal_uint32)Buffer;
561 kal_uint32 read_len = 0;
562 kal_uint32 copy_size = 0;
563
564 if (FOTAData.Status == STATUS_FOTA_NOT_INITIAL)
565 return ERROR_FOTA_NOT_INITIALIZED;
566
567 while(Length > read_len)
568 {
569 if( ( (Length-read_len) >= FOTA_BUFFER_SIZE) && (0 == ((buffer_addr)&0x03)) )
570 {
571 /* directly read into user's buffer */
572 result = FOTA_MTD_Read_Buffer((void*)buffer_addr, FOTA_BUFFER_SIZE);
573 if(result < 0)
574 break;
575 buffer_addr += FOTA_BUFFER_SIZE;
576 read_len += FOTA_BUFFER_SIZE;
577 }
578 else
579 {
580 if( (Length-read_len) >= FOTA_BUFFER_SIZE)
581 copy_size = FOTA_BUFFER_SIZE;
582 else
583 copy_size = (Length-read_len);
584
585 /* read into temporary buffer */
586 result = FOTA_MTD_Read_Buffer(FOTAData.FOTAReadBuffer, copy_size);
587 if (result < 0)
588 break;
589
590 kal_mem_cpy((void *)buffer_addr, FOTAData.FOTAReadBuffer, copy_size);
591 buffer_addr += copy_size;
592 read_len += copy_size;
593 }
594 }
595
596 return result;
597}
598
599/* ---------------------------------------------------------------------------------
600FUNCTION
601 FOTA_Finalize
602DESCRIPTION
603 FOTA finalization API
604 1. compare calculated checksum with image checksum in the header after
605 whole image is written
606 2. mark the status to UPDATE_NEEDED
607PARAMETER
608 void
609RETURN
610 0: means pass error check step (ERROR_FOTA_SUCCESS)
611 < 0: means fail
612 ERROR_FOTA_AUTH_FAIL: authentication fail, final step is not allowed
613 ERROR_FOTA_IMAGE_CHECKSUM: image checksum error
614--------------------------------------------------------------------------------- */
615kal_int32 FOTA_Finalize(void)
616{
617 kal_int32 result = 0;
618
619 if (FOTAData.Status == STATUS_FOTA_NOT_INITIAL)
620 return ERROR_FOTA_NOT_INITIALIZED;
621
622 if(FOTAData.BufferIndex != 0)
623 {
624 result = FOTA_MTD_Program_Buffer((void*)FOTAData.FOTAWriteBuffer, FOTAData.BufferIndex);
625 FOTA_FinishPackageBlock();
626 if (result < 0)
627 return result;
628 FOTAData.BufferIndex = 0;
629 }
630
631 FOTAData.Status = STATUS_FOTA_FINAL;
632
633 return ERROR_FOTA_SUCCESS;
634}
635
636/* --------------------------------------------------------------------------------- *
637 * Flash device wrapper functions
638 * --------------------------------------------------------------------------------- */
639
640/************************************************************************************
641 * NAND flash part
642 *************************************************************************************/
643static kal_int32 FOTA_MTD_Program_Buffer(void *Buffer, kal_uint32 write_len)
644{
645 kal_uint32 buff_offset = 0;
646 kal_int32 left_length = write_len;
647 kal_uint32 page_size = 0;
648 kal_int32 ret_code = ERROR_FOTA_SUCCESS;
649
650 if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
651 {
652 ASSERT(0);
653 return ERROR_FOTA_NOT_INITIALIZED;
654 }
655
656 while(left_length > 0)
657 {
658 ret_code = FOTA_ProgramPackagePage((void*)(((kal_uint32)Buffer)+buff_offset), &page_size);
659 if(ERROR_FOTA_SUCCESS == ret_code)
660 {
661 buff_offset += page_size;
662 left_length -= page_size;
663 FOTAData.SpareCurrWriteAddr += page_size;
664 }
665 else if( (ERROR_FOTA_NO_AVAILABLE_BLOCK == ret_code) || (ERROR_FOTA_FLASH_DEVICE==ret_code) ||
666 (ERROR_FOTA_UNSUPPORTED_CASES == ret_code) )
667 {
668 break;
669 }
670 }
671 return ret_code;
672
673}
674
675/* ---------------------------------------------------------------------------------
676FUNCTION
677 FOTA_FinishePackageBlock
678DESCRIPTION
679 download is finished, complete current package block
680PARAMETER
681 NULL
682RETURN
683 0: means pass initialization step (ERROR_FOTA_SUCCESS)
684 < 0: means fail
685 ERROR_FOTA_CUSTOMIZATION: wrong customization
686--------------------------------------------------------------------------------- */
687kal_int32 FOTA_FinishPackageBlock(void)
688{
689 kal_uint32 page_per_blk = 0;
690 FOTA_Package_Info_st *pkg_info = NULL;
691 kal_int32 ret_code = ERROR_FOTA_SUCCESS;
692 FUE_ERROR_CODE result = ERROR_FUE_NONE;
693 Logical_Flash_info_st info;
694 Flash_GAL_st *fgal = FOTA_Package_Ctrl.m_pkg_fgal;
695
696 if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
697 {
698 ASSERT(0);
699 return ERROR_FOTA_NOT_INITIALIZED;
700 }
701 ASSERT(fgal);
702 pkg_info = &FOTA_Package_Ctrl.m_fota_pkg_info;;
703 //page_per_blk = 1 << FOTA_Package_Ctrl.m_fota_flash_info.Flash_offset_shift;
704 fgal->query_info(&info);
705 page_per_blk = fgal->block_size(pkg_info->m_pkg_current_block)/info.Flash_page_size;
706
707 if(pkg_info->m_pkg_current_page == page_per_blk)
708 {
709 /* current package has been marked as complete in last package program operation */
710 if( pkg_info->m_pkg_valid_pages == (page_per_blk-3))
711 {
712 fue_dbg_print("FOTA_FinishPackageBlock: mark blk:%d as complete is already done!\n\r",\
713 pkg_info->m_pkg_current_block);
714 }
715 #ifdef _FUE_PKG_DEBUG_
716 else
717 {
718 fue_dbg_print("FOTA_FinishPackageBlock: incomplete blk:%d has been marked complete already!\n\r",\
719 pkg_info->m_pkg_current_block);
720 #if defined(__FOTA_DEBUG_ASSERT__)
721 ASSERT(0);
722 #endif /* __FOTA_DEBUG_ASSERT__ */
723 }
724 #endif /* _FUE_PKG_DEBUG_ */
725
726 /* indicate current package download is done */
727 FOTA_Package_Ctrl.m_fota_pkg_index = INVALID_DWORD;
728 }
729 else
730 {
731 while(1)
732 {
733 /* mark this package block as complete */
734 result = FUE_NFB_Mark_Package_Block_Complete(&FOTA_Package_Ctrl, pkg_info, fue_dbg_print);
735 if(ERROR_FUE_NONE == result)
736 {
737 fue_dbg_print("FOTA_FinishPackageBlock: mark blk:%d as complete done!\n\r",\
738 pkg_info->m_pkg_current_block);
739 /* indicate current package download is done */
740 FOTA_Package_Ctrl.m_fota_pkg_index = INVALID_DWORD;
741 break;
742 }
743 else if(ERROR_FUE_PROGRAM_FAILED == result)
744 {
745 /* block replacement procedure - caused by marking complete function */
746 result = FUE_NFB_Replace_Current_Package_Block(&FOTA_Package_Ctrl, fota_replace_page_buffer, \
747 fue_dbg_print);
748 if( ERROR_FUE_OVER_DESIGN == result )
749 {
750 ret_code = ERROR_FOTA_UNSUPPORTED_CASES;
751 break;
752 }
753 else if( ERROR_FUE_NO_AVAILABLE_BLOCK == result )
754 {
755 ret_code = ERROR_FOTA_NO_AVAILABLE_BLOCK;
756 break;
757 }
758 else if(ERROR_FUE_NOT_INITIALIZED == result)
759 {
760 ret_code = ERROR_FOTA_NOT_INITIALIZED;
761 break;
762 }
763 }
764 else
765 {
766 /* unexpected status, abort current update package */
767 fue_dbg_print("FOTA_FinishPackageBlock: unexpected error on blk:%d, Abort!!\n\r",\
768 pkg_info->m_pkg_current_block);
769 break;
770 }
771 }
772 }
773 return ret_code;
774}
775
776/* ---------------------------------------------------------------------------------
777FUNCTION
778 FOTA_ProgramPackagePage
779DESCRIPTION
780 clear downloaded update package
781PARAMETER
782 NULL
783RETURN
784 0: means pass initialization step (ERROR_FOTA_SUCCESS)
785 < 0: means fail
786 ERROR_FOTA_CUSTOMIZATION: wrong customization
787--------------------------------------------------------------------------------- */
788kal_int32 FOTA_ProgramPackagePage(void* buff, kal_uint32 *page_size)
789{
790 kal_int32 ret_code = ERROR_FOTA_SUCCESS;
791 kal_uint32 page_per_blk = 0;
792 kal_uint32 curr_blk = INVALID_DWORD;
793 kal_uint32 curr_order = INVALID_DWORD;
794 kal_uint32 alloc_block = INVALID_DWORD;
795 FOTA_Package_Info_st *pkg_info = NULL;
796 Logical_Flash_info_st info;
797 Flash_GAL_st *fgal = FOTA_Package_Ctrl.m_pkg_fgal;
798 _FGAL_ERROR_CODE status = ERROR_FGAL_NONE;
799 FUE_ERROR_CODE result = ERROR_FUE_NONE;
800 kal_bool op_done = KAL_FALSE;
801
802 if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
803 {
804 ASSERT(0);
805 return ERROR_FOTA_NOT_INITIALIZED;
806 }
807 ASSERT(fgal);
808
809 pkg_info = &FOTA_Package_Ctrl.m_fota_pkg_info;
810 fgal = FOTA_Package_Ctrl.m_pkg_fgal;
811 //page_per_blk = 1 << FOTA_Package_Ctrl.m_fota_flash_info.Flash_offset_shift;
812 fgal->query_info(&info);
813 *page_size = 0;
814
815 if( INVALID_DWORD != pkg_info->m_pkg_current_block )
816 {
817 page_per_blk = fgal->block_size(pkg_info->m_pkg_current_block)/info.Flash_page_size;
818 if( pkg_info->m_pkg_current_page < (page_per_blk-1) )
819 {
820 do
821 {
822 if(pkg_info->m_pkg_current_page == (page_per_blk-2))
823 {
824 /* mark current package block as complete */
825 result = FUE_NFB_Mark_Package_Block_Complete(&FOTA_Package_Ctrl, pkg_info, fue_dbg_print);
826 if(ERROR_FUE_NONE == result)
827 {
828 break;
829 }
830 }
831 else if(0 == *page_size)
832 {
833 status = fgal->write_page(buff, pkg_info->m_pkg_current_block, pkg_info->m_pkg_current_page);
834 if(ERROR_FGAL_NONE == status)
835 {
836 pkg_info->m_pkg_current_page++;
837 pkg_info->m_pkg_valid_pages++;
838 FOTA_Package_Ctrl.m_fota_pkg_pages++;
839 *page_size = info.Flash_page_size;
840 op_done = KAL_TRUE;
841 }
842 else if(ERROR_FGAL_OPERATION_RETRY == status)
843 {
844 ret_code = ERROR_FOTA_FLASH_DEVICE;
845 break;
846 }
847 }
848 else
849 {
850 /* package page program done */
851 break;
852 }
853
854 if( (ERROR_FGAL_WRITE_FAILURE == status) || (ERROR_FUE_PROGRAM_FAILED == result) )
855 {
856 /* copy valid pages in bad block to new package block */
857 result = FUE_NFB_Replace_Current_Package_Block(&FOTA_Package_Ctrl, fota_replace_page_buffer, \
858 fue_dbg_print);
859 if( ERROR_FUE_OVER_DESIGN == result )
860 {
861 ret_code = ERROR_FOTA_UNSUPPORTED_CASES;
862 break;
863 }
864 else if( ERROR_FUE_NO_AVAILABLE_BLOCK == result )
865 {
866 ret_code = ERROR_FOTA_NO_AVAILABLE_BLOCK;
867 break;
868 }
869 else if( ERROR_FUE_NOT_INITIALIZED == result )
870 {
871 ret_code = ERROR_FOTA_NOT_INITIALIZED;
872 break;
873 }
874 }
875 }while(1);
876 }
877 }
878 /*
879 * else start to allocate new package block
880 */
881
882 if(!op_done)
883 {
884 if(INVALID_DWORD == pkg_info->m_pkg_current_block)
885 {
886 ASSERT(INVALID_DWORD == FOTA_Package_Ctrl.m_fota_pkg_index);
887 ASSERT(INVALID_DWORD == pkg_info->m_pkg_block_session);
888 curr_blk = FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_base;
889 curr_order = INVALID_DWORD;
890 }
891 else
892 {
893 ASSERT(INVALID_DWORD != FOTA_Package_Ctrl.m_fota_pkg_index);
894 curr_blk = pkg_info->m_pkg_current_block;
895 curr_order = FOTA_Package_Ctrl.m_fota_pkg_list[FOTA_Package_Ctrl.m_fota_pkg_index].m_pkg_block_order;
896 FOTA_Package_Ctrl.m_fota_pkg_list[FOTA_Package_Ctrl.m_fota_pkg_index].m_pkg_valid_pages =
897 pkg_info->m_pkg_valid_pages;
898 FOTA_Package_Ctrl.m_fota_pkg_list[FOTA_Package_Ctrl.m_fota_pkg_index].m_pkg_block_complete =
899 KAL_TRUE;
900 }
901 while(1)
902 {
903 /* allocate new package block */
904 result = FUE_NFB_Allocate_PackageBlock(&FOTA_Package_Ctrl, curr_blk, &alloc_block, fue_dbg_print);
905 if(ERROR_FUE_NONE == result)
906 {
907 status = fgal->erase_block(alloc_block);
908 if(ERROR_FGAL_ERASE_FAILURE == status)
909 {
910 fgal->mark_bad(alloc_block);
911 curr_blk = alloc_block;
912 continue;
913 }
914 else if(ERROR_FGAL_NONE != status)
915 {
916 fue_dbg_print("FOTA_ProgramPackagePage: erase operation on block:%d error!\n\r", \
917 alloc_block);
918 ret_code = ERROR_FOTA_FLASH_DEVICE;
919 break;
920 }
921 /* create package block */
922 result = FUE_NFB_Create_Package_Block(&FOTA_Package_Ctrl, alloc_block, \
923 pkg_info->m_pkg_current_block,\
924 INVALID_DWORD, KAL_TRUE, fue_dbg_print);
925 if( (ERROR_FUE_INSUFFICIENT_BUFFER == result) || (ERROR_FUE_INVALID_PARAMETER == result) )
926 {
927 ret_code = ERROR_FOTA_INVALID_PARAMETER;
928 break;
929 }
930 else if(ERROR_FUE_NONE == result)
931 {
932 status = fgal->write_page(buff, alloc_block, 1);
933 if(ERROR_FGAL_NONE == status)
934 {
935 /* program done, update RAM copy information */
936 FOTA_Package_Ctrl.m_fota_pkg_index++;
937 FOTA_Package_Ctrl.m_fota_pkg_pages++;
938 FOTA_Package_Ctrl.m_fota_pkg_list[FOTA_Package_Ctrl.m_fota_pkg_index].m_pkg_block_position =
939 alloc_block;
940 FOTA_Package_Ctrl.m_fota_pkg_list[FOTA_Package_Ctrl.m_fota_pkg_index].m_pkg_block_order =
941 curr_order+1;
942
943 pkg_info->m_pkg_previous_block = pkg_info->m_pkg_current_block;
944 pkg_info->m_pkg_current_block = alloc_block;
945 pkg_info->m_pkg_current_page = 2;
946 pkg_info->m_pkg_valid_pages = 1;
947 pkg_info->m_pkg_block_session++;
948 *page_size = info.Flash_page_size;
949
950 fue_dbg_print("FOTA_ProgramPackagePage: program on new package block:%d done!\n\r", \
951 pkg_info->m_pkg_current_block);
952 break;
953 }
954 }
955 //else if(ERROR_FUE_PROGRAM_FAILED == result)
956 if( (ERROR_FUE_PROGRAM_FAILED == result) || (ERROR_FGAL_WRITE_FAILURE == status) )
957 {
958 /* create package block or program new page failed - try again */
959 fgal->erase_block(alloc_block);
960 fgal->mark_bad(alloc_block);
961 curr_blk = alloc_block;
962 continue;
963 }
964 else if(ERROR_FUE_OPERATION_STOP == result)
965 {
966 ret_code = ERROR_FOTA_FLASH_DEVICE;
967 break;
968 }
969 else if(ERROR_FUE_OVER_DESIGN == result)
970 {
971 ret_code = ERROR_FOTA_UNSUPPORTED_CASES;
972 break;
973 }
974 }
975 else if(ERROR_FUE_NO_AVAILABLE_BLOCK == result)
976 {
977 ret_code = ERROR_FOTA_NO_AVAILABLE_BLOCK;
978 break;
979 }
980 }
981 }
982 return ret_code;
983}
984
985/* ---------------------------------------------------------------------------------
986FUNCTION
987 FOTA_ReadPackagePage
988DESCRIPTION
989 clear downloaded update package
990PARAMETER
991 NULL
992RETURN
993 0: means pass initialization step (ERROR_FOTA_SUCCESS)
994 < 0: means fail
995 ERROR_FOTA_CUSTOMIZATION: wrong customization
996--------------------------------------------------------------------------------- */
997kal_int32 FOTA_ReadPackagePage(void* buff, kal_uint32 page_addr, kal_uint32 *page_size)
998{
999 kal_int32 ret_code = ERROR_FOTA_SUCCESS;
1000 kal_uint32 page_count = 0;
1001 kal_int32 left_pages = 0;
1002 kal_uint32 blk_idx = 0;
1003 kal_uint32 page_idx = 0;
1004 kal_uint32 phy_blk = 0;
1005 FOTA_Package_Info_st *pkg_info = NULL;
1006 Logical_Flash_info_st info;
1007 FOTA_Package_Access_st *pkg_read = &FOTA_Package_Ctrl.m_fota_curr_read;
1008 Flash_GAL_st *fgal = FOTA_Package_Ctrl.m_pkg_fgal;
1009 _FGAL_ERROR_CODE status = ERROR_FGAL_NONE;
1010
1011 if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
1012 {
1013 ASSERT(0);
1014 return ERROR_FOTA_NOT_INITIALIZED;
1015 }
1016 ASSERT(fgal);
1017 *page_size = 0;
1018
1019 fgal = FOTA_Package_Ctrl.m_pkg_fgal;
1020 pkg_info = &FOTA_Package_Ctrl.m_fota_pkg_info;
1021 fgal->query_info(&info);
1022 if( ((pkg_read->m_pkg_curr_addr+info.Flash_page_size) != page_addr) || (INVALID_DWORD == pkg_read->m_pkg_curr_addr))
1023 {
1024 page_idx = page_addr/info.Flash_page_size;
1025 for(blk_idx = 0 ; blk_idx <= FOTA_Package_Ctrl.m_fota_pkg_index ; blk_idx++)
1026 {
1027 phy_blk = FOTA_Package_Ctrl.m_fota_pkg_list[blk_idx].m_pkg_block_position;
1028 page_count = (fgal->block_size(phy_blk)/info.Flash_page_size) - 3;
1029 if(page_idx < page_count)
1030 break;
1031 else
1032 page_idx -= page_count;
1033 }
1034 }
1035 else
1036 {
1037 blk_idx = pkg_read->m_pkg_curr_blk;
1038 phy_blk = FOTA_Package_Ctrl.m_fota_pkg_list[blk_idx].m_pkg_block_position;
1039 page_count = (fgal->block_size(phy_blk)/info.Flash_page_size) - 3;
1040 if( (pkg_read->m_pkg_curr_page+1) == page_count)
1041 {
1042 /* advance to next block */
1043 blk_idx = pkg_read->m_pkg_curr_blk+1;
1044 page_idx = 0;
1045 }
1046 else
1047 {
1048 blk_idx = pkg_read->m_pkg_curr_blk;
1049 page_idx = pkg_read->m_pkg_curr_page+1;
1050 }
1051 }
1052
1053 /* sanity check
1054 * !CAUTION! all package blocks are assumed to have same size.
1055 */
1056 left_pages = FOTA_Package_Ctrl.m_fota_pkg_pages - blk_idx*page_count;
1057 if( (blk_idx > FOTA_Package_Ctrl.m_fota_pkg_index) ||
1058 ((blk_idx == FOTA_Package_Ctrl.m_fota_pkg_index) && ((page_idx+1) > left_pages)) )
1059 {
1060 fue_dbg_print("FOTA_ReadPackagePage: read over range:(%d,%d) > (%d,%d)!\n\r", \
1061 blk_idx, page_idx, FOTA_Package_Ctrl.m_fota_pkg_index, pkg_info->m_pkg_valid_pages);
1062 ret_code = ERROR_FOTA_OVERRANGE;
1063 return ret_code;
1064 }
1065 else
1066 {
1067 pkg_read->m_pkg_curr_addr = page_addr;
1068 pkg_read->m_pkg_curr_blk = blk_idx;
1069 pkg_read->m_pkg_curr_page = page_idx;
1070 phy_blk = FOTA_Package_Ctrl.m_fota_pkg_list[blk_idx].m_pkg_block_position;
1071 status = fgal->read_page((kal_uint32 *)buff, phy_blk, page_idx+1);/* plus one to bypass header page */
1072 if(ERROR_FGAL_NONE == status)
1073 {
1074 //*page_size = FOTA_Package_Ctrl.m_fota_flash_info.Flash_page_size;
1075 *page_size = info.Flash_page_size;
1076 }
1077 else if(ERROR_FGAL_READ_FAILURE == status)
1078 {
1079 ret_code = ERROR_FOTA_READ;
1080 }
1081 else if(ERROR_FGAL_OPERATION_RETRY == status)
1082 {
1083 ret_code = ERROR_FOTA_UNSUPPORTED_CASES;
1084 }
1085 else if(ERROR_FGAL_INVALID_PARAMETER == status)
1086 {
1087 ret_code = ERROR_FOTA_INVALID_PARAMETER;
1088 }
1089 }
1090
1091 return ret_code;
1092}
1093
1094/* --------------------------------------------------------------------------------- */
1095static kal_int32 FOTA_MTD_Read_Buffer(void *Buffer, kal_uint32 read_len)
1096{
1097 kal_uint32 buff_offset = 0;
1098 kal_int32 left_length = read_len;
1099 kal_int32 result = 0;
1100 kal_uint32 page_size = 0;
1101 kal_uint32 buff_addr = (kal_uint32)Buffer;
1102
1103 while(left_length > 0)
1104 {
1105 result = FOTA_ReadPackagePage((void*)(buff_addr+buff_offset), FOTAData.SpareCurrReadAddr, \
1106 &page_size);
1107
1108 if(ERROR_FOTA_SUCCESS == result)
1109 {
1110 buff_offset += page_size;
1111 left_length -= page_size;
1112 FOTAData.SpareCurrReadAddr += page_size;
1113 }
1114 else
1115 break;
1116 }
1117 return result;
1118}
1119
1120/* --------------------------------------------------------------------------------- *
1121 * Update package download module
1122 * --------------------------------------------------------------------------------- */
1123/* ---------------------------------------------------------------------------------
1124FUNCTION
1125 FOTA_InitializePackageReservoir
1126DESCRIPTION
1127 find out whether any update record block exists
1128PARAMETER
1129 NULL
1130RETURN
1131 0: means pass initialization step (ERROR_FOTA_SUCCESS)
1132 < 0: means fail
1133 ERROR_FOTA_CUSTOMIZATION: wrong customization
1134--------------------------------------------------------------------------------- */
1135kal_int32 FOTA_InitializePackageReservoir(void)
1136{
1137 kal_uint32 idx = 0;
1138 kal_int32 ret_code = ERROR_FOTA_SUCCESS;
1139
1140 /* set package module control to default value */
1141 FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_block_session = INVALID_DWORD;
1142 FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_previous_block = INVALID_DWORD;
1143 FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_current_block = INVALID_DWORD;
1144 FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_valid_pages = INVALID_DWORD;
1145 FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_current_page = INVALID_DWORD;
1146
1147 FOTA_Package_Ctrl.m_fota_pkg_index = INVALID_DWORD;
1148 FOTA_Package_Ctrl.m_fota_pkg_pages = 0;
1149
1150 FOTA_Package_Ctrl.m_fota_curr_read.m_pkg_curr_addr = INVALID_DWORD;
1151 FOTA_Package_Ctrl.m_fota_curr_read.m_pkg_curr_blk = INVALID_DWORD;
1152 FOTA_Package_Ctrl.m_fota_curr_read.m_pkg_curr_page = INVALID_DWORD;
1153
1154 for(idx = 0 ; idx < FOTA_PKG_BLOCKS ; idx++)
1155 {
1156 FOTA_Package_Ctrl.m_fota_pkg_list[idx].m_pkg_block_order = INVALID_DWORD;
1157 FOTA_Package_Ctrl.m_fota_pkg_list[idx].m_pkg_block_position = INVALID_DWORD;
1158 FOTA_Package_Ctrl.m_fota_pkg_list[idx].m_pkg_valid_pages = INVALID_DWORD;
1159 FOTA_Package_Ctrl.m_fota_pkg_list[idx].m_pkg_block_complete = KAL_FALSE;
1160 }
1161
1162 /* initialize FGAL driver */
1163 FOTA_Package_Ctrl.m_pkg_fgal = FOTA_Setup_FGAL();
1164
1165 /* get initial reserved area information */
1166 FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_base = FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_start;
1167 FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_end = FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_end;
1168
1169 /* get flash information */
1170 //FOTA_Package_Ctrl.m_pkg_fgal->query_info(&FOTA_Package_Ctrl.m_fota_flash_info);
1171
1172 FOTA_Package_Ctrl.m_fota_pkg_state = FOTA_UPDATE_PACKAGE_STATE;
1173
1174 return ret_code;
1175}
1176
1177/* ---------------------------------------------------------------------------------
1178FUNCTION
1179 FOTA_ResumeUpdatePackage
1180DESCRIPTION
1181 find out whether any valid update package blocks exist
1182PARAMETER
1183 NULL
1184RETURN
1185 0: means pass initialization step (ERROR_FOTA_SUCCESS)
1186 < 0: means fail
1187 ERROR_FOTA_CUSTOMIZATION: wrong customization
1188--------------------------------------------------------------------------------- */
1189kal_int32 FOTA_ResumeUpdatePackage(void)
1190{
1191 kal_uint32 pkg_blocks = INVALID_DWORD;
1192 kal_uint32 buff_len = FOTA_FLASH_MAX_PAGE_SIZE;
1193 kal_uint32 idx = 0;
1194 kal_uint32 start_idx = INVALID_DWORD;
1195 kal_uint32 blk_order = 0;
1196 FUE_ERROR_CODE result = ERROR_FUE_NONE;
1197 kal_int32 ret_code = ERROR_FOTA_SUCCESS;
1198 kal_uint32 pkg_pages = 0;
1199 FOTA_Package_List_st *pkg_list = NULL;
1200 Logical_Flash_info_st info;
1201 Flash_GAL_st *fgal = FOTA_Package_Ctrl.m_pkg_fgal;
1202
1203 if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
1204 {
1205 ret_code = ERROR_FOTA_NOT_INITIALIZED;
1206 return ret_code;
1207 }
1208
1209 /* try to resume interrupted download process */
1210 /* update current package state to RAM copy */
1211 result = FUE_BlkInfo_Resume_Package_Blocks(&FOTA_Package_Ctrl, &pkg_blocks, g_fota_package_blocks,
1212 fota_temp_page_buffer, &buff_len,
1213 fue_dbg_print);
1214 if(ERROR_FUE_NONE == result)
1215 {
1216 if( pkg_blocks )
1217 {
1218 /* get first element index */
1219 for(idx = 0 ; idx < FOTA_PKG_BLOCKS ; idx++)
1220 {
1221 if( INVALID_DWORD == g_fota_package_blocks[idx].m_pkg_prev_idx )
1222 {
1223 if( INVALID_DWORD != g_fota_package_blocks[idx].m_pkg_block_order )
1224 {
1225 start_idx = idx;
1226 break;
1227 }
1228 }
1229 }
1230 #ifdef _FUE_PKG_DEBUG_
1231 if( INVALID_DWORD == start_idx )
1232 {
1233 fue_dbg_print("FOTA_ResumeUpdatePackage: first valid block not found in %d blocks!\n\r", pkg_blocks);
1234 #if defined(__FOTA_DEBUG_ASSERT__)
1235 ASSERT(0);
1236 #endif /* __FOTA_DEBUG_ASSERT__ */
1237 }
1238 #endif
1239
1240 pkg_list = FOTA_Package_Ctrl.m_fota_pkg_list;
1241 while(blk_order < pkg_blocks)
1242 {
1243 idx = start_idx;
1244 while(1)
1245 {
1246 if(blk_order == g_fota_package_blocks[idx].m_pkg_block_order)
1247 {
1248 pkg_list[blk_order].m_pkg_block_order = g_fota_package_blocks[idx].m_pkg_block_order;
1249 pkg_list[blk_order].m_pkg_block_position = g_fota_package_blocks[idx].m_pkg_block_position;
1250 pkg_list[blk_order].m_pkg_valid_pages = g_fota_package_blocks[idx].m_pkg_valid_pages;
1251 pkg_list[blk_order].m_pkg_block_complete = g_fota_package_blocks[idx].m_pkg_block_complete;
1252 pkg_pages += pkg_list[blk_order].m_pkg_valid_pages;
1253 if( (INVALID_DWORD == pkg_list[blk_order].m_pkg_valid_pages) ||
1254 (0 == pkg_list[blk_order].m_pkg_valid_pages) )
1255 {
1256 #ifdef _FUE_PKG_DEBUG_
1257 fue_dbg_print("FOTA_ResumeUpdatePackage: resume operation failed on %dth blk:%d\n\r", \
1258 blk_order, pkg_list[blk_order].m_pkg_block_position);
1259 #endif /* _FUE_PKG_DEBUG_ */
1260 #if defined(__FOTA_DEBUG_ASSERT__)
1261 ASSERT(0);
1262 #endif /* __FOTA_DEBUG_ASSERT__ */
1263 }
1264 blk_order++;
1265 break;
1266 /*TODO: remove this element from g_fota_package_blocks to save searching time */
1267 }
1268 idx = g_fota_package_blocks[idx].m_pkg_next_idx;
1269 if(INVALID_DWORD == idx)
1270 {
1271 #ifdef _FUE_PKG_DEBUG_
1272 fue_dbg_print("FOTA_ResumeUpdatePackage: downloading sequence is lost!(%d,%d)\n\r", \
1273 blk_order, pkg_blocks);
1274 #if defined(__FOTA_DEBUG_ASSERT__)
1275 ASSERT(0);
1276 #endif /* __FOTA_DEBUG_ASSERT__ */
1277 #endif /* _FUE_PKG_DEBUG_ */
1278 /* package block order is lost, re-download package from the beggining */
1279 ret_code = ERROR_FOTA_NO_UPDATE_PACKAGE;
1280 break;
1281 }
1282 }
1283 }
1284
1285 #ifdef _FUE_PKG_DEBUG_
1286 #if 0 /* removed since we do not update m_fota_pkg_info during FUE_BlkInfo_Resume_Package_Blocks() */
1287/* under construction !*/
1288/* under construction !*/
1289/* under construction !*/
1290/* under construction !*/
1291/* under construction !*/
1292/* under construction !*/
1293/* under construction !*/
1294/* under construction !*/
1295/* under construction !*/
1296/* under construction !*/
1297/* under construction !*/
1298 #endif /* removed */
1299 #endif
1300 if(INVALID_DWORD != FOTA_Package_Ctrl.m_fota_pkg_list[blk_order-1].m_pkg_block_position)
1301 {
1302 FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_current_block =
1303 FOTA_Package_Ctrl.m_fota_pkg_list[blk_order-1].m_pkg_block_position;
1304 if(pkg_list[blk_order-1].m_pkg_block_complete)
1305 {
1306 fgal->query_info(&info);
1307 FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_current_page =
1308 fgal->block_size(FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_current_block)/info.Flash_page_size;
1309 }
1310 else
1311 {
1312 FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_current_page = pkg_list[blk_order-1].m_pkg_valid_pages+1;
1313 }
1314
1315 FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_valid_pages = pkg_list[blk_order-1].m_pkg_valid_pages;
1316 FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_block_session = blk_order-1;
1317 FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_previous_block = (blk_order > 1) ?
1318 FOTA_Package_Ctrl.m_fota_pkg_list[blk_order-2].m_pkg_block_position : INVALID_DWORD;
1319 }
1320 FOTA_Package_Ctrl.m_fota_pkg_index = blk_order-1;
1321 FOTA_Package_Ctrl.m_fota_pkg_blocks = pkg_blocks;
1322 FOTA_Package_Ctrl.m_fota_pkg_pages = pkg_pages;
1323
1324 //FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_valid_pages = ;
1325 if(pkg_blocks != blk_order)
1326 {
1327 #ifdef _FUE_PKG_DEBUG_
1328 fue_dbg_print("FOTA_ResumeUpdatePackage: blk number:%d <-> blk order:%d!\n\r", \
1329 pkg_blocks, blk_order);
1330 #endif /* _FUE_PKG_DEBUG_ */
1331 #if defined(__FOTA_DEBUG_ASSERT__)
1332 ASSERT(0);
1333 #endif /* __FOTA_DEBUG_ASSERT__ */
1334 ret_code = ERROR_FOTA_NO_UPDATE_PACKAGE;
1335 }
1336 #ifdef _FUE_PKG_DEBUG_
1337 fue_dbg_print("FOTA_ResumeUpdatePackage: %dth package blk:%d!\n\r",
1338 FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_block_session, \
1339 FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_current_block);
1340 #endif
1341 }
1342 else
1343 {
1344 ret_code = ERROR_FOTA_NO_UPDATE_PACKAGE;
1345 }
1346 }
1347 else if((ERROR_FUE_INSUFFICIENT_BUFFER == result) || (ERROR_FUE_INVALID_PARAMETER == result))
1348 {
1349 ret_code = ERROR_FOTA_INVALID_PARAMETER;
1350 FOTA_Package_Ctrl.m_fota_pkg_state = INVALID_DWORD;
1351 }
1352 else if( (ERROR_FUE_NOT_FOUND == result) || (ERROR_FUE_TOO_MANY_PACKAGE_BLOCKS == result) )
1353 {
1354 ret_code = ERROR_FOTA_NO_UPDATE_PACKAGE;
1355 }
1356 else if( (ERROR_FUE_OPERATION_STOP == result) || (ERROR_FUE_READ_FAILURE == result) )
1357 {
1358 ret_code = ERROR_FOTA_UNSUPPORTED_CASES;
1359 }
1360
1361 return ret_code;
1362}
1363/* ---------------------------------------------------------------------------------
1364FUNCTION
1365 FOTA_CheckAvailablePackageBlocks
1366DESCRIPTION
1367 scan all block in package reservoir area to estimate the available storage size
1368PARAMETER
1369 NULL
1370RETURN
1371 0: means pass initialization step (ERROR_FOTA_SUCCESS)
1372 < 0: means fail
1373 ERROR_FOTA_CUSTOMIZATION: wrong customization
1374--------------------------------------------------------------------------------- */
1375kal_int32 FOTA_CheckAvailablePackageBlocks(kal_uint32 *available_num)
1376{
1377 kal_int32 ret_code = ERROR_FOTA_SUCCESS;
1378 kal_uint32 base_blk = INVALID_DWORD;
1379 kal_uint32 end_blk = INVALID_DWORD;
1380 kal_uint32 blk_idx = 0;
1381 kal_uint32 blk_num = 0;
1382 _FGAL_ERROR_CODE status = ERROR_FGAL_NONE;
1383 Flash_GAL_st *fgal = NULL;
1384 //Logical_Flash_info_st info;
1385
1386 if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
1387 {
1388 ASSERT(0);
1389 return ERROR_FOTA_NOT_INITIALIZED;
1390 }
1391
1392 base_blk = FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_base;
1393 end_blk = FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_end;
1394
1395 fgal = FOTA_Package_Ctrl.m_pkg_fgal;
1396
1397 //fgal->query_info(&info);
1398 *available_num = 0;
1399
1400 for(blk_idx = base_blk ; blk_idx < (end_blk+1) ; blk_idx++)
1401 {
1402 status = fgal->check_block(blk_idx);
1403 if(ERROR_FGAL_NONE == status)
1404 {
1405 /* check whether it is occupied */
1406 if(FUE_NFB_Is_Available_Block(blk_idx, fota_temp_page_buffer, fgal, fue_dbg_print))
1407 {
1408 blk_num++;
1409 }
1410 }
1411 else if(ERROR_FGAL_READ_FAILURE == status)
1412 {
1413 ret_code = ERROR_FOTA_READ;
1414 break;
1415 }
1416 else if(ERROR_FGAL_OPERATION_RETRY == status)
1417 {
1418 ret_code = ERROR_FOTA_FLASH_DEVICE;
1419 break;
1420 }
1421 }
1422 if(blk_idx == (end_blk+1))
1423 *available_num = blk_num;
1424
1425 return ret_code;
1426}
1427
1428/* ---------------------------------------------------------------------------------
1429FUNCTION
1430 FOTA_ClearPackageReservoir
1431DESCRIPTION
1432 clear downloaded update package
1433PARAMETER
1434 NULL
1435RETURN
1436 0: means pass initialization step (ERROR_FOTA_SUCCESS)
1437 < 0: means fail
1438 ERROR_FOTA_CUSTOMIZATION: wrong customization
1439--------------------------------------------------------------------------------- */
1440kal_int32 FOTA_ClearPackageReservoir(void)
1441{
1442 kal_int32 ret_code = ERROR_FOTA_SUCCESS;
1443 kal_uint32 base_blk = INVALID_DWORD;
1444 kal_uint32 end_blk = INVALID_DWORD;
1445 kal_uint32 index = 0;
1446 kal_uint32 blk_idx = 0;
1447 kal_uint32 erase_round = 0;
1448 kal_uint32 pkg_num = FOTA_PKG_BLOCKS;
1449 kal_uint32 erased_blk = 0;
1450 FUE_ERROR_CODE result = ERROR_FUE_NOT_FOUND;
1451 _FGAL_ERROR_CODE status = ERROR_FGAL_NONE;
1452 Flash_GAL_st *fgal = NULL;
1453
1454 if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
1455 {
1456 return ERROR_FOTA_NOT_INITIALIZED;
1457 }
1458
1459 base_blk = FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_base;
1460 end_blk = FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_end;
1461
1462 fgal = FOTA_Package_Ctrl.m_pkg_fgal;
1463
1464 /* try to erase all blocks occupied by update package */
1465 for( blk_idx = base_blk ; blk_idx <= end_blk ; blk_idx++ )
1466 {
1467 status = fgal->check_block(blk_idx);
1468 if(ERROR_FGAL_NONE == status)
1469 {
1470 result = FUE_BlkInfo_Is_Update_Block(&FOTA_Update_Ctrl, blk_idx, fue_dbg_print);
1471 if(ERROR_FUE_NOT_FOUND == result) /* in this flash space, only package or update blocks exist */
1472 {
1473 /* erase block */
1474 status = fgal->erase_block(blk_idx);
1475 if(ERROR_FGAL_ERASE_FAILURE == status)
1476 {
1477 fgal->mark_bad(blk_idx);
1478 #ifdef _FUE_PKG_DEBUG_
1479 fue_dbg_print("FOTA_ClearPackageReservoir: erase failed on block:%d!\n\r", blk_idx);
1480 #endif
1481 }
1482 else if(ERROR_FGAL_OPERATION_RETRY == status)
1483 {
1484 #ifdef _FUE_PKG_DEBUG_
1485 fue_dbg_print("FOTA_ClearPackageReservoir: erase operation stopped on block:%d!\n\r", blk_idx);
1486 #endif
1487 ret_code = ERROR_FOTA_FLASH_DEVICE;
1488 break;
1489 }
1490 erased_blk++;
1491 }
1492 else if( (ERROR_FUE_OPERATION_STOP == result) || (ERROR_FUE_OVER_DESIGN == result) )
1493 {
1494 #ifdef _FUE_PKG_DEBUG_
1495 fue_dbg_print("FOTA_ClearPackageReservoir: read operation stopped on block:%d!\n\r", blk_idx);
1496 #endif
1497 ret_code = ERROR_FOTA_FLASH_DEVICE;
1498 break;
1499 }
1500 else if(ERROR_FUE_NONE == result)
1501 {
1502 continue;
1503 }
1504 else
1505 {
1506 #ifdef _FUE_PKG_DEBUG_
1507 fue_dbg_print("FOTA_ClearPackageReservoir: unexpected error on block:%d!\n\r", blk_idx);
1508 #endif
1509 ret_code = ERROR_FOTA_UNSUPPORTED_CASES;
1510 break;
1511 }
1512 }
1513 else if(ERROR_FGAL_READ_FAILURE == status)
1514 {
1515 ret_code = ERROR_FOTA_READ;
1516 break;
1517 }
1518 else if(ERROR_FGAL_OPERATION_RETRY == status)
1519 {
1520 ret_code = ERROR_FOTA_FLASH_DEVICE;
1521 break;
1522 }
1523 }
1524 #ifdef _FUE_PKG_DEBUG_
1525 fue_dbg_print("FOTA_ClearPackageReservoir: clear %d in %d blocks!\n\r", erased_blk, blk_idx-base_blk);
1526 #endif
1527 return ret_code;
1528}
1529
1530/* ---------------------------------------------------------------------------------
1531FUNCTION
1532 FOTA_Get_TotalPackageBlock
1533DESCRIPTION
1534 return current package block number
1535PARAMETER
1536 NULL
1537RETURN
1538 0: means pass initialization step (ERROR_FOTA_SUCCESS)
1539 < 0: means fail
1540 ERROR_FOTA_CUSTOMIZATION: wrong customization
1541--------------------------------------------------------------------------------- */
1542kal_int32 FOTA_Get_TotalPackageBlock(kal_uint32 *pkg_blks, kal_uint32* pkg_pages)
1543{
1544 if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
1545 {
1546 ASSERT(0);
1547 return ERROR_FOTA_NOT_INITIALIZED;
1548 }
1549
1550 if(INVALID_DWORD != FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_valid_pages)
1551 {
1552 *pkg_blks = FOTA_Package_Ctrl.m_fota_pkg_blocks-1;
1553 *pkg_pages = FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_valid_pages;
1554 }
1555 else
1556 {
1557 *pkg_blks = FOTA_Package_Ctrl.m_fota_pkg_blocks;
1558 *pkg_pages = 0;
1559 }
1560
1561 return ERROR_FOTA_SUCCESS;
1562}
1563
1564/* ---------------------------------------------------------------------------------
1565FUNCTION
1566 FOTA_Get_CurrentPackagePosition
1567DESCRIPTION
1568 return current package block position
1569PARAMETER
1570 NULL
1571RETURN
1572 0: means pass initialization step (ERROR_FOTA_SUCCESS)
1573 < 0: means fail
1574 ERROR_FOTA_CUSTOMIZATION: wrong customization
1575--------------------------------------------------------------------------------- */
1576kal_int32 FOTA_Get_CurrentPackagePosition(kal_uint32 *curr_blk, kal_uint32* curr_page)
1577{
1578 if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
1579 {
1580 ASSERT(0);
1581 return ERROR_FOTA_NOT_INITIALIZED;
1582 }
1583
1584 *curr_blk = FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_current_block;
1585 *curr_page = FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_current_page;
1586
1587 return ERROR_FOTA_SUCCESS;
1588}
1589
1590/* ---------------------------------------------------------------------------------
1591FUNCTION
1592 FOTA_Get_AvailablePackageSpace
1593DESCRIPTION
1594 return currently downloaded package size
1595PARAMETER
1596 NULL
1597RETURN
1598 0: means pass initialization step (ERROR_FOTA_SUCCESS)
1599 < 0: means fail
1600 ERROR_FOTA_CUSTOMIZATION: wrong customization
1601--------------------------------------------------------------------------------- */
1602kal_int32 FOTA_Get_AvailablePackageSpace(kal_uint32 *avail_size)
1603{
1604 Logical_Flash_info_st info;
1605 kal_int32 ret_code = ERROR_FOTA_SUCCESS;
1606 kal_uint32 page_size;
1607 kal_uint32 blk_idx = 0;
1608 kal_uint32 start_blk = 0;
1609 kal_uint32 end_blk = 0;
1610 kal_uint32 free_size = 0;
1611 _FGAL_ERROR_CODE status = ERROR_FGAL_NONE;
1612 Flash_GAL_st *fgal = NULL;
1613
1614 if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
1615 {
1616 ASSERT(0);
1617 return ERROR_FOTA_NOT_INITIALIZED;
1618 }
1619
1620 fgal = FOTA_Package_Ctrl.m_pkg_fgal;
1621
1622 fgal->query_info(&info);
1623 page_size = info.Flash_page_size;
1624 start_blk = FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_base;
1625 end_blk = FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_end;
1626
1627 /* try to erase all blocks occupied by update package */
1628 for( blk_idx = start_blk ; blk_idx <= end_blk ; blk_idx++ )
1629 {
1630 status = fgal->check_block(blk_idx);
1631 if(ERROR_FGAL_NONE == status)
1632 {
1633 /* check whether it is occupied */
1634 if( FUE_NFB_Is_Available_Block(blk_idx, fota_temp_page_buffer, fgal, fue_dbg_print) ||
1635 FUE_BlkInfo_Is_Package_Block(&FOTA_Package_Ctrl, blk_idx, fue_dbg_print) )
1636 {
1637 free_size += fgal->block_size(blk_idx)-3*page_size;/* header and end mark pages are reserved */
1638 }
1639 }
1640 else if(ERROR_FGAL_READ_FAILURE == status)
1641 {
1642 ret_code = ERROR_FOTA_READ;
1643 break;
1644 }
1645 else if(ERROR_FGAL_OPERATION_RETRY == status)
1646 {
1647 ret_code = ERROR_FOTA_FLASH_DEVICE;
1648 break;
1649 }
1650 }
1651
1652 FOTA_Get_CurrentPackagePosition(&start_blk, &end_blk);
1653 if(INVALID_DWORD != start_blk)
1654 {
1655 /* header, end mark and current valid pages are excluded */
1656 free_size += fgal->block_size(start_blk)-(end_blk+3)*page_size;
1657 }
1658
1659 *avail_size = free_size;
1660
1661 return ret_code;
1662}
1663
1664/* ---------------------------------------------------------------------------------
1665FUNCTION
1666 FOTA_Get_TotalPackageSpace
1667DESCRIPTION
1668 return currently downloaded package size
1669PARAMETER
1670 NULL
1671RETURN
1672 0: means pass initialization step (ERROR_FOTA_SUCCESS)
1673 < 0: means fail
1674 ERROR_FOTA_CUSTOMIZATION: wrong customization
1675--------------------------------------------------------------------------------- */
1676kal_int32 FOTA_Get_TotalPackageSpace(kal_uint32 *avail_size)
1677{
1678 Logical_Flash_info_st info;
1679 kal_int32 ret_code = ERROR_FOTA_SUCCESS;
1680 kal_uint32 page_size;
1681 kal_uint32 blk_idx = 0;
1682 kal_uint32 start_blk = 0;
1683 kal_uint32 end_blk = 0;
1684 kal_uint32 free_size = 0;
1685 _FGAL_ERROR_CODE status = ERROR_FGAL_NONE;
1686 Flash_GAL_st *fgal = NULL;
1687
1688 if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
1689 {
1690 ASSERT(0);
1691 return ERROR_FOTA_NOT_INITIALIZED;
1692 }
1693
1694 fgal = FOTA_Package_Ctrl.m_pkg_fgal;
1695
1696 fgal->query_info(&info);
1697 page_size = info.Flash_page_size;
1698 start_blk = FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_base;
1699 end_blk = FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_end;
1700
1701 /* try to erase all blocks occupied by update package */
1702 for( blk_idx = start_blk ; blk_idx <= end_blk ; blk_idx++ )
1703 {
1704 status = fgal->check_block(blk_idx);
1705 if(ERROR_FGAL_NONE == status)
1706 {
1707 /* check whether it is occupied */
1708 if( (ERROR_FUE_NONE == FUE_NFB_Is_Available_Block(blk_idx, fota_temp_page_buffer, fgal, fue_dbg_print)) ||
1709 (ERROR_FUE_NONE == FUE_BlkInfo_Is_Package_Block(&FOTA_Package_Ctrl, blk_idx, fue_dbg_print)) )
1710 {
1711 free_size += fgal->block_size(blk_idx)-3*page_size;/* header and end mark pages are reserved */
1712 }
1713 }
1714 else if(ERROR_FGAL_READ_FAILURE == status)
1715 {
1716 ret_code = ERROR_FOTA_READ;
1717 break;
1718 }
1719 else if(ERROR_FGAL_OPERATION_RETRY == status)
1720 {
1721 ret_code = ERROR_FOTA_FLASH_DEVICE;
1722 break;
1723 }
1724 }
1725
1726 /* one block is reserved for update state record replacement */
1727 *avail_size = free_size-(fgal->block_size(start_blk)-3*page_size);/* header and end mark pages are reserved */
1728
1729 return ret_code;
1730}
1731
1732/* ---------------------------------------------------------------------------------
1733FUNCTION
1734 FOTA_Get_DownloadedPackageSize
1735DESCRIPTION
1736 return currently downloaded package size
1737PARAMETER
1738 NULL
1739RETURN
1740 0: means pass initialization step (ERROR_FOTA_SUCCESS)
1741 < 0: means fail
1742 ERROR_FOTA_CUSTOMIZATION: wrong customization
1743--------------------------------------------------------------------------------- */
1744kal_int32 FOTA_Get_DownloadedPackageSize(kal_uint32 *curr_size)
1745{
1746 Logical_Flash_info_st info;
1747 if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
1748 {
1749 ASSERT(0);
1750 return ERROR_FOTA_NOT_INITIALIZED;
1751 }
1752
1753 FOTA_Package_Ctrl.m_pkg_fgal->query_info(&info);
1754 if(INVALID_DWORD != FOTA_Package_Ctrl.m_fota_pkg_pages)
1755 *curr_size = FOTA_Package_Ctrl.m_fota_pkg_pages*info.Flash_page_size;
1756 else
1757 *curr_size = 0;
1758
1759 return ERROR_FOTA_SUCCESS;
1760}
1761
1762#if 0
1763/* under construction !*/
1764/* under construction !*/
1765/* under construction !*/
1766/* under construction !*/
1767/* under construction !*/
1768/* under construction !*/
1769/* under construction !*/
1770/* under construction !*/
1771/* under construction !*/
1772/* under construction !*/
1773/* under construction !*/
1774/* under construction !*/
1775/* under construction !*/
1776/* under construction !*/
1777/* under construction !*/
1778/* under construction !*/
1779/* under construction !*/
1780/* under construction !*/
1781/* under construction !*/
1782#endif
1783/* --------------------------------------------------------------------------------- *
1784 * Update staus record control module
1785 * --------------------------------------------------------------------------------- */
1786
1787/* ---------------------------------------------------------------------------------
1788FUNCTION
1789 FOTA_InitializeUpdateRecord
1790DESCRIPTION
1791 create an update record block or find out the existing update record block
1792PARAMETER
1793 NULL
1794RETURN
1795 0: means pass initialization step (ERROR_FOTA_SUCCESS)
1796 < 0: means fail
1797 ERROR_FOTA_CUSTOMIZATION: wrong customization
1798--------------------------------------------------------------------------------- */
1799kal_int32 FOTA_InitializeUpdateRecord(void)
1800{
1801 kal_uint32 start_block = INVALID_DWORD;
1802 kal_uint32 end_block = INVALID_DWORD;
1803 FUE_ERROR_CODE result = ERROR_FUE_NONE;
1804 _FGAL_ERROR_CODE status = ERROR_FGAL_NONE;
1805
1806 /* initialize FGAL driver */
1807 FOTA_Update_Ctrl.m_update_fgal = FOTA_Setup_FGAL();
1808
1809 /* get initial reserved area information */
1810 start_block = FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_start;
1811 end_block = FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_end;
1812 //FOTA_Update_Ctrl.m_update_fgal->query_info(&FOTA_Update_Ctrl.m_nand_flash_info);
1813
1814 /* set up update record module */
1815 result = FUE_InitializeUpdateRecord(start_block, end_block, \
1816 FOTA_Update_Ctrl.m_update_fgal/*&FOTA_Nand_Fgal*/,\
1817 fue_dbg_print);
1818 if(ERROR_FUE_NO_AVAILABLE_BLOCK == result)
1819 {
1820 status = ERROR_FOTA_NO_AVAILABLE_BLOCK;
1821 }
1822 else if(ERROR_FUE_OPERATION_STOP == result)
1823 {
1824 status = ERROR_FOTA_FLASH_DEVICE;
1825 }
1826 else if(ERROR_FUE_OVER_DESIGN == result)
1827 {
1828 status = ERROR_FOTA_UNSUPPORTED_CASES;
1829 }
1830 else
1831 {
1832 FOTA_Update_Ctrl.FOTA_UPDATE_ID = UPDATE_STATE_RECORD_ID;
1833 }
1834
1835 return status;
1836}
1837
1838/* ---------------------------------------------------------------------------------
1839FUNCTION
1840 FOTA_WriteUpdateRecord
1841DESCRIPTION
1842 FOTA update state information write API
1843 download client and update agent use this information to communicate with each other
1844PARAMETER
1845 NULL
1846RETURN
1847 0: means pass initialization step (ERROR_FOTA_SUCCESS)
1848 < 0: means fail
1849 ERROR_FOTA_CUSTOMIZATION: wrong customization
1850--------------------------------------------------------------------------------- */
1851kal_int32 FOTA_WriteUpdateRecord(FOTA_Custom_Update_Info* record)
1852{
1853 kal_int32 ret = ERROR_FOTA_SUCCESS;
1854 FUE_ERROR_CODE result = ERROR_FUE_NONE;
1855
1856 /* check whether FOTA is initialized */
1857 if(UPDATE_STATE_RECORD_ID != FOTA_Update_Ctrl.FOTA_UPDATE_ID)
1858 {
1859 ret = ERROR_FOTA_NOT_INITIALIZED;
1860 }
1861 else
1862 {
1863 result = FUE_NFB_Flush_Update_Record(record, fue_dbg_print);
1864
1865 if(ERROR_FUE_NONE == result )
1866 {
1867 ret = ERROR_FOTA_SUCCESS;
1868 }
1869 else if(ERROR_FUE_OPERATION_STOP == result)
1870 {
1871 #ifdef FOTA_DEBUG
1872 ASSERT(0);
1873 #endif
1874 ret = ERROR_FOTA_FLASH_DEVICE;
1875 }
1876 }
1877 return ret;
1878}
1879
1880/* ---------------------------------------------------------------------------------
1881FUNCTION
1882 FOTA_ReadUpdateRecord
1883DESCRIPTION
1884 FOTA update state information read API
1885 download client and update agent use this information to communicate with each other
1886PARAMETER
1887 NULL
1888RETURN
1889 0: means pass initialization step (ERROR_FOTA_SUCCESS)
1890 < 0: means fail
1891 ERROR_FOTA_CUSTOMIZATION: wrong customization
1892--------------------------------------------------------------------------------- */
1893kal_int32 FOTA_ReadUpdateRecord(FOTA_Custom_Update_Info* record)
1894{
1895 kal_int32 ret = ERROR_FOTA_SUCCESS;
1896 FUE_ERROR_CODE result = ERROR_FUE_NONE;
1897
1898 /* check whether FOTA is initialized */
1899 if(UPDATE_STATE_RECORD_ID != FOTA_Update_Ctrl.FOTA_UPDATE_ID)
1900 {
1901 ret = ERROR_FOTA_NOT_INITIALIZED;
1902 }
1903 else
1904 {
1905 result = FUE_NFB_Get_Update_Record(record, fue_dbg_print);
1906
1907 if(ERROR_FUE_UNRECOVERABLE_ECC == result)
1908 {
1909 ret = ERROR_FOTA_READ;
1910 }
1911 else if(ERROR_FUE_OPERATION_STOP == result)
1912 {
1913 ret = ERROR_FOTA_FLASH_DEVICE;
1914 }
1915 }
1916 return ret;
1917}
1918
1919/* ---------------------------------------------------------------------------------
1920FUNCTION
1921 FOTA_Inform_Update_State
1922DESCRIPTION
1923 Download client use this function to query the result of update process
1924PARAMETER
1925 NULL
1926RETURN
1927--------------------------------------------------------------------------------- */
1928FOTA_update_result FOTA_Inform_Update_State(void)
1929{
1930 FOTA_update_result ret = FOTA_UPDATE_NONE;
1931 FUE_ERROR_CODE result = ERROR_FUE_NONE;
1932 FOTA_Custom_Update_Info upt_info;
1933
1934 /* check whether FOTA is initialized */
1935 if(UPDATE_STATE_RECORD_ID != FOTA_Update_Ctrl.FOTA_UPDATE_ID)
1936 {
1937 ret = FOTA_UPDATE_NONE;
1938 }
1939 else
1940 {
1941 result = FOTA_ReadUpdateRecord(&upt_info);
1942
1943 if(ERROR_FUE_NONE == result)
1944 {
1945 /* check customer's state */
1946 if( FUE_UA_COMPLETE_PHASE == upt_info.FOTA_test_info1 )
1947 {
1948 ret = FOTA_UPDATE_SUCCEEDED;
1949 }
1950 else
1951 {
1952#if 0
1953/* under construction !*/
1954/* under construction !*/
1955/* under construction !*/
1956/* under construction !*/
1957/* under construction !*/
1958/* under construction !*/
1959/* under construction !*/
1960#endif
1961 {
1962 ret = FOTA_UPDATE_FAILED;
1963 }
1964 }
1965 }
1966 else
1967 {
1968 ret = FOTA_UPDATE_NONE;
1969 }
1970 }
1971
1972 return ret;
1973}
1974
1975/* ---------------------------------------------------------------------------------
1976FUNCTION
1977 FOTA_Start_Download_State
1978DESCRIPTION
1979 Download client use this function to query the result of update process
1980PARAMETER
1981 NULL
1982RETURN
1983--------------------------------------------------------------------------------- */
1984kal_int32 FOTA_Start_Download_State(void)
1985{
1986 kal_int32 ret = ERROR_FOTA_SUCCESS;
1987 FOTA_Custom_Update_Info upt_info;
1988
1989 if(UPDATE_STATE_RECORD_ID != FOTA_Update_Ctrl.FOTA_UPDATE_ID)
1990 {
1991 ret = ERROR_FOTA_NOT_INITIALIZED;
1992 }
1993 else
1994 {
1995 kal_mem_set(&upt_info,0xff,sizeof(FOTA_Custom_Update_Info));
1996 FUE_Start_Download_State();
1997 ret = FOTA_WriteUpdateRecord(&upt_info);
1998 }
1999
2000 return ret;
2001}
2002
2003/* ---------------------------------------------------------------------------------
2004FUNCTION
2005 FOTA_Start_Update_State
2006DESCRIPTION
2007 Download client use this function to query the result of update process
2008PARAMETER
2009 NULL
2010RETURN
2011--------------------------------------------------------------------------------- */
2012kal_int32 FOTA_Start_Update_State(void)
2013{
2014 kal_int32 ret = ERROR_FOTA_SUCCESS;
2015 FOTA_Custom_Update_Info upt_info;
2016
2017 if(UPDATE_STATE_RECORD_ID != FOTA_Update_Ctrl.FOTA_UPDATE_ID)
2018 {
2019 ret = ERROR_FOTA_NOT_INITIALIZED;
2020 }
2021 else
2022 {
2023 kal_mem_set(&upt_info,0xff,sizeof(FOTA_Custom_Update_Info));
2024 FUE_Start_Package_Verification_State();
2025 ret = FOTA_WriteUpdateRecord(&upt_info);
2026 }
2027
2028 return ret;
2029}
2030
2031
2032/* --------------------------------------------------------------------------------- *
2033 * Flash Generic Access Layer
2034 * --------------------------------------------------------------------------------- */
2035#define FOTA_FGAL_READY (0x59445246)
2036kal_uint32 g_FOTA_fgal_state;
2037
2038#if defined(_NAND_FLASH_BOOTING_) || (defined(__UP_PKG_ON_NAND__) && defined(NAND_SUPPORT))
2039
2040#if !defined(__NAND_FDM_50__)
2041#include "NAND_FDM.h"
2042#include "nand_mtd.h"
2043#include "nand_mtd_internal.h"
2044#else
2045#include "NAND_MTD_FDM50.h"
2046#include "NAND_DAL.h"
2047#include "NAND_MTD_FDM50_internal.h"
2048#include "NAND_DAL_internal.h"
2049
2050extern kal_uint8 IsGoodBlock(void* D, void * Spare);
2051#endif /* !__NAND_FDM_50__ */
2052
2053/* Following functions and variables are located in NAND_MTD.c */
2054extern int NFB_ReadPhysicalPage(kal_uint32 PhyBlock, kal_uint32 PhyPage, void * Data);
2055extern int NFB_ReadPhysicalSpare(kal_uint32 PhyBlock, kal_uint32 PhyPage, void * Data, kal_bool chksum);
2056extern int NFB_ProgramPhysicalPage(kal_uint32 PhyBlock, kal_uint32 PhyPage, void * Data, kal_bool DALRemap);
2057extern int NFB_ProgramPhysicalSpare(kal_uint32 PhyBlock, kal_uint32 PhyPage, void * Data, kal_bool chksum, kal_bool DALRemap);
2058extern int NFB_ErasePhysicalBlock(kal_uint32 PhyBlock, kal_bool DALRemap);
2059extern void get_NFI_bus(void);
2060extern void free_NFI_bus(void);
2061
2062extern int NFBPageSize;
2063extern int NFBBlockSize;
2064
2065#if defined(__NAND_FDM_50__)
2066
2067extern flash_info_2 Flash_Info;
2068
2069#else /* NAND FDM 4.x */
2070
2071extern NAND_FLASH_DRV_DATA NANDFlashDriveData;
2072
2073#endif
2074
2075/* Forward declaration */
2076_FGAL_ERROR_CODE FOTA_NAND_Init_func(void);
2077_FGAL_ERROR_CODE FOTA_NAND_Page_Read_func(kal_uint32* ptr, kal_uint32 blk, kal_uint32 page);
2078_FGAL_ERROR_CODE FOTA_NAND_Query_Info_func(Logical_Flash_info_st* info);
2079_FGAL_ERROR_CODE FOTA_NAND_Page_Program_func(kal_uint32* ptr, kal_uint32 blk, kal_uint32 page);
2080_FGAL_ERROR_CODE FOTA_NAND_Is_Good_Block_func(kal_uint32 blk);
2081_FGAL_ERROR_CODE FOTA_NAND_Mark_Bad_Block_func(kal_uint32 blk);
2082_FGAL_ERROR_CODE FOTA_NAND_Erase_Block_func(kal_uint32 blk);
2083_FGAL_ERROR_CODE FOTA_NAND_Is_Page_Empty_func(kal_uint32 *buff, kal_uint32 blk, kal_uint32 page);
2084_FGAL_ERROR_CODE FOTA_NAND_Lock_Block_func(kal_uint32 blk, kal_bool locked);
2085kal_uint32 FOTA_NAND_Block_Size_func(kal_uint32 blk);
2086kal_uint32 FOTA_NAND_Block_Index_func(kal_uint32 blk_addr);
2087
2088/*
2089 * Macro definition
2090 */
2091#define FOTA_NAND_STATE_VALID (0x5644544D)
2092
2093#define FOTA_MAX_SPARE_SIZE (64)
2094
2095/*
2096 * Global variable definition
2097 */
2098kal_uint32 g_FOTA_NAND_MTD_STATE;
2099
2100kal_uint32 g_fota_spare_buffer[FOTA_MAX_SPARE_SIZE>>2];
2101
2102/* For flash generic access layer */
2103Flash_GAL_st FOTA_Nand_Fgal;
2104
2105/*****************************************************************
2106Description : wait for a specific period counted by 32Khz tick.
2107Input :
2108Output : None
2109******************************************************************/
2110static void delay32KHzTick(kal_uint32 count)
2111{
2112 kal_uint32 begin_time = 0;
2113 kal_uint32 current_time = 0;
2114
2115 begin_time = INT_GetCurrentTime();
2116 do
2117 {
2118 current_time = INT_GetCurrentTime();
2119 if(current_time > begin_time)
2120 {
2121 if( (current_time-begin_time) > count )
2122 break;
2123 }
2124 else
2125 {
2126 if( (0xFFFFFFFF - begin_time + current_time + 1) > count)
2127 break;
2128 }
2129 }while(1);
2130}
2131
2132/*****************************************************************
2133Description : set up FGAL structure.
2134Input :
2135Output : None
2136******************************************************************/
2137
2138
2139Flash_GAL_st *FOTA_Setup_FGAL(void)
2140{
2141 if(FOTA_FGAL_READY == g_FOTA_fgal_state)
2142 return &FOTA_Nand_Fgal;
2143
2144 /* set up FGAL */
2145 FOTA_Nand_Fgal.init_drv = FOTA_NAND_Init_func;
2146 FOTA_Nand_Fgal.query_info = FOTA_NAND_Query_Info_func;
2147 FOTA_Nand_Fgal.read_page = FOTA_NAND_Page_Read_func;
2148 FOTA_Nand_Fgal.write_page = FOTA_NAND_Page_Program_func;
2149 FOTA_Nand_Fgal.check_block = FOTA_NAND_Is_Good_Block_func;
2150 FOTA_Nand_Fgal.mark_bad = FOTA_NAND_Mark_Bad_Block_func;
2151 FOTA_Nand_Fgal.erase_block = FOTA_NAND_Erase_Block_func;
2152 FOTA_Nand_Fgal.check_empty_page = FOTA_NAND_Is_Page_Empty_func;
2153 FOTA_Nand_Fgal.block_size = FOTA_NAND_Block_Size_func;
2154 FOTA_Nand_Fgal.block_index = FOTA_NAND_Block_Index_func;
2155 FOTA_Nand_Fgal.lock_block = FOTA_NAND_Lock_Block_func;
2156
2157 /* initialize FGAL driver */
2158 FOTA_Nand_Fgal.init_drv();
2159
2160 g_FOTA_fgal_state = FOTA_FGAL_READY;
2161 return &FOTA_Nand_Fgal;
2162}
2163
2164/*****************************************************************
2165Description : check whether the provided buffer comes from empty page.
2166Input :
2167Output : None
2168******************************************************************/
2169kal_bool FOTA_NAND_MTD_Check_Page_Empty(kal_uint8* page_buffer, kal_uint8* spare_buffer)
2170{
2171 kal_uint32 spare_len = 0;
2172 kal_uint32 idx = 0, j = 0;
2173 kal_uint32* long_ptr = NULL;
2174 kal_int32 byte_count = 0;
2175 kal_int32 long_len = 0;
2176 kal_uint32 page_size = NFBPageSize;
2177
2178 switch(page_size)
2179 {
2180 case 4096:
2181 spare_len = 128;
2182 break;
2183 case 2048:
2184 spare_len = 64;
2185 break;
2186 case 512:
2187 spare_len = 16;
2188 break;
2189 default:
2190 ASSERT(0);
2191 }
2192 /* compare with 0xFF */
2193 if(page_buffer)
2194 {
2195 long_ptr = (kal_uint32 *)(((kal_uint32)page_buffer+3) & ~(0x03));
2196 long_len = ((((kal_uint32)page_buffer+page_size) & ~(0x03)) - (kal_uint32)long_ptr) >> 2;
2197 byte_count = (kal_uint32)long_ptr - (kal_uint32)page_buffer;
2198 /* chech page content */
2199 if(byte_count > 0)
2200 {
2201 for(j = 0 ; j < byte_count ; j++)
2202 {
2203 if(page_buffer[j] != 0xFF)
2204 return KAL_FALSE;
2205 }
2206 }
2207 for(idx = 0 ; idx < long_len ; idx++)
2208 {
2209 if(long_ptr[idx] != 0xFFFFFFFF)
2210 return KAL_FALSE;
2211 }
2212 byte_count = page_size - byte_count - (long_len<<2);
2213 if(byte_count > 0)
2214 {
2215 for(j = byte_count ; j > 0 ; j--)
2216 {
2217 if(page_buffer[page_size-j] != 0xFF)
2218 return KAL_FALSE;
2219 }
2220 }
2221 }
2222
2223 if(spare_buffer)
2224 {
2225 /* check spare content */
2226 long_ptr = (kal_uint32 *)(((kal_uint32)spare_buffer+3) & ~(0x03));
2227 long_len = ((((kal_uint32)spare_buffer+spare_len) & ~(0x03)) - (kal_uint32)long_ptr) >> 2;
2228 byte_count = (kal_uint32)long_ptr - (kal_uint32)spare_buffer;
2229 if(byte_count > 0)
2230 {
2231 for(j = 0 ; j < byte_count ; j++)
2232 {
2233 if(spare_buffer[j] != 0xFF)
2234 return KAL_FALSE;
2235 }
2236 }
2237 for(idx = 0 ; idx < long_len ; idx++)
2238 {
2239 if(long_ptr[idx] != 0xFFFFFFFF)
2240 return KAL_FALSE;
2241 }
2242 byte_count = spare_len - byte_count - (long_len<<2);
2243 if(byte_count > 0)
2244 {
2245 for(j = byte_count ; j > 0 ; j--)
2246 {
2247 if(spare_buffer[page_size-j] != 0xFF)
2248 return KAL_FALSE;
2249 }
2250 }
2251 }
2252 return KAL_TRUE;;
2253}
2254
2255/*****************************************************************
2256Description : check whether the provided buffer comes from spare area of bad block.
2257Input :
2258Output : None
2259******************************************************************/
2260void FOTA_NAND_MTD_Set_Spare_Bad_Mark(kal_uint8* spare_buffer)
2261{
2262 kal_uint8 *byte_ptr = spare_buffer;
2263 kal_bool word_flag = KAL_FALSE;
2264#if !defined(__NAND_FDM_50__)
2265 flash_info_struct *nand_info = &NANDFlashDriveData.flash_info;
2266
2267 if(IO_ACCESS_16BIT == nand_info->io_width)
2268 {
2269 word_flag = KAL_TRUE;
2270 }
2271
2272#else
2273
2274 if(Flash_Info.deviceInfo_CE[0].IOWidth == 16)
2275 {
2276 word_flag = KAL_TRUE;
2277 }
2278
2279#endif /* __NAND_FDM_50__ */
2280
2281 if(512 == NFBPageSize)
2282 {
2283 if(!word_flag)
2284 {
2285 byte_ptr[5] = 0x0B;
2286 }
2287 else
2288 {
2289 byte_ptr[0] = 0x0B;
2290 byte_ptr[10] = 0x0B;
2291 }
2292 }
2293 else if((2048 == NFBPageSize)||(4096 == NFBPageSize))
2294 {
2295 if(!word_flag)
2296 {
2297 byte_ptr[0] = 0x0B;
2298 }
2299 else
2300 {
2301 byte_ptr[0] = 0x0B;
2302 byte_ptr[1] = 0x0B;
2303 }
2304 }
2305}
2306/*************************************************************************
2307* FUNCTION
2308* FOTA_NAND_Init_func
2309*
2310* DESCRIPTION
2311* Initialze NAND flash MTD driver
2312 ************************************************************************/
2313_FGAL_ERROR_CODE FOTA_NAND_Init_func(void)
2314{
2315 kal_int32 status = -1;
2316
2317 status = NFB_ReadPhysicalPage(0xFFFFFFFF, 0xFFFFFFFF, NULL);
2318
2319 g_FOTA_NAND_MTD_STATE = FOTA_NAND_STATE_VALID;
2320
2321 #if defined(__NAND_FDM_50__)
2322 NFBPageSize = Flash_Info.pageSize;
2323 //NFBBlockSize = Flash_Info.pageSize*Flash_Info.blockPage;
2324 #endif /* __NAND_FDM_50__ */
2325
2326 #if defined(__UP_PKG_ON_NAND__)
2327 FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_start = FOTA_NAND_Block_Index_func(FOTA_PACKAGE_STORAGE_BASE);
2328 FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_end = FOTA_NAND_Block_Index_func(FOTA_PACKAGE_STORAGE_BASE+FOTA_PACKAGE_STORAGE_SIZE)-1;
2329 #endif /* __UP_PKG_ON_NAND__ */
2330
2331 return ERROR_FGAL_NONE;
2332}
2333
2334/*************************************************************************
2335* FUNCTION
2336* FOTA_NAND_Page_Read_func
2337*
2338* DESCRIPTION
2339* Read one page from NAND flash
2340 ************************************************************************/
2341_FGAL_ERROR_CODE FOTA_NAND_Page_Read_func(kal_uint32* ptr, kal_uint32 blk, kal_uint32 page)
2342{
2343 _FGAL_ERROR_CODE result = ERROR_FGAL_NONE;
2344 kal_int32 status = 0;
2345 #if !defined(__NFI_VERSION2__) && !defined(__NFI_VERSION3_1__)
2346 static kal_uint32 empty_spare[64>>2];
2347 #endif /* !__NFI_VERSION2__ && !__NFI_VERSION3_1__*/
2348
2349 ASSERT( FOTA_NAND_STATE_VALID == g_FOTA_NAND_MTD_STATE);
2350
2351 status = NFB_ReadPhysicalPage(blk, page, ptr);
2352
2353 switch(status)
2354 {
2355 case ERROR_NFB_BAD_BLOCK:
2356 result = ERROR_FGAL_BAD_BLOCK;
2357 /* should not happen */
2358 EXT_ASSERT(0, 0, 0, 0);
2359 break;
2360 case ERROR_NFB_READ:
2361 #if !defined(__NFI_VERSION2__) && !defined(__NFI_VERSION3_1__)
2362 /* empty page read will generate ECC failure on NFI version1 */
2363 kal_mem_set(empty_spare, 0xFF, 64);
2364 NFB_ReadPhysicalSpare(blk, page, empty_spare, KAL_FALSE);
2365 if(FOTA_NAND_MTD_Check_Page_Empty((kal_uint8 *)ptr, (kal_uint8 *)empty_spare))
2366 {
2367 result = ERROR_FGAL_NONE;
2368 }
2369 else
2370 {
2371 result = ERROR_FGAL_ECC_FAILURE;
2372 }
2373 #else /* __NFI_VERSION2__ || __NFI_VERSION3_1__*/
2374 result = ERROR_FGAL_ECC_FAILURE;
2375 #endif /* !__NFI_VERSION2__ && !__NFI_VERSION3_1__*/
2376 break;
2377 default:
2378 if(NFBPageSize == status)
2379 result = ERROR_FGAL_NONE;
2380 else
2381 {
2382 ASSERT(0);
2383 result = ERROR_FGAL_OPERATION_RETRY;
2384 }
2385 }
2386
2387 return result;
2388}
2389
2390/*************************************************************************
2391* FUNCTION
2392* FOTA_NAND_Query_Info_func
2393*
2394* DESCRIPTION
2395* Query NAND flash device information
2396 ************************************************************************/
2397_FGAL_ERROR_CODE FOTA_NAND_Query_Info_func(Logical_Flash_info_st* info)
2398{
2399 _FGAL_ERROR_CODE result = ERROR_FGAL_NONE;
2400 kal_uint32 page_size = 0;
2401 kal_uint32 offset = 0;
2402 kal_uint32 pages_per_block = 0;
2403 kal_uint32 page_shift = 0;
2404#if !defined(__NAND_FDM_50__)
2405 flash_info_struct *nand_info = &NANDFlashDriveData.flash_info;
2406#endif /* __NAND_FDM_50__ */
2407
2408 ASSERT( FOTA_NAND_STATE_VALID == g_FOTA_NAND_MTD_STATE);
2409
2410#if defined(__NAND_FDM_50__)
2411
2412 page_size = Flash_Info.pageSize;
2413 if(4096 == page_size)
2414 {
2415 page_shift = 12;
2416 }
2417 else if(2048 == page_size)
2418 {
2419 page_shift = 11;
2420 }
2421 else if(512 == page_size)
2422 {
2423 page_shift = 9;
2424 }
2425 else
2426 {
2427 /* incorrect device configuration */
2428 ASSERT(0);
2429 }
2430
2431 pages_per_block = Flash_Info.blockPage;
2432
2433 info->Flash_page_size = page_size;
2434 info->Flash_block_size = page_size*pages_per_block;
2435 info->Flash_io_width = Flash_Info.deviceInfo_CE[0].IOWidth;
2436
2437#else /* NAND FDM 4 */
2438
2439 if(PAGE_2K == nand_info->page_type)
2440 {
2441 page_size = 2048;
2442 page_shift = 11;
2443 }
2444 else if(PAGE_512 == nand_info->page_type)
2445 {
2446 page_size = 512;
2447 page_shift = 9;
2448 }
2449 else
2450 {
2451 /* incorrect device configuration */
2452 ASSERT(0);
2453 }
2454
2455 pages_per_block = nand_info->pages_per_block;
2456
2457 info->Flash_page_size = page_size;
2458 info->Flash_block_size = page_size*nand_info->pages_per_block;
2459 info->Flash_io_width = nand_info->io_width;
2460
2461#endif
2462
2463 /* Assumptions: pages per block is power of 2 */
2464 info->Flash_offset_shift = INVALID_DWORD;
2465 for( offset = 0 ; offset < 32 ; offset++)
2466 {
2467 if( (1 << offset) == pages_per_block )
2468 {
2469 info->Flash_offset_shift = offset;
2470 info->Flash_block_shift = offset+page_shift;
2471 break;
2472 }
2473 }
2474 if(INVALID_DWORD == info->Flash_offset_shift)
2475 ASSERT(0); /* incorrect device configuration */
2476
2477 return result;
2478}
2479
2480/*************************************************************************
2481* FUNCTION
2482* FOTA_NAND_Page_Program_func
2483*
2484* DESCRIPTION
2485* Write one page to NAND flash
2486 ************************************************************************/
2487_FGAL_ERROR_CODE FOTA_NAND_Page_Program_func(kal_uint32* ptr, kal_uint32 blk, kal_uint32 page)
2488{
2489 _FGAL_ERROR_CODE result = ERROR_FGAL_NONE;
2490 kal_int32 status = 0;
2491
2492 ASSERT( FOTA_NAND_STATE_VALID == g_FOTA_NAND_MTD_STATE);
2493
2494 status = NFB_ProgramPhysicalPage(blk, page, ptr, KAL_TRUE);
2495
2496 switch(status)
2497 {
2498 case ERROR_NFB_BAD_BLOCK:
2499 result = ERROR_FGAL_BAD_BLOCK;
2500 /* should not happen */
2501 EXT_ASSERT(0, 0, 0, 0);
2502 break;
2503 case ERROR_NFB_PROGRAM:
2504 result = ERROR_FGAL_WRITE_FAILURE;
2505 break;
2506 default:
2507 if(NFBPageSize == status)
2508 result = ERROR_FGAL_NONE;
2509 else
2510 {
2511 ASSERT(0);
2512 result = ERROR_FGAL_OPERATION_RETRY;
2513 }
2514 }
2515
2516 return result;
2517}
2518
2519/*************************************************************************
2520* FUNCTION
2521* FOTA_NAND_Is_Good_Block_func
2522*
2523* DESCRIPTION
2524* Check whether block is good or bad.
2525 ************************************************************************/
2526_FGAL_ERROR_CODE FOTA_NAND_Is_Good_Block_func(kal_uint32 blk)
2527{
2528 _FGAL_ERROR_CODE result = ERROR_FGAL_NONE;
2529 kal_int32 status = 0;
2530 kal_uint8 *byte_ptr = (kal_uint8 *)g_fota_spare_buffer;
2531#if !defined(__NAND_FDM_50__)
2532 void *nand_info = (void *)&NANDFlashDriveData;
2533#else /* !__NAND_FDM_50__ */
2534 void *nand_info = (void *)&Flash_Info;
2535#endif
2536
2537 ASSERT( FOTA_NAND_STATE_VALID == g_FOTA_NAND_MTD_STATE);
2538
2539 status = NFB_ReadPhysicalSpare(blk, 0, g_fota_spare_buffer, KAL_FALSE);
2540 if(ERROR_NFB_SUCCESS == status)
2541 {
2542 if(IsGoodBlock(nand_info, byte_ptr) > 0)
2543 {
2544 status = NFB_ReadPhysicalSpare(blk, 1, g_fota_spare_buffer, KAL_FALSE);
2545 if(ERROR_NFB_SUCCESS == status)
2546 {
2547 if(IsGoodBlock(nand_info, byte_ptr) > 0)
2548 {
2549 result = ERROR_FGAL_NONE;
2550 }
2551 else
2552 {
2553 result = ERROR_FGAL_BAD_BLOCK;
2554 }
2555 }
2556 }
2557 else
2558 {
2559 result = ERROR_FGAL_BAD_BLOCK;
2560 }
2561 }
2562 else
2563 {
2564 if(ERROR_NFB_READ == status)
2565 result = ERROR_FGAL_READ_FAILURE;
2566 else
2567 ASSERT(0);
2568 }
2569
2570 return result;
2571}
2572
2573/*************************************************************************
2574* FUNCTION
2575* FOTA_NAND_Mark_Bad_Block_func
2576*
2577* DESCRIPTION
2578* Read one page from NAND flash
2579 *************************************************************************/
2580_FGAL_ERROR_CODE FOTA_NAND_Mark_Bad_Block_func(kal_uint32 blk)
2581{
2582 _FGAL_ERROR_CODE result = ERROR_FGAL_NONE;
2583 kal_int32 status = 0;
2584 kal_uint8 *byte_ptr = (kal_uint8 *)g_fota_spare_buffer;
2585
2586 ASSERT( FOTA_NAND_STATE_VALID == g_FOTA_NAND_MTD_STATE);
2587
2588 NFB_ErasePhysicalBlock(blk, KAL_TRUE);
2589
2590 kal_mem_set(g_fota_spare_buffer, 0xFF, FOTA_MAX_SPARE_SIZE);
2591 FOTA_NAND_MTD_Set_Spare_Bad_Mark(byte_ptr);
2592
2593 status = NFB_ProgramPhysicalSpare(blk, 0, byte_ptr, KAL_FALSE, KAL_TRUE);
2594 if(ERROR_NFB_SUCCESS == status)
2595 {
2596 status = NFB_ProgramPhysicalSpare(blk, 1, byte_ptr, KAL_FALSE, KAL_TRUE);
2597 }
2598
2599 switch(status)
2600 {
2601 case ERROR_NFB_BAD_BLOCK:
2602 result = ERROR_FGAL_BAD_BLOCK;
2603 /* should not happen */
2604 EXT_ASSERT(0, 0, 0, 0);
2605 break;
2606 case ERROR_NFB_PROGRAM:
2607 result = ERROR_FGAL_WRITE_FAILURE;
2608 break;
2609 case ERROR_NFB_SUCCESS:
2610 result = ERROR_FGAL_NONE;
2611 break;
2612 default:
2613 ASSERT(0);
2614 result = ERROR_FGAL_OPERATION_RETRY;
2615 }
2616
2617 return result;
2618}
2619
2620/*************************************************************************
2621* FUNCTION
2622* FOTA_NAND_Erase_Block_func
2623*
2624* DESCRIPTION
2625* Erase one block on NAND flash
2626 *************************************************************************/
2627_FGAL_ERROR_CODE FOTA_NAND_Erase_Block_func(kal_uint32 blk)
2628{
2629 kal_uint32 trial = 0;
2630 kal_int32 status = -1;
2631 _FGAL_ERROR_CODE result = ERROR_FGAL_NONE;
2632
2633 ASSERT( FOTA_NAND_STATE_VALID == g_FOTA_NAND_MTD_STATE);
2634
2635 for(trial = 0 ; trial < 3 ; trial++)
2636 {
2637 status = NFB_ErasePhysicalBlock(blk, KAL_TRUE);
2638 if(ERROR_NFB_ERASE != status)
2639 break;
2640 delay32KHzTick(1000);
2641 }
2642
2643 switch(status)
2644 {
2645 case ERROR_NFB_BAD_BLOCK:
2646 result = ERROR_FGAL_BAD_BLOCK;
2647 /* should not happen */
2648 EXT_ASSERT(0, 0, 0, 0);
2649 break;
2650 case ERROR_NFB_ERASE:
2651 result = ERROR_FGAL_ERASE_FAILURE;
2652 break;
2653 case ERROR_NFB_SUCCESS:
2654 result = ERROR_FGAL_NONE;
2655 break;
2656 default:
2657 ASSERT(0);
2658 result = ERROR_FGAL_OPERATION_RETRY;
2659 }
2660
2661 return result;
2662}
2663
2664/*************************************************************************
2665* FUNCTION
2666* FOTA_NAND_Is_Page_Empty_func
2667*
2668* DESCRIPTION
2669* Read one page from NAND flash
2670 *************************************************************************/
2671_FGAL_ERROR_CODE FOTA_NAND_Is_Page_Empty_func(kal_uint32 *buff, kal_uint32 blk, kal_uint32 page)
2672{
2673 _FGAL_ERROR_CODE result = ERROR_FGAL_NONE;
2674 kal_int32 status = ERROR_NFB_READ;
2675 kal_int32 status2 = ERROR_NFB_READ;
2676
2677 ASSERT( FOTA_NAND_STATE_VALID == g_FOTA_NAND_MTD_STATE);
2678
2679 kal_mem_set(g_fota_spare_buffer, 0x0, FOTA_MAX_SPARE_SIZE);
2680 kal_mem_set(buff, 0x0, NFBPageSize);
2681
2682 status = NFB_ReadPhysicalPage(blk, page, buff);
2683 status2 = NFB_ReadPhysicalSpare(blk, page, g_fota_spare_buffer, KAL_FALSE);
2684
2685 if( (NFBPageSize == status) && (ERROR_NFB_SUCCESS == status2) )
2686 {
2687 status = ERROR_NFB_SUCCESS;
2688 }
2689 else
2690 {
2691 status = ERROR_NFB_READ;
2692 }
2693
2694 switch(status)
2695 {
2696 case ERROR_NFB_BAD_BLOCK:
2697 result = ERROR_FGAL_BAD_BLOCK;
2698 /* should not happen */
2699 EXT_ASSERT(0, 0, 0, 0);
2700 break;
2701 case ERROR_NFB_READ: /* empty page in 28/29 is covered here */
2702 if(!FOTA_NAND_MTD_Check_Page_Empty((kal_uint8 *)buff, (kal_uint8 *)g_fota_spare_buffer))
2703 result = ERROR_FGAL_NON_EMPTY;
2704 break;
2705 case ERROR_NFB_SUCCESS:
2706 if(!FOTA_NAND_MTD_Check_Page_Empty((kal_uint8 *)buff, (kal_uint8 *)g_fota_spare_buffer))
2707 result = ERROR_FGAL_NON_EMPTY_CHECK;
2708 break;
2709 default:
2710 ASSERT(0);
2711 result = ERROR_FGAL_OPERATION_RETRY;
2712 }
2713
2714 return result;
2715}
2716
2717/*************************************************************************
2718* FUNCTION
2719* FOTA_NAND_Lock_Block_func
2720*
2721* DESCRIPTION
2722* Lock one block on NAND flash
2723 *************************************************************************/
2724_FGAL_ERROR_CODE FOTA_NAND_Lock_Block_func(kal_uint32 blk, kal_bool locked)
2725{
2726 return ERROR_FGAL_NONE;
2727}
2728
2729/*************************************************************************
2730* FUNCTION
2731* FOTA_NAND_Block_Size_func
2732*
2733* DESCRIPTION
2734* Erase one block on NAND flash
2735 *************************************************************************/
2736kal_uint32 FOTA_NAND_Block_Size_func(kal_uint32 blk)
2737{
2738 kal_uint32 blk_size = 0;
2739#if !defined(__NAND_FDM_50__)
2740 flash_info_struct *nand_info = &NANDFlashDriveData.flash_info;
2741
2742 if(PAGE_2K == nand_info->page_type)
2743 {
2744 blk_size = 2048*nand_info->pages_per_block;
2745 }
2746 else if(PAGE_512 == nand_info->page_type)
2747 {
2748 blk_size = 512*nand_info->pages_per_block;
2749 }
2750 else
2751 ASSERT(0); /* incorrect configuration */
2752
2753#else
2754
2755 blk_size = Flash_Info.pageSize*Flash_Info.blockPage;
2756
2757#endif
2758
2759 return blk_size;
2760}
2761
2762/*************************************************************************
2763* FUNCTION
2764* FOTA_NAND_Block_Index_func
2765*
2766* DESCRIPTION
2767* Erase one block on NAND flash
2768 *************************************************************************/
2769kal_uint32 FOTA_NAND_Block_Index_func(kal_uint32 blk_addr)
2770{
2771 kal_uint32 blk_size = 0;
2772#if !defined(__NAND_FDM_50__)
2773 flash_info_struct *nand_info = &NANDFlashDriveData.flash_info;
2774
2775 if(PAGE_2K == nand_info->page_type)
2776 {
2777 blk_size = 2048*nand_info->pages_per_block;
2778 }
2779 else if(PAGE_512 == nand_info->page_type)
2780 {
2781 blk_size = 512*nand_info->pages_per_block;
2782 }
2783 else
2784 ASSERT(0); /* incorrect configuration */
2785
2786#else
2787
2788 blk_size = Flash_Info.pageSize*Flash_Info.blockPage;
2789
2790#endif
2791
2792 ASSERT(blk_size);/* incorrect device configuration */
2793
2794 return blk_addr/blk_size;
2795}
2796
2797#elif defined(__EMMC_BOOTING__)
2798
2799/* For flash generic access layer */
2800Flash_GAL_st FOTA_eMMC_Fgal;
2801
2802Flash_GAL_st *FOTA_Setup_FGAL(void)
2803{
2804 if(FOTA_FGAL_READY == g_FOTA_fgal_state)
2805 return &FOTA_eMMC_Fgal;
2806
2807 /* set up FGAL */
2808 FOTA_eMMC_Fgal.init_drv = FGAL2FTL_Init;
2809 FOTA_eMMC_Fgal.query_info = FGAL2FTL_Query_Info;
2810 FOTA_eMMC_Fgal.read_page = FGAL2FTL_Read_Page;
2811 FOTA_eMMC_Fgal.write_page = FGAL2FTL_Write_Page;
2812 FOTA_eMMC_Fgal.check_block = FGAL2FTL_Is_Good_Block;
2813 FOTA_eMMC_Fgal.mark_bad = FGAL2FTL_Mard_Bad_Block;
2814 FOTA_eMMC_Fgal.erase_block = FGAL2FTL_Erase_Block;
2815 FOTA_eMMC_Fgal.check_empty_page = FGAL2FTL_Is_Empty_Page;
2816 FOTA_eMMC_Fgal.block_size = FGAL2FTL_Block_Size;
2817 FOTA_eMMC_Fgal.block_index = FGAL2FTL_Block_Index;
2818 FOTA_eMMC_Fgal.lock_block = FGAL2FTL_Lock_Block;
2819
2820 /* initialize FGAL driver */
2821 FOTA_eMMC_Fgal.init_drv();
2822
2823 g_FOTA_fgal_state = FOTA_FGAL_READY;
2824 return &FOTA_eMMC_Fgal;
2825}
2826
2827
2828#else /* !_NAND_FLASH_BOOTING_ */
2829
2830#include "custom_MemoryDevice.h"
2831#include "DrvFlash.h"
2832#include "reg_base.h"
2833#include "fue_init.h"
2834
2835/* Forward declaration */
2836_FGAL_ERROR_CODE FOTA_NOR_Init_func(void);
2837_FGAL_ERROR_CODE FOTA_NOR_Page_Read_func(kal_uint32* ptr, kal_uint32 blk, kal_uint32 page);
2838_FGAL_ERROR_CODE FOTA_NOR_Query_Info_func(Logical_Flash_info_st* info);
2839_FGAL_ERROR_CODE FOTA_NOR_Page_Program_func(kal_uint32* ptr, kal_uint32 blk, kal_uint32 page);
2840_FGAL_ERROR_CODE FOTA_NOR_Is_Good_Block_func(kal_uint32 blk);
2841_FGAL_ERROR_CODE FOTA_NOR_Mark_Bad_Block_func(kal_uint32 blk);
2842_FGAL_ERROR_CODE FOTA_NOR_Erase_Block_func(kal_uint32 blk);
2843_FGAL_ERROR_CODE FOTA_NOR_Is_Page_Empty_func(kal_uint32 *buff, kal_uint32 blk, kal_uint32 page);
2844_FGAL_ERROR_CODE FOTA_NOR_Lock_Block_func(kal_uint32 blk, kal_bool locked);
2845kal_uint32 FOTA_NOR_Block_Size_func(kal_uint32 blk);
2846kal_uint32 FOTA_NOR_Block_Index_func(kal_uint32 blk_addr);
2847
2848/* Following functions and variables are located in custom_blconfig.c */
2849extern kal_uint32 custom_Block_Size(kal_uint32 nor_addr);
2850extern kal_uint32 custom_get_NORFLASH_ROMSpace(void);
2851extern kal_uint32 custom_get_NORFLASH_Base(void);
2852
2853/*
2854 * Macro definition
2855 */
2856#define FOTA_NOR_STATE_VALID (0x5644544D)
2857
2858#define FOTA_MAX_SPARE_SIZE (64)
2859
2860/*
2861 * Global variable definition
2862 */
2863kal_uint32 g_FOTA_NOR_MTD_STATE;
2864/*
2865 * For flash generic access layer
2866 */
2867Flash_GAL_st FOTA_Nor_Fgal;
2868
2869NOR_FLASH_DRV_Data NORFlashDriveData;
2870NOR_Flash_MTD_Data FOTA_nor_mtdflash;
2871
2872
2873/*
2874 * External variable reference
2875 */
2876
2877extern NOR_MTD_Driver NORFlashMtd;
2878
2879
2880/*****************************************************************
2881Description : acquire FDM synchronization lock.
2882Input :
2883Output : None
2884******************************************************************/
2885void retrieve_FDM_lock(void)
2886{
2887 #if defined(__NOR_FDM5__)
2888
2889 extern void nFDM_LOCK(void);
2890 nFDM_LOCK();
2891
2892 #else
2893
2894 extern void FDM_LOCK(void);
2895 FDM_LOCK();
2896
2897 #endif
2898}
2899
2900/*****************************************************************
2901Description : relieve FDM synchronization lock.
2902Input :
2903Output : None
2904******************************************************************/
2905void release_FDM_lock(void)
2906{
2907 #if defined(__NOR_FDM5__)
2908
2909 extern void nFDM_UNLOCK(void);
2910 nFDM_UNLOCK();
2911
2912 #else
2913
2914 extern void FDM_UNLOCK(void);
2915 FDM_UNLOCK();
2916
2917 #endif
2918}
2919
2920/*****************************************************************
2921Description : Wait device ready before operation
2922Input :
2923Output : None
2924******************************************************************/
2925void FOTA_WaitEraseDone(void)
2926{
2927 #if defined(__NOR_FDM5__)
2928
2929 return;
2930
2931 #else // !__SINGLE_BANK_NOR_FLASH_SUPPORT__ && __NOR_FDM4__
2932
2933 extern NOR_FLASH_DRV_Data FlashDriveData;
2934 extern void WaitEraseDone(NOR_FLASH_DRV_Data * D, kal_uint32 frame_tick);
2935 //#define INVALID_BLOCK_INDEX 0xFFFFFFFF
2936 if( FlashDriveData.ReclaimBlockID != 0xFFFFFFFF )
2937 {
2938 WaitEraseDone(&FlashDriveData,70);
2939 }
2940 #endif
2941}
2942
2943/*****************************************************************
2944Description : set up FGAL structure.
2945Input :
2946Output : None
2947******************************************************************/
2948#define FOTA_FGAL_READY (0x59445246)
2949kal_uint32 g_FOTA_fgal_state;
2950extern kal_uint8 RandomNum;
2951
2952Flash_GAL_st *FOTA_Setup_FGAL(void)
2953{
2954
2955 if(FOTA_FGAL_READY == g_FOTA_fgal_state)
2956 return &FOTA_Nor_Fgal;
2957
2958 /* set up FGAL */
2959 FOTA_Nor_Fgal.init_drv = FOTA_NOR_Init_func;
2960 FOTA_Nor_Fgal.query_info = FOTA_NOR_Query_Info_func;
2961 FOTA_Nor_Fgal.read_page = FOTA_NOR_Page_Read_func;
2962 FOTA_Nor_Fgal.write_page = FOTA_NOR_Page_Program_func;
2963 FOTA_Nor_Fgal.check_block = FOTA_NOR_Is_Good_Block_func;
2964 FOTA_Nor_Fgal.mark_bad = FOTA_NOR_Mark_Bad_Block_func;
2965 FOTA_Nor_Fgal.erase_block = FOTA_NOR_Erase_Block_func;
2966 FOTA_Nor_Fgal.check_empty_page = FOTA_NOR_Is_Page_Empty_func;
2967 FOTA_Nor_Fgal.block_size = FOTA_NOR_Block_Size_func;
2968 FOTA_Nor_Fgal.block_index = FOTA_NOR_Block_Index_func;
2969 FOTA_Nor_Fgal.lock_block = FOTA_NOR_Lock_Block_func;
2970
2971 /* initialize FGAL driver */
2972 FOTA_Nor_Fgal.init_drv();
2973
2974 g_FOTA_fgal_state = FOTA_FGAL_READY;
2975
2976
2977 return &FOTA_Nor_Fgal;
2978}
2979
2980/*************************************************************************
2981* FUNCTION
2982* FOTA_NOR_Init_func
2983*
2984* DESCRIPTION
2985* Initialze NOR flash MTD driver
2986 ************************************************************************/
2987
2988#if defined(__SERIAL_FLASH__)
2989
2990extern FlashRegionInfo CMEM_FOTA_NORRegionInfo[];
2991
2992_FGAL_ERROR_CODE FOTA_NOR_Init_func(void)
2993{
2994
2995 if( (FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE) &&
2996 (~((kal_uint32)CMEM_FOTA_NORRegionInfo) == ((NOR_Flash_MTD_Data*)(NORFlashDriveData.MTDData))->Signature) )
2997 return ERROR_FGAL_NONE;
2998
2999 g_FOTA_NOR_MTD_STATE = FOTA_NOR_STATE_VALID;
3000
3001 /* Initialize MTD data table */
3002 CMEM_Init_FOTA();
3003
3004 /* prepare update package area information */
3005 // RegionInfo must be assigned before invoke FOTA_NOR_Block_Index_func
3006 FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_start = FOTA_NOR_Block_Index_func(FOTA_PACKAGE_STORAGE_BASE);
3007 FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_end = FOTA_NOR_Block_Index_func(FOTA_PACKAGE_STORAGE_BASE+FOTA_PACKAGE_STORAGE_SIZE)-1;
3008
3009 NORFlashDriveData.FlashInfo.baseUnlockBlock = FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_start;
3010 NORFlashDriveData.FlashInfo.endUnlockBlock = FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_end;
3011
3012 NORFlashDriveData.MTDDriver->MountDevice(NORFlashDriveData.MTDData, (void*)&NORFlashDriveData.FlashInfo);
3013 /* prepare update package area information */
3014 //FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_start = FOTA_NOR_Block_Index_func(FOTA_PACKAGE_STORAGE_BASE);
3015 //FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_end = FOTA_NOR_Block_Index_func(FOTA_PACKAGE_STORAGE_BASE+FOTA_PACKAGE_STORAGE_SIZE)-1;
3016 /* TODO: unlock all blocks reserved for update package */
3017 return ERROR_FGAL_NONE;
3018}
3019
3020#else // !__COMBO_MEMORY_SUPPORT__ && !__SERIAL_FLASH__
3021_FGAL_ERROR_CODE FOTA_NOR_Init_func(void)
3022{
3023 if( (FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE) &&
3024 (~((kal_uint32)NORRegionInfo) == FOTA_nor_mtdflash.Signature) )
3025 return ERROR_FGAL_NONE;
3026
3027 g_FOTA_NOR_MTD_STATE = FOTA_NOR_STATE_VALID;
3028 /* Initialize MTD data table */
3029 FOTA_nor_mtdflash.Signature = ~((kal_uint32)NORRegionInfo);
3030
3031 NORFlashDriveData.MTDDriver = &NORFlashMtd;
3032 NORFlashDriveData.MTDData = &FOTA_nor_mtdflash;
3033
3034#ifdef __MTK_TARGET__
3035 FOTA_nor_mtdflash.BaseAddr = (BYTE *)INT_RetrieveFlashBaseAddr();
3036#endif /* __MTK_TARGET__ */
3037
3038 FOTA_nor_mtdflash.RegionInfo = (FlashRegionInfo *)NORRegionInfo;
3039 /* prepare update package area information */
3040 FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_start = FOTA_NOR_Block_Index_func(FOTA_PACKAGE_STORAGE_BASE);
3041 FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_end = FOTA_NOR_Block_Index_func(FOTA_PACKAGE_STORAGE_BASE+FOTA_PACKAGE_STORAGE_SIZE)-1;
3042
3043 NORFlashDriveData.FlashInfo.baseUnlockBlock = FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_start;
3044 NORFlashDriveData.FlashInfo.endUnlockBlock = FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_end;
3045
3046 NORFlashDriveData.MTDDriver->MountDevice(NORFlashDriveData.MTDData, (void*)&NORFlashDriveData.FlashInfo);
3047 /* prepare update package area information */
3048 //FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_start = FOTA_NOR_Block_Index_func(FOTA_PACKAGE_STORAGE_BASE);
3049 //FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_end = FOTA_NOR_Block_Index_func(FOTA_PACKAGE_STORAGE_BASE+FOTA_PACKAGE_STORAGE_SIZE)-1;
3050 /* TODO: unlock all blocks reserved for update package */
3051 return ERROR_FGAL_NONE;
3052}
3053#endif //__COMBO_MEMORY_SUPPORT__ || __SERIAL_FLASH__
3054
3055/*************************************************************************
3056* FUNCTION
3057* FOTA_NOR_Page_Read_func
3058*
3059* DESCRIPTION
3060* Read one page from NOR flash
3061 ************************************************************************/
3062_FGAL_ERROR_CODE FOTA_NOR_Page_Read_func(kal_uint32* ptr, kal_uint32 blk, kal_uint32 page)
3063{
3064 NOR_Flash_MTD_Data *mtdflash = (NOR_Flash_MTD_Data *)NORFlashDriveData.MTDData;
3065 _FGAL_ERROR_CODE result = ERROR_FGAL_NONE;
3066 kal_int32 status = 0;
3067 kal_uint32 blk_size = 0;
3068 kal_uint32 src_addr = 0;
3069
3070 ASSERT( FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE);
3071 retrieve_FDM_lock();
3072
3073 FOTA_WaitEraseDone();
3074
3075 blk_size = BlockSize(mtdflash, blk);
3076 ASSERT(page < (blk_size/FOTA_FLASH_MAX_PAGE_SIZE));
3077 src_addr = (kal_uint32)BlockAddress(mtdflash, blk) + page*FOTA_FLASH_MAX_PAGE_SIZE;
3078 kal_mem_cpy(ptr, (void *)src_addr, FOTA_FLASH_MAX_PAGE_SIZE);
3079
3080 release_FDM_lock();
3081 return result;
3082}
3083
3084/*************************************************************************
3085* FUNCTION
3086* FOTA_NOR_Query_Info_func
3087*
3088* DESCRIPTION
3089* Query NOR flash device information
3090* The information is specific for flash area reserved for update package
3091 ************************************************************************/
3092_FGAL_ERROR_CODE FOTA_NOR_Query_Info_func(Logical_Flash_info_st* info)
3093{
3094 _FGAL_ERROR_CODE result = ERROR_FGAL_NONE;
3095 #if 0
3096/* under construction !*/
3097/* under construction !*/
3098/* under construction !*/
3099/* under construction !*/
3100/* under construction !*/
3101/* under construction !*/
3102/* under construction !*/
3103/* under construction !*/
3104/* under construction !*/
3105/* under construction !*/
3106/* under construction !*/
3107/* under construction !*/
3108/* under construction !*/
3109/* under construction !*/
3110/* under construction !*/
3111/* under construction !*/
3112/* under construction !*/
3113/* under construction !*/
3114/* under construction !*/
3115/* under construction !*/
3116/* under construction !*/
3117/* under construction !*/
3118/* under construction !*/
3119/* under construction !*/
3120/* under construction !*/
3121/* under construction !*/
3122/* under construction !*/
3123/* under construction !*/
3124/* under construction !*/
3125/* under construction !*/
3126/* under construction !*/
3127/* under construction !*/
3128/* under construction !*/
3129/* under construction !*/
3130/* under construction !*/
3131/* under construction !*/
3132/* under construction !*/
3133/* under construction !*/
3134/* under construction !*/
3135/* under construction !*/
3136/* under construction !*/
3137/* under construction !*/
3138/* under construction !*/
3139 #else
3140 info->Flash_page_size = FOTA_FLASH_MAX_PAGE_SIZE;
3141 info->Flash_io_width = 16;
3142 #endif
3143
3144 return result;
3145}
3146
3147/*************************************************************************
3148* FUNCTION
3149* FOTA_NOR_Page_Program_func
3150*
3151* DESCRIPTION
3152* Write one page to NOR flash
3153 ************************************************************************/
3154_FGAL_ERROR_CODE FOTA_NOR_Page_Program_func(kal_uint32* ptr, kal_uint32 blk, kal_uint32 page)
3155{
3156 _FGAL_ERROR_CODE result = ERROR_FGAL_NONE;
3157 kal_int32 status = 0;
3158 kal_uint32 blk_size = 0;
3159 kal_uint32 dst_addr = 0;
3160 kal_uint32 src_addr = (kal_uint32)ptr;
3161 kal_uint32 left_len = FOTA_FLASH_MAX_PAGE_SIZE;
3162 kal_uint32 write_len = 0;
3163 kal_uint32 pbp_len = 0;
3164 NOR_MTD_Driver *mtd_drv = NORFlashDriveData.MTDDriver;
3165 NOR_Flash_MTD_Data *mtdflash = (NOR_Flash_MTD_Data *)NORFlashDriveData.MTDData;
3166
3167 ASSERT( FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE);
3168 blk_size = BlockSize(mtdflash, blk);
3169 ASSERT(page < (blk_size/FOTA_FLASH_MAX_PAGE_SIZE));
3170
3171 MapWindow(mtdflash, blk, 0);
3172 //mtdflash->CurrAddr = (BYTE *)BlockAddress(mtdflash, blk);
3173
3174 dst_addr = (kal_uint32)mtdflash->CurrAddr + page*FOTA_FLASH_MAX_PAGE_SIZE;
3175
3176 retrieve_FDM_lock();
3177
3178 FOTA_WaitEraseDone();
3179
3180
3181
3182 if(BUFFER_PROGRAM_ITERATION_LENGTH)
3183 {
3184 pbp_len = BUFFER_PROGRAM_ITERATION_LENGTH<<1;
3185 }
3186 else
3187 {
3188 pbp_len = 2;
3189 }
3190
3191 while(left_len)
3192 {
3193 if(left_len > pbp_len)
3194 {
3195 write_len = pbp_len;
3196 }
3197 else
3198 {
3199 write_len = left_len;
3200 }
3201
3202 status = mtd_drv->ProgramData(mtdflash, (void *)dst_addr, (void *)src_addr, write_len);
3203 if(RESULT_FLASH_FAIL == status)
3204 {
3205 break;
3206 }
3207 else
3208 {
3209 left_len -= write_len;
3210 dst_addr += write_len;
3211 src_addr += write_len;
3212 }
3213 }
3214
3215
3216 release_FDM_lock();
3217
3218 if(RESULT_FLASH_FAIL == status)
3219 {
3220 result = ERROR_FGAL_WRITE_FAILURE;
3221 }
3222
3223 return result;
3224}
3225
3226/*************************************************************************
3227* FUNCTION
3228* FOTA_NOR_Is_Good_Block_func
3229*
3230* DESCRIPTION
3231* Check whether block is good or bad.
3232* Always return good since no bad block is allowed in NOR flash
3233 ************************************************************************/
3234_FGAL_ERROR_CODE FOTA_NOR_Is_Good_Block_func(kal_uint32 blk)
3235{
3236 ASSERT( FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE);
3237
3238 return ERROR_FGAL_NONE;
3239}
3240
3241/*************************************************************************
3242* FUNCTION
3243* FOTA_NOR_Mark_Bad_Block_func
3244*
3245* DESCRIPTION
3246* mark a block as bad, should not be called on NOR flash
3247 *************************************************************************/
3248_FGAL_ERROR_CODE FOTA_NOR_Mark_Bad_Block_func(kal_uint32 blk)
3249{
3250 ASSERT( FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE);
3251
3252 /* should not happen */
3253 EXT_ASSERT(0, 0, 0, 0);
3254
3255 return ERROR_FGAL_OPERATION_RETRY;
3256}
3257
3258/*************************************************************************
3259* FUNCTION
3260* FOTA_NOR_Erase_Block_func
3261*
3262* DESCRIPTION
3263* Erase one block on NOR flash
3264 *************************************************************************/
3265_FGAL_ERROR_CODE FOTA_NOR_Erase_Block_func(kal_uint32 blk)
3266{
3267 kal_uint32 trial = 0;
3268 kal_int32 status = -1;
3269 _FGAL_ERROR_CODE result = ERROR_FGAL_NONE;
3270 NOR_MTD_Driver *mtd_drv = NORFlashDriveData.MTDDriver;
3271 NOR_Flash_MTD_Data *mtdflash = (NOR_Flash_MTD_Data *)NORFlashDriveData.MTDData;
3272
3273 MapWindow(mtdflash, blk, 0);
3274
3275 ASSERT( FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE);
3276 retrieve_FDM_lock();
3277
3278 FOTA_WaitEraseDone();
3279
3280
3281
3282 status = mtd_drv->EraseBlock(mtdflash, blk);
3283
3284
3285 release_FDM_lock();
3286
3287 return result;
3288}
3289
3290/*************************************************************************
3291* FUNCTION
3292* FOTA_NOR_Is_Page_Empty_func
3293*
3294* DESCRIPTION
3295* Read one page from NOR flash
3296 *************************************************************************/
3297_FGAL_ERROR_CODE FOTA_NOR_Is_Page_Empty_func(kal_uint32 *buff, kal_uint32 blk, kal_uint32 page)
3298{
3299 kal_uint32 *page_ptr = NULL;
3300 kal_uint32 blk_size = 0;
3301 kal_uint32 idx = 0;
3302 _FGAL_ERROR_CODE result = ERROR_FGAL_NONE;
3303 NOR_Flash_MTD_Data *mtdflash = (NOR_Flash_MTD_Data *)NORFlashDriveData.MTDData;
3304
3305 ASSERT( FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE);
3306 blk_size = BlockSize(mtdflash, blk);
3307 ASSERT(page < (blk_size/FOTA_FLASH_MAX_PAGE_SIZE));
3308
3309 mtdflash->CurrAddr = (BYTE *)BlockAddress(mtdflash, blk);
3310 page_ptr = (kal_uint32 *)((kal_uint32)mtdflash->CurrAddr + page*FOTA_FLASH_MAX_PAGE_SIZE);
3311
3312 retrieve_FDM_lock();
3313
3314 FOTA_WaitEraseDone();
3315
3316 for(idx = 0 ; idx < (FOTA_NOR_FLASH_PAGE_SIZE>>2) ; idx++)
3317 {
3318 if(*(page_ptr+idx) != INVALID_DWORD)
3319 {
3320 result = ERROR_FGAL_NON_EMPTY_CHECK;
3321 break;
3322 }
3323 }
3324
3325 release_FDM_lock();
3326
3327 if(ERROR_FGAL_NON_EMPTY_CHECK == result)
3328 {
3329 kal_mem_cpy(buff, page_ptr, FOTA_FLASH_MAX_PAGE_SIZE);
3330 }
3331
3332 return result;
3333}
3334
3335/*************************************************************************
3336* FUNCTION
3337* FOTA_NOR_Lock_Block_func
3338*
3339* DESCRIPTION
3340* Erase one block on NOR flash
3341 *************************************************************************/
3342_FGAL_ERROR_CODE FOTA_NOR_Lock_Block_func(kal_uint32 blk, kal_bool locked)
3343{
3344 _FGAL_ERROR_CODE result = ERROR_FGAL_NONE;
3345 kal_uint32 blk_addr = 0;
3346 kal_uint32 blk_action = 0;
3347 NOR_Flash_MTD_Data *mtdflash = (NOR_Flash_MTD_Data *)NORFlashDriveData.MTDData;
3348 NOR_MTD_Driver *mtd_drv = NORFlashDriveData.MTDDriver;
3349
3350 ASSERT( FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE);
3351 blk_addr = (kal_uint32)BlockAddress(mtdflash, blk);
3352 if(locked)
3353 {
3354 blk_action = ACTION_LOCK;
3355 }
3356 else
3357 {
3358 blk_action = ACTION_UNLOCK;
3359 }
3360
3361 retrieve_FDM_lock();
3362
3363 FOTA_WaitEraseDone();
3364
3365 mtd_drv->LockEraseBlkAddr(mtdflash, (void *)blk_addr, blk_action);
3366
3367 release_FDM_lock();
3368 return ERROR_FGAL_NONE;
3369}
3370
3371/*************************************************************************
3372* FUNCTION
3373* FOTA_NOR_Block_Size_func
3374*
3375* DESCRIPTION
3376* Erase one block on NAND flash
3377 *************************************************************************/
3378kal_uint32 FOTA_NOR_Block_Size_func(kal_uint32 blk)
3379{
3380 NOR_Flash_MTD_Data *mtdflash = (NOR_Flash_MTD_Data *)NORFlashDriveData.MTDData;
3381 ASSERT( FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE);
3382
3383 return BlockSize((void *)mtdflash, blk);
3384}
3385
3386/*************************************************************************
3387* FUNCTION
3388* FOTA_NOR_Block_Index_func
3389*
3390* DESCRIPTION
3391* Erase one block on NAND flash
3392 *************************************************************************/
3393kal_uint32 FOTA_NOR_Block_Index_func(kal_uint32 blk_addr)
3394{
3395 NOR_Flash_MTD_Data *mtdflash = (NOR_Flash_MTD_Data *)NORFlashDriveData.MTDData;
3396 ASSERT( FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE);
3397
3398 return BlockIndex((void *)mtdflash, blk_addr & (~((kal_uint32)mtdflash->BaseAddr)));
3399 //return BlockIndex((void *)mtdflash, blk_addr - FOTA_PACKAGE_STORAGE_BASE);
3400}
3401
3402#endif /* NAND_FLASH_BOOTING */
3403
3404
3405#endif /* __FOTA_DM__ */