/*****************************************************************************/
/*                                                                           */
/* COMPONENT   : Rainbow				                                     */
/* MODULE      : FTL				                                         */
/* NAME    	   : FTL types definition header                                 */
/* FILE        : FTLTypes.h	                                                 */
/* PURPOSE 	   : This header defines Data types which are shared             */
/*               by all FTL submodules                                       */
/*                                                                           */
/*---------------------------------------------------------------------------*/
/*                                                                           */
/*          COPYRIGHT 2003-2005 SAMSUNG ELECTRONICS CO., LTD.                */
/*                          ALL RIGHTS RESERVED                              */
/*                                                                           */
/*   Permission is hereby granted to licensees of Samsung Electronics        */
/*   Co., Ltd. products to use or abstract this computer program for the     */
/*   sole purpose of implementing a product based on Samsung                 */
/*   Electronics Co., Ltd. products. No other rights to reproduce, use,      */
/*   or disseminate this computer program, whether in part or in whole,      */
/*   are granted.                                                            */
/*                                                                           */
/*   Samsung Electronics Co., Ltd. makes no representation or warranties     */
/*   with respect to the performance of this computer program, and           */
/*   specifically disclaims any responsibility for any damages,              */
/*   special or consequential, connected with the use of this program.       */
/*                                                                           */
/*---------------------------------------------------------------------------*/
/*                                                                           */
/* REVISION HISTORY                                                          */
/*                                                                           */
/*   22-JUL-2005 [Jaesung Jung] : first writing                              */
/*   03-NOV-2005 [Yangsup Lee ] : Add wear-leveling algorithm				 */
/*   14-MAR-2006 [Yangsup Lee ] : Don't use bad mark area                    */
/*   29-MAR-2006 [Yangsup Lee ] : modify wear-leveling structure             */
/*   31-MAR-2006 [Yangsup Lee ] : support ftl meta block wear leveling       */
/*                                                                           */
/*****************************************************************************/
#ifndef _FTL_TYPES_H_
#define _FTL_TYPES_H_

#include "WMRConfig.h"

typedef struct
{
    // Info generated by CalcGlobal
    UInt16 wPagesPerVb;                /* the count of pages per virtual block */
    UInt16 wUserVbTotal;               /* the total number of data virtual block */
    UInt32 dwUserPagesTotal;           /* the total number of data sector   */
    UInt16 wBytesPerPage;              /* bytes per page (main)			 */

    UInt16 wNumOfBanks;                /* the number of banks				 */
} FTLWMRDeviceInfo;

#define     PAGES_PER_SUBLK         (stFTLDeviceInfo.wPagesPerVb)
#define     USER_SUBLKS_TOTAL       (stFTLDeviceInfo.wUserVbTotal)
#define     USER_PAGES_TOTAL        (stFTLDeviceInfo.dwUserPagesTotal)
#define     BYTES_PER_PAGE          (stFTLDeviceInfo.wBytesPerPage)

#define     BANKS_TOTAL             (stFTLDeviceInfo.wNumOfBanks)
#define     WMR_NUM_OF_BANKS        (8) /* the maximum number of bank		 */
#define     BYTES_PER_SECTOR        (512)

#define     FTL_INFO_SECTION_SIZE   FTL_CXT_SECTION_SIZE
#define     FREE_SECTION_START      FTL_CXT_SECTION_SIZE
#define     DATA_SECTION_START      (FTL_CXT_SECTION_SIZE + FREE_SECTION_SIZE)

#define     LOG_SECTION_SIZE        (FREE_SECTION_SIZE - FREE_LIST_SIZE)

#define     FREE_SECTION_SIZE       (20)
#define     FREE_LIST_SIZE          (3)

#define     FTL_AREA_SIZE           (FTL_CXT_SECTION_SIZE + FREE_SECTION_SIZE + USER_SUBLKS_TOTAL)

