[rtems commit] bsps/xnandpsu: Allow manipulation of BBT

Joel Sherrill joel at rtems.org
Thu Dec 14 19:11:58 UTC 2023


Module:    rtems
Branch:    master
Commit:    3798c5735d005b5dcb0e835c9290d26412fe7a20
Changeset: http://git.rtems.org/rtems/commit/?id=3798c5735d005b5dcb0e835c9290d26412fe7a20

Author:    Kinsey Moore <kinsey.moore at oarcorp.com>
Date:      Fri Dec  1 13:18:28 2023 -0600

bsps/xnandpsu: Allow manipulation of BBT

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    | 46 +++++++++++++++++++++++++++++++++++++
 bsps/shared/dev/nand/xnandpsu_bbm.c | 41 +++++++++++++++++++++++++++++++++
 2 files changed, 87 insertions(+)

diff --git a/bsps/include/dev/nand/xnandpsu.h b/bsps/include/dev/nand/xnandpsu.h
index 85343f4b96..5c87be08c2 100644
--- a/bsps/include/dev/nand/xnandpsu.h
+++ b/bsps/include/dev/nand/xnandpsu.h
@@ -564,6 +564,52 @@ s32 XNandPsu_ScanBbt(XNandPsu *InstancePtr);
 
 s32 XNandPsu_MarkBlockBad(XNandPsu *InstancePtr, u32 Block);
 
+#ifdef __rtems__
+#include <stdbool.h>
+/*****************************************************************************/
+/**
+* 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
+
 /** @} */



More information about the vc mailing list