www.pudn.com > efs.rar > fs_pm_types.h


/**********************************************************************
 * fs_pm_types.h
 *
 * Copyright (C) 2003, 2004, 2005, 2006, QUALCOMM, Inc.
 * Page manager types.
 */

/*===========================================================================

                        EDIT HISTORY FOR MODULE

  This section contains comments describing changes made to the module.
  Notice that changes are listed in reverse chronological order.

  $Header: //depot/asic/MSMSHARED/services/efs/MSM_EFS.01.02/fs_pm_types.h#4 $

when          who     what, where, why
--------      ---     ------------------------------------------------------
2005-12-14    dlb     Add log entry for log alloc.
2005-10-21    dlb     Mark unsigned constants as such.
2005-04-26    dlb     Add 2K page support.
2004-10-15    dlb     Update copyright header.
2004-05-05    dlb     Handle page write failures in data region.
2003-06-17    bgc     Added FS_LOG_ENTRY_GARBAGE.
                      Added change log.
===========================================================================*/

#ifndef __FS_PM_TYPES_H__
#define __FS_PM_TYPES_H__

/* Entries that are possible in the reverse map.  The first three are block
 * states (indicates the entire rest of the block is the same state).
 * These indicate the state of blocks that have no data in them.  UNKNOWN
 * is the same as INVALID_CLUSTER_ID, since that is what we will get from
 * tables when they are created.
 * FS_RMAP_BLOCK_ERASED can be placed at any page within a block to
 * indicate that the rest of that block is erased. */

/* All the entries are encoded using some of the top bits.  If the high bit
 * is clear, this is a cluster_id or page_id, this gives us 31 bit id's,
 * which is still 1TB with 512 byte clusters.
 *
 * If the high bit is set, bit 30 indicates the speciality of the value.  A
 * 1 indicates a marker other than a page table entry, a 0 indicates a page
 * table entry.  This is chosen so that the erased value (0xFFFFFFFF) can
 * be a special entry.
 *
 * For a page table entry, the next 3 bits indicate the level of the table
 * affected.  The rest of the bits store the affected page table index,
 * shifted down appropriately (so that it fits),  As long as at least 5
 * bits worth of entries fit in a page (32), this scheme works.  This does
 * restrict our minimum page size to 128 bytes, however. */

#define FS_RMAP_BLOCK_UNKNOWN   (INVALID_CLUSTER_ID)
#define FS_RMAP_BLOCK_ERASED    ((cluster_id) 0xFFFFFFF1U)
#define FS_RMAP_BLOCK_BAD       ((cluster_id) 0xFFFFFFF2U)

/* Once a block has data, each page can be a valid cluster_id, or one of
 * these. */
#define FS_RMAP_PAGE_GARBAGE    ((cluster_id) 0xFFFFFFF4U)
#define FS_RMAP_PAGE_SUPER      ((cluster_id) 0xFFFFFFF7U)
#define FS_RMAP_PAGE_LOG        ((cluster_id) 0xFFFFFFF8U)
#define FS_RMAP_PAGE_RESERVED   ((cluster_id) 0xFFFFFFF9U)

#define FS_RMAP_IS_SPECIAL(x)   ((((uint32) x) >> 31) == 1)

#define FS_RMAP_IS_TABLE(x)     ((((uint32) x) >> 30) == 2)

/* Construct the table entry for a given page table. */
#define FS_RMAP_PAGE_TABLE(table, level, index) \
        (0x80000000U | \
        ((table) << 29) | \
        ((level) << 26) | \
        ((index) >> 6))

/* Get the various fields. */
#define FS_RMAP_GET_TABLE(entry)  (((entry) >> 29) & 1)
#define FS_RMAP_GET_LEVEL(entry)  (((entry) >> 26) & 0x7)
#define FS_RMAP_GET_INDEX(entry)  (((entry) & 0x03FFFFFFU) << 6)

