GCC Code Coverage Report


Directory: common/src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 0.0% 0 / 0 / 38
Functions: 0.0% 0 / 0 / 1
Branches: 0.0% 0 / 0 / 20

lx_nand_flash_block_data_move.c
Line Branch Exec Source
1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 * Copyright (c) 2026-present Eclipse ThreadX contributors
4 *
5 * This program and the accompanying materials are made available under the
6 * terms of the MIT License which is available at
7 * https://opensource.org/licenses/MIT.
8 *
9 * SPDX-License-Identifier: MIT
10 **************************************************************************/
11
12 // Portions of this file were generated with AI assistance.
13
14 /**************************************************************************/
15 /**************************************************************************/
16 /** */
17 /** LevelX Component */
18 /** */
19 /** NAND Flash */
20 /** */
21 /**************************************************************************/
22 /**************************************************************************/
23
24 #define LX_SOURCE_CODE
25
26
27 /* Disable ThreadX error checking. */
28
29 #ifndef LX_DISABLE_ERROR_CHECKING
30 #define LX_DISABLE_ERROR_CHECKING
31 #endif
32
33
34 /* Include necessary system files. */
35
36 #include "lx_api.h"
37
38
39 /**************************************************************************/
40 /* */
41 /* FUNCTION RELEASE */
42 /* */
43 /* _lx_nand_flash_block_data_move PORTABLE C */
44 /* 6.2.1 */
45 /* AUTHOR */
46 /* */
47 /* Xiuwen Cai, Microsoft Corporation */
48 /* */
49 /* DESCRIPTION */
50 /* */
51 /* This function finds a block with less erase count and copies pages */
52 /* into new block. */
53 /* */
54 /* INPUT */
55 /* */
56 /* nand_flash NAND flash instance */
57 /* new_block New block number */
58 /* */
59 /* OUTPUT */
60 /* */
61 /* return status */
62 /* */
63 /* CALLS */
64 /* */
65 /* _lx_nand_flash_mapped_block_list_get Get mapped block index */
66 /* _lx_nand_flash_block_find Find the mapped block */
67 /* _lx_nand_flash_data_page_copy Copy data pages */
68 /* _lx_nand_flash_free_block_list_add Add free block to list */
69 /* _lx_nand_flash_block_status_set Set block status */
70 /* _lx_nand_flash_block_mapping_set Set block mapping */
71 /* _lx_nand_flash_mapped_block_list_add Add mapped block to list */
72 /* _lx_nand_flash_driver_block_erase Erase block */
73 /* _lx_nand_flash_erase_count_set Set erase count */
74 /* _lx_nand_flash_free_block_list_add Add free block to list */
75 /* _lx_nand_flash_system_error Internal system error handler */
76 /* tx_mutex_get Get thread protection */
77 /* tx_mutex_put Release thread protection */
78 /* */
79 /* CALLED BY */
80 /* */
81 /* Application Code */
82 /* */
83 /**************************************************************************/
84 ✗ UINT _lx_nand_flash_block_data_move(LX_NAND_FLASH *nand_flash, ULONG new_block)
85 {
86
87 UINT status;
88 ULONG block;
89 USHORT block_status;
90 USHORT new_block_status;
91 ULONG block_mapping_index;
92
93
94 /* Get the mapped address to move the data. */
95 ✗ status = _lx_nand_flash_mapped_block_list_get(nand_flash, &block_mapping_index);
96
97 ✗ if (status)
98 {
99
100 /* Return an error. */
101 ✗ return(LX_ERROR);
102 }
103
104 /* Find the block number to be moved. */
105 ✗ status = _lx_nand_flash_block_find(nand_flash, block_mapping_index * nand_flash -> lx_nand_flash_pages_per_block, &block, &block_status);
106
107 /* Check the status. */
108 ✗ if (status)
109 {
110
111 /* Return an error. */
112 ✗ return(LX_ERROR);
113 }
114
115 #ifdef LX_NAND_FLASH_ENABLE_LAZY_SECTOR_RELEASE
116 /* If this logical group has a pending compaction source, redirect the
117 data move to a full logical-group compact to correctly merge data from
118 both source blocks. */
119 if (nand_flash -> lx_nand_flash_block_compaction_table[block_mapping_index] != (USHORT)LX_NAND_BLOCK_UNMAPPED)
120 {
121
122 /* Return the pre-allocated new_block to the free list. */
123 status = _lx_nand_flash_block_status_set(nand_flash, new_block, LX_NAND_BLOCK_STATUS_FREE);
124
125 if (status)
126 {
127 _lx_nand_flash_system_error(nand_flash, status, new_block, 0);
128 return(LX_ERROR);
129 }
130
131 _lx_nand_flash_free_block_list_add(nand_flash, new_block);
132
133 /* Restore block_mapping_index to the mapped list; mapped_block_list_get
134 already removed it before this function was called. */
135 _lx_nand_flash_mapped_block_list_add(nand_flash, block_mapping_index);
136
137 /* Perform full compaction merge of both source blocks. */
138 return(_lx_nand_flash_logical_group_compact(nand_flash, block_mapping_index));
139 }
140 #endif /* LX_NAND_FLASH_ENABLE_LAZY_SECTOR_RELEASE */
141
142 /* Set new block status to allocated for now. */
143 ✗ new_block_status = LX_NAND_BLOCK_STATUS_ALLOCATED;
144
145 /* Copy data from old block to new block. */
146 ✗ status = _lx_nand_flash_data_page_copy(nand_flash, block_mapping_index * nand_flash -> lx_nand_flash_pages_per_block, block, block_status, new_block, &new_block_status, nand_flash -> lx_nand_flash_pages_per_block);
147
148 /* Check the status. */
149 ✗ if (status)
150 {
151
152 /* Call system error handler. */
153 ✗ _lx_nand_flash_system_error(nand_flash, status, new_block, 0);
154
155 /* Return an error. */
156 ✗ return(LX_ERROR);
157 }
158
159 /* Check if no page was written. */
160 ✗ if ((new_block_status & LX_NAND_BLOCK_STATUS_PAGE_NUMBER_MASK) == 0)
161 {
162
163 /* Mark the new block as free. */
164 ✗ new_block_status = LX_NAND_BLOCK_STATUS_FREE;
165
166 /* Add the new block to free list. */
167 ✗ _lx_nand_flash_free_block_list_add(nand_flash, new_block);
168
169 }
170
171 /* Set the block status for the new block. */
172 ✗ status = _lx_nand_flash_block_status_set(nand_flash, new_block, new_block_status);
173
174 /* Check for an error from flash driver. */
175 ✗ if (status)
176 {
177
178 /* Call system error handler. */
179 ✗ _lx_nand_flash_system_error(nand_flash, status, new_block, 0);
180
181 /* Return an error. */
182 ✗ return(LX_ERROR);
183 }
184
185 /* Check if the block is actually mapped. */
186 ✗ if (new_block_status == LX_NAND_BLOCK_STATUS_FREE)
187 {
188
189 /* Unmap the block. */
190 ✗ new_block = LX_NAND_BLOCK_UNMAPPED;
191 }
192
193 /* Update block mapping. */
194 ✗ _lx_nand_flash_block_mapping_set(nand_flash, block_mapping_index * nand_flash -> lx_nand_flash_pages_per_block, new_block);
195
196 /* Check if the block is actually mapped. */
197 ✗ if (new_block != LX_NAND_BLOCK_UNMAPPED)
198 {
199
200 /* Add the block to mapped list. */
201 ✗ _lx_nand_flash_mapped_block_list_add(nand_flash, block_mapping_index);
202 }
203
204 /* Erase the old block. */
205 ✗ status = _lx_nand_flash_driver_block_erase(nand_flash, block, nand_flash -> lx_nand_flash_base_erase_count + nand_flash -> lx_nand_flash_erase_count_table[block] + 1);
206
207 /* Check for an error from flash driver. */
208 ✗ if (status)
209 {
210
211 /* Call system error handler. */
212 ✗ _lx_nand_flash_system_error(nand_flash, status, block, 0);
213
214 /* Return an error. */
215 ✗ return(LX_ERROR);
216 }
217
218 /* Update the erase count for the erased block. */
219 ✗ status = _lx_nand_flash_erase_count_set(nand_flash, block, (UCHAR)(nand_flash -> lx_nand_flash_erase_count_table[block] + 1));
220
221 /* Check for an error from flash driver. */
222 ✗ if (status)
223 {
224
225 /* Call system error handler. */
226 ✗ _lx_nand_flash_system_error(nand_flash, status, block, 0);
227
228 /* Return an error. */
229 ✗ return(LX_ERROR);
230 }
231
232 /* Set the block status to free. */
233 ✗ status = _lx_nand_flash_block_status_set(nand_flash, block, LX_NAND_BLOCK_STATUS_FREE);
234
235 /* Check for an error from flash driver. */
236 ✗ if (status)
237 {
238
239 /* Call system error handler. */
240 ✗ _lx_nand_flash_system_error(nand_flash, status, block, 0);
241
242
243 /* Return an error. */
244 ✗ return(LX_ERROR);
245 }
246
247 /* Add the block to free block list. */
248 ✗ status = _lx_nand_flash_free_block_list_add(nand_flash, block);
249
250 /* Return status. */
251 ✗ return(status);
252 }
253
254