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

_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to