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