changeset 209:6f4a12b4582f

gsm-fw FFS: starting to integrate C code
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Thu, 26 Dec 2013 03:59:59 +0000
parents 2abe6ade042d
children 1d87b335fc50
files gsm-fw/services/ffs/Makefile gsm-fw/services/ffs/core.h gsm-fw/services/ffs/drv.c gsm-fw/services/ffs/drv.h gsm-fw/services/ffs/ffs.h gsm-fw/services/ffs/ffs_api.h gsm-fw/services/ffs/ffs_env.h gsm-fw/services/ffs/ffs_pool_size.h gsm-fw/services/ffs/ffstrace.h gsm-fw/services/ffs/intctl.h gsm-fw/services/ffs/ramffs.h
diffstat 11 files changed, 1942 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/services/ffs/Makefile	Thu Dec 26 03:59:59 2013 +0000
@@ -0,0 +1,18 @@
+CC=	arm-elf-gcc
+CFLAGS=	-O2 -fno-builtin -mthumb-interwork -mthumb
+LD=	arm-elf-ld
+
+OBJS=	drv.o
+
+HDRS=	core.h drv.h ffs.h ffs_api.h ffs_env.h ffs_pool_size.h ffstrace.h \
+	intctl.h ramffs.h
+
+all:	xipcode.o
+
+${OBJS}:	${HDRS}
+
+xipcode.o:	${OBJS}
+	${LD} -r -o $@ ${OBJS}
+
+clean:
+	rm -f *.[oa] *errs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/services/ffs/core.h	Thu Dec 26 03:59:59 2013 +0000
@@ -0,0 +1,579 @@
+/******************************************************************************
+ * Flash File System (ffs)
+ * Idea, design and coding by Mads Meisner-Jensen, mmj@ti.com
+ *
+ * ffs core functions
+ *
+ * $Id: core.h 1.80.1.15.1.36 Thu, 08 Jan 2004 15:05:23 +0100 tsj $
+ *
+ ******************************************************************************/
+
+#if (TARGET == 1)
+#include "../../riviera/rv/rv_defined_swe.h"
+#endif
+
+/******************************************************************************
+ * Compile option switches
+ ******************************************************************************/
+
+// FFS compiled with extra test functionality
+#define FFS_TEST 1
+
+// Default max number of simultaneous open files
+#ifdef RVM_MSFE_SWE
+#define FFS_FD_MAX 20
+#else
+#define FFS_FD_MAX 4
+#endif
+
+#define FFS_RECLAIM_NEW 1
+
+/******************************************************************************
+ * Compile constants
+ ******************************************************************************/
+
+// FFS API version (in four-digit BCD format)
+#define FFS_API_VERSION ((uint16) 0x0642)
+
+// FFS_DRV_VERSION is in drv.h
+
+// TMFFS protocol version is in tmffs.h
+
+// Magic for determining (formatted) file system version. First two digits
+// represent major version, bottom two digits represent minor version. An
+// ffs code compiled for one major version X is compatible with any other
+// format version with major = X. Minor version is incremented when adding
+// new features that does not break compatibility.
+#define FFS_FORMAT_VERSION (0x0210)
+#define BLOCK_MAGIC_LOW    ('f'<<8|'F') // "Ffs#"
+#define BLOCK_MAGIC_HIGH   ('#'<<8|'s')
+#define BLOCK_MAGIC        ((BLOCK_MAGIC_HIGH << 8)|(BLOCK_MAGIC_LOW))
+
+// Absolute maximum number of inodes allowed
+#define FFS_INODES_MAX 2048
+
+// Default maximum number of inodes allowed
+#define FFS_INODES_MAX_DEFAULT 1024
+
+// Default number of path components (limit due to recursiveness of
+// inodes_reclaim())
+#define FFS_PATH_DEPTH_MAX 6
+
+// Maximum number of blocks (flash sectors) in a ffs system. FFS_BLOCKS_MAX
+// must be >= the number of blocks in the largest flash device memory
+// map. It is used to allocate the number of entries in the static bstat
+// array.
+#define FFS_BLOCKS_MAX 128
+// Default size of journal file (represented as 256'ths of the blocksize)
+#define FFS_JOURNAL_SIZE_IN256THS 16  // one 16'ths of the block size. 
+
+// Without the min size will the maximum of files (fs.blocks_files_max) in
+// one block be 32 files if the blocksize is 8kB!
+#define FFS_JOURNAL_SIZE_MIN 1024
+
+#define FFS_JOURNAL_NAME ".journal"
+
+// Default max size of file name (excluding null terminator)
+#define FFS_FILENAME_MAX 20
+
+// Maximum distance in age between youngest and oldest blocks
+#define FFS_DAGE_MAX 256
+#define FFS_DAGE_GAIN_MIN (FFS_DAGE_MAX / 4)
+#define FFS_DAGE_EARLY_WIDTH 64
+
+// Offset on file descriptors 
+#define FFS_FD_OFFSET '1'
+
+// Macros to set flags and test bits in flash memory words (negative logic)
+#define BIT_SET(value, bits) ((value) & (~bits))
+#define IS_BIT_SET(value, bits) (~(value) & (bits))
+
+// Number of free inodes and journal entries to keep for "emergencies"
+#define FFS_INODES_MARGIN  4
+#define FFS_JOURNAL_MARGIN 4
+
+
+/******************************************************************************
+ * Macros used in both drv.c and core.c
+ ******************************************************************************/
+
+// Convert a offset_t value to a block index
+#define offset2block(offset) (((uint32) offset) >> dev.binfo[0].size_ld)
+ 
+// Convert between offset and address
+#define offset2addr(offset) (dev.base + (offset))
+
+// Size of a block
+#define blocksize(block) (1 << dev.binfo[block].size_ld)
+
+// Test if flag is set
+#define is_open_option(options, flags) ((options & flags) == flags)
+
+// Amount of reserved space. 
+#define	RESERVED_LOW  2 * fs.journal_size 
+#define RESERVED_NONE 0
+
+// We have to saturate because a recently reclaimed inodes block could
+// theoretically possess a high age
+#define saturate_dage(dage) (dage > (2*FFS_DAGE_MAX) ? (2*FFS_DAGE_MAX) : dage) 
+
+/******************************************************************************
+ * External declarations
+ ******************************************************************************/
+
+extern struct fs_s fs;
+extern struct block_stat_s bstat[FFS_BLOCKS_MAX];
+
+extern struct ffs_stats_s stats;
+
+extern const struct block_info_s *binfo;
+
+
+/******************************************************************************
+ * Block Types
+ ******************************************************************************/
+
+// Block age, ie. number of times block has been erased
+typedef uint16 age_t;
+
+// Maximum age a block can have
+#define BLOCK_AGE_MAX 0xFFFF
+
+// ffs block status flags. These are stored in the first 2 bytes of
+// the ffs block in the flash sector.
+enum BLOCK_FLAGS {
+    BF_LOST        =  0x80,  // block is lost and will soon be erased
+    BF_FREE        =  0x40,  // free (preformatted and with block magic)
+    BF_DATA        =  0x02,  // data
+    BF_CLEANING    =  0x01,  // block is being cleaned
+    BF_INODES      =  0x10,  // block contains inodes
+    BF_COPYING     =  0x04   // block is a coming inodes block
+};
+enum BLOCK_STATES {
+    BF_IS_EMPTY       = ~(0),
+    BF_IS_FREE        = ~(BF_FREE),
+    BF_IS_DATA        = ~(BF_FREE | BF_DATA),
+    BF_IS_CLEANING    = ~(BF_FREE | BF_DATA | BF_CLEANING),
+    BF_IS_COPYING     = ~(BF_FREE | BF_COPYING),
+    BF_IS_INODES      = ~(BF_FREE | BF_COPYING | BF_INODES),
+    BF_IS_INODES_LOST = ~(BF_FREE | BF_COPYING | BF_INODES | BF_LOST)
+};
+
+// Header of each FFS block
+struct block_header_s {
+    uint16 magic_low;  // 32-bit magic number
+    uint16 magic_high;
+    uint16 version;    // FFS_FORMAT_VERSION used for formatting
+    age_t  age;        // number of times this block has been erased
+    uint16 flags;      // status flags of this block (BLOCK_FLAGS)
+    uint16 reserved0;
+    uint16 reserved1;
+    uint16 reserved2;
+};
+
+// Important the below define MUST fit to the size of the header that is written
+#define BHEADER_SIZE sizeof(struct block_header_s)
+
+#define OLD_BLOCK_MAGIC_LOW    ('S'<<8|'F') // "FS"
+#define OLD_FFS_FORMAT_VERSION (0x0100)     // 1.00 (in four-digit BCD format)
+
+// Old header of each FFS block. From old/previous FFS format version
+struct block_header_old_s {
+    uint8  flags;
+    uint8  copied;
+    uint8  magicflags;
+    uint8  reserved0;
+    uint16 magic_low;
+    uint16 magic_high;
+    uint16 reserved1;
+    uint16 reserved2;
+};
+
+// Block status. This struct holds the status of one ffs block This relation
+// is always valid: <block size> = <used> + <lost> + <free>. The block size
+// is obtained from the corresponding block_info structure. <used> and
+// <lost> variables always holds a value which is a multiple of
+// FFS_GRANULARITY.  For inodes, <used> is number of inodes in active use,
+// <lost> is number of deleted/lost inodes, <numfiles> is the index of the
+// first free inode.
+struct block_stat_s {
+    blocksize_t used;    // number of used bytes
+    blocksize_t lost;    // number of lost bytes
+    uint16      flags;   // flash block flags (first 16 bits of each block)
+    uint16      objects; // number of valid objects
+};
+
+
+/******************************************************************************
+ * Object Types
+ ******************************************************************************/
+
+// This enum MUST be in sync with the one in ffs.h.
+enum OBJECT_TYPE_E {
+    // remaining filetypes are in ffs.h
+    OT_ERASED  = 0,
+    OT_NULL    = 7,
+    OT_MASK    = 7,
+    OT_MAX     = 4
+};
+
+// This enum MUST be in sync with the one in ffs.h.
+enum OBJECT_FLAGS_E {
+    // remaining object flags are in ffs.h
+    OF_UNDEF0   = 1<<5,
+    OF_UNDEF1   = 1<<6,
+    OF_EXACT    = 1<<7, // used by control()/update_commit() interaction. This
+                        // is *not* an object flag!
+    OF_ALL      = OF_READONLY, // all flags allowed to be changed by user
+    OF_MASK     = 0xF0
+};
+
+struct inode_s {
+    uint16      size;
+    uint8       reserved;  // size extension?
+    objflags_t  flags;
+    iref_t      child;     // link to first inode in dir (this inode is a dir)
+    iref_t      sibling;   // link to next inode in same directory
+    location_t  location;  // location of object
+    uint16      sequence;  // 
+    uint16      updates;   // times this object has been updated
+};
+
+struct file_descriptor_s {      
+    char    *buf;          // Write buffer 
+    iref_t  seghead;       // First chunk. Contain file name and optional data 
+    iref_t  wch;           // Inode of work chunk (if chunk is read to buf)
+    int     fp;            // File pointer
+    int     wfp;           // Work file pointer always points to start of wch
+    int     size;          // Size of object (all chunks and data from buf)
+    int8    options;       // Open options
+    int     dirty;         // Indicate if buf contain valid data or not
+};
+
+
+/******************************************************************************
+ * Journal types and global fs structure
+ ******************************************************************************/
+
+enum JOURNAL_FLAGS {
+    JOURNAL_WRITING = 0x02,  // journal is being written to journal file
+    JOURNAL_READY   = 0x04,  // journal has been written to journal file
+    JOURNAL_DONE    = 0x08   // journal has been written to ffs
+};
+
+enum JOURNAL_STATES {
+    JOURNAL_IS_EMPTY   = ~(0),
+    JOURNAL_IS_WRITING = ~(JOURNAL_WRITING),
+    JOURNAL_IS_READY   = ~(JOURNAL_WRITING | JOURNAL_READY),
+    JOURNAL_IS_DONE    = ~(JOURNAL_WRITING | JOURNAL_READY | JOURNAL_DONE)
+};
+
+// Journal entry structure. Note that the state byte *MUST* be the first
+// byte of the structure!
+struct journal_s {
+    uint8      state;    // state of journal entry.
+    objflags_t flags;    // type of object
+    iref_t     i;        // iref of object
+    iref_t     diri;     // iref of object that is this object's parent/sibling
+    iref_t     oldi;     // iref of object being replaced (only for updates)
+    location_t location; // object's location
+    uint16     size;     // object's size
+    iref_t     repli;    // inode which is replaced
+};
+
+// Main ffs info struct (initialised by ffs_initialize())
+struct fs_s {
+    struct inode_s *inodes_addr; // base address of inodes
+    iref_t    root;            // iref of root directory
+    bref_t    inodes;          // index into bstat containing inode block
+    bref_t    newinodes;       // index into bstat containing new inode block
+    bref_t    blocks_free_min; // Number of spare blocks (0 or 1)
+    int       filesize_max;    // Max size of object data
+    int       reserved_space;  // Byte size of space reserved for journal relocation
+    iref_t    inodes_max;      // Max number of inodes possible
+    iref_t    inodes_high;     // number of inodes triggering an inodes_reclaim()
+    iref_t    objects_max;     // Max number of objects (valid inodes) allowed
+    age_t     age_max;         // Max block age found by blocks_fsck()
+    iref_t    block_files_max; // max number of files in a block
+    iref_t    block_files_reserved;    // Reserved for journals
+    uint16    format;          // FFS version as formatted in flash blocks
+    uint16    sequence;        // Object sequence number (for debug only)
+    effs_t    initerror;       // ffs_initialize() return code
+    uint8     lost_threshold;  // Threshold percentage for data block reclaim
+    uint8     flags;           // Global FFS options/flags
+    uint8     filename_max;    // Max length of a filename
+    uint8     path_depth_max;  // Max path componenents allowed
+    uint8     numfds;          // Mumber of available file descriptors
+    uint8     testflags;
+    int8      journal_depth;   // Current journal nesting depth (0 or 1)
+    iref_t    ijournal;        // iref of journal file
+    uint32    journal_size;    // Byte size of journal file
+    uint32    journal_pos;     // Byte offset to first free entry in journal file
+    struct journal_s journal;
+    uint8     fd_max;          // number of max available file descriptors
+    int       fd_buf_size;     // size of stream buffer
+    struct file_descriptor_s fd[FFS_FD_MAX];
+    struct journal_s ojournal; // "Old" journal
+    int       link_child;      // Link child in journal or not
+    iref_t    i_backup;        // Used by ffs_file_write()
+    int       chunk_size_max;  // Max size of one chunk
+    int       chunk_size_min;  // Min size of one chunk 
+    uint32    debug[4];
+};
+
+// This is the layout of the FFS performance statistics file. The file is
+// created with the name ".statistics" in the root directory at format. It
+// is updated after each data and inodes reclaim (after writing the file
+// that provoked the reclaim). The file is only updated if it exists, so if
+// the user does not want the file, she can erase it after the initial
+// format. FIXME: The use of the .statistics file is not yet implemented
+struct ffs_stats_s {
+    uint32 data_allocated;   // implemented
+
+    struct {                 // Not yet implemented
+        uint32 created;
+        uint32 updated;
+        uint32 read;
+    } files;
+    struct {                 // Not yet implemented
+        uint32 written[2];
+        uint32 read[2];
+    } bytes;
+    struct {
+        uint32 most_lost;    // Block candidate
+        uint32 most_unused;  // Block candidate
+        uint32 youngest;     // Block candidate
+        uint32 valid[2];     // Amount of valid reclaimed data 
+        uint32 lost[2];      // Amount of lost reclaimed data 
+    } drec;
+    struct { 
+        uint32 num;          // Number of inode reclaims
+        uint32 valid;        // Number of valid reclaimed inodes
+        uint32 lost;         // Number of lost reclaimed inodes
+    } irec;
+};
+extern struct ffs_stats_s stats;
+
+
+/******************************************************************************
+ * Miscellaneous types
+ ******************************************************************************/
+
+// only used with (FFS_TEST == 1)
+enum TEST_RECOVERY {
+    JOURNAL_TEST_BASE       = 0x10,
+    JOURNAL_TEST_EMPTY,
+    JOURNAL_TEST_WRITING,
+    JOURNAL_TEST_READY,
+    JOURNAL_TEST_COMMITTING,
+    JOURNAL_TEST_COMMITTED,
+    JOURNAL_TEST_DONE,
+    BLOCK_COMMIT_BASE       = 0x20,
+    BLOCK_COMMIT_BEFORE,
+    BLOCK_COMMIT_NO_VALID,
+    BLOCK_COMMIT_OLD_FREE,
+    BLOCK_COMMIT_AFTER,
+    BLOCK_RECLAIM_BASE      = 0x40,
+    BLOCK_RECLAIM_ALLOC,
+    BLOCK_RECLAIM_CLEANING,
+    BLOCK_RECLAIM_NO_CLEAN,
+    BLOCK_RECOVER_OBJECTS
+};
+
+enum FLASH_DATA {
+    FLASH_NULL8  = 0xFF,
+    FLASH_NULL16 = 0xFFFF,
+    FLASH_NULL32 = 0xFFFFFFFFL,
+    IREF_NULL    = FLASH_NULL16
+};
+
+
+// This enum MUST be in sync with the one in ffs.h.
+enum OBJECT_CONTROL {
+    // remaining object control codes are in ffs.h
+    OC_FS_FLAGS       =  80,
+    OC_TRACE_INIT     =  82,
+    OC_DEV_MANUFACT   =  88,
+    OC_DEV_DEVICE     =  89,
+
+    OC_DEBUG_FIRST    = 120,
+    OC_DEBUG_0        = 120,
+    OC_DEBUG_1        = 121,
+    OC_DEBUG_2        = 122,
+    OC_DEBUG_3        = 123,
+    OC_DEBUG_LAST     = 123,
+
+    OC_FS_TESTFLAGS   = 127
+};
+
+enum FS_FLAGS {
+    FS_DIR_DATA   = 0x01   // allow directory objects to contain data.
+};
+
+enum RECLAIM_CANDIDATE {
+    MOST_LOST,
+    MOST_UNUSED,
+    YOUNGEST
+};
+
+/******************************************************************************
+ * Macros
+ ******************************************************************************/
+
+// Convert between location and offset
+#define location2offset(location) ((location) << dev.atomlog2)
+#define offset2location(offset) (((uint32) offset) >> dev.atomlog2)
+
+// test if object is of a specific type
+#define is_object(objp, type) (((objp)->flags & OT_MASK) == (type))
+
+// test if object is valid (directory, file or symlink)
+#define is_object_valid(ip) ((ip->flags & OT_MASK) <= OT_MAX && (ip->flags & OT_MASK) != OT_ERASED)
+
+// test if block is in a specific state
+#define is_block(block, state) (bstat[block].flags == (uint16) (state))
+
+// test if block has certain flags set
+#define is_block_flag(block, bits) (IS_BIT_SET(bstat[block].flags, (bits)))
+
+// convert an object's data address to the address of the object's name
+#define addr2name(addr) (addr)
+
+// Convert a size to an aligned size
+#define atomalign(size) (((size) + dev.atomsize-1) & ~dev.atomnotmask)
+#define wordalign(size) (((size) + 3) & ~3)
+#define halfwordalign(size) (((size) + 1) & ~1)
+
+#define inode_addr(i)   (fs.inodes_addr + i)
+
+#define JOURNAL_POS_INITIAL (wordalign(2 + sizeof(FFS_JOURNAL_NAME) + 1))
+
+
+/******************************************************************************
+ * Function prototypes
+ ******************************************************************************/
+
+// Helper functions
+
+effs_t is_filename(const char *s);
+int ffs_strlen(const char *s);
+int ffs_strcmp(const char *s, const char *p);
+char *addr2data(const char *addr, const struct inode_s *ip);
+
+int object_datasize(iref_t i);
+iref_t is_readonly(iref_t i, const char *name);
+iref_t dir_traverse(iref_t i, iref_t *entries);
+
+bref_t block_alloc(bref_t n, uint16 flags);
+bref_t block_alloc_try(bref_t *n);
+void block_flags_write(uint8 block, uint8 flags);
+
+offset_t data_alloc(int size);
+offset_t data_alloc_try(int size);
+offset_t data_reserved_alloc(int size);
+
+iref_t inode_alloc(void);
+
+effs_t is_fd_valid(fd_t fdi);
+effs_t is_offset_in_buf(int offset, fd_t fdi);
+
+iref_t chunk_alloc(int realsize, int is_journal, offset_t *offset);  
+
+iref_t inode_alloc_try(void);
+fd_t get_fdi(iref_t i);
+
+offset_t data_prealloc(int realsize);
+
+// Functions used by API
+
+effs_t object_update(iref_t oldi);
+iref_t object_create(const char *name, const char *buf, int size,
+                         iref_t dir);
+int file_read(const char *name, void *addr, int size);
+int stream_read(fd_t fdi, void *src, int size);
+int object_read(const char *name, char *buf, int size, int linkflag);
+
+iref_t object_stat(const char *name, struct xstat_s *stat,
+                       int linkflag, int fdi, int extended);
+effs_t object_remove(iref_t i);
+iref_t object_rename(iref_t oldi, const char *newname, iref_t newdir);
+effs_t object_control(iref_t i, int8 action, int value);
+int object_truncate(const char *pathname, fd_t fdi, offset_t length);
+iref_t object_lookup(const char *path, char **leaf, iref_t *dir);
+iref_t object_lookup_once(const char *path, char **leaf, iref_t *dir);
+iref_t dir_open(const char *name);
+iref_t dir_next (iref_t dir, iref_t i, char *name, int8 size);
+
+
+// Journalling
+
+void journal_begin(iref_t oldi);
+void journal_end(uint8 type);
+void journal_commit(uint8 type);
+int journal_push(void);
+int journal_pop(void);
+iref_t journal_create(iref_t oldi);
+effs_t journal_init(iref_t i);
+
+
+// Format, Init and Reclaim
+
+void block_preformat(bref_t b, age_t age);
+effs_t fs_preformat(void);
+effs_t is_formattable(int8 flag);
+effs_t fs_format(const char *fsname_and_options);
+
+effs_t ffs_initialize(void);
+void fs_params_init(const char *p);
+blocksize_t block_used(bref_t b);
+
+effs_t ffs_begin(void);
+int ffs_end(int error);
+
+int block_reclaim(bref_t b);
+int blocks_reclaim(void);
+void block_commit(void);
+
+iref_t data_reclaim(int space);
+int data_reclaim_try(int space);
+iref_t data_block_reclaim(bref_t b, int reclaim_candidate);
+iref_t object_relocate(iref_t oldi);
+iref_t block_clean(bref_t b);
+
+void block_free(bref_t block);
+
+void inodes_set(iref_t i);
+effs_t inodes_reclaim(void);
+
+int reclaim(void);
+
+// Internally used functions
+
+effs_t file_read_int(const char *path, void *src, int size);
+effs_t file_update(const char *path, void *src, int size);
+
+int statistics_file_create(void);
+int statistics_write(void);
+void statistics_init(void);
+void statistics_update_drec(int valid, int lost, int candidate);
+void statistics_update_irec(int valid, int lost);
+
+// Chunk Operations
+iref_t segment_create(const char *buf, int size, iref_t dir);
+int segment_datasize(const struct inode_s *ip);
+int segment_read(iref_t i, char *buf, int size, int offset);
+iref_t segment_next(iref_t i);
+iref_t segment_traverse(iref_t i, iref_t *entries);
+int segfile_seek(iref_t in_i, int in_pos, 
+                     iref_t *out_i, int *out_pos_i);
+iref_t chunk_traverse(iref_t i);
+effs_t datasync(fd_t fdi);
+// debug/test functions
+
+void tr_bstat(void);
+void tr_fd(fd_t fdi);
+
+// These prototypes really belong in ffs.h but as they have not been
+// implemented, we will not show these prototypes to application
+// programmers.
+effs_t fcntl(fd_t fd, int8 action, uint32 *param);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/services/ffs/drv.c	Thu Dec 26 03:59:59 2013 +0000
@@ -0,0 +1,423 @@
+/******************************************************************************
+ * Flash File System (ffs)
+ * Idea, design and coding by Mads Meisner-Jensen, mmj@ti.com
+ *
+ * ffs low level flash driver
+ *
+ * $Id: drv.c 1.30.1.6.1.51.1.1.1.13.1.11 Tue, 06 Jan 2004 14:36:52 +0100 tsj $
+ *
+ ******************************************************************************/
+
+#include "../../include/config.h"
+#include "ffs.h"
+#include "drv.h"
+#include "ffstrace.h"
+#include "intctl.h"
+#include "ramffs.h"
+#include <string.h>
+
+
+/******************************************************************************
+ * Macros
+ ******************************************************************************/
+
+#define addr2offset(address) ( (int) (address) - (int) dev.base )
+
+
+/******************************************************************************
+ * Generic Driver Functions
+ ******************************************************************************/
+
+// Note: This function is designed for little-endian memory addressing!
+void ffsdrv_write_byte(void *dst, uint8 value)
+{
+    uint16 halfword;
+
+    tw(tr(TR_FUNC, TrDrvWrite, "ffsdrv_write_byte(0x%05x, 0x%x)\n",
+       (int) (addr2offset(dst)), value));
+    ttw(str(TTrDrvWrite, "wb" NL));
+
+    if ((int) dst & 1)
+        halfword =                (value << 8) | *((uint8 *) dst - 1);
+    else
+        halfword = (*((uint8 *) dst + 1) << 8) | (value);
+
+    ffsdrv.write_halfword((uint16 *) ((int) dst & ~1), halfword);
+}
+
+void ffsdrv_generic_write(void *dst, const void *src, uint16 size)
+{
+    uint8 *mydst = dst;
+    const uint8 *mysrc = src;
+
+    if (size > 0)
+    {
+        if ((unsigned int) mydst & 1) {
+            ffsdrv_write_byte(mydst++, *mysrc++);
+            size--;
+        }
+        while (size >= 2) {
+            ffsdrv.write_halfword((uint16 *) mydst,
+                                  mysrc[0] | (mysrc[1] << 8));
+            size -= 2;
+            mysrc += 2;
+            mydst += 2;
+        }
+        if (size == 1)
+            ffsdrv_write_byte(mydst++, *mysrc++);
+    }
+}
+
+/******************************************************************************
+ * Dummy Functions
+ ******************************************************************************/
+
+int ffsdrv_null_init(void)
+{
+    ttw(ttr(TTrDrvOther, "ffsdrv_null_init()" NL));
+
+    return 0;
+}
+
+void ffsdrv_null_erase(uint8 block)
+{
+    ttw(ttr(TTrDrvErase, "ffsdrv_null_erase(%d)" NL, block));
+}
+
+void ffsdrv_null_write_halfword(volatile uint16 *addr, uint16 value)
+{
+    ttw(ttr(TTrDrvWrite, "ffsdrv_null_write_halfword(0x%x, 0x%x)" NL, addr, value));
+}
+
+void ffsdrv_null_write(void *dst, const void *src, uint16 size)
+{
+    ttw(ttr(TTrDrvWrite, "ffsdrv_null_write(0x%x, 0x%x, %d)" NL, dst, src, size));
+}
+
+void ffsdrv_null_erase_suspend(void)
+{
+    ttw(str(TTrDrvErase, "ffsdrv_null_erase_suspend()" NL));
+}
+
+void ffsdrv_null_erase_resume(void)
+{
+    ttw(str(TTrDrvErase, "ffsdrv_null_erase_resume()" NL));
+}
+
+void ffsdrv_null_write_end(void)
+{
+    ttw(str(TTrDrvWrite, "ffsdrv_null_write_end()" NL));
+}
+
+void ffsdrv_null_erase_end(void)
+{
+    ttw(str(TTrDrvErase, "ffsdrv_null_erase_end()" NL));
+}
+
+/*
+ * FreeCalypso change from TI: we only compile one flash "driver" type
+ * based on the build configuration.
+ */
+
+#if FFS_IN_RAM
+
+/******************************************************************************
+ * RAM Family Functions
+ ******************************************************************************/
+
+struct block_info_s ramffs_block_info[RAMFFS_NBLOCKS];
+
+int ffsdrv_ram_init(void)
+{
+    unsigned i;
+    uint32 offset;
+
+    ttw(ttr(TTrDrvOther, "ffsdrv_ram_init()" NL));
+    memset(_RAMFFS_area, 0xFF, RAMFFS_TOTAL_SIZE);
+    offset = 0;
+    for (i = 0; i < RAMFFS_NBLOCKS; i++) {
+	ramffs_block_info[i].offset = offset;
+	ramffs_block_info[i].size_ld = RAMFFS_BLKSIZE_LOG2;
+	offset += RAMFFS_BLKSIZE_BYTES;
+    }
+    return 0;
+}
+
+void ffsdrv_ram_write_halfword(volatile uint16 *dst, uint16 value)
+{
+  *dst = value;
+}
+
+#if 0
+/* duplicates ffsdrv_generic_write */
+void ffsdrv_ram_write(void *dst, const void *src, uint16 size)
+{
+    uint8 *mydst = dst;
+    const uint8 *mysrc = src;
+  
+    if (size == 0)
+        return;
+    else if (size == 1)
+        ffsdrv_write_byte(mydst, *mysrc);
+    else {
+        if ((int) mydst & 1) {
+            ffsdrv_write_byte(mydst++, *mysrc++);
+            size--;
+        }
+        while (size >= 2) {
+            ffsdrv_ram_write_halfword((uint16 *) mydst, mysrc[0]|(mysrc[1] << 8));
+            size -= 2;
+            mysrc += 2;
+            mydst += 2;
+        }
+        if (size == 1)
+            ffsdrv_write_byte(mydst++, *mysrc++);
+    }
+}
+#endif
+
+void ffsdrv_ram_erase(uint8 block) 
+{
+    int i;
+    char *addr;
+
+    addr = block2addr(block);
+    
+    for (i = 0; i < (1 << dev.binfo[block].size_ld); i++) {
+        *addr++ = 0xFF;
+    }
+}
+
+const struct ffsdrv_s ffsdrv = {
+    ffsdrv_ram_init,
+    ffsdrv_ram_erase,
+    ffsdrv_ram_write_halfword,
+    ffsdrv_generic_write,
+    ffsdrv_null_write_end,
+    ffsdrv_null_erase_suspend,
+    ffsdrv_null_erase_resume
+};
+
+#elif CONFIG_FLASH_WRITE
+
+/******************************************************************************
+ * AMD Dual/Multi Bank Driver Functions
+ ******************************************************************************/
+
+// All erase and write operations are performed atomically (interrupts
+// disabled). Otherwise we cannot trust the value of dev.state and we cannot
+// determine exactly how many of the command words have already been
+// written.
+
+// in ffs_end() when we resume an erasure that was previously suspended, how
+// does that affect multiple tasks doing that simultaneously?
+
+void ffsdrv_amd_write_end(void);
+void ffsdrv_amd_erase_end(void);
+
+void ffsdrv_amd_write_halfword(volatile uint16 *addr, uint16 value)
+{
+    volatile char *flash = dev.base;
+    uint32 cpsr;
+
+    tlw(led_on(LED_WRITE));
+    ttw(ttr(TTrDrvWrite, "wh(%x,%x)" NL, addr, value));
+
+    dev.addr = addr;
+    dev.data = value;
+
+    if (~*addr & value) {
+        ttw(ttr(TTrFatal, "wh(%x,%x->%x) fatal" NL, addr, *addr, value));
+        return;
+    }
+
+    cpsr = int_disable();
+    tlw(led_toggle(LED_WRITE_SUSPEND));
+    dev.state = DEV_WRITE;
+    flash[0xAAAA] = 0xAA; // unlock cycle 1
+    flash[0x5555] = 0x55; // unlock cycle 2
+    flash[0xAAAA] = 0xA0;
+    *addr         = value;
+    int_enable(cpsr);
+    tlw(led_toggle(LED_WRITE_SUSPEND));
+
+    ffsdrv_amd_write_end();
+}
+
+#if 0
+/* duplicates ffsdrv_generic_write */
+void ffsdrv_amd_write(void *dst, const void *src, uint16 size)
+{
+    uint8 *mydst = dst;
+    const uint8 *mysrc = src;
+
+    if (size > 0)
+    {
+        if ((unsigned int) mydst & 1) {
+            ffsdrv_write_byte(mydst++, *mysrc++);
+            size--;
+        }
+        while (size >= 2) {
+            ffsdrv_amd_write_halfword((uint16 *) mydst,
+                                      mysrc[0] | (mysrc[1] << 8));
+            size -= 2;
+            mysrc += 2;
+            mydst += 2;
+        }
+        if (size == 1)
+            ffsdrv_write_byte(mydst++, *mysrc++);
+    }
+}
+#endif
+
+void ffsdrv_amd_write_end(void)
+{
+    while ((*dev.addr ^ dev.data) & 0x80)
+        tlw(led_toggle(LED_WRITE_SUSPEND));
+
+    dev.state = DEV_READ;
+
+    tlw(led_off(LED_WRITE));
+}
+
+void ffsdrv_amd_erase(uint8 block)
+{
+    volatile char *flash = dev.base;
+    uint32 cpsr;
+
+    tlw(led_on(LED_ERASE));
+    ttw(ttr(TTrDrvErase, "e(%d)" NL, block));
+
+    dev.addr = (uint16 *) block2addr(block);
+
+    cpsr = int_disable();
+    dev.state = DEV_ERASE;
+    flash[0xAAAA] = 0xAA; // unlock cycle 1
+    flash[0x5555] = 0x55; // unlock cycle 2
+    flash[0xAAAA] = 0x80; 
+    flash[0xAAAA] = 0xAA; // unlock cycle 1
+    flash[0x5555] = 0x55; // unlock cycle 2
+    *dev.addr = 0x30; // AMD erase sector command
+    int_enable(cpsr);
+
+    ffsdrv_amd_erase_end();
+}
+
+void ffsdrv_amd_erase_end(void)
+{
+    while ((*dev.addr & 0x80) == 0)
+        ;
+
+    dev.state = DEV_READ;
+
+    tlw(led_off(LED_ERASE));
+}
+
+void ffsdrv_amd_erase_suspend(void)
+{
+    uint32 cpsr;
+
+    tlw(led_on(LED_ERASE_SUSPEND));
+    ttw(str(TTrDrvErase, "es" NL));
+
+    // if erase has finished then all is ok
+    if (*dev.addr & 0x80) {
+        ffsdrv_amd_erase_end();
+        tlw(led_off(LED_ERASE_SUSPEND));
+        return;
+    }
+
+    // NOTEME: As there is no way to be absolutely certain that erase
+    // doesn't finish between last poll and the following erase suspend
+    // command, we assume that the erase suspend is safe even though the
+    // erase IS actually already finished.
+
+    cpsr = int_disable();
+    dev.state = DEV_ERASE_SUSPEND;
+    *dev.addr = 0xB0;
+
+    // Wait for erase suspend to finish
+    while ((*dev.addr & 0x80) == 0)
+        ;
+
+    int_enable(cpsr);
+}
+
+void ffsdrv_amd_erase_resume(void)
+{
+    uint32 cpsr;
+
+    ttw(str(TTrDrvErase, "er" NL));
+
+    // NOTEME: See note in erase_suspend()... We assume that the erase
+    // resume is safe even though the erase IS actually already finished.
+    cpsr = int_disable();
+    dev.state = DEV_ERASE;
+    *dev.addr = 0x30;
+    int_enable(cpsr);
+
+    tlw(led_off(LED_ERASE_SUSPEND));
+}
+
+const struct ffsdrv_s ffsdrv = {
+    ffsdrv_null_init,
+    ffsdrv_amd_erase,
+    ffsdrv_amd_write_halfword,
+    ffsdrv_generic_write,
+    ffsdrv_amd_write_end,
+    ffsdrv_amd_erase_suspend,
+    ffsdrv_amd_erase_resume
+};
+
+#else
+
+/*
+ * This part will get compiled if we have real FFS (FFS_IN_RAM=0),
+ * but not allowed to write to flash (CONFIG_FLASH_WRITE=0).
+ */
+
+const struct ffsdrv_s ffsdrv = {
+    ffsdrv_null_init,
+    ffsdrv_null_erase,
+    ffsdrv_null_write_halfword,
+    ffsdrv_null_write,
+    ffsdrv_null_write_end,
+    ffsdrv_null_erase_suspend,
+    ffsdrv_null_erase_resume
+};
+
+#endif
+
+
+/******************************************************************************
+ * Initialization
+ *
+ * Significantly simplified in FreeCalypso.
+ *
+ ******************************************************************************/
+
+effs_t ffsdrv_init(void)
+{
+    int error;
+
+    tw(tr(TR_BEGIN, TrDrvInit, "drv_init() {\n"));
+    ttw(str(TTrDrvOther, "ffsdrv_init() {" NL));
+
+    dev.state = DEV_READ;
+    dev.atomlog2 = FFS_ATOM_LOG2;
+    dev.atomsize = 1 << dev.atomlog2;
+    dev.atomnotmask = dev.atomsize - 1;
+
+    error = ffsdrv.init();
+
+    tw(tr(TR_FUNC, TrDrvInit, "dev.binfo     = 0x%x\n", (unsigned int) dev.binfo));
+    tw(tr(TR_FUNC, TrDrvInit, "dev.base      = 0x%x\n", (unsigned int) dev.base));
+    tw(tr(TR_FUNC, TrDrvInit, "dev.numblocks = %d\n", dev.numblocks));
+    tw(tr(TR_FUNC, TrDrvInit, "dev.blocksize = %d\n", dev.blocksize));
+    tw(tr(TR_FUNC, TrDrvInit, "dev.atomlog2/atomsize/atomnotmask = %d/%d/%x\n",
+          dev.atomlog2, dev.atomsize, dev.atomnotmask));
+    tw(tr(TR_END, TrDrvInit, "} %d\n", error));
+    ttw(ttr(TTrDrvOther, "} %d" NL, error));
+
+    return error;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/services/ffs/drv.h	Thu Dec 26 03:59:59 2013 +0000
@@ -0,0 +1,187 @@
+/******************************************************************************
+ * Flash File System (ffs)
+ * Idea, design and coding by Mads Meisner-Jensen, mmj@ti.com
+ *
+ * ffs low level flash driver
+ *
+ * $Id: drv.h 1.15.1.25.1.1.1.20 Mon, 17 Nov 2003 08:51:37 +0100 tsj $
+ *
+ ******************************************************************************/
+
+#ifndef TARGET
+#define	TARGET	1
+#define	_RVF	1
+#endif
+
+/******************************************************************************
+ * Compile constants
+ ******************************************************************************/
+
+// FFS driver version (in four-digit BCD format). Format is MMID, where MM
+// is major revision number, incremented e.g. for major revision or support
+// for new flash family/driver. I is minor revision that is incremented for
+// minor changes or when a bug is corrected. D is incremented when support
+// of another device is added.
+#define FFS_DRV_VERSION ((uint16) 0x1011)
+
+// Default Allocation granularity of ffs data sectors (as power of two)
+#define FFS_ATOM_LOG2 4
+
+
+/******************************************************************************
+ * Macros
+ ******************************************************************************/
+
+// Convert between address and block index. Only works if all blocks are the
+// same size!
+#define block2addr(block) (dev.base + dev.binfo[block].offset)
+
+// Note that it is *VERY* important that pointers to hardware and flash are
+// declared volatile, otherwise the compiler optimizes some reads and writes
+// out and this results in non-working code!
+#define FLASH_WRITE_HALFWORD(addr, data) *(volatile uint16 *) (addr) = (data)
+#define FLASH_READ_HALFWORD(addr) *((volatile uint16 *) (addr))
+
+#if (TARGET == 1)
+
+#include "../../include/config.h"
+#include "../../bsp/mem.h"
+#if (CHIPSET == 12)
+  #include "sys_inth.h"
+#else
+#include "../../bsp/inth.h" 
+#endif
+
+#if (CHIPSET == 3)
+#define INT_REQUESTED (*(volatile uint16 *) INTH_IT_REG) & \
+                        ~(*(volatile uint16 *) INTH_MASK_REG)
+#elif (CHIPSET == 4 || CHIPSET == 5 || CHIPSET == 6 || CHIPSET == 7 || CHIPSET == 8 || CHIPSET == 9 || CHIPSET == 10 || CHIPSET == 11)
+#define INT_REQUESTED ((*(volatile uint16 *) INTH_IT_REG1) & \
+                         ~(*(volatile uint16 *) INTH_MASK_REG1)) || \
+                        ((*(volatile uint16 *) INTH_IT_REG2) & \
+                         ~(*(volatile uint16 *) INTH_MASK_REG2))
+#elif (CHIPSET == 12)
+#define INT_REQUESTED ((*(volatile uint16 *) C_INTH_IT_REG1) & \
+                         ~(*(volatile uint16 *) C_INTH_MASK_REG1)) || \
+                        ((*(volatile uint16 *) C_INTH_IT_REG2) & \
+                         ~(*(volatile uint16 *) C_INTH_MASK_REG2))
+#endif
+#endif // (TARGET == 1)
+
+
+/******************************************************************************
+ * Types
+ ******************************************************************************/
+
+// Flash driver identifiers.
+enum FFS_DRIVER {
+    FFS_DRIVER_NULL          =  0, // Null driver
+
+    FFS_DRIVER_AMD           =  2, // AMD dual/multi-bank driver
+    FFS_DRIVER_AMD_SB        =  3, // AMD single-bank driver
+
+    FFS_DRIVER_SST           =  8, // SST dual/multi-bank driver
+    FFS_DRIVER_SST_SB        =  9, // SST single-bank driver
+
+    FFS_DRIVER_INTEL         = 16, // Intel dual/multi-bank driver
+    FFS_DRIVER_INTEL_SB      = 17, // Intel single-bank driver
+
+    FFS_DRIVER_AMD_PSEUDO_SB = 32, // Test driver
+    FFS_DRIVER_TEST          = 34, // Test driver
+
+    FFS_DRIVER_RAM           = 64  // Ram driver
+};
+
+
+// Manufacturer identifiers. These should never have to be changed. They are
+// ordered in alphabetically ascending order.
+enum FFS_MANUFACTURER {
+    MANUFACT_AMD     = 0x01,
+    MANUFACT_ATMEL   = 0x1F,
+    MANUFACT_FUJITSU = 0x04,
+    MANUFACT_INTEL   = 0x89,
+    MANUFACT_MXIC    = 0xC2,
+    MANUFACT_SAMSUNG = 0xEC,
+    MANUFACT_SHARP   = 0xB0,
+    MANUFACT_SST     = 0xBF,
+    MANUFACT_TOSHIBA = 0x98,
+    MANUFACT_RAM     = 0xFE, // Ram 
+    MANUFACT_TEST    = 0x54  // 'T'est manufacturer
+};
+
+
+// Flash block information for one ffs block (flash sector). Note that the
+// ffs block definition might be of a smaller size then the physical flash
+// sector. The ffs blocks must be defined in ascending order of addresses.
+struct block_info_s {
+    uint32 offset;
+    uint8  size_ld;   // log2 of block size
+    uint8  unused1;
+    uint8  unused2;
+    uint8  unused3;
+};
+
+
+// General flash information for one flash device
+struct flash_info_s {
+    const struct block_info_s *binfo; // block info array for this device
+    char   *base;      // base flash address of ffs blocks
+    uint16 manufact;   // read with flash A0 = 0
+    uint16 device;     // read with flash A0 = 1
+    uint8  driver;     // flash driver type
+    uint8  numblocks;  // number of blocks defined for use by ffs
+};
+extern const struct flash_info_s flash_info[];
+
+enum DEVICE_STATE {
+    DEV_READ,
+    DEV_ERASE,
+    DEV_ERASE_SUSPEND,
+    DEV_WRITE
+};
+
+
+// Note that it is *VERY* important that pointers to hardware and flash are
+// declared volatile, otherwise the compiler optimizes some reads and writes
+// out and this results in non-working code!
+struct dev_s {
+    char   *base;       // base flash address of ffs blocks
+    struct block_info_s *binfo;
+    uint16 manufact;
+    uint16 device;
+    volatile uint16 *addr; // address being written or erased
+    uint16 data;           // data currently being written (dev.state = WRITE)
+    uint32 blocksize;
+    uint8  blocksize_ld;
+    uint8  atomlog2;
+    uint8  driver;
+    uint8  state;       // state of device (DEVICE_STATE)
+    uint8  numblocks;
+    uint8  atomsize;
+    uint8  atomnotmask;
+};
+extern struct dev_s dev;
+
+    
+// Flash low level driver function pointers
+struct ffsdrv_s {
+    int  (* init)(void);
+    void (* erase)(uint8 block);
+    void (* write_halfword)(volatile uint16 *dst, uint16 value);
+    void (* write)(void *dst, const void *src, uint16 size);
+    void (* write_end)(void);
+    void (* erase_suspend)(void);
+    void (* erase_resume)(void);
+};
+extern const struct ffsdrv_s ffsdrv;	/* const added for FreeCalypso */
+
+
+/******************************************************************************
+ * Function Prototypes
+ ******************************************************************************/
+
+void ffsdrv_write_byte(void *dst, uint8 value);
+effs_t ffsdrv_init(void);
+
+//extern int ffs_ram_image_address;
+// We do it in a different way in FreeCalypso
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/services/ffs/ffs.h	Thu Dec 26 03:59:59 2013 +0000
@@ -0,0 +1,406 @@
+/******************************************************************************
+ * Flash File System (ffs)
+ * Idea, design and coding by Mads Meisner-Jensen, mmj@ti.com
+ *
+ * FFS Types and globals
+ *
+ * $Id: ffs.h 1.19.1.45.1.26 Mon, 28 Apr 2003 11:27:14 +0200 cm $
+ *
+ ******************************************************************************/
+
+#ifndef _FFS_H_
+#define _FFS_H_
+
+#ifndef TARGET
+#define	TARGET	1
+#define	_RVF	1
+#endif
+
+#ifdef _RVF
+#include "../../riviera/rvf/rvf_api.h"
+#include "../../riviera/rvm/rvm_use_id_list.h"
+#endif
+
+/******************************************************************************
+ * Types
+ ******************************************************************************/
+
+#ifndef BASIC_TYPES
+#define BASIC_TYPES
+typedef signed   char  int8;
+typedef unsigned char  uint8;
+typedef signed   short int16;
+typedef unsigned short uint16;
+typedef signed   int   int32;
+typedef unsigned int   uint32;
+#endif
+
+#if (TARGET == 1)
+// Unique message offset returned in the header of each mail (msg_id).
+#define FFS_MESSAGE_OFFSET	 BUILD_MESSAGE_OFFSET(FFS_USE_ID)
+#endif
+
+typedef int8   effs_t;      // error type
+//typedef int    effs_t;
+typedef int32  req_id_t;    // request id
+typedef int32  offset_t;    // offset from first address of ffs.
+typedef uint32 location_t;  // object location offset
+typedef int32  blocksize_t; // can hold size of a block
+typedef uint8  objflags_t;  // object flags
+typedef uint8  objtype_t;   // object type
+
+typedef int16  iref_t;      // inode reference
+typedef int8   bref_t;      // block reference
+
+typedef int32  fd_t;        // file descriptor
+typedef uint16 ffs_options_t;  // option flags to open() and file_write()
+
+// For directory operations
+struct dir_s {
+    iref_t this;   // iref of dir that was opened
+    iref_t index;  // last inode returned by ffs_readdir()
+};
+
+// File stat structure
+struct stat_s {
+    objtype_t  type;
+    objflags_t flags;
+    iref_t     inode;
+    int        size;     // size of data space occupied by object
+};
+
+// File xstat structure
+struct xstat_s {
+    objtype_t  type;
+    objflags_t flags;
+    iref_t     inode;
+    int        size;     // size of data space occupied by object
+    int        space;    // size of physical data space occupied by object
+    location_t location;
+    uint8      reserved; // only for debug
+    bref_t     block;    // only for debug
+    uint16     sequence; // only for debug
+    uint16     updates;  // only for debug
+};
+
+#if (TARGET == 0)
+// Only use to run on PC and not in target. Must be syncron with the typedef
+// from rv_general.h
+typedef void (*CALLBACK_FUNC)(void *);
+
+typedef uint16 T_RVF_ADDR_ID;
+
+/* define return_path */              
+typedef struct
+{
+	T_RVF_ADDR_ID	addr_id;
+	void			(*callback_func)(void *);
+} T_RV_RETURN;
+
+/* Define the header of each message used in Riviera. */
+typedef struct {
+    uint32			msg_id;
+	void			(*callback_func)(void *);
+    T_RVF_ADDR_ID	src_addr_id;
+	T_RVF_ADDR_ID	dest_addr_id;
+} T_RV_HDR;
+
+// Used riviera types
+typedef uint16          UINT16;
+typedef int8            INT8;
+
+#endif 
+
+// Confirm mail sent from FFS task to caller (application)
+struct ffs_file_cnf_s {
+    T_RV_HDR header;
+    int       error;      // error code of FFS operation
+    req_id_t  request_id; // Unique id number
+    char      *path;      // path name of object operation was performed on
+};
+
+struct ffs_stream_cnf_s {
+    T_RV_HDR header;
+    int       error;      // error code of FFS operation
+    req_id_t  request_id; // Unique id number
+    fd_t      fdi;        // file descriptor
+};
+
+/******************************************************************************
+ * RVF Types
+ ******************************************************************************/
+
+typedef ffs_options_t   T_FFS_OPEN_FLAGS;
+typedef int             T_FFS_SIZE;
+typedef offset_t        T_FFS_OFFSET;
+typedef effs_t          T_FFS_RET;
+typedef req_id_t        T_FFS_REQ_ID;
+typedef int             T_FFS_WHENCE;
+typedef fd_t            T_FFS_FD;
+typedef objtype_t       T_FFS_OBJECT_TYPE;
+typedef objflags_t      T_FFS_FLAGS;
+typedef struct stat_s   T_FFS_STAT;
+typedef struct xstat_s  T_FFS_XSTAT;
+typedef struct dir_s    T_FFS_DIR;
+typedef struct ffs_file_cnf_s     T_FFS_FILE_CNF;
+typedef struct ffs_stream_cnf_s   T_FFS_STREAM_CNF;
+
+/******************************************************************************
+ * Errors
+ ******************************************************************************/
+
+enum FFS_ERRORS {
+    EFFS_OK          =  0,  /* ok */
+    EFFS_NODEVICE    = -1,  /* flash device unknown */
+    EFFS_CORRUPTED   = -2,  /* filesystem corrupted!? */
+    EFFS_NOPREFORMAT = -3,  /* ffs not preformatted */
+    EFFS_NOFORMAT    = -4,  /* ffs not formatted */
+    EFFS_BADFORMAT   = -5,  /* incompatible ffs version, re-format needed */
+    EFFS_MAGIC       = -6,  /* bad magic */
+    EFFS_AGAIN       = -7,  /* not ready, try again later */
+    EFFS_NOSYS       = -8,  /* function not implemented */
+    EFFS_DRIVER      = -9,  /* ffs device driver error */
+
+    EFFS_NOSPACE     = -10, /* out of data space */
+    EFFS_FSFULL      = -11, /* file system full, no free inodes */
+    EFFS_BADNAME     = -12, /* bad filename */
+    EFFS_NOTFOUND    = -13, /* object not found */
+    EFFS_EXISTS      = -14, /* object exists */
+    EFFS_ACCESS      = -15, /* access permission violation */
+    EFFS_NAMETOOLONG = -16, /* filename too long */
+    EFFS_INVALID     = -17, /* invalid argument */
+    EFFS_DIRNOTEMPTY = -18, /* directory not empty */
+    EFFS_NOTADIR     = -19, /* object is not a directory */
+    EFFS_SPARE       = -20, /* SPARE */
+    EFFS_FILETOOBIG  = -21, /* file too big */
+    EFFS_NOTAFILE    = -22, /* object is not a file */
+    EFFS_PATHTOODEEP = -23, /* path too deep */
+
+    EFFS_NUMFD       = -24, /* Max number of open files reached */
+    EFFS_BADFD       = -25, /* Bad file descriptor */
+    EFFS_BADOP       = -26, /* Bad operation */
+    EFFS_LOCKED      = -27, /* The file is locked */
+
+    EFFS_TOOBIG      = -30, /* too big (tmffs buffer overflow) */
+    EFFS_MEMORY      = -31, /* out of memory */
+    EFFS_MSGSEND     = -32, /* message send failed */
+
+    /* debug errors */
+
+    EFFS_SIBLINGLOOP = -40, /* directory sibling loop */
+    EFFS_NOBLOCKS    = -41, /* No more blocks!? */
+    EFFS_DBR         = -42, /* Data reclaim did not finish!? */
+    EFFS_RECLAIMLOOP = -43  /* Data reclaim loop */
+};
+
+
+/******************************************************************************
+ * Enumerations
+ ******************************************************************************/
+
+enum FFS_OBJECT_CONTROL_ACTION {
+    OC_FLAGS = 1
+};
+
+enum FFS_OBJECT_TYPE {
+    OT_FILE    = 1,
+    OT_DIR     = 2,
+    OT_LINK    = 3,
+    OT_SEGMENT = 4
+};
+
+enum FFS_OBJECT_FLAGS {
+    OF_READONLY = 1<<4  // object cannot be modified
+};
+
+enum FFS_OPEN {
+    FFS_O_EMPTY  = 0x00,  // Okay?
+    FFS_O_CREATE = 0x01,
+    FFS_O_APPEND = 0x02,
+    FFS_O_EXCL   = 0x04,
+    FFS_O_TRUNC  = 0x08,
+    FFS_O_RDONLY = 0x10,
+    FFS_O_WRONLY = 0x20,
+    FFS_O_RDWR   = FFS_O_RDONLY | FFS_O_WRONLY
+};
+
+enum FFS_SEEK {
+    FFS_SEEK_SET = 0,
+    FFS_SEEK_CUR = 1,
+    FFS_SEEK_END = 2
+};
+
+// FIXME: debug indices to go into core.h
+enum FFS_QUERY {              // data size, description
+    Q_BYTES_FREE        =  1, // 4, number of free bytes in FFS
+    Q_BYTES_USED        =  2, // 4, number of used bytes in FFS
+    Q_BYTES_LOST        =  3, // 4, number of lost bytes in FFS
+    Q_BYTES_MAX         =  4, // 4, number of max available bytes in FFS
+    Q_BYTES_FREE_RAW    =  5, // 4, number of free raw bytes in FFS (used internal)
+
+    Q_FD_BUF_SIZE       = 10, // 4, size of buffer used by stream functions
+
+    Q_TM_BUFADDR        = 11, // 4, testmode buffer addr
+    Q_TM_BUFSIZE        = 12, // 4, testmode ffs buffer size
+    Q_DEV_BASE          = 13, // 4, FFS device base address
+    Q_CHUNK_SIZE_MAX    = 14, // 4, max size of chunks made by non stream fkt.
+
+    // FFS versions
+    Q_FFS_API_VERSION   = 16, // 2, FFS API Version
+    Q_FFS_DRV_VERSION   = 17, // 2, FFS Driver Version
+    Q_FFS_REVISION      = 18, // 2, FFS Revision (from PRCS)
+    Q_FFS_FORMAT_READ   = 19, // 2, FFS version as read from ffs
+    Q_FFS_LASTERROR     = 20, // 2, FFS last error (from init)
+    Q_FFS_FORMAT_WRITE  = 21, // 2, FFS version as written to ffs on format
+	Q_FFS_TM_VERSION    = 22, // 2, FFS Testmode version
+
+    // File system queries
+    Q_FILENAME_MAX      = 24, // 2, max filename length
+    Q_PATH_DEPTH_MAX    = 25, // 2, max path/directory nesting depth
+    Q_FD_MAX            = 26, // 2, max numbers of simultaneous open files
+
+    Q_OBJECTS_FREE      = 32, // 2, number of objects that can be created
+    Q_INODES_USED       = 33, // 2, number of inodes used
+    Q_INODES_LOST       = 34, // 2, number of inodes lost
+    Q_OBJECTS_USED      = 33, // 2, DEPRECATED: old name for Q_INODES_USED
+    Q_OBJECTS_LOST      = 34, // 2, DEPRECATED: old name for Q_INODES_LOST
+    Q_OBJECTS_MAX       = 35, // 2, max number of valid objects allowed
+    Q_INODES_MAX        = 36, // 2, physical total max number of inodes
+    Q_INODES_HIGH       = 37, // 2, watermark for when inodes will be reclaimed
+    Q_LOST_HIGH         = 38, // 2, watermark for when data block will be reclaimed
+
+    // Device queries
+    Q_DEV_MANUFACTURER  = 48, // 2, flash manufacturer ID
+    Q_DEV_DEVICE        = 49, // 2, flash device ID
+    Q_DEV_BLOCKS        = 50, // 2, number of FFS blocks in device
+    Q_DEV_ATOMSIZE      = 51, // 2, atomsize used by FFS for this device
+    Q_DEV_DRIVER        = 52, // 2, flash device driver
+
+    // All queries below here are for debug purpose only, are unsupported
+    // and can change at any time without notice!
+
+    // Miscellaneous/Internal
+    Q_BLOCKS_FREE_MIN   = 64, // 2, Number of spare blocks (0 or 1)
+
+    Q_BLOCKS_FREE       = 70, // 2, number of free blocks
+
+    // Debug queries
+    Q_FS_FLAGS          = 80,
+    Q_FS_INODES         = 81,
+    Q_FS_ROOT           = 82,
+
+    Q_OBJECTS_TOTAL     = 90, // 2, Accumulated number of valid objects
+    Q_TOTAL_OBJECTS     = 90, // 2, DEPRECATED: old name for Q_OBJECTS_TOTAL
+
+    Q_STATS_FIRST             = 100,
+    Q_STATS_DRECLAIMS         = 100,
+    Q_STATS_IRECLAIMS         = 101,
+    Q_STATS_BRECLAIMS         = 102,
+    Q_STATS_DATA_RECLAIMED    = 103,
+    Q_STATS_INODES_RECLAIMED  = 104,
+    Q_STATS_DATA_ALLOCATED    = 105,
+
+    Q_REQUEST_ID_LAST         = 110,
+
+    Q_DEBUG_FIRST             = 120,
+    Q_DEBUG_0                 = 120,
+    Q_DEBUG_1                 = 121,
+    Q_DEBUG_2                 = 122,
+    Q_DEBUG_3                 = 123,
+    Q_DEBUG_LAST              = 127,
+
+    // individual lines of the bstat array can be returned by the following
+    // id plus the bstat index of the line wanted.
+    Q_BSTAT                   = -128
+};
+
+
+/******************************************************************************
+ * Function prototypes
+ ******************************************************************************/
+
+// Call-back function prototypes
+T_FFS_REQ_ID ffs_fcreate_nb(const char *name, void *addr, T_FFS_SIZE size,
+                         T_RV_RETURN *cp);
+T_FFS_REQ_ID ffs_fupdate_nb(const char *name, void *addr, T_FFS_SIZE size,
+                         T_RV_RETURN *cp);
+T_FFS_REQ_ID ffs_fwrite_nb(const char *name, void *addr, T_FFS_SIZE size,
+                        T_RV_RETURN *cp);
+T_FFS_REQ_ID ffs_file_write_nb(const char *name, void *addr, T_FFS_SIZE size,
+                            T_FFS_OPEN_FLAGS flags, T_RV_RETURN *cp);
+
+T_FFS_REQ_ID ffs_mkdir_nb(const char *name, T_RV_RETURN *cp);
+T_FFS_REQ_ID ffs_symlink_nb(const char *name, const char *actualpath, 
+                            T_RV_RETURN *cp);
+
+T_FFS_REQ_ID ffs_remove_nb(const char *namestruct, T_RV_RETURN *cp);
+T_FFS_REQ_ID ffs_fcontrol_nb(const char *pathname, INT8 action, int param, 
+                             T_RV_RETURN *cp);
+
+T_FFS_REQ_ID ffs_rename_nb(const char *oldname, const char *newname,
+                           T_RV_RETURN *cp);
+T_FFS_REQ_ID ffs_preformat_nb(UINT16 magic, T_RV_RETURN *cp);
+T_FFS_REQ_ID ffs_format_nb(const char *name, UINT16 magic, T_RV_RETURN *cp);
+
+T_FFS_REQ_ID  ffs_open_nb(const char *name, T_FFS_OPEN_FLAGS option, 
+                          T_RV_RETURN *cp);
+T_FFS_REQ_ID ffs_close_nb(T_FFS_FD fdi, T_RV_RETURN *cp);
+T_FFS_REQ_ID ffs_write_nb(T_FFS_FD fdi, void *src, T_FFS_SIZE size, 
+                          T_RV_RETURN *cp);
+T_FFS_REQ_ID ffs_seek_nb(T_FFS_FD fdi, T_FFS_SIZE offset, T_FFS_WHENCE whence
+                         , T_RV_RETURN *cp); 
+T_FFS_REQ_ID ffs_truncate_nb(const char *path, T_FFS_OFFSET length, 
+                             T_RV_RETURN *cp); 
+T_FFS_REQ_ID ffs_ftruncate_nb(T_FFS_FD fdi, T_FFS_OFFSET length, 
+                              T_RV_RETURN *cp);
+T_FFS_REQ_ID ffs_fdatasync_nb(T_FFS_FD fdi, T_RV_RETURN *cp); 
+
+// No-call-back function prototypes
+T_FFS_RET ffs_fcreate(const char *name, void *addr, T_FFS_SIZE size);
+T_FFS_RET ffs_fupdate(const char *name, void *addr, T_FFS_SIZE size);
+T_FFS_RET ffs_fwrite(const char *name, void *addr, T_FFS_SIZE size);
+T_FFS_RET ffs_file_write(const char *name, void *addr, T_FFS_SIZE size, 
+                         T_FFS_OPEN_FLAGS flags);
+T_FFS_SIZE ffs_fread(const char *name, void *addr, T_FFS_SIZE size);
+T_FFS_SIZE ffs_file_read(const char *name, void *addr, T_FFS_SIZE size);
+
+T_FFS_RET ffs_mkdir(const char *name);
+T_FFS_SIZE ffs_opendir(const char *name, T_FFS_DIR *dir);
+T_FFS_SIZE ffs_readdir (T_FFS_DIR *dir, char *name, T_FFS_SIZE size);
+
+T_FFS_RET ffs_symlink(const char *name, const char *actualpath);
+T_FFS_SIZE ffs_readlink(const char *name, char *addr, T_FFS_SIZE size);
+
+T_FFS_RET ffs_stat(const char *name, T_FFS_STAT *stat);
+T_FFS_RET ffs_linkstat(const char *name, T_FFS_STAT *stat);
+T_FFS_RET ffs_lstat(const char *name, T_FFS_STAT *stat);
+T_FFS_RET ffs_xlstat(const char *name, T_FFS_XSTAT *stat);
+T_FFS_RET ffs_fstat(T_FFS_FD fdi, T_FFS_STAT *stat);
+
+T_FFS_RET ffs_remove(const char *name);
+T_FFS_RET ffs_fcontrol(const char *pathname, INT8 action, int param);
+
+
+T_FFS_RET ffs_rename(const char *oldname, const char *newname);
+
+T_FFS_RET ffs_query(INT8 query, void *p);
+
+T_FFS_RET ffs_preformat(UINT16 magic);
+T_FFS_RET ffs_format(const char *name, UINT16 magic);
+
+T_FFS_FD  ffs_open(const char *name, T_FFS_OPEN_FLAGS option);
+T_FFS_RET ffs_close(T_FFS_FD fdi);
+T_FFS_SIZE ffs_write(T_FFS_FD fdi, void *src, T_FFS_SIZE amount);
+T_FFS_SIZE ffs_seek(T_FFS_FD fdi, T_FFS_SIZE offset, T_FFS_WHENCE whence);
+T_FFS_SIZE ffs_read(T_FFS_FD fdi, void *src, T_FFS_SIZE size);
+
+T_FFS_RET ffs_truncate(const char *path, T_FFS_OFFSET length); 
+
+T_FFS_RET ffs_ftruncate(T_FFS_FD fdi, T_FFS_OFFSET length); 
+
+T_FFS_RET ffs_fdatasync(T_FFS_FD fdi); 
+
+// This function is to be implemented by user. It is defined in cfgffs.c.
+extern T_FFS_RET ffs_is_modifiable(const char *name);
+
+#endif //_FFS_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/services/ffs/ffs_api.h	Thu Dec 26 03:59:59 2013 +0000
@@ -0,0 +1,28 @@
+/****************************************************************************/
+/*                                                                          */
+/*  File Name:  ffs_api.h                                                   */
+/*                                                                          */
+/*                                                                          */
+/*  Version   0.1                                                           */
+/*                                                                          */
+/*  Date                Modification                                        */
+/*  ------------------------------------                                    */
+/*  28 January   2002   Create                                              */
+/*                                                                          */
+/*  Author       Stephanie Gerthoux                                         */
+/*                                                                          */
+/* (C) Copyright 2002 by Texas Instruments Incorporated, All Rights Reserved*/
+/****************************************************************************/
+
+#ifndef _FFS_API_H_
+#define _FFS_API_H_
+
+#include "ffs.h"
+
+/******************************************************************************
+    * Types
+ ******************************************************************************/
+
+   #define FFS_OBJECT_TYPE   T_FFS_OBJECT_TYPE      
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/services/ffs/ffs_env.h	Thu Dec 26 03:59:59 2013 +0000
@@ -0,0 +1,58 @@
+/****************************************************************************/
+/*                                                                          */
+/*  File Name:	ffs_env.h						    */
+/*                                                                          */
+/*  Purpose:	This file contains prototypes for RV manager related	    */
+/*		functions used to get info, start and stop the ffs block.   */
+/*                                                                          */
+/*  Version	0.1							    */
+/*									    */
+/*  Date       	Modification						    */
+/*  ------------------------------------				    */
+/*  10/24/2000	Create							    */
+/*									    */
+/*  Author	Pascal Puel						    */
+/*									    */
+/*  This code is in the public domain per the order of the Supreme	    */
+/*  Revolutionary Command.						    */
+/****************************************************************************/
+#ifndef __FFS_ENV_H_
+#define __FFS_ENV_H_
+
+
+#include "../../riviera/rvm/rvm_gen.h"
+#include "ffs_pool_size.h"	/* Stack & Memory Bank sizes definitions */
+
+
+/* FFS mailbox */
+#define FFS_MAILBOX	RVF_TASK_MBOX_0
+
+/* min mem size: fd_max * fd_buf_size + 1k */
+/* memory bank size and watermark */	
+#define FFS_MB_PRIM_SIZE      FFS_MB1_SIZE
+
+#define FFS_MB_PRIM_WATERMARK (FFS_MB_PRIM_SIZE - 3000)
+
+
+typedef struct {
+	T_RVF_MB_ID	mbid;
+	T_RVF_ADDR_ID   addr_id;
+} T_FFS_TASK_INFO;
+
+extern T_FFS_TASK_INFO ffs_task_info;
+
+/* generic functions declarations */
+T_RVM_RETURN ffs_get_info (T_RVM_INFO_SWE  *infoSWE);
+T_RVM_RETURN ffs_set_info(T_RVF_ADDR_ID  addr_id,
+			  T_RV_RETURN		ReturnPath[],
+			  T_RVF_MB_ID mbId[],
+			  T_RVM_RETURN (*callBackFct)(T_RVM_NAME SWEntName,
+						T_RVM_RETURN errorCause,
+						T_RVM_ERROR_TYPE errorType,
+						T_RVM_STRING errorMsg));
+T_RVM_RETURN ffs_init (void);
+T_RVM_RETURN ffs_start (void);
+T_RVM_RETURN ffs_stop (void);
+T_RVM_RETURN ffs_kill (void);
+
+#endif /*__FFS_ENV_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/services/ffs/ffs_pool_size.h	Thu Dec 26 03:59:59 2013 +0000
@@ -0,0 +1,52 @@
+/**
+ * @file	ffs_pool_size.h
+ *
+ * Declarations of:
+ * - the memory bank sizes and their watermark
+ * - the SWE stack size
+ * - the pool size needed (generally the sum of memory bank and stack sizes)
+ *
+ * @author	Vincent Oberle
+ * @version 0.1
+ */
+
+/*
+ * History:
+ *
+ *  Date       	Author			Modification
+ *  -------------------------------------------------------------------
+ *  07/08/2003	Vincent Oberle		Extracted from rvf_pool_size.h
+ *  09/03/2004  Tommy Jensen            Split pool size into several defines
+ *
+ * This code is in the public domain per the order of the
+ * Supreme Revolutionary Command.
+ */
+
+#ifndef __FFS_POOL_SIZE_H_
+#define __FFS_POOL_SIZE_H_
+
+#include "../../include/config.h"
+#include "../../riviera/rv/rv_defined_swe.h"
+
+/*
+ * Values used in ffs_env.h
+ */
+#define FFS_STACK_SIZE   (1024)
+#define FFS_MAILBUF_SIZE (1024)      // Default: Max 20 pending FFS mails.
+#define FFS_TESTBUF_SIZE (0)         // Must be set to zero
+
+#if (!GSMLITE)
+#ifdef RVM_MSFE_SWE
+   #define FFS_STREAMBUF_SIZE (40960)
+#else
+   #define FFS_STREAMBUF_SIZE (8192)
+#endif // RVM_MSFE_SWE
+#else 
+   #define FFS_STREAMBUF_SIZE (4096)
+#endif // GSMLITE
+
+#define FFS_MB1_SIZE (FFS_STREAMBUF_SIZE + FFS_MAILBUF_SIZE + FFS_TESTBUF_SIZE)
+#define FFS_POOL_SIZE  (FFS_STACK_SIZE + FFS_MB1_SIZE)
+
+
+#endif /*__FFS_POOL_SIZE_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/services/ffs/ffstrace.h	Thu Dec 26 03:59:59 2013 +0000
@@ -0,0 +1,154 @@
+/******************************************************************************
+ * Flash File System (ffs)
+ * Idea, design and coding by Mads Meisner-Jensen, mmj@ti.com
+ *
+ * ffs tracing
+ *
+ * $Id: ffstrace.h 1.38.1.4 Wed, 14 Aug 2002 13:02:34 +0200 tsj $
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ ** Common Tracing and logging
+ *****************************************************************************/
+
+int tr_query(int mask);
+
+
+/******************************************************************************
+ ** Target Tracing
+ ******************************************************************************/
+
+#if (TARGET == 1)
+
+#define tw(contents)
+#define ttw(contents) contents
+#define tlw(contents)
+#define NL
+void ttr_init(unsigned int mask);
+void ttr(unsigned trmask, char *format, ...);
+void str(unsigned mask, char *string);
+
+void led_config(unsigned char n);
+void led_set(unsigned char n);
+void led_counter(unsigned char n);
+void led_on(unsigned char n);
+void led_off(unsigned char n);
+void led_toggle(unsigned char n);
+
+enum TargetTraceMask {
+    TTrTest       = 0x00000001,
+    TTrTestInfo   = 0x00000002,
+
+    TTrApi        = 0x00000010,
+    TTrDrvWrite   = 0x00000020,
+    TTrDrvErase   = 0x00000040,
+    TTrDrvOther   = 0x00000080,
+
+    TTrInit       = 0x00000100,
+    TTrInitLow    = 0x00000200,
+    TTrFormat     = 0x00000400,
+
+    TTrObj        = 0x00001000,
+    TTrInode      = 0x00002000,
+    TTrData       = 0x00004000,
+    TTrMisc       = 0x00008000,
+
+    TTrRec        = 0x00020000,
+    TTrPcmRead    = 0x00040000,
+    TTrPcmWrite   = 0x00080000,
+
+    TTrTask       = 0x00100000,
+    TTrTaskLow    = 0x00200000,
+    TTrBstat      = 0x00400000,
+
+    TTrTmffs      = 0x08000000,
+
+    TTrTaskDelays = 0x10000000,
+    TTrFatal      = 0x80000000,
+
+    TTrAll        = 0xFFFFFFFF
+};
+
+enum {
+    LED_INIT          = 0,
+    LED_DRV_INIT      = 1,
+    LED_BLOCKS_FSCK   = 2,
+    LED_INODES_FSCK   = 3,
+    LED_WRITE_SUSPEND = 4,
+    LED_WRITE         = 5,
+    LED_ERASE_SUSPEND = 6,
+    LED_ERASE         = 7
+};
+
+
+/******************************************************************************
+ ** PC Tracing
+ ******************************************************************************/
+
+#else // (TARGET == 1)
+
+void tr_init(unsigned int mask, int spaces, char *filename);
+void tr(int type, unsigned int mask, char *format, ...);
+
+
+//void tr_init(int mask, int level,int spaces, char *filename);
+//void tr(int level, int type, char *format, ...);
+#define tw(contents) contents
+#define ttw(contents)
+#define tlw(contents)
+
+#define led_config(n)
+#define led_set(n)
+#define led_counter(n)
+#define led_on(n)
+#define led_off(n)
+
+enum SimulationTraceMask {
+    TrTest       = 0x00000001,
+    TrTestHigh   = 0x00000002,
+    TrTestLow    = 0x00000004,
+    TrApi        = 0x00000008,
+
+    TrBstat      = 0x00000010,
+    TrFormat     = 0x00000020,
+    TrFsck       = 0x00000040,
+    TrFsckLow    = 0x00000080,
+
+    TrObject     = 0x00000100, // object_create/remove/read/stat, etc.
+    TrLookup     = 0x00000200,
+    TrDirLow     = 0x00000400,
+    TrDirHigh    = 0x00000800,
+
+    TrBlock      = 0x00001000, // block_alloc/free, etc.
+    TrInode      = 0x00002000, // inode_alloc, etc.
+    TrData       = 0x00004000, // data_alloc
+
+    TrIReclaim   = 0x00010000,
+    TrDReclaim   = 0x00020000,
+    TrReclaimLow = 0x00040000,
+    TrJournal    = 0x00080000,
+
+    TrDrvInit    = 0x00100000,
+    TrDrvWrite   = 0x00200000,
+    TrDrvErase   = 0x00400000,
+
+    TrOther      = 0x01000000, // object_control, query, etc.
+    TrUtil       = 0x02000000,
+    TrTmffs      = 0x03000000,
+    TrServer     = 0x08000000,
+
+    TrTrace      = 0x80000000,
+    TrAll        = 0xFFFFFFFF
+};
+
+enum TRACE_TYPES {
+    TR_BEGIN = 0x100,
+    TR_END =   0x200,
+    TR_FUNC =  0x400,
+    TR_NULL =  0x800
+};
+
+
+#endif // (TARGET == 1)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/services/ffs/intctl.h	Thu Dec 26 03:59:59 2013 +0000
@@ -0,0 +1,21 @@
+/*
+ * The int_disable() and int_enable() calls in TI's FFS code are nothing
+ * more than TCT_Control_Interrupts() aka NU_Control_Interrupts().
+ * TI's original code used assembly (proprietary toolchain asm syntax and
+ * ABI semantics) to make the needed Thumb->ARM calls; we don't need such
+ * idiocy in FreeCalypso, so we have turned int_disable() and int_enable()
+ * into simple inline functions.
+ */
+
+#include "ffs.h"
+#include "../../nucleus/nucleus.h"
+
+static inline uint32 int_disable(void)
+{
+	return NU_Control_Interrupts(NU_DISABLE_INTERRUPTS);
+}
+
+static inline void int_enable(uint32 tmp)
+{
+	NU_Control_Interrupts(tmp);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/services/ffs/ramffs.h	Thu Dec 26 03:59:59 2013 +0000
@@ -0,0 +1,16 @@
+/*
+ * This FFS implementation header file is a FreeCalypso addition.
+ * Here we have some preprocessor magic and extern declarations
+ * for the FFS-in-RAM configuration which are needed at both
+ * "flash driver" and "FFS configuration" abstraction levels.
+ */
+
+#include "../../include/config.h"
+#if FFS_IN_RAM
+
+#define	RAMFFS_BLKSIZE_BYTES	(1 << RAMFFS_BLKSIZE_LOG2)
+#define	RAMFFS_TOTAL_SIZE	(RAMFFS_BLKSIZE_BYTES * RAMFFS_NBLOCKS)
+
+extern char _RAMFFS_area[RAMFFS_TOTAL_SIZE];
+
+#endif	/* FFS_IN_RAM */