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_memory_initialize                    PORTABLE C      */
42 /*                                                           6.2.1       */
43 /*  AUTHOR                                                                */
44 /*                                                                        */
45 /*    Xiuwen Cai, Microsoft Corporation                                   */
46 /*                                                                        */
47 /*  DESCRIPTION                                                           */
48 /*                                                                        */
49 /*    This function imitialize memory buffer for NAND flash instance.     */
50 /*                                                                        */
51 /*  INPUT                                                                 */
52 /*                                                                        */
53 /*    nand_flash                            NAND flash instance           */
54 /*    memory_ptr                            Pointer to memory used by the */
55 /*                                            LevelX for this NAND.       */
56 /*    memory_size                           Size of memory                */
57 /*                                                                        */
58 /*  OUTPUT                                                                */
59 /*                                                                        */
60 /*    return status                                                       */
61 /*                                                                        */
62 /*  CALLS                                                                 */
63 /*                                                                        */
64 /*    LX_MEMSET                             Initialize memory             */
65 /*                                                                        */
66 /*  CALLED BY                                                             */
67 /*                                                                        */
68 /*    Internal LevelX                                                     */
69 /*                                                                        */
70 /*  RELEASE HISTORY                                                       */
71 /*                                                                        */
72 /*    DATE              NAME                      DESCRIPTION             */
73 /*                                                                        */
74 /*  03-08-2023     Xiuwen Cai               Initial Version 6.2.1        */
75 /*                                                                        */
76 /**************************************************************************/
_lx_nand_flash_memory_initialize(LX_NAND_FLASH * nand_flash,ULONG * memory_ptr,UINT memory_size)77 UINT  _lx_nand_flash_memory_initialize(LX_NAND_FLASH  *nand_flash, ULONG* memory_ptr, UINT memory_size)
78 {
79 
80 UINT    memory_offset;
81 UINT    buffer_size;
82 
83 
84     /* Clear the memory buffer.  */
85     LX_MEMSET(memory_ptr, 0, memory_size);
86 
87     /* Reset the memory offset.  */
88     memory_offset = 0;
89 
90     /* Set memory size for block mapping table.  */
91     buffer_size = nand_flash -> lx_nand_flash_total_blocks * sizeof(*nand_flash -> lx_nand_flash_block_mapping_table);
92 
93     /* Make sure the size is at least one page size.  */
94     if (buffer_size < nand_flash -> lx_nand_flash_bytes_per_page)
95     {
96         buffer_size = nand_flash -> lx_nand_flash_bytes_per_page;
97     }
98 
99     /* Assign memory for block mapping table.  */
100     nand_flash -> lx_nand_flash_block_mapping_table = (USHORT*)(((UCHAR*)memory_ptr) + memory_offset);
101 
102     /* Update block mapping table size.  */
103     nand_flash -> lx_nand_flash_block_mapping_table_size = buffer_size;
104 
105     /* Update memory offset.  */
106     memory_offset += buffer_size;
107 
108     /* Check if there is enough memory.  */
109     if (memory_offset > memory_size)
110     {
111 
112         /* No enough memory, return error.  */
113         return(LX_NO_MEMORY);
114     }
115 
116     /* Set memory size for erase count table.  */
117     buffer_size = nand_flash -> lx_nand_flash_total_blocks * sizeof(*nand_flash -> lx_nand_flash_erase_count_table);
118 
119     /* Make sure the size is at least one page size.  */
120     if (buffer_size < nand_flash -> lx_nand_flash_bytes_per_page)
121     {
122         buffer_size = nand_flash -> lx_nand_flash_bytes_per_page;
123     }
124 
125     /* Assign memory for erase count table.  */
126     nand_flash -> lx_nand_flash_erase_count_table = (UCHAR*)(((UCHAR*)memory_ptr) + memory_offset);
127 
128     /* Update memory offset.  */
129     memory_offset += buffer_size;
130 
131     /* Update erase count table size.  */
132     nand_flash -> lx_nand_flash_erase_count_table_size = buffer_size;
133 
134     /* Check if there is enough memory.  */
135     if (memory_offset > memory_size)
136     {
137 
138         /* No enough memory, return error.  */
139         return(LX_NO_MEMORY);
140     }
141 
142     /* Assign memory for block list.  */
143     nand_flash -> lx_nand_flash_block_list = (USHORT*)(((UCHAR*)memory_ptr) + memory_offset);
144 
145     /* Update memory offset.  */
146     memory_offset += nand_flash -> lx_nand_flash_total_blocks * sizeof(*nand_flash -> lx_nand_flash_block_list);
147 
148     /* Check if there is enough memory.  */
149     if (memory_offset > memory_size)
150     {
151 
152         /* No enough memory, return error.  */
153         return(LX_NO_MEMORY);
154     }
155 
156     /* Update block list size.  */
157     nand_flash -> lx_nand_flash_block_list_size = nand_flash -> lx_nand_flash_total_blocks;
158 
159     /* Initialize block list. */
160     nand_flash -> lx_nand_flash_free_block_list_tail = 0;
161     nand_flash -> lx_nand_flash_mapped_block_list_head = nand_flash -> lx_nand_flash_block_list_size - 1;
162 
163     /* Set memory size for block status table.  */
164     buffer_size = nand_flash -> lx_nand_flash_total_blocks * sizeof(*nand_flash -> lx_nand_flash_block_status_table);
165 
166     /* Make sure the size is at least one page size.  */
167     if (buffer_size < nand_flash -> lx_nand_flash_bytes_per_page)
168     {
169         buffer_size = nand_flash -> lx_nand_flash_bytes_per_page;
170     }
171 
172     /* Assign memory for block status table.  */
173     nand_flash -> lx_nand_flash_block_status_table = (USHORT*)(((UCHAR*)memory_ptr) + memory_offset);
174 
175     /* Update memory offset.  */
176     memory_offset += buffer_size;
177 
178     /* Update block status table size.  */
179     nand_flash -> lx_nand_flash_block_status_table_size = buffer_size;
180 
181     /* Check if there is enough memory.  */
182     if (memory_offset > memory_size)
183     {
184 
185         /* No enough memory, return error.  */
186         return(LX_NO_MEMORY);
187     }
188 
189     /* Assign memory for page buffer.  */
190     nand_flash -> lx_nand_flash_page_buffer = ((UCHAR*)memory_ptr) + memory_offset;
191 
192     /* Update page buffer size.  */
193     nand_flash -> lx_nand_flash_page_buffer_size = memory_size - memory_offset;
194 
195     /* Check if there is enough memory.  */
196     if (nand_flash -> lx_nand_flash_page_buffer_size < (nand_flash -> lx_nand_flash_bytes_per_page + nand_flash -> lx_nand_flash_spare_total_length) * 2)
197     {
198 
199         /* No enough memory, return error.  */
200         return(LX_NO_MEMORY);
201     }
202 
203     /* Return a successful completion.  */
204     return(LX_SUCCESS);
205 }
206 
207