Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ target_sources(${PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_format_extended.c
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_free_block_list_add.c
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_logical_group_compact.c
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_mapped_block_list_add.c
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_mapped_block_list_get.c
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_mapped_block_list_remove.c
Expand Down
25 changes: 25 additions & 0 deletions common/inc/lx_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,17 @@ typedef unsigned long long ULONG64;
#define LX_NAND_FLASH_MAX_METADATA_BLOCKS 4
#endif

/* When LX_NAND_FLASH_ENABLE_LAZY_SECTOR_RELEASE is defined, sector releases from full blocks
are deferred when free block count exceeds the threshold below (opt-in, default: off).
Requires pages_per_block <= 4095 (bit 12 is reserved for COMPACTION_PENDING flag). */
/* #define LX_NAND_FLASH_ENABLE_LAZY_SECTOR_RELEASE */

#ifdef LX_NAND_FLASH_ENABLE_LAZY_SECTOR_RELEASE
#ifndef LX_NAND_FLASH_SECTOR_RELEASE_LAZY_THRESHOLD
#define LX_NAND_FLASH_SECTOR_RELEASE_LAZY_THRESHOLD 10u
#endif
#endif

#ifndef LX_UTILITY_SHORT_SET
#define LX_UTILITY_SHORT_SET(address, value) *((USHORT*)(address)) = (USHORT)(value)
#endif
Expand Down Expand Up @@ -328,6 +339,11 @@ typedef unsigned long long ULONG64;
#define LX_NAND_BLOCK_STATUS_FULL 0x4000u
#define LX_NAND_BLOCK_STATUS_NON_SEQUENTIAL 0x2000u
#define LX_NAND_BLOCK_STATUS_MAPPING_PRESENT 0x1000u
#ifdef LX_NAND_FLASH_ENABLE_LAZY_SECTOR_RELEASE
/* Repurpose the otherwise-unused MAPPING_PRESENT bit to signal a block whose compaction
has been deferred. Only valid when pages_per_block <= 4095. */
#define LX_NAND_BLOCK_STATUS_COMPACTION_PENDING LX_NAND_BLOCK_STATUS_MAPPING_PRESENT
#endif
#define LX_NAND_BLOCK_STATUS_PAGE_NUMBER_MASK 0x0FFFu
#define LX_NAND_BLOCK_STATUS_FREE 0xFFFFu
#define LX_NAND_BLOCK_STATUS_BAD 0xFF00u
Expand Down Expand Up @@ -402,6 +418,12 @@ typedef struct LX_NAND_FLASH_STRUCT
USHORT *lx_nand_flash_block_list;
ULONG lx_nand_flash_block_list_size;
ULONG lx_nand_flash_free_block_list_tail;
#ifdef LX_NAND_FLASH_ENABLE_LAZY_SECTOR_RELEASE
/* Parallel to block_mapping_table: physical block with pending compaction for a group,
or LX_NAND_BLOCK_UNMAPPED when no compaction is pending. */
USHORT *lx_nand_flash_block_compaction_table;
ULONG lx_nand_flash_block_compaction_table_size;
#endif
ULONG lx_nand_flash_mapped_block_list_head;

ULONG lx_nand_flash_metadata_block_number;
Expand Down Expand Up @@ -771,6 +793,9 @@ UINT _lx_nand_flash_metadata_write(LX_NAND_FLASH *nand_flash, UCHAR* main_buf
VOID _lx_nand_flash_system_error(LX_NAND_FLASH *nand_flash, UINT error_code, ULONG block, ULONG page);
UINT _lx_nand_flash_256byte_ecc_check(UCHAR *page_buffer, UCHAR *ecc_buffer);
UINT _lx_nand_flash_256byte_ecc_compute(UCHAR *page_buffer, UCHAR *ecc_buffer);
#ifdef LX_NAND_FLASH_ENABLE_LAZY_SECTOR_RELEASE
UINT _lx_nand_flash_logical_group_compact(LX_NAND_FLASH *nand_flash, ULONG logical_group);
#endif

UINT _lx_nor_flash_block_reclaim(LX_NOR_FLASH *nor_flash);
UINT _lx_nor_flash_driver_block_erase(LX_NOR_FLASH *nor_flash, ULONG block, ULONG erase_count);
Expand Down
38 changes: 38 additions & 0 deletions common/src/lx_nand_flash_block_allocate.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/

// Some portions generated by Copilot (Sonnet 4.6).

/**************************************************************************/
/**************************************************************************/
Expand Down Expand Up @@ -75,6 +76,43 @@ UINT _lx_nand_flash_block_allocate(LX_NAND_FLASH* nand_flash, ULONG* block)
if (nand_flash -> lx_nand_flash_free_block_list_tail == 0)
{

#ifdef LX_NAND_FLASH_ENABLE_LAZY_SECTOR_RELEASE
{

ULONG lg;
UINT compact_status;

/* Emergency compaction: find any pending compaction and execute it to
reclaim the old full block. */
for (lg = 0; lg < nand_flash -> lx_nand_flash_total_blocks; lg++)
{

if (nand_flash -> lx_nand_flash_block_compaction_table[lg] != (USHORT)LX_NAND_BLOCK_UNMAPPED)
{

compact_status = _lx_nand_flash_logical_group_compact(nand_flash, lg);

if (compact_status == LX_SUCCESS)
{

/* Retry the allocation after compaction freed a block. */
if (nand_flash -> lx_nand_flash_free_block_list_tail > 0)
{

nand_flash -> lx_nand_flash_free_block_list_tail--;
*block = nand_flash -> lx_nand_flash_block_list[nand_flash -> lx_nand_flash_free_block_list_tail];
return(LX_SUCCESS);
}
}

/* Attempt only one compaction per allocate call. */
break;
}
}

}
#endif /* LX_NAND_FLASH_ENABLE_LAZY_SECTOR_RELEASE */

/* Empty list, return error. */
return(LX_NO_BLOCKS);
}
Expand Down
28 changes: 28 additions & 0 deletions common/src/lx_nand_flash_block_data_move.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/

// Some portions generated by Copilot (Sonnet 4.6).

/**************************************************************************/
/**************************************************************************/
Expand Down Expand Up @@ -111,6 +112,33 @@ ULONG block_mapping_index;
return(LX_ERROR);
}

#ifdef LX_NAND_FLASH_ENABLE_LAZY_SECTOR_RELEASE
/* If this logical group has a pending compaction source, redirect the
data move to a full logical-group compact to correctly merge data from
both source blocks. */
if (nand_flash -> lx_nand_flash_block_compaction_table[block_mapping_index] != (USHORT)LX_NAND_BLOCK_UNMAPPED)
{

/* Return the pre-allocated new_block to the free list. */
status = _lx_nand_flash_block_status_set(nand_flash, new_block, LX_NAND_BLOCK_STATUS_FREE);

if (status)
{
_lx_nand_flash_system_error(nand_flash, status, new_block, 0);
return(LX_ERROR);
}

_lx_nand_flash_free_block_list_add(nand_flash, new_block);

/* Restore block_mapping_index to the mapped list; mapped_block_list_get
already removed it before this function was called. */
_lx_nand_flash_mapped_block_list_add(nand_flash, block_mapping_index);

/* Perform full compaction merge of both source blocks. */
return(_lx_nand_flash_logical_group_compact(nand_flash, block_mapping_index));
}
#endif /* LX_NAND_FLASH_ENABLE_LAZY_SECTOR_RELEASE */

/* Set new block status to allocated for now. */
new_block_status = LX_NAND_BLOCK_STATUS_ALLOCATED;

Expand Down
29 changes: 29 additions & 0 deletions common/src/lx_nand_flash_defragment.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/

// Some portions generated by Copilot (Sonnet 4.6).

/**************************************************************************/
/**************************************************************************/
Expand Down Expand Up @@ -72,10 +73,38 @@
UINT _lx_nand_flash_defragment(LX_NAND_FLASH *nand_flash)
{

#ifdef LX_NAND_FLASH_ENABLE_LAZY_SECTOR_RELEASE

UINT status;
ULONG lg;

/* Compact every logical group that has a deferred compaction pending. */
for (lg = 0; lg < nand_flash -> lx_nand_flash_total_blocks; lg++)
{

if (nand_flash -> lx_nand_flash_block_compaction_table[lg] != (USHORT)LX_NAND_BLOCK_UNMAPPED)
{

status = _lx_nand_flash_logical_group_compact(nand_flash, lg);

/* On error, continue to compact remaining groups. */
if (status)
{
_lx_nand_flash_system_error(nand_flash, status, lg, 0);
}
}
}

return(LX_SUCCESS);

#else

LX_PARAMETER_NOT_USED(nand_flash);

/* Return not supported. */
return(LX_NOT_SUPPORTED);

#endif /* LX_NAND_FLASH_ENABLE_LAZY_SECTOR_RELEASE */
}


Loading
Loading