Files
levelx/common/src/lx_nor_flash_driver_block_erase.c
T
Frédéric DesbiensandCodex 309d2bd91b Covered NOR cache block erase boundary
Invalidate extended cache entries that end exactly at the erased block boundary and cover the last-sector case in the zero-base regression test.

Co-authored-by: Codex <codex@openai.com>
2026-06-30 10:04:02 -04:00

132 lines
6.4 KiB
C

/***************************************************************************
* Copyright (c) 2024 Microsoft Corporation
* Copyright (c) 2026-present Eclipse ThreadX contributors
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
* SPDX-License-Identifier: MIT
**************************************************************************/
// Some portions generated by Codex (GPT-5).
/**************************************************************************/
/**************************************************************************/
/** */
/** LevelX Component */
/** */
/** NOR Flash */
/** */
/**************************************************************************/
/**************************************************************************/
#define LX_SOURCE_CODE
/* Disable ThreadX error checking. */
#ifndef LX_DISABLE_ERROR_CHECKING
#define LX_DISABLE_ERROR_CHECKING
#endif
/* Include necessary system files. */
#include "lx_api.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _lx_nor_flash_driver_block_erase PORTABLE C */
/* 6.2.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function performs a NOR flash block erase. */
/* */
/* INPUT */
/* */
/* nor_flash NOR flash instance */
/* block Block number to erase */
/* erase_count Erase count for this block */
/* */
/* OUTPUT */
/* */
/* return status */
/* */
/* CALLS */
/* */
/* (lx_nor_flash_driver_block_erase) Actual driver block erase */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/**************************************************************************/
UINT _lx_nor_flash_driver_block_erase(LX_NOR_FLASH *nor_flash, ULONG block, ULONG erase_count)
{
UINT status;
#ifndef LX_NOR_DISABLE_EXTENDED_CACHE
UINT i;
ULONG block_start_address;
ULONG block_end_address;
ULONG *cache_entry_start;
ULONG cache_entry_start_value;
ULONG cache_entry_end_value;
/* Calculate the block starting address.
MISRA C:2012 Rule 11.4 deviation: NOR driver addresses may be logical
address tokens, including zero, so compare address values without
dereferencing them. */
block_start_address = (ULONG)(nor_flash -> lx_nor_flash_base_address) + (block * nor_flash -> lx_nor_flash_words_per_block * sizeof(ULONG));
block_end_address = block_start_address + (nor_flash -> lx_nor_flash_words_per_block * sizeof(ULONG));
/* Loop through the cache entries to see if there is a sector in cache. */
for (i = 0; i < nor_flash -> lx_nor_flash_extended_cache_entries; i++)
{
/* Search through the cache to see if this cache entry needs to be invalidated. */
/* Determine the cache entry addresses. */
cache_entry_start = nor_flash -> lx_nor_flash_extended_cache[i].lx_nor_flash_extended_cache_entry_sector_address;
/* Determine if the cache entry is in the block being erased. */
if (nor_flash -> lx_nor_flash_extended_cache[i].lx_nor_flash_extended_cache_entry_valid)
{
cache_entry_start_value = (ULONG)cache_entry_start;
cache_entry_end_value = cache_entry_start_value + (LX_NOR_SECTOR_SIZE * sizeof(ULONG));
if ((block_start_address <= cache_entry_start_value) && (block_end_address >= cache_entry_end_value))
{
/* Yes, this cache entry is in the block to be erased so invalidate it. */
nor_flash -> lx_nor_flash_extended_cache[i].lx_nor_flash_extended_cache_entry_sector_address = LX_NULL;
nor_flash -> lx_nor_flash_extended_cache[i].lx_nor_flash_extended_cache_entry_access_count = 0;
nor_flash -> lx_nor_flash_extended_cache[i].lx_nor_flash_extended_cache_entry_valid = LX_FALSE;
}
}
}
#endif
/* Call the actual driver block erase function. */
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
status = (nor_flash -> lx_nor_flash_driver_block_erase)(nor_flash, block, erase_count);
#else
status = (nor_flash -> lx_nor_flash_driver_block_erase)(block, erase_count);
#endif
/* Return completion status. */
return(status);
}