www.pudn.com > efs.rar > fs_pm_super.h
/**********************************************************************
* fs_pm_super.h
*
* Super-block management for Embedded File System.
* Copyright (C) 2002, 2003, 2004, 2005, 2006 Qualcomm, Inc.
*
* This file describes the interface to the code the manages the EFS
* superblock.
*/
/*===========================================================================
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_super.h#15 $ $DateTime: 2006/08/31 17:09:53 $ $Author: davidb $
when who what, where, why
-------- --- ------------------------------------------------------
2006-08-31 dlb New minor version for DB GID fix.
2006-08-23 sh Adjust the NAND LOG region size with page size.
2006-08-17 dlb New minor version for LOG CRC improvements.
2006-05-12 sh Swap the NOR/NAND version bits back again
2006-04-18 dlb Add forward-updates of superblock.
2006-03-03 sh Force NAND and NOR Superblock versions to be different
2006-03-02 sh Bump the ver number because Soft Limit is removed
2006-01-27 sh Renamed some Q&R defines to be more explanatory
2006-01-17 dlb Support multiple NOR write styles.
2006-01-11 nrs Fixed Copyright header
2005-12-14 sh Expand Log Region from 8 to 32 blocks.
2005-11-09 nrs Quota and Reservation cleanup
2005-10-18 nrs Fixes for quotas and reservations
2005-07-20 nrs Support for quotas and reservations
2005-04-20 dlb Support 2k pages.
2005-01-04 dlb Update copyright line.
2004-12-30 dlb Utilize new factory image code.
2004-10-15 dlb Update copyright header.
2004-10-07 dlb Whitespace cleanup.
2004-04-26 drh Update both NAND and NOR super version for release
2003-11-16 gr Updated NAND super version so that 6300 3xxx builds
and 5xxx builds can be distinguished.
2003-06-17 jkl Updated NOR and NAND SUPER VERSION.
2003-06-12 adm Add support for factory start.
2003-04-24 bgc Updated NOR_VERSION from 3 to 5 due to the old ptables
that lack the validity check are now invalid.
2002-08-08 drh Created by dlb. Added history header.
===========================================================================*/
#ifndef __FS_NOR_SUPER_H__
#define __FS_NOR_SUPER_H__
#include "customer.h"
#include "fs_device.h"
#include "fs_sys_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* The data associated with the superblock. All fields of this structure
* are internal. */
struct fs_super_data;
typedef struct fs_super_data *fs_super_t;
/* Initialize the superblock code. Searches the device for an existing
* superblock, and loads it. If it is not found, then it will erase as
* necessary and write a simple superblock out. */
void
fs_super_init (
fs_super_t super,
fs_device_t dev,
int *fresh_start);
/* Write out an updated superblock to the given segment. */
void
fs_super_update (
fs_super_t super,
page_id page);
/* Ensure that the page size is properly configured. */
#ifndef EFS_PAGE_SIZE
#error EFS_PAGE_SIZE must be defined
#endif
/**********************************************************************
* _ _ ___ _____ _____
* | \ | |/ _ \_ _| ____|_
* | \| | | | || | | _| (_)
* | |\ | |_| || | | |___ _
* |_| \_|\___/ |_| |_____(_)
*
* Although this information is in a publically accessible structure (since
* it is needed), please do not make changes to this data aside from
* calling the above functions.
*/
/* First is the actual superblock itself. This is the data written to the
* device. The in-memory copy will always be modified as changes are made,
* even though the changes will not be written as timely. It is important
* that this structure be exactly the size of the smallest page size we
* support (512 bytes). */
/* There are two version fields for alternative types of implementations.
* These values _MUST_ be distinct, but it is possible to change only one
* of them. */
/* Since the version codes now contain a bit indicating type, have some
* macros to check these bits. */
/* This was the first version number that used the lowest bit to indicate
* NOR/NAND. */
#define FS_SUPER_LOWEST_ENCODED_VERSION 0x0024
/* Macros to construct and deconstruct version numbers. */
#define FS_SUPER_NANDIFY_VERSION(x) ((x << 1) | 1)
#define FS_SUPER_NORIFY_VERSION(x) ((x << 1) | 0)
#define FS_SUPER_VERSION_IS_NAND(x) (((x) & 1) == 1)
#define FS_SUPER_VERSION_IS_NOR(x) (((x) & 1) == 0)
#define FS_SUPER_VERSIONOF(x) ((x) >> 1)
/* Given a superblock pointer, these query macros are useful for deciding
* which particular algorithms to use. */
#define FS_ISNOR(super) FS_SUPER_VERSION_IS_NOR((super)->data.version)
#define FS_ISNAND(super) FS_SUPER_VERSION_IS_NAND((super)->data.version)
/* Older superblock versions. These are named after the feature change
* that caused the bump. Non-forward-compatible changes should indicate
* this change with a larger version bump (such as to the next multiple of
* 0x100). */
#define FS_SUPER_VERSION_QANDR 0x0012
#define FS_SUPER_VERSION_LONGNAME 0x0013
#define FS_SUPER_VERSION_LOGCRC 0x0014
#define FS_SUPER_VERSION_DBGID 0x0015
#define FS_SUPER_VERSION FS_SUPER_VERSION_DBGID
#define FS_SUPER_VERSION_NOR FS_SUPER_NORIFY_VERSION (FS_SUPER_VERSION)
#define FS_SUPER_VERSION_NAND FS_SUPER_NANDIFY_VERSION (FS_SUPER_VERSION)
/* There are two magic numbers in the superblock itself. These are to
* reduce the likelyhood of deciding alternative data is a superblock.
* In little endian, this is viewed in ASCII as "EFSSuper". */
#define FS_SUPER_MAGIC1 0x53534645
#define FS_SUPER_MAGIC2 0x72657075
/* Version 1 supports the superblock in this many diverse locations. */
#define SUPER_SEGMENTS 4
/* Maximum number of regions supported by this version of the superblock. */
#define FS_MAXIMUM_REGIONS 4
/* The number of superblock contained page table entries. This is chosen
* to make the superblock fit inside a single page. */
#if EFS_PAGE_SIZE == 512
#define SUPERBLOCK_PAGE_ENTRIES 34
#elif EFS_PAGE_SIZE == 2048
#define SUPERBLOCK_PAGE_ENTRIES 226
#endif
/* Definitions of which page table is which. */
#define FS_PTABLE 0
#define FS_RTABLE 1
/**********************************************************************/
/* Constants defining the region boundaries in NAND flash. */
/* Number of blocks used by the log region in NAND. These are always at
* the very end of flash. Too few, and the wear in this region becomes
* too concentrated and expires these blocks before others.
* Too many, and it wastes space that could be used for data.
* 512KB is a reasonable size. A target may wish to override the value
* by defining EFS_NAND_LOG_REGION_BLOCKS. */
#ifdef EFS_NAND_LOG_REGION_BLOCKS
#define FS_NAND_LOG_REGION_BLOCKS (EFS_NAND_LOG_REGION_BLOCKS)
#elif EFS_PAGE_SIZE == 512
#define FS_NAND_LOG_REGION_BLOCKS 32
#elif EFS_PAGE_SIZE == 2048
#define FS_NAND_LOG_REGION_BLOCKS 8
#endif
/* Number of regions in the NAND flash. */
#define FS_NAND_REGION_COUNT 4
struct nor_info {
fs_device_write_style_t style;
};
struct nand_info {
uint16 nodes_per_page;
uint16 page_depth; /* Depth of page table, including
nodes within the superblock. */
uint16 super_nodes; /* Page nodes within the
superblock. */
uint16 num_regions; /* How many regions are in this FS. */
uint32 regions[FS_MAXIMUM_REGIONS];
/* Offset of the start of each
* region. Region 0 is assumed to
* start at 0, regions[0] indicates
* the start of region 1, and so
* on. */
uint32 logr_badmap; /* Map of bad blocks in the log
region. */
uint32 pad;
uint32 tables[2][SUPERBLOCK_PAGE_ENTRIES];
};
struct superblock_data {
uint32 page_header;
uint16 version;
uint16 age;
uint32 magic1;
uint32 magic2;
uint32 block_size; /* Number of pages per block. */
uint32 page_size; /* Page size in bytes. */
uint32 block_count; /* Total number of blocks in
filesystem. */
uint32 log_head;
uint32 alloc_next[FS_MAXIMUM_REGIONS];
uint32 gc_next[FS_MAXIMUM_REGIONS];
/* data stored in the superblock on behalf of an upper layer of code */
uint32 upper_data[FS_UPPER_DATA_COUNT];
union {
struct nand_info nand;
struct nor_info nor;
} u;
uint32 _padding[3]; /* Superblock must be 512 bytes */
uint32 crc32;
};
typedef struct superblock_data *superblock_data_t;
/* This is the data structure holding the superblock information. This
* also holds a cache of various other computed information. */
struct fs_super_data {
struct superblock_data data;
/* Device this superblock resides in. */
fs_device_t dev;
/* Number of bits to shift a block into a page number. This is the log
* base 2 of the block size. The block mask has the low bits cleared to
* mask out and only get the block part of a page.*/
int block_shift;
uint32 block_mask;
/* A count of the total number of pages. Again, just to save math. */
uint32 total_pages;
/* Locations where each superblock will be written. These are block
* numbers, and the superblock should be written as the first page of
* that block. These values can change if blocks wear out. */
uint32 segment_offsets[SUPER_SEGMENTS];
/* Tracking for updates. During the update, the superblock will remain
* at the older version. Once it is finished, the next superblock update
* will switch to the correct version. */
uint32 desired_version;
};
/* Needed for factory code. */
/* Create an initial superblock. Assumes that no other superblocks were
* found (otherwise the new one wouldn't be always be the oldest. */
void fs_super_create_superblock (fs_super_t super);
/* Needed for wipeefs and for factory startup code. Invalidates any
* existing superblocks. */
void fs_pm_super_invalidate_superblocks (void);
#ifdef __cplusplus
}
#endif
#endif /* __FS_NOR_SUPER_H__ */