/* Possible log file entries. */
#define FS_LOG_ENTRY_ERASE_START        FS_LOG_CODE_MAKE (1, 1)
#define FS_LOG_ENTRY_ERASE_FINISH       FS_LOG_CODE_MAKE (2, 1)
#define FS_LOG_ENTRY_LOG_FLUSH          FS_LOG_CODE_MAKE (3, 1)
#define FS_LOG_ENTRY_PAGE_MOVE          FS_LOG_CODE_MAKE (4, 3)
#define FS_LOG_ENTRY_NEW_DATA           FS_LOG_CODE_MAKE (5, 2)
#define FS_LOG_ENTRY_PTABLE_MOVE        FS_LOG_CODE_MAKE (6, 3)
#define FS_LOG_ENTRY_UPPER_DATA         FS_LOG_CODE_MAKE (7, 2)
#define FS_LOG_ENTRY_XACT_START         FS_LOG_CODE_MAKE (8, 0)
#define FS_LOG_ENTRY_XACT_END           FS_LOG_CODE_MAKE (9, 0)
#define FS_LOG_ENTRY_KEYRANGE           FS_LOG_CODE_MAKE (10, 2)
#define FS_LOG_ENTRY_GC_MOVE            FS_LOG_CODE_MAKE (11, 3)
#define FS_LOG_ENTRY_XACT_SKIP          FS_LOG_CODE_MAKE (12, 0)
#define FS_LOG_ENTRY_GC_DEALLOC         FS_LOG_CODE_MAKE (13, 2)
#define FS_LOG_ENTRY_GARBAGE            FS_LOG_CODE_MAKE (14, 1)
#define FS_LOG_ENTRY_ERASE_FAIL         FS_LOG_CODE_MAKE (15, 1)
#define FS_LOG_ENTRY_WRITE_FAIL         FS_LOG_CODE_MAKE (16, 1)
#define FS_LOG_ENTRY_LOG_ALLOC          FS_LOG_CODE_MAKE (17, 1)

/* Encode an decode table/level into a journal type. */
#define FS_JOURNAL_ENCODE(table, level) (((table) << 6) | (level))
#define FS_JOURNAL_TABLEOF(jt)          ((jt) >> 6)
#define FS_JOURNAL_LEVELOF(jt)          ((jt) & 0x3F)

/* The maximum size of an EFS2 transaction. The size refers to the number
 * of pages in flash that are affected by the transaction.
 */
#define FS_MAX_TRANSACTION_SIZE         20

/**********************************************************************
 * Constant definitions based on the page size.
 */
#ifndef EFS_PAGE_SIZE
  #error Must define EFS_PAGE_SIZE
#endif

/* Number of page table entries per page.  We hardcode the sizeof entry so
 * that the CPP can check some of our definitions for us. */
#define SIZEOF_PAGE_ID   4
#define FS_PTE_PER_PAGE   (EFS_PAGE_SIZE / SIZEOF_PAGE_ID)

#if ((EFS_PAGE_SIZE % SIZEOF_PAGE_ID) != 0)
  #error Page size is not multiple of page_id.
#endif

/* Mask for the above. */
#define FS_PTE_PAGE_MASK  (FS_PTE_PER_PAGE - 1)

#if ((FS_PTE_PER_PAGE & (FS_PTE_PER_PAGE-1)) != 0)
  #error Page size is not a power of two.
#endif

/* Shift for above. */
#if EFS_PAGE_SIZE==512
  #define FS_PTE_SHIFT 7
#elif EFS_PAGE_SIZE==2048
  #define FS_PTE_SHIFT 9
#else
  #error Unsupported EFS_PAGE_SIZE
#endif

#if ((1 << FS_PTE_SHIFT) != FS_PTE_PER_PAGE)
  #error Invalid FS_PTE macro config with FS_PTE_SHIFT
#endif

#endif /* __FS_PM_TYPES_H__ */