feat(nand): count bad blocks before a given offset

In case of FIP, the offsets given in the FIP header are relative.
If bad blocks are found between the FIP base address and this offset,
the offset should be updated, taking care of the bad blocks.

Change-Id: I96fefabb583b3d030ab05191bae7d45cfeefe341
Signed-off-by: Lionel Debieve <lionel.debieve@st.com>
Signed-off-by: Yann Gautier <yann.gautier@foss.st.com>
This commit is contained in:
Yann Gautier 2020-08-05 14:39:00 +02:00
parent 7e87ba2598
commit bc3eebb25d
2 changed files with 53 additions and 2 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, STMicroelectronics - All Rights Reserved
* Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -112,6 +112,47 @@ int nand_read(unsigned int offset, uintptr_t buffer, size_t length,
return 0;
}
int nand_seek_bb(uintptr_t base, unsigned int offset, size_t *extra_offset)
{
unsigned int block;
unsigned int offset_block;
unsigned int max_block;
int is_bad;
size_t count_bb = 0U;
block = base / nand_dev.block_size;
if (offset != 0U) {
offset_block = (base + offset - 1U) / nand_dev.block_size;
} else {
offset_block = block;
}
max_block = nand_dev.size / nand_dev.block_size;
while (block <= offset_block) {
if (offset_block >= max_block) {
return -EIO;
}
is_bad = nand_dev.mtd_block_is_bad(block);
if (is_bad < 0) {
return is_bad;
}
if (is_bad == 1) {
count_bb++;
offset_block++;
}
block++;
}
*extra_offset = count_bb * nand_dev.block_size;
return 0;
}
struct nand_device *get_nand_device(void)
{
return &nand_dev;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, STMicroelectronics - All Rights Reserved
* Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -45,6 +45,16 @@ struct nand_device {
int nand_read(unsigned int offset, uintptr_t buffer, size_t length,
size_t *length_read);
/*
* Look for an extra offset to be added in case of bad blocks
*
* @base: Base address of the area
* @offset: Byte offset to read from in device
* @extra_offset: [out] Extra offset to be added if bad blocks are found
* Return: 0 on success, a negative errno on failure
*/
int nand_seek_bb(uintptr_t base, unsigned int offset, size_t *extra_offset);
/*
* Get NAND device instance
*