[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