lx_nor_flash_logical_sector_find.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 | |||
| 13 | /**************************************************************************/ | ||
| 14 | /**************************************************************************/ | ||
| 15 | /** */ | ||
| 16 | /** LevelX Component */ | ||
| 17 | /** */ | ||
| 18 | /** NOR Flash */ | ||
| 19 | /** */ | ||
| 20 | /**************************************************************************/ | ||
| 21 | /**************************************************************************/ | ||
| 22 | |||
| 23 | #define LX_SOURCE_CODE | ||
| 24 | |||
| 25 | |||
| 26 | /* Disable ThreadX error checking. */ | ||
| 27 | |||
| 28 | #ifndef LX_DISABLE_ERROR_CHECKING | ||
| 29 | #define LX_DISABLE_ERROR_CHECKING | ||
| 30 | #endif | ||
| 31 | |||
| 32 | |||
| 33 | /* Include necessary system files. */ | ||
| 34 | |||
| 35 | #include "lx_api.h" | ||
| 36 | |||
| 37 | |||
| 38 | /**************************************************************************/ | ||
| 39 | /* */ | ||
| 40 | /* FUNCTION RELEASE */ | ||
| 41 | /* */ | ||
| 42 | /* _lx_nor_flash_logical_sector_find PORTABLE C */ | ||
| 43 | /* 6.3.0 */ | ||
| 44 | /* AUTHOR */ | ||
| 45 | /* */ | ||
| 46 | /* William E. Lamie, Microsoft Corporation */ | ||
| 47 | /* */ | ||
| 48 | /* DESCRIPTION */ | ||
| 49 | /* */ | ||
| 50 | /* This function attempts to find the specified logical sector in */ | ||
| 51 | /* the NOR flash. */ | ||
| 52 | /* */ | ||
| 53 | /* INPUT */ | ||
| 54 | /* */ | ||
| 55 | /* nor_flash NOR flash instance */ | ||
| 56 | /* logical_sector Logical sector number */ | ||
| 57 | /* superceded_check Check for sector being */ | ||
| 58 | /* superceded (can happen if */ | ||
| 59 | /* on interruptions of sector */ | ||
| 60 | /* write) */ | ||
| 61 | /* physical_sector_map_entry Destination for physical */ | ||
| 62 | /* sector map entry address */ | ||
| 63 | /* physical_sector_address Destination for physical */ | ||
| 64 | /* sector data */ | ||
| 65 | /* */ | ||
| 66 | /* OUTPUT */ | ||
| 67 | /* */ | ||
| 68 | /* return status */ | ||
| 69 | /* */ | ||
| 70 | /* CALLS */ | ||
| 71 | /* */ | ||
| 72 | /* _lx_nor_flash_driver_read Driver flash sector read */ | ||
| 73 | /* _lx_nor_flash_driver_write Driver flash sector write */ | ||
| 74 | /* _lx_nor_flash_system_error Internal system error handler */ | ||
| 75 | /* */ | ||
| 76 | /* CALLED BY */ | ||
| 77 | /* */ | ||
| 78 | /* Internal LevelX */ | ||
| 79 | /* */ | ||
| 80 | /**************************************************************************/ | ||
| 81 | 56762 | UINT _lx_nor_flash_logical_sector_find(LX_NOR_FLASH *nor_flash, ULONG logical_sector, ULONG superceded_check, ULONG **physical_sector_map_entry, ULONG **physical_sector_address) | |
| 82 | { | ||
| 83 | |||
| 84 | ULONG *block_word_ptr; | ||
| 85 | ULONG *list_word_ptr; | ||
| 86 | ULONG list_word; | ||
| 87 | ULONG min_logical_sector; | ||
| 88 | ULONG max_logical_sector; | ||
| 89 | ULONG mapped_sectors; | ||
| 90 | ULONG total_blocks; | ||
| 91 | ULONG total_sectors; | ||
| 92 | ULONG i, j; | ||
| 93 | ULONG search_start; | ||
| 94 | 56762 | LX_NOR_SECTOR_MAPPING_CACHE_ENTRY *sector_mapping_cache_entry_ptr = LX_NULL; | |
| 95 | LX_NOR_SECTOR_MAPPING_CACHE_ENTRY temp_sector_mapping_cache_entry; | ||
| 96 | #ifndef LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE | ||
| 97 | ULONG valid_sector_found; | ||
| 98 | #endif | ||
| 99 | #if !defined(LX_DIRECT_READ) || !defined(LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE) | ||
| 100 | UINT status; | ||
| 101 | #endif | ||
| 102 | |||
| 103 | |||
| 104 | /* Initialize the return parameters. */ | ||
| 105 | 56762 | *physical_sector_map_entry = (ULONG *) 0; | |
| 106 | 56762 | *physical_sector_address = (ULONG *) 0; | |
| 107 | |||
| 108 | /* Determine if there are any mapped physical sectors. */ | ||
| 109 |
2/2✓ Branch 2 → 3 taken 70 times.
✓ Branch 2 → 4 taken 56692 times.
|
56762 | if (nor_flash -> lx_nor_flash_mapped_physical_sectors == 0) |
| 110 | { | ||
| 111 | |||
| 112 | /* No mapped sector so nothing can be found!. */ | ||
| 113 | 70 | return(LX_SECTOR_NOT_FOUND); | |
| 114 | } | ||
| 115 | |||
| 116 | #ifndef LX_NOR_DISABLE_EXTENDED_CACHE | ||
| 117 | #ifdef LX_NOR_ENABLE_MAPPING_BITMAP | ||
| 118 | |||
| 119 | /* Determine if the logical sector is in the range of mapping bitmap cache. */ | ||
| 120 |
2/2✓ Branch 4 → 5 taken 5965 times.
✓ Branch 4 → 7 taken 5374 times.
|
11339 | if (logical_sector < nor_flash -> lx_nor_flash_extended_cache_mapping_bitmap_max_logical_sector) |
| 121 | { | ||
| 122 | |||
| 123 | /* Determine if the logical sector is mapped. */ | ||
| 124 |
2/2✓ Branch 5 → 6 taken 612 times.
✓ Branch 5 → 7 taken 5353 times.
|
5965 | if ((nor_flash -> lx_nor_flash_extended_cache_mapping_bitmap[logical_sector >> 5] & (ULONG)(1 << (logical_sector & 31))) == 0) |
| 125 | { | ||
| 126 | |||
| 127 | /* Not mapped, return not found. */ | ||
| 128 | 612 | return(LX_SECTOR_NOT_FOUND); | |
| 129 | } | ||
| 130 | } | ||
| 131 | #endif | ||
| 132 | #endif | ||
| 133 | |||
| 134 | /* Determine if the sector mapping cache is enabled. */ | ||
| 135 |
4/4✓ Branch 4 → 5 taken 45321 times.
✓ Branch 4 → 14 taken 32 times.
✓ Branch 7 → 8 taken 10719 times.
✓ Branch 7 → 17 taken 8 times.
|
56080 | if (nor_flash -> lx_nor_flash_sector_mapping_cache_enabled) |
| 136 | { | ||
| 137 | |||
| 138 | /* Calculate the starting index of the sector cache for this sector entry. */ | ||
| 139 | 56040 | i = (logical_sector & LX_NOR_SECTOR_MAPPING_CACHE_HASH_MASK) * LX_NOR_SECTOR_MAPPING_CACHE_DEPTH; | |
| 140 | |||
| 141 | /* Build a pointer to the cache entry. */ | ||
| 142 | 56040 | sector_mapping_cache_entry_ptr = &nor_flash -> lx_nor_flash_sector_mapping_cache[i]; | |
| 143 | |||
| 144 | /* Determine if the sector is in the sector mapping cache - assuming the depth of the sector | ||
| 145 | mapping cache is LX_NOR_SECTOR_MAPPING_CACHE_DEPTH entries. */ | ||
| 146 |
4/4✓ Branch 5 → 6 taken 19360 times.
✓ Branch 5 → 7 taken 25961 times.
✓ Branch 8 → 9 taken 4840 times.
✓ Branch 8 → 10 taken 5879 times.
|
56040 | if ((sector_mapping_cache_entry_ptr -> lx_nor_sector_mapping_cache_logical_sector) == (logical_sector | LX_NOR_SECTOR_MAPPING_CACHE_ENTRY_VALID)) |
| 147 | { | ||
| 148 | |||
| 149 | /* Increment the sector mapping cache hit counter. */ | ||
| 150 | 24200 | nor_flash -> lx_nor_flash_sector_mapping_cache_hits++; | |
| 151 | |||
| 152 | /* Yes, return the cached values associated with the sector. */ | ||
| 153 | 24200 | *physical_sector_map_entry = sector_mapping_cache_entry_ptr -> lx_nor_sector_mapping_cache_physical_sector_map_entry; | |
| 154 | 24200 | *physical_sector_address = sector_mapping_cache_entry_ptr -> lx_nor_sector_mapping_cache_physical_sector_address; | |
| 155 | |||
| 156 | /* Don't move anything since we found the entry at the top. */ | ||
| 157 | |||
| 158 | /* Return a successful status. */ | ||
| 159 | 24200 | return(LX_SUCCESS); | |
| 160 | } | ||
| 161 |
4/4✓ Branch 7 → 8 taken 544 times.
✓ Branch 7 → 9 taken 25417 times.
✓ Branch 10 → 11 taken 136 times.
✓ Branch 10 → 12 taken 5743 times.
|
31840 | else if (((sector_mapping_cache_entry_ptr + 1) -> lx_nor_sector_mapping_cache_logical_sector) == (logical_sector | LX_NOR_SECTOR_MAPPING_CACHE_ENTRY_VALID)) |
| 162 | { | ||
| 163 | |||
| 164 | /* Increment the sector mapping cache hit counter. */ | ||
| 165 | 680 | nor_flash -> lx_nor_flash_sector_mapping_cache_hits++; | |
| 166 | |||
| 167 | /* Yes, return the cached values associated with the sector. */ | ||
| 168 | 680 | *physical_sector_map_entry = (sector_mapping_cache_entry_ptr + 1) -> lx_nor_sector_mapping_cache_physical_sector_map_entry; | |
| 169 | 680 | *physical_sector_address = (sector_mapping_cache_entry_ptr + 1) -> lx_nor_sector_mapping_cache_physical_sector_address; | |
| 170 | |||
| 171 | /* Just swap the first and second entry. */ | ||
| 172 | 680 | temp_sector_mapping_cache_entry = *(sector_mapping_cache_entry_ptr); | |
| 173 | 680 | *(sector_mapping_cache_entry_ptr) = *(sector_mapping_cache_entry_ptr + 1); | |
| 174 | 680 | *(sector_mapping_cache_entry_ptr + 1) = temp_sector_mapping_cache_entry; | |
| 175 | |||
| 176 | /* Return a successful status. */ | ||
| 177 | 680 | return(LX_SUCCESS); | |
| 178 | } | ||
| 179 |
4/4✓ Branch 9 → 10 taken 608 times.
✓ Branch 9 → 11 taken 24809 times.
✓ Branch 12 → 13 taken 152 times.
✓ Branch 12 → 14 taken 5591 times.
|
31160 | else if (((sector_mapping_cache_entry_ptr + 2) -> lx_nor_sector_mapping_cache_logical_sector) == (logical_sector | LX_NOR_SECTOR_MAPPING_CACHE_ENTRY_VALID)) |
| 180 | { | ||
| 181 | |||
| 182 | /* Increment the sector mapping cache hit counter. */ | ||
| 183 | 760 | nor_flash -> lx_nor_flash_sector_mapping_cache_hits++; | |
| 184 | |||
| 185 | /* Yes, return the cached value. */ | ||
| 186 | 760 | *physical_sector_map_entry = (sector_mapping_cache_entry_ptr + 2) -> lx_nor_sector_mapping_cache_physical_sector_map_entry; | |
| 187 | 760 | *physical_sector_address = (sector_mapping_cache_entry_ptr + 2) -> lx_nor_sector_mapping_cache_physical_sector_address; | |
| 188 | |||
| 189 | /* Move the third entry to the top and the first two entries down. */ | ||
| 190 | 760 | temp_sector_mapping_cache_entry = *(sector_mapping_cache_entry_ptr); | |
| 191 | 760 | *(sector_mapping_cache_entry_ptr) = *(sector_mapping_cache_entry_ptr + 2); | |
| 192 | 760 | *(sector_mapping_cache_entry_ptr + 2) = *(sector_mapping_cache_entry_ptr + 1); | |
| 193 | 760 | *(sector_mapping_cache_entry_ptr + 1) = temp_sector_mapping_cache_entry; | |
| 194 | |||
| 195 | /* Return a successful status. */ | ||
| 196 | 760 | return(LX_SUCCESS); | |
| 197 | } | ||
| 198 |
4/4✓ Branch 11 → 12 taken 160 times.
✓ Branch 11 → 13 taken 24649 times.
✓ Branch 14 → 15 taken 40 times.
✓ Branch 14 → 16 taken 5551 times.
|
30400 | else if (((sector_mapping_cache_entry_ptr + 3) -> lx_nor_sector_mapping_cache_logical_sector) == (logical_sector | LX_NOR_SECTOR_MAPPING_CACHE_ENTRY_VALID)) |
| 199 | { | ||
| 200 | |||
| 201 | /* Increment the sector mapping cache hit counter. */ | ||
| 202 | 200 | nor_flash -> lx_nor_flash_sector_mapping_cache_hits++; | |
| 203 | |||
| 204 | /* Yes, return the cached value. */ | ||
| 205 | 200 | *physical_sector_map_entry = (sector_mapping_cache_entry_ptr + 3) -> lx_nor_sector_mapping_cache_physical_sector_map_entry; | |
| 206 | 200 | *physical_sector_address = (sector_mapping_cache_entry_ptr + 3) -> lx_nor_sector_mapping_cache_physical_sector_address; | |
| 207 | |||
| 208 | /* Move the last entry to the top and the first three entries down. */ | ||
| 209 | 200 | temp_sector_mapping_cache_entry = *(sector_mapping_cache_entry_ptr); | |
| 210 | 200 | *(sector_mapping_cache_entry_ptr) = *(sector_mapping_cache_entry_ptr + 3); | |
| 211 | 200 | *(sector_mapping_cache_entry_ptr + 3) = *(sector_mapping_cache_entry_ptr + 2); | |
| 212 | 200 | *(sector_mapping_cache_entry_ptr + 2) = *(sector_mapping_cache_entry_ptr + 1); | |
| 213 | 200 | *(sector_mapping_cache_entry_ptr + 1) = temp_sector_mapping_cache_entry; | |
| 214 | |||
| 215 | /* Return a successful status. */ | ||
| 216 | 200 | return(LX_SUCCESS); | |
| 217 | } | ||
| 218 | |||
| 219 | /* If we get here, we have a cache miss so increment the counter before we fall through the loop. */ | ||
| 220 | 30200 | nor_flash -> lx_nor_flash_sector_mapping_cache_misses++; | |
| 221 | } | ||
| 222 | |||
| 223 | /* Setup the total number of mapped sectors. */ | ||
| 224 | 30240 | mapped_sectors = nor_flash -> lx_nor_flash_mapped_physical_sectors; | |
| 225 | |||
| 226 | /* Start searching from the last found block. */ | ||
| 227 | 30240 | i = nor_flash -> lx_nor_flash_found_block_search; | |
| 228 | |||
| 229 | /* Setup the starting sector to look at. */ | ||
| 230 | 30240 | j = nor_flash -> lx_nor_flash_found_sector_search; | |
| 231 | |||
| 232 | /* Pickup the total number of blocks. */ | ||
| 233 | 30240 | total_blocks = nor_flash -> lx_nor_flash_total_blocks; | |
| 234 | |||
| 235 | /* Loop through the blocks to attempt to find the mapped logical sector. */ | ||
| 236 |
10/10✓ Branch 57 → 15 taken 25662 times.
✓ Branch 57 → 58 taken 882 times.
✓ Branch 67 → 15 taken 12834 times.
✓ Branch 67 → 68 taken 441 times.
✓ Branch 69 → 15 taken 64155 times.
✓ Branch 69 → 70 taken 2205 times.
✓ Branch 70 → 18 taken 10694 times.
✓ Branch 70 → 71 taken 179 times.
✓ Branch 72 → 18 taken 10691 times.
✓ Branch 72 → 73 taken 179 times.
|
127922 | while (total_blocks--) |
| 237 | { | ||
| 238 | |||
| 239 | #ifdef LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE | ||
| 240 | /* Determine if the obsolete sector count is available in the cache. */ | ||
| 241 |
4/4✓ Branch 15 → 16 taken 6857 times.
✓ Branch 15 → 20 taken 5977 times.
✓ Branch 18 → 19 taken 4717 times.
✓ Branch 18 → 23 taken 5977 times.
|
23528 | if (i < nor_flash -> lx_nor_flash_extended_cache_obsolete_count_max_block) |
| 242 | { | ||
| 243 | |||
| 244 | /* Check if the block contains obsolete sectors only. */ | ||
| 245 |
4/4✓ Branch 16 → 17 taken 5 times.
✓ Branch 16 → 20 taken 6852 times.
✓ Branch 19 → 20 taken 5 times.
✓ Branch 19 → 23 taken 4712 times.
|
11574 | if ((ULONG)nor_flash -> lx_nor_flash_extended_cache_obsolete_count[i] == nor_flash -> lx_nor_flash_physical_sectors_per_block) |
| 246 | { | ||
| 247 | |||
| 248 | /* Move to the next block. */ | ||
| 249 | 10 | i++; | |
| 250 | |||
| 251 | /* Determine if we have wrapped. */ | ||
| 252 |
2/4✗ Branch 17 → 18 not taken.
✓ Branch 17 → 19 taken 5 times.
✗ Branch 20 → 21 not taken.
✓ Branch 20 → 22 taken 5 times.
|
10 | if (i >= nor_flash -> lx_nor_flash_total_blocks) |
| 253 | { | ||
| 254 | |||
| 255 | /* Yes, we have wrapped, set to block 0. */ | ||
| 256 | ✗ | i = 0; | |
| 257 | } | ||
| 258 | |||
| 259 | /* Start at the first sector in the next block. */ | ||
| 260 | 10 | j = 0; | |
| 261 | |||
| 262 | /* No point in looking further into this block, just continue the loop. */ | ||
| 263 | 10 | continue; | |
| 264 | |||
| 265 | } | ||
| 266 | } | ||
| 267 | #endif | ||
| 268 | |||
| 269 | /* Setup the block word pointer to the first word of the search block. */ | ||
| 270 | 124026 | block_word_ptr = (nor_flash -> lx_nor_flash_base_address + (i * nor_flash -> lx_nor_flash_words_per_block)); | |
| 271 | |||
| 272 | /* Determine if the minimum and maximum logical sector values are present in the block header. If these are | ||
| 273 | present, we can quickly skip blocks that don't have our sector. */ | ||
| 274 | |||
| 275 | /* Read the minimum and maximum logical sector values in this block. */ | ||
| 276 | #ifdef LX_DIRECT_READ | ||
| 277 | |||
| 278 | /* Read the word directly. */ | ||
| 279 | 25662 | min_logical_sector = *(block_word_ptr + LX_NOR_FLASH_MIN_LOGICAL_SECTOR_OFFSET); | |
| 280 | #else | ||
| 281 | 98364 | status = _lx_nor_flash_driver_read(nor_flash, block_word_ptr + LX_NOR_FLASH_MIN_LOGICAL_SECTOR_OFFSET, &min_logical_sector, 1); | |
| 282 | |||
| 283 | /* Check for an error from flash driver. Drivers should never return an error.. */ | ||
| 284 |
4/8✗ Branch 16 → 17 not taken.
✓ Branch 16 → 19 taken 64155 times.
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 22 taken 10691 times.
✗ Branch 21 → 22 not taken.
✓ Branch 21 → 24 taken 12829 times.
✗ Branch 24 → 25 not taken.
✓ Branch 24 → 27 taken 10689 times.
|
98364 | if (status) |
| 285 | { | ||
| 286 | |||
| 287 | /* Call system error handler. */ | ||
| 288 | ✗ | _lx_nor_flash_system_error(nor_flash, status); | |
| 289 | |||
| 290 | /* Return the error. */ | ||
| 291 | ✗ | return(status); | |
| 292 | } | ||
| 293 | #endif | ||
| 294 | |||
| 295 | /* Is the value valid? */ | ||
| 296 |
10/10✓ Branch 15 → 16 taken 18188 times.
✓ Branch 15 → 22 taken 7474 times.
✓ Branch 19 → 20 taken 45470 times.
✓ Branch 19 → 30 taken 18685 times.
✓ Branch 22 → 23 taken 8212 times.
✓ Branch 22 → 33 taken 2479 times.
✓ Branch 24 → 25 taken 9090 times.
✓ Branch 24 → 35 taken 3739 times.
✓ Branch 27 → 28 taken 8208 times.
✓ Branch 27 → 38 taken 2481 times.
|
124026 | if (min_logical_sector != LX_ALL_ONES) |
| 297 | { | ||
| 298 | #ifdef LX_DIRECT_READ | ||
| 299 | |||
| 300 | /* Read the word directly. */ | ||
| 301 | 18188 | max_logical_sector = *(block_word_ptr + LX_NOR_FLASH_MAX_LOGICAL_SECTOR_OFFSET); | |
| 302 | #else | ||
| 303 | 70980 | status = _lx_nor_flash_driver_read(nor_flash, block_word_ptr + LX_NOR_FLASH_MAX_LOGICAL_SECTOR_OFFSET, &max_logical_sector, 1); | |
| 304 | |||
| 305 | /* Check for an error from flash driver. Drivers should never return an error.. */ | ||
| 306 |
4/8✗ Branch 21 → 22 not taken.
✓ Branch 21 → 24 taken 45470 times.
✗ Branch 24 → 25 not taken.
✓ Branch 24 → 27 taken 8212 times.
✗ Branch 26 → 27 not taken.
✓ Branch 26 → 29 taken 9090 times.
✗ Branch 29 → 30 not taken.
✓ Branch 29 → 32 taken 8208 times.
|
70980 | if (status) |
| 307 | { | ||
| 308 | |||
| 309 | /* Call system error handler. */ | ||
| 310 | ✗ | _lx_nor_flash_system_error(nor_flash, status); | |
| 311 | |||
| 312 | /* Return the error. */ | ||
| 313 | ✗ | return(status); | |
| 314 | } | ||
| 315 | #endif | ||
| 316 | |||
| 317 | /* Is the value valid? */ | ||
| 318 |
5/10✓ Branch 16 → 17 taken 18188 times.
✗ Branch 16 → 23 not taken.
✓ Branch 24 → 25 taken 45470 times.
✗ Branch 24 → 31 not taken.
✓ Branch 27 → 28 taken 8212 times.
✗ Branch 27 → 34 not taken.
✓ Branch 29 → 30 taken 9090 times.
✗ Branch 29 → 36 not taken.
✓ Branch 32 → 33 taken 8208 times.
✗ Branch 32 → 39 not taken.
|
89168 | if (max_logical_sector != LX_ALL_ONES) |
| 319 | { | ||
| 320 | |||
| 321 | /* Now let's check to see if the search sector is within this range. */ | ||
| 322 |
20/20✓ Branch 17 → 18 taken 17496 times.
✓ Branch 17 → 19 taken 692 times.
✓ Branch 18 → 19 taken 3860 times.
✓ Branch 18 → 23 taken 13636 times.
✓ Branch 25 → 26 taken 43740 times.
✓ Branch 25 → 27 taken 1730 times.
✓ Branch 26 → 27 taken 9650 times.
✓ Branch 26 → 31 taken 34090 times.
✓ Branch 28 → 29 taken 7866 times.
✓ Branch 28 → 30 taken 346 times.
✓ Branch 29 → 30 taken 1048 times.
✓ Branch 29 → 34 taken 6818 times.
✓ Branch 30 → 31 taken 8744 times.
✓ Branch 30 → 32 taken 346 times.
✓ Branch 31 → 32 taken 1925 times.
✓ Branch 31 → 36 taken 6819 times.
✓ Branch 33 → 34 taken 7862 times.
✓ Branch 33 → 35 taken 346 times.
✓ Branch 34 → 35 taken 1043 times.
✓ Branch 34 → 39 taken 6819 times.
|
89168 | if ((logical_sector < min_logical_sector) || (logical_sector > max_logical_sector)) |
| 323 | { | ||
| 324 | |||
| 325 | /* Move to the next block. */ | ||
| 326 | 20986 | i++; | |
| 327 | |||
| 328 | /* Determine if we have wrapped. */ | ||
| 329 |
10/10✓ Branch 19 → 20 taken 196 times.
✓ Branch 19 → 21 taken 4356 times.
✓ Branch 27 → 28 taken 490 times.
✓ Branch 27 → 29 taken 10890 times.
✓ Branch 30 → 31 taken 97 times.
✓ Branch 30 → 32 taken 1297 times.
✓ Branch 32 → 33 taken 98 times.
✓ Branch 32 → 34 taken 2173 times.
✓ Branch 35 → 36 taken 97 times.
✓ Branch 35 → 37 taken 1292 times.
|
20986 | if (i >= nor_flash -> lx_nor_flash_total_blocks) |
| 330 | { | ||
| 331 | |||
| 332 | /* Yes, we have wrapped, set to block 0. */ | ||
| 333 | 978 | i = 0; | |
| 334 | } | ||
| 335 | |||
| 336 | /* Start at the first sector in the next block. */ | ||
| 337 | 20986 | j = 0; | |
| 338 | |||
| 339 | /* No point in looking further into this block, just continue the loop. */ | ||
| 340 | 20986 | continue; | |
| 341 | } | ||
| 342 | } | ||
| 343 | } | ||
| 344 | else | ||
| 345 | { | ||
| 346 | |||
| 347 | /* Set the max logical sector to all ones. */ | ||
| 348 | 34858 | max_logical_sector = LX_ALL_ONES; | |
| 349 | } | ||
| 350 | #ifndef LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE | ||
| 351 | |||
| 352 | /* Clear the valid sector found flag. */ | ||
| 353 | 83182 | valid_sector_found = LX_FALSE; | |
| 354 | #endif | ||
| 355 | |||
| 356 | /* Setup the total number of sectors. */ | ||
| 357 | 103040 | total_sectors = nor_flash -> lx_nor_flash_physical_sectors_per_block; | |
| 358 | |||
| 359 | /* Remember the start of the search. */ | ||
| 360 | 103040 | search_start = j; | |
| 361 | |||
| 362 | /* Now search through the sector list to find a match. */ | ||
| 363 |
10/10✓ Branch 44 → 24 taken 190392 times.
✓ Branch 44 → 45 taken 9398 times.
✓ Branch 56 → 32 taken 475980 times.
✓ Branch 56 → 57 taken 23495 times.
✓ Branch 59 → 35 taken 91852 times.
✓ Branch 59 → 60 taken 4698 times.
✓ Branch 60 → 37 taken 95209 times.
✓ Branch 60 → 61 taken 4700 times.
✓ Branch 63 → 40 taken 91865 times.
✓ Branch 63 → 64 taken 4699 times.
|
992288 | while (total_sectors--) |
| 364 | { | ||
| 365 | |||
| 366 | /* Setup a pointer to the mapped list. */ | ||
| 367 | 945298 | list_word_ptr = block_word_ptr + nor_flash -> lx_nor_flash_block_physical_sector_mapping_offset + j; | |
| 368 | |||
| 369 | |||
| 370 | /* Read in the mapped list for this block. */ | ||
| 371 | #ifdef LX_DIRECT_READ | ||
| 372 | |||
| 373 | /* Read the word directly. */ | ||
| 374 | 190392 | list_word = *(list_word_ptr); | |
| 375 | #else | ||
| 376 | 754906 | status = _lx_nor_flash_driver_read(nor_flash, list_word_ptr, &list_word, 1); | |
| 377 | |||
| 378 | /* Check for an error from flash driver. Drivers should never return an error.. */ | ||
| 379 |
4/8✗ Branch 33 → 34 not taken.
✓ Branch 33 → 36 taken 475980 times.
✗ Branch 36 → 37 not taken.
✓ Branch 36 → 39 taken 91852 times.
✗ Branch 38 → 39 not taken.
✓ Branch 38 → 41 taken 95209 times.
✗ Branch 41 → 42 not taken.
✓ Branch 41 → 44 taken 91865 times.
|
754906 | if (status) |
| 380 | { | ||
| 381 | |||
| 382 | /* Call system error handler. */ | ||
| 383 | ✗ | _lx_nor_flash_system_error(nor_flash, status); | |
| 384 | |||
| 385 | /* Return the error. */ | ||
| 386 | ✗ | return(status); | |
| 387 | } | ||
| 388 | #endif | ||
| 389 | |||
| 390 | /* Determine if the entry hasn't been used. */ | ||
| 391 |
10/10✓ Branch 24 → 25 taken 7142 times.
✓ Branch 24 → 28 taken 183250 times.
✓ Branch 36 → 37 taken 17855 times.
✓ Branch 36 → 40 taken 458125 times.
✓ Branch 39 → 40 taken 2313 times.
✓ Branch 39 → 43 taken 89539 times.
✓ Branch 41 → 42 taken 3573 times.
✓ Branch 41 → 45 taken 91636 times.
✓ Branch 44 → 45 taken 2315 times.
✓ Branch 44 → 48 taken 89550 times.
|
945298 | if (list_word == LX_NOR_PHYSICAL_SECTOR_FREE) |
| 392 | { | ||
| 393 | |||
| 394 | /* Since the mapping is done sequentially in the block, we know nothing | ||
| 395 | else exists after this point. */ | ||
| 396 | |||
| 397 | /* Determine if the search started at the beginning of the block. */ | ||
| 398 |
10/10✓ Branch 25 → 26 taken 6572 times.
✓ Branch 25 → 27 taken 570 times.
✓ Branch 37 → 38 taken 16430 times.
✓ Branch 37 → 39 taken 1425 times.
✓ Branch 40 → 41 taken 2029 times.
✓ Branch 40 → 42 taken 284 times.
✓ Branch 42 → 43 taken 3287 times.
✓ Branch 42 → 44 taken 286 times.
✓ Branch 45 → 46 taken 2030 times.
✓ Branch 45 → 47 taken 285 times.
|
33198 | if (search_start == 0) |
| 399 | { | ||
| 400 | |||
| 401 | /* Yes, we started at the beginning of the block. We are now done with this block. */ | ||
| 402 | 30348 | break; | |
| 403 | } | ||
| 404 | else | ||
| 405 | { | ||
| 406 | |||
| 407 | /* Setup the new total to the search start. */ | ||
| 408 | 2850 | total_sectors = search_start; | |
| 409 | |||
| 410 | /* Clear search start. */ | ||
| 411 | 2850 | search_start = 0; | |
| 412 | |||
| 413 | /* Start search over. */ | ||
| 414 | 2850 | j = 0; | |
| 415 | 2850 | continue; | |
| 416 | } | ||
| 417 | } | ||
| 418 | |||
| 419 | /* Is this entry valid? */ | ||
| 420 |
10/10✓ Branch 28 → 29 taken 174750 times.
✓ Branch 28 → 41 taken 8500 times.
✓ Branch 40 → 41 taken 436875 times.
✓ Branch 40 → 53 taken 21250 times.
✓ Branch 43 → 44 taken 85333 times.
✓ Branch 43 → 56 taken 4206 times.
✓ Branch 45 → 46 taken 87386 times.
✓ Branch 45 → 57 taken 4250 times.
✓ Branch 48 → 49 taken 85344 times.
✓ Branch 48 → 60 taken 4206 times.
|
912100 | if ((list_word & (LX_NOR_PHYSICAL_SECTOR_VALID | LX_NOR_PHYSICAL_SECTOR_MAPPING_NOT_VALID)) == LX_NOR_PHYSICAL_SECTOR_VALID) |
| 421 | { | ||
| 422 | |||
| 423 | /* Decrement the number of mapped sectors. */ | ||
| 424 | 869688 | mapped_sectors--; | |
| 425 | |||
| 426 | /* Do we have a valid sector match? */ | ||
| 427 |
10/10✓ Branch 29 → 30 taken 5144 times.
✓ Branch 29 → 40 taken 169606 times.
✓ Branch 41 → 42 taken 12860 times.
✓ Branch 41 → 52 taken 424015 times.
✓ Branch 44 → 45 taken 2572 times.
✓ Branch 44 → 55 taken 82761 times.
✓ Branch 46 → 47 taken 2573 times.
✓ Branch 46 → 57 taken 84813 times.
✓ Branch 49 → 50 taken 2573 times.
✓ Branch 49 → 60 taken 82771 times.
|
869688 | if ((list_word & LX_NOR_LOGICAL_SECTOR_MASK) == logical_sector) |
| 428 | { | ||
| 429 | |||
| 430 | /* Determine if we care about the superceded bit. */ | ||
| 431 |
10/10✓ Branch 30 → 31 taken 5136 times.
✓ Branch 30 → 36 taken 8 times.
✓ Branch 42 → 43 taken 12840 times.
✓ Branch 42 → 48 taken 20 times.
✓ Branch 45 → 46 taken 2568 times.
✓ Branch 45 → 51 taken 4 times.
✓ Branch 47 → 48 taken 2569 times.
✓ Branch 47 → 53 taken 4 times.
✓ Branch 50 → 51 taken 2569 times.
✓ Branch 50 → 56 taken 4 times.
|
25722 | if (superceded_check == LX_FALSE) |
| 432 | { | ||
| 433 | |||
| 434 | /* Prepare the return information. */ | ||
| 435 | 25682 | *physical_sector_map_entry = list_word_ptr; | |
| 436 | 25682 | *physical_sector_address = block_word_ptr + nor_flash -> lx_nor_flash_block_physical_sector_offset + (j * LX_NOR_SECTOR_SIZE); | |
| 437 | |||
| 438 | /* Determine if the sector mapping cache is enabled. */ | ||
| 439 |
5/10✓ Branch 31 → 32 taken 5136 times.
✗ Branch 31 → 33 not taken.
✓ Branch 43 → 44 taken 12840 times.
✗ Branch 43 → 45 not taken.
✓ Branch 46 → 47 taken 2568 times.
✗ Branch 46 → 48 not taken.
✓ Branch 48 → 49 taken 2569 times.
✗ Branch 48 → 50 not taken.
✓ Branch 51 → 52 taken 2569 times.
✗ Branch 51 → 53 not taken.
|
25682 | if (nor_flash -> lx_nor_flash_sector_mapping_cache_enabled) |
| 440 | { | ||
| 441 | |||
| 442 | /* Yes, update the cache with the sector mapping. */ | ||
| 443 | |||
| 444 | /* Move all the cache entries down so the oldest is at the bottom. */ | ||
| 445 | 25682 | *(sector_mapping_cache_entry_ptr + 3) = *(sector_mapping_cache_entry_ptr + 2); | |
| 446 | 25682 | *(sector_mapping_cache_entry_ptr + 2) = *(sector_mapping_cache_entry_ptr + 1); | |
| 447 | 25682 | *(sector_mapping_cache_entry_ptr + 1) = *(sector_mapping_cache_entry_ptr); | |
| 448 | |||
| 449 | /* Setup the new sector information in the cache. */ | ||
| 450 | 25682 | sector_mapping_cache_entry_ptr -> lx_nor_sector_mapping_cache_logical_sector = (logical_sector | LX_NOR_SECTOR_MAPPING_CACHE_ENTRY_VALID); | |
| 451 | 25682 | sector_mapping_cache_entry_ptr -> lx_nor_sector_mapping_cache_physical_sector_map_entry = *physical_sector_map_entry; | |
| 452 | 25682 | sector_mapping_cache_entry_ptr -> lx_nor_sector_mapping_cache_physical_sector_address = *physical_sector_address; | |
| 453 | } | ||
| 454 | |||
| 455 | /* Remember the last found block for next search. */ | ||
| 456 | 25682 | nor_flash -> lx_nor_flash_found_block_search = i; | |
| 457 | |||
| 458 | /* Remember the last found sector. */ | ||
| 459 | 25682 | nor_flash -> lx_nor_flash_found_sector_search = j+1; | |
| 460 | |||
| 461 | /* Has this wrapped around? */ | ||
| 462 |
10/10✓ Branch 33 → 34 taken 86 times.
✓ Branch 33 → 35 taken 5050 times.
✓ Branch 45 → 46 taken 215 times.
✓ Branch 45 → 47 taken 12625 times.
✓ Branch 48 → 49 taken 43 times.
✓ Branch 48 → 50 taken 2525 times.
✓ Branch 50 → 51 taken 43 times.
✓ Branch 50 → 52 taken 2526 times.
✓ Branch 53 → 54 taken 43 times.
✓ Branch 53 → 55 taken 2526 times.
|
25682 | if (nor_flash -> lx_nor_flash_found_sector_search >= nor_flash -> lx_nor_flash_physical_sectors_per_block) |
| 463 | { | ||
| 464 | |||
| 465 | /* Reset to the beginning sector. */ | ||
| 466 | 430 | nor_flash -> lx_nor_flash_found_sector_search = 0; | |
| 467 | } | ||
| 468 | |||
| 469 | /* Return success! */ | ||
| 470 | 25682 | return(LX_SUCCESS); | |
| 471 | } | ||
| 472 | |||
| 473 | /* Check for the superceded bit being clear, which means the sector was superceded. */ | ||
| 474 |
10/10✓ Branch 36 → 37 taken 4 times.
✓ Branch 36 → 40 taken 4 times.
✓ Branch 48 → 49 taken 10 times.
✓ Branch 48 → 52 taken 10 times.
✓ Branch 51 → 52 taken 2 times.
✓ Branch 51 → 55 taken 2 times.
✓ Branch 53 → 54 taken 2 times.
✓ Branch 53 → 57 taken 2 times.
✓ Branch 56 → 57 taken 2 times.
✓ Branch 56 → 60 taken 2 times.
|
40 | else if (list_word & LX_NOR_PHYSICAL_SECTOR_SUPERCEDED) |
| 475 | { | ||
| 476 | |||
| 477 | /* Prepare the return information. */ | ||
| 478 | 20 | *physical_sector_map_entry = list_word_ptr; | |
| 479 | 20 | *physical_sector_address = block_word_ptr + nor_flash -> lx_nor_flash_block_physical_sector_offset + (j * LX_NOR_SECTOR_SIZE); | |
| 480 | |||
| 481 | /* No need to update the cache here, since this condition only happens during initialization. */ | ||
| 482 | |||
| 483 | /* Remember the last found block for next search. */ | ||
| 484 | 20 | nor_flash -> lx_nor_flash_found_block_search = i; | |
| 485 | |||
| 486 | /* Remember the last found sector. */ | ||
| 487 | 20 | nor_flash -> lx_nor_flash_found_sector_search = j+1; | |
| 488 | |||
| 489 | /* Has this wrapped around? */ | ||
| 490 |
5/10✗ Branch 37 → 38 not taken.
✓ Branch 37 → 39 taken 4 times.
✗ Branch 49 → 50 not taken.
✓ Branch 49 → 51 taken 10 times.
✗ Branch 52 → 53 not taken.
✓ Branch 52 → 54 taken 2 times.
✗ Branch 54 → 55 not taken.
✓ Branch 54 → 56 taken 2 times.
✗ Branch 57 → 58 not taken.
✓ Branch 57 → 59 taken 2 times.
|
20 | if (nor_flash -> lx_nor_flash_found_sector_search >= nor_flash -> lx_nor_flash_physical_sectors_per_block) |
| 491 | { | ||
| 492 | |||
| 493 | /* Reset to the beginning sector. */ | ||
| 494 | ✗ | nor_flash -> lx_nor_flash_found_sector_search = 0; | |
| 495 | } | ||
| 496 | |||
| 497 | /* Return success! */ | ||
| 498 | 20 | return(LX_SUCCESS); | |
| 499 | } | ||
| 500 | } | ||
| 501 | #ifndef LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE | ||
| 502 | |||
| 503 | /* Set the valid sector found flag. */ | ||
| 504 | 676398 | valid_sector_found = LX_TRUE; | |
| 505 | #endif | ||
| 506 | } | ||
| 507 | |||
| 508 | /* Move to the next list entry. */ | ||
| 509 | 886398 | j++; | |
| 510 | |||
| 511 | /* Check for wrap around. */ | ||
| 512 |
10/10✓ Branch 41 → 42 taken 9444 times.
✓ Branch 41 → 43 taken 168666 times.
✓ Branch 53 → 54 taken 23610 times.
✓ Branch 53 → 55 taken 421665 times.
✓ Branch 56 → 57 taken 4722 times.
✓ Branch 56 → 58 taken 82247 times.
✓ Branch 57 → 58 taken 4722 times.
✓ Branch 57 → 59 taken 84343 times.
✓ Branch 60 → 61 taken 4722 times.
✓ Branch 60 → 62 taken 82257 times.
|
886398 | if (j >= nor_flash -> lx_nor_flash_physical_sectors_per_block) |
| 513 | { | ||
| 514 | |||
| 515 | /* Yes, wrap around, go back to the beginning. */ | ||
| 516 | 47220 | j = 0; | |
| 517 | } | ||
| 518 | } | ||
| 519 | #ifndef LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE | ||
| 520 | /* Check if the block contains no valid sectors. */ | ||
| 521 |
9/12✓ Branch 45 → 46 taken 5154 times.
✓ Branch 45 → 51 taken 10816 times.
✗ Branch 46 → 47 not taken.
✓ Branch 46 → 51 taken 5154 times.
✓ Branch 57 → 58 taken 12885 times.
✓ Branch 57 → 63 taken 27040 times.
✗ Branch 58 → 59 not taken.
✓ Branch 58 → 63 taken 12885 times.
✓ Branch 60 → 61 taken 1607 times.
✓ Branch 60 → 66 taken 5120 times.
✗ Branch 61 → 62 not taken.
✓ Branch 61 → 66 taken 1607 times.
|
62622 | if ((valid_sector_found == LX_FALSE) && (max_logical_sector != LX_ALL_ONES)) |
| 522 | { | ||
| 523 | |||
| 524 | /* Clear max logical sector to indicate sectors are all obsoleted. */ | ||
| 525 | ✗ | max_logical_sector = 0; | |
| 526 | |||
| 527 | /* Write the max logical sector to the block header. */ | ||
| 528 | ✗ | status = _lx_nor_flash_driver_write(nor_flash, block_word_ptr + LX_NOR_FLASH_MAX_LOGICAL_SECTOR_OFFSET, &max_logical_sector, 1); | |
| 529 | |||
| 530 | /* Check for an error from flash driver. Drivers should never return an error.. */ | ||
| 531 | ✗ | if (status) | |
| 532 | { | ||
| 533 | |||
| 534 | /* Call system error handler. */ | ||
| 535 | ✗ | _lx_nor_flash_system_error(nor_flash, status); | |
| 536 | |||
| 537 | /* Return the error. */ | ||
| 538 | ✗ | return(status); | |
| 539 | } | ||
| 540 | } | ||
| 541 | #endif | ||
| 542 | |||
| 543 | /* Determine if there are any more mapped sectors. */ | ||
| 544 |
10/10✓ Branch 51 → 52 taken 148 times.
✓ Branch 51 → 53 taken 15822 times.
✓ Branch 61 → 62 taken 74 times.
✓ Branch 61 → 63 taken 7913 times.
✓ Branch 63 → 64 taken 370 times.
✓ Branch 63 → 65 taken 39555 times.
✓ Branch 64 → 65 taken 30 times.
✓ Branch 64 → 66 taken 6699 times.
✓ Branch 66 → 67 taken 30 times.
✓ Branch 66 → 68 taken 6697 times.
|
77338 | if (mapped_sectors == 0) |
| 545 | 652 | break; | |
| 546 | |||
| 547 | /* Move to the next block. */ | ||
| 548 | 76686 | i++; | |
| 549 | |||
| 550 | /* Determine if we have wrapped. */ | ||
| 551 |
10/10✓ Branch 53 → 54 taken 2344 times.
✓ Branch 53 → 55 taken 13478 times.
✓ Branch 63 → 64 taken 1173 times.
✓ Branch 63 → 65 taken 6740 times.
✓ Branch 65 → 66 taken 5860 times.
✓ Branch 65 → 67 taken 33695 times.
✓ Branch 66 → 67 taken 912 times.
✓ Branch 66 → 68 taken 5787 times.
✓ Branch 68 → 69 taken 911 times.
✓ Branch 68 → 70 taken 5786 times.
|
76686 | if (i >= nor_flash -> lx_nor_flash_total_blocks) |
| 552 | { | ||
| 553 | |||
| 554 | /* Yes, we have wrapped, set to block 0. */ | ||
| 555 | 11200 | i = 0; | |
| 556 | } | ||
| 557 | |||
| 558 | /* Start at the first sector in the next block. */ | ||
| 559 | 76686 | j = 0; | |
| 560 | } | ||
| 561 | |||
| 562 | /* Return sector not found status. */ | ||
| 563 | 4538 | return(LX_SECTOR_NOT_FOUND); | |
| 564 | } | ||
| 565 | |||
| 566 |