#define MAX_NUM_OF_MAP_TABLES       (WMR_MAX_VB / (WMR_SECTORS_PER_PAGE_MIN * WMR_SECTOR_SIZE) + (WMR_MAX_VB % (WMR_SECTORS_PER_PAGE_MIN * WMR_SECTOR_SIZE) ? 1 : 0)) * (sizeof(UInt16))
#define MAX_NUM_OF_EC_TABLES        (WMR_MAX_VB / (WMR_SECTORS_PER_PAGE_MIN * WMR_SECTOR_SIZE) + (WMR_MAX_VB % (WMR_SECTORS_PER_PAGE_MIN * WMR_SECTOR_SIZE) ? 1 : 0)) * (sizeof(UInt32))
#define MAX_NUM_OF_LOGCXT_MAPS      (((LOG_SECTION_SIZE * WMR_MAX_PAGES_PER_BLOCK * WMR_NUM_OF_BANKS * sizeof(UInt16)) / (WMR_SECTOR_SIZE * WMR_SECTORS_PER_PAGE_MIN)) + (((LOG_SECTION_SIZE * WMR_MAX_PAGES_PER_BLOCK * WMR_NUM_OF_BANKS * sizeof(UInt16)) % (WMR_SECTOR_SIZE * WMR_SECTORS_PER_PAGE_MIN)) ? 1 : 0))

#define BBT_SIZE_PER_CS             ((BLOCKS_PER_CS / 8) + (BLOCKS_PER_CS % 8 ? 1 : 0))

#if defined(FTL_SMALL_MERGE_BUFFER) && FTL_SMALL_MERGE_BUFFER
#define FTL_SIMPLEMERGE_MIN_PAGES   (4)
#else
#define FTL_SIMPLEMERGE_MIN_PAGES   (PAGES_PER_SUBLK >> 3) /* creates a 64K to 128K buffer in current units */
#endif
#define FTL_RESTORE_MIN_PAGES       (((FTL_AREA_SIZE * sizeof(FTLRestoreStruct)) - 1) / BYTES_PER_PAGE + 1)

/*
 * pstSimpleMergeDataBuffer is used in the following functions and must adhere to the following rules:
 * 1. _DoSimpleMerge() - Must be aligned to BANKS_TOTAL pages and a power of 2.
 * 2. _StoreFTLCxt() - Must be of size BANKS_TOTAL page at least.
 * 3. _FTLRestore() - Must be of size FTL_RESTORE_MIN_PAGES at least.
 */
#define PAGES_PER_SIMPLE_MERGE_BUFFER (1 << (WMR_LOG2(WMR_MAX(FTL_SIMPLEMERGE_MIN_PAGES, FTL_RESTORE_MIN_PAGES) - 1) + 1))

/*****************************************************************************/
/* Data structure for storing the FTL log block context definition			 */
/*****************************************************************************/
#ifdef AND_COLLECT_STATISTICS

typedef struct
{
    UInt64 ddwPagesWrittenCnt;
    UInt64 ddwPagesReadCnt;
    UInt64 ddwFTLWriteCnt;
    UInt64 ddwFTLReadCnt;
    UInt64 ddwDoMoveMergeCnt;
    UInt64 ddwDoCopyMergeCnt1; /* case there is NO data to copy */
    UInt64 ddwDoCopyMergeCnt2; /* case there is data to copy */
    UInt64 ddwDoSimpleMergeCnt;
    UInt64 ddwMoveD2FCnt;
    UInt64 ddwFTLRestoreCnt;
    UInt64 ddwReadDisturbHandleCall;
    UInt64 ddwWearLevelCnt;
    UInt64 ddwFlushCnt;
} FTLStatistics;

#define FTL_STATISTICS_DESCREPTION { \
        "ddwPagesWrittenCnt", \
        "ddwPagesReadCnt", \
        "ddwFTLWriteCnt", \
        "ddwFTLReadCnt", \
        "ddwDoMoveMergeCnt", \
        "ddwDoCopyMergeCnt1", \
        "ddwDoCopyMergeCnt2", \
        "ddwDoSimpleMergeCnt", \
        "ddwMoveD2FCnt", \
        "ddwFTLRestoreCnt", \
        "ddwReadDisturbHandleCall", \
        "ddwWearLevelCnt", \
        "ddwFlushCnt", \
}

#endif /* AND_COLLECT_STATISTICS */

#define FTL_VERSION         (0x46560001)
#define FTL_VERSION_NOT     (~(FTL_VERSION))

/*****************************************************************************/
/* Data structure for log block spare area									 */
/*****************************************************************************/
typedef struct
{
    UInt32 dwLogAge;          /* log age - uses a global counter starting from 0 */
    UInt16 wVbn;              /* the virtual block number of log block */
    UInt16 wLbn;              /* the logical block number of log block */
    UInt16      *paPOffsetL2P; /* L2P page offset mapping table		 *//* size - PAGES_PER_SUBLK * sizeof(UInt16) functionality - maps pages of a logical block inside the block */
    UInt16 wFreePOffset; /* free page offset in log block		 *//* the next physical page to write to */
    UInt16 wNumOfValidLP; /* the number of valid page				 *//* the number of valid pages in the log - stay the same when rewriting a page */
    BOOL32 boolCopyMerge; /* can be copymerged or not				 *//* ??? */
    /* name sure this structure is aligned 16-bit */
} LOGCxt;

typedef struct
{
    UInt16 wLbn;
    UInt16 wVbn;
} FTLReadRefreshStruct;

/*****************************************************************************/
/* Data structure for storing the FTL context definition					 */
/*****************************************************************************/
/* NOTICE !!!														*/
/* this structure is used directly to load FTL context by WMR_MEMCPY*/
/* so the byte pad of this structure must be 0		   				*/
typedef struct
{
    UInt32 dwAge;         /* Cxt Write Age - Counter starting From 0xFFFFFFFF going down */

    UInt32 dwWriteAge;    /* counter starting from 0 - unique age of the first ftl write operation to the block */

    UInt16 wNumOfFreeVb;  /* number of free VB */
    UInt16 wFreeVbListTail; /* marks the first available VB in a cyclic list */
    UInt16 wWearLevelCounter; /* this counter is by the FTL to decide whether an Autowearlevel operation is needed after FTL_Write is done */

    UInt16 awFreeVbList[FREE_SECTION_SIZE]; /* cyclic list of the free VBs */

    UInt32 adwMapTablePtrs[MAX_NUM_OF_MAP_TABLES]; /* page address (Vpn) of the Map table pages in the Cxt block - only valid when boolFlashCxtIsValid is TRUE32 */
    UInt32 adwECTablePtrs[MAX_NUM_OF_EC_TABLES]; /* page address of the Erase Counter table */
    UInt32 adwLOGCxtMapPtrs[MAX_NUM_OF_LOGCXT_MAPS]; /* page address of the LOGCxt map table */

    UInt16 *     pawMapTable; /* cached map table logical blocks to virtual blocks - value will be recalculated in FTL_Init */
    UInt16 *     pawECCacheTable;  /* cached Erase counter table - value will be recalculated in FTL_Init - data is recovered from the last valid Erase Map in case of power failure */
    UInt16 *     pawLOGCxtMapTable;  /* pointer to the map of the logs - this is a pointer and will be calculated in the Init - data can be restored if the info is flushed */
    LOGCxt aLOGCxtTable[LOG_SECTION_SIZE + 1]; /* LOGCxt array */

    UInt32 dwMetaWearLevelCounter; /* used to decide whether the index info super blocks need to be replaced or not (slows down VFL Cxt blocks wear) */
    UInt16 wOverErasedBlock; /* should not be used - mark the last erased vb before setting boolFlushECTable */

    UInt16 awMapCxtVbn[FTL_CXT_SECTION_SIZE]; /* vb address of the FTL Cxt information */
    UInt32 dwCurrMapCxtPage; /* pointer to the last written Cxt info page */

    BOOL32 boolFlashCxtIsValid; /* mark whether the FTLCxt on the flash is up to date or not */

    // this code was added Apr 4th 2007
    UInt32 adwRCTablePtrs[MAX_NUM_OF_EC_TABLES]; /* page address of the Read Counter table */
    UInt16 *     pawRCCacheTable;  /* cached Erase counter table - value will be recalculated in FTL_Init - data is recovered from the last valid Erase Map in case of power failure */
    FTLReadRefreshStruct aFTLReadRefreshList[FTL_READ_REFRESH_LIST_SIZE];
    UInt32 dwRefreshListIdx;
    UInt32 dwReadsSinceLastRefreshMark;
    // this code was added Apr 20th 2007
    UInt32 adwStatPtrs[2]; // allocate 2 pages for stats
} FTLCxt2;

typedef struct
{
    FTLCxt2 stFTLCxt;
    UInt8 abReserved[((BYTES_PER_SECTOR - 2) * sizeof(UInt32)) - sizeof(FTLCxt2)];
    UInt32 dwVersion;
    UInt32 dwVersionNot;
} FTLMeta;

/*****************************************************************************/
/* Data structure of the FTL context & virtual block mapping table definition*/
/*****************************************************************************/
/* NOTICE !!!														*/
/* this structure is used directly to load FTL context by WMR_MEMCPY*/
/* so the byte pad of this structure must be 0		   				*/

/*****************************************************************************/
/* Data structure for FTL context spare area								 */
/*****************************************************************************/

/*
    Spare area of the flash:
    The implementation used here assumes a page has 12 free bytes in the redundant area to store data (index, age, etc).
    Bytes 0-7 are used for data
    Byte 8 - is currently reserved.
    Byte 9 is used for data type - bits 6-7 of the byte is 00 for VFL spare types and 01 for FTL spare types.
    Byte 10 is used to mark ECC error in LOGCxt reserved for Cxt
    Byte 11 is currently reserved
 */

/* NirW - possibly need to define the next two structures as compact (i.e. no alignment should be done by the compiler). */

/* spare layout for SLC & MLC							*/
typedef struct
{
    UInt32 dwCxtAge;                   /* context age 0xFFFFFFFF --> 0x0   */
    UInt16 wLogicalNumber;             /* status (confirm) mark		     */
    UInt8 bStatusMark;                /* status (confirm) mark		     */
    UInt8 baReserved[1];
    UInt8 bECCMark;
    UInt8 bSpareType;
} FTLCxtSpare;

/* spare layout for SLC						*/
typedef struct
{
    UInt32 dwLPOffset;
    UInt32 dwWriteAge;
    UInt8 bReserved;
    UInt8 bSpareType;
} LOGSpare;

typedef struct
{
    UInt16 wLbn;   /* this struct can only handle 32K super blocks */
    UInt8 bSpareType;
    UInt8 bIsBlkFull; /* 0 - block is full; 1 - page 0 is written; 2 - page 0 is empty; 3 - page 0 is invalid */
    UInt32 dwWriteAge;
} FTLRestoreStruct;

FTLCxt2 * FTL_GetFTLCxt2Ptr(void);

// defines
/*
    FTL_SPARE_TYPE_LOG - log block (either not full or not fill consecutively
    we should look for this mark in page 0 and in the last page of the block for recovery
 */
#define FTL_SPARE_TYPE_LOG              0x40
/*
    FTL_SPARE_TYPE_DATA - either originally data block or a log block filled from page 0 to the end (consecutively) -
    look for this mark at the last page of the block
 */
#define FTL_SPARE_TYPE_DATA             0x41

#define FTL_SPARE_TYPE_CXT              0x42    /* used only in restore operation */
#define FTL_SPARE_TYPE_CXT_INDEX        0x43
#define FTL_SPARE_TYPE_CXT_MAP_TABLE    0x44
#define FTL_SPARE_TYPE_CXT_LOGCXT_MAP   0x45
#define FTL_SPARE_TYPE_CXT_EC_TABLE     0x46
#define FTL_SPARE_TYPE_CXT_STAT         0x47

#define FTL_SPARE_IS_CXT_MARK(x)        ((x) >= FTL_SPARE_TYPE_CXT_INDEX && (x) <= FTL_SPARE_TYPE_CXT_INVALID)

#define FTL_SPARE_TYPE_FREE             0x48 /* this is not to be written on the flash but to use as a mark that a block can be erased */
#define FTL_SPARE_TYPE_CXT_RC_TABLE     0x49
#define FTL_SPARE_TYPE_CXT_INVALID      0x4F    /* mark that the CXT saved is no longer relevant - write this mark before
                                                    executing any ftl writes */

/*
   The ECC mark was originally in byte 10, but we have since shrunk to 10 total bytes of meta data.
   The FMSS guarantees bytes 10 and 11 to be 0xFFFF.
   To check ECC mark, check for any value besides 0xFF in either byte 8 or 10.
 */
#define FTL_SPARE_TYPE_LOCATION         9  /* the byte location of the spare type in the spare area */
#define FTL_ECC_MARK_BYTE               8  /* the location of the byte in the spare that contains the mark */
#define FTL_ECC_MARK_BYTE_LEGACY        10 /* the old location of the byte in the spare that contains the mark */
#define FTL_ECC_MARK_WORD               2  /* the location of the word in the spare that contains the marks */
#define FTL_ECC_MARK_MASK               0x00FF00FF /* use this mask on the 2nd word to check for ECC mark */
#define FTL_TABLE_PTR_INVALID_VALUE     0xFFFFFFFF

#define         LOG_EMPTY_SLOT                  (0xFFFF)

#endif /* _FTL_TYPES_H_ */
