[PATCH 9/9] bsps/xnandpsu: Allow manipulation of BBT
Kinsey Moore
kinsey.moore at oarcorp.com
Sat Dec 9 02:31:26 UTC 2023
Expose functions to directly manipulate the bad block table (BBT). These
functions are necessary to correct possible BBT corruption caused by
bugs in the BBT management layer.
---
bsps/include/dev/nand/xnandpsu.h | 45 +++++++++++++++++++++++++++++
bsps/shared/dev/nand/xnandpsu_bbm.c | 41 ++++++++++++++++++++++++++
2 files changed, 86 insertions(+)
diff --git a/bsps/include/dev/nand/xnandpsu.h b/bsps/include/dev/nand/xnandpsu.h
index 85343f4b96..e1147ad27e 100644
--- a/bsps/include/dev/nand/xnandpsu.h
+++ b/bsps/include/dev/nand/xnandpsu.h
@@ -564,6 +564,51 @@ s32 XNandPsu_ScanBbt(XNandPsu *InstancePtr);
s32 XNandPsu_MarkBlockBad(XNandPsu *InstancePtr, u32 Block);
+#ifdef __rtems__
+/*****************************************************************************/
+/**
+* This function changes the marking of a block in the RAM based Bad Block Table(BBT). It
+* also updates the Bad Block Table(BBT) in the flash if necessary.
+*
+* @param InstancePtr is the pointer to the XNandPsu instance.
+* @param Block is the block number.
+*
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if fail.
+*
+******************************************************************************/
+s32 XNandPsu_MarkBlock(XNandPsu *InstancePtr, u32 Block, u8 BlockMark);
+
+/*****************************************************************************/
+/**
+* This function changes the marking of a block in the RAM based Bad Block Table(BBT). It
+* does not update the Bad Block Table(BBT) in the flash.
+*
+* @param InstancePtr is the pointer to the XNandPsu instance.
+* @param Block is the block number.
+*
+* @return
+* - true if the BBT needs updating.
+* - false if the BBT does not need updating.
+*
+******************************************************************************/
+bool XNandPsu_StageBlockMark(XNandPsu *InstancePtr, u32 Block, u8 BlockMark);
+
+/*****************************************************************************/
+/**
+* This function updates the primary and mirror Bad Block Table(BBT) in the
+* flash.
+*
+* @param InstancePtr is the pointer to the XNandPsu instance.
+* @return
+* - XST_SUCCESS if successful.
+* - XST_FAILURE if fail.
+*
+******************************************************************************/
+s32 XNandPsu_UpdateBbt(XNandPsu *InstancePtr, u32 Target);
+#endif
+
void XNandPsu_EnableDmaMode(XNandPsu *InstancePtr);
void XNandPsu_DisableDmaMode(XNandPsu *InstancePtr);
diff --git a/bsps/shared/dev/nand/xnandpsu_bbm.c b/bsps/shared/dev/nand/xnandpsu_bbm.c
index 4fb62b2f6d..b8428a7328 100644
--- a/bsps/shared/dev/nand/xnandpsu_bbm.c
+++ b/bsps/shared/dev/nand/xnandpsu_bbm.c
@@ -62,7 +62,9 @@ static s32 XNandPsu_WriteBbt(XNandPsu *InstancePtr, XNandPsu_BbtDesc *Desc,
static s32 XNandPsu_MarkBbt(XNandPsu* InstancePtr, XNandPsu_BbtDesc *Desc,
u32 Target);
+#ifndef __rtems__
static s32 XNandPsu_UpdateBbt(XNandPsu *InstancePtr, u32 Target);
+#endif
/************************** Variable Definitions *****************************/
@@ -770,7 +772,11 @@ Out:
* - XST_FAILURE if fail.
*
******************************************************************************/
+#ifdef __rtems__
+s32 XNandPsu_UpdateBbt(XNandPsu *InstancePtr, u32 Target)
+#else
static s32 XNandPsu_UpdateBbt(XNandPsu *InstancePtr, u32 Target)
+#endif
{
s32 Status;
u8 Version;
@@ -919,11 +925,22 @@ s32 XNandPsu_IsBlockBad(XNandPsu *InstancePtr, u32 Block)
*
******************************************************************************/
s32 XNandPsu_MarkBlockBad(XNandPsu *InstancePtr, u32 Block)
+#ifdef __rtems__
+{
+ return XNandPsu_MarkBlock(InstancePtr, Block, XNANDPSU_BLOCK_BAD );
+}
+
+s32 XNandPsu_MarkBlock(XNandPsu *InstancePtr, u32 Block, u8 BlockMark)
+#endif
{
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY)
Xil_AssertNonvoid(Block < InstancePtr->Geometry.NumBlocks);
+#ifdef __rtems__
+ BlockMark &= XNANDPSU_BLOCK_TYPE_MASK;
+#endif
+
u8 Data;
u8 BlockShift;
u32 BlockOffset;
@@ -941,7 +958,11 @@ s32 XNandPsu_MarkBlockBad(XNandPsu *InstancePtr, u32 Block)
/* Mark the block as bad in the RAM based Bad Block Table */
OldVal = Data;
Data &= ~(XNANDPSU_BLOCK_TYPE_MASK << BlockShift);
+#ifdef __rtems__
+ Data |= (BlockMark << BlockShift);
+#else
Data |= (XNANDPSU_BLOCK_BAD << BlockShift);
+#endif
NewVal = Data;
InstancePtr->Bbt[BlockOffset] = Data;
@@ -957,4 +978,24 @@ s32 XNandPsu_MarkBlockBad(XNandPsu *InstancePtr, u32 Block)
Out:
return Status;
}
+
+#ifdef __rtems__
+bool XNandPsu_StageBlockMark(XNandPsu *InstancePtr, u32 Block, u8 BlockMark)
+{
+ u8 BlockShift;
+ u32 BlockOffset;
+ u8 OldVal;
+
+ BlockMark &= XNANDPSU_BLOCK_TYPE_MASK;
+
+ BlockOffset = Block >> XNANDPSU_BBT_BLOCK_SHIFT;
+ BlockShift = XNandPsu_BbtBlockShift(Block);
+ OldVal = InstancePtr->Bbt[BlockOffset] >> BlockShift;
+ OldVal &= XNANDPSU_BLOCK_TYPE_MASK;
+ InstancePtr->Bbt[BlockOffset] &= ~(XNANDPSU_BLOCK_TYPE_MASK << BlockShift);
+ InstancePtr->Bbt[BlockOffset] |= (BlockMark << BlockShift);
+ return BlockMark != OldVal;
+}
+#endif
+
/** @} */
--
2.39.2
More information about the devel
mailing list