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