1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** LevelX Component                                                      */
16 /**                                                                       */
17 /**   NAND Flash                                                          */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 #define LX_SOURCE_CODE
23 
24 
25 /* Disable ThreadX error checking.  */
26 
27 #ifndef LX_DISABLE_ERROR_CHECKING
28 #define LX_DISABLE_ERROR_CHECKING
29 #endif
30 
31 
32 /* Include necessary system files.  */
33 
34 #include "lx_api.h"
35 
36 
37 /**************************************************************************/
38 /*                                                                        */
39 /*  FUNCTION                                               RELEASE        */
40 /*                                                                        */
41 /*    _lx_nand_flash_metadata_write                       PORTABLE C      */
42 /*                                                           6.2.1       */
43 /*  AUTHOR                                                                */
44 /*                                                                        */
45 /*    Xiuwen Cai, Microsoft Corporation                                   */
46 /*                                                                        */
47 /*  DESCRIPTION                                                           */
48 /*                                                                        */
49 /*    This function writes metadata pages into current metadata block and */
50 /*    allocates new blocks for metadata.                                  */
51 /*                                                                        */
52 /*  INPUT                                                                 */
53 /*                                                                        */
54 /*    nand_flash                            NAND flash instance           */
55 /*    main_buffer                           Main page buffer              */
56 /*    spare_value                           Value for spare bytes         */
57 /*                                                                        */
58 /*  OUTPUT                                                                */
59 /*                                                                        */
60 /*    return status                                                       */
61 /*                                                                        */
62 /*  CALLS                                                                 */
63 /*                                                                        */
64 /*    lx_nand_flash_driver_pages_write      Driver pages write            */
65 /*    _lx_nand_flash_metadata_allocate      Allocate blocks for metadata  */
66 /*    _lx_nand_flash_system_error           Internal system error handler */
67 /*                                                                        */
68 /*  CALLED BY                                                             */
69 /*                                                                        */
70 /*    Internal LevelX                                                     */
71 /*                                                                        */
72 /*  RELEASE HISTORY                                                       */
73 /*                                                                        */
74 /*    DATE              NAME                      DESCRIPTION             */
75 /*                                                                        */
76 /*  03-08-2023     Xiuwen Cai               Initial Version 6.2.1        */
77 /*                                                                        */
78 /**************************************************************************/
_lx_nand_flash_metadata_write(LX_NAND_FLASH * nand_flash,UCHAR * main_buffer,ULONG spare_value)79 UINT  _lx_nand_flash_metadata_write(LX_NAND_FLASH *nand_flash, UCHAR* main_buffer, ULONG spare_value)
80 {
81 
82 ULONG   block;
83 ULONG   page;
84 UINT    status;
85 UCHAR   *spare_buffer_ptr;
86 
87 
88     /* Setup spare buffer pointer.  */
89     spare_buffer_ptr = nand_flash -> lx_nand_flash_page_buffer + nand_flash -> lx_nand_flash_bytes_per_page;
90 
91     /* Initialize the spare buffer.  */
92     LX_MEMSET(spare_buffer_ptr, 0xFF, nand_flash -> lx_nand_flash_spare_total_length);
93 
94     /* Check if there is enough spare data for metadata block number.  */
95     if (nand_flash -> lx_nand_flash_spare_data2_length >= 2)
96     {
97 
98         /* Save metadata block number in spare bytes.  */
99         LX_UTILITY_SHORT_SET(&spare_buffer_ptr[nand_flash -> lx_nand_flash_spare_data2_offset], nand_flash -> lx_nand_flash_metadata_block_number);
100     }
101 
102     /* Save metadata type data in spare bytes.  */
103     LX_UTILITY_LONG_SET(&spare_buffer_ptr[nand_flash -> lx_nand_flash_spare_data1_offset], spare_value);
104 
105     /* Get current metadata block number. */
106     block = nand_flash -> lx_nand_flash_metadata_block_number_current;
107 
108     /* Get current metadata page number. */
109     page = nand_flash -> lx_nand_flash_metadata_block_current_page;
110 
111     /* Write the page.  */
112 #ifdef LX_NAND_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
113     status = (nand_flash -> lx_nand_flash_driver_pages_write)(nand_flash, block, page, main_buffer, spare_buffer_ptr, 1);
114 #else
115     status = (nand_flash -> lx_nand_flash_driver_pages_write)(block, page, main_buffer, spare_buffer_ptr, 1);
116 #endif
117 
118     /* Check for an error from flash driver.   */
119     if (status)
120     {
121 
122         /* Call system error handler.  */
123         _lx_nand_flash_system_error(nand_flash, status, block, 0);
124 
125         /* Return an error.  */
126         return(status);
127     }
128 
129     /* Increase current page for metadata block.  */
130     nand_flash -> lx_nand_flash_metadata_block_current_page++;
131 
132     /* Get current backup metadata block number. */
133     block = nand_flash -> lx_nand_flash_backup_metadata_block_number_current;
134 
135     /* Get current backup metadata page number. */
136     page = nand_flash -> lx_nand_flash_backup_metadata_block_current_page;
137 
138     /* Write the page.  */
139 #ifdef LX_NAND_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
140     status = (nand_flash -> lx_nand_flash_driver_pages_write)(nand_flash, block, page, main_buffer, spare_buffer_ptr, 1);
141 #else
142     status = (nand_flash -> lx_nand_flash_driver_pages_write)(block, page, main_buffer, spare_buffer_ptr, 1);
143 #endif
144 
145     /* Check for an error from flash driver.   */
146     if (status)
147     {
148 
149         /* Call system error handler.  */
150         _lx_nand_flash_system_error(nand_flash, status, block, 0);
151 
152         /* Return an error.  */
153         return(status);
154     }
155 
156     /* Increase current page for backup metadata block.  */
157     nand_flash -> lx_nand_flash_backup_metadata_block_current_page++;
158 
159     /* Allocate new block for metadata if necessary.  */
160     _lx_nand_flash_metadata_allocate(nand_flash);
161 
162     /* Return sector not found status.  */
163     return(status);
164 }
165 
166