Skip to content

Commit

Permalink
libflash/libffs: Rework libffs
Browse files Browse the repository at this point in the history
This patch attempts a rework of libffs to prepare it for future changes.

Firstly the types are split in two:
  1. Packed, big endian structures used to map exactly how the data is on flash.
  2. CPU endian, sane valued, not packed structures used to manipulate FFS data.

Secondly:
The packed struct can use BE types so that in future tools like sparse can be
run over the code to check for endian conversion bugs.

Thirdly:
defines of sizeof(struct ...) were removed for clarity.

Finally:
For ease of manipulation, the in memory FFS structures contain a linked list of
entries as this will make addition and removal operations much easier.

This patch should be invisible to consumers of libffs.

Signed-off-by: Cyril Bur <cyril.bur@au1.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
  • Loading branch information
cyrilbur-ibm authored and stewartsmith committed Mar 24, 2017
1 parent 9ffbfe2 commit 602dee4
Show file tree
Hide file tree
Showing 3 changed files with 368 additions and 200 deletions.
155 changes: 98 additions & 57 deletions libflash/ffs.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,56 +25,39 @@
#define __FFS_H__

/* Pull in the correct header depending on what is being built */
#if defined(__KERNEL__)
#ifndef __SKIBOOT__
#include <linux/types.h>
#else
#include <stdint.h>
#endif
#include <ccan/short_types/short_types.h>
#include <ccan/endian/endian.h>
#include <ccan/list/list.h>

#include "libffs.h"

/* The version of this partition implementation */
#define FFS_VERSION_1 1

/* Magic number for the partition header (ASCII 'PART') */
#define FFS_MAGIC 0x50415254

/* The maximum length of the partition name */
#define PART_NAME_MAX 15

/*
* Sizes of the data structures
*/
#define FFS_HDR_SIZE sizeof(struct ffs_hdr)
#define FFS_ENTRY_SIZE sizeof(struct ffs_entry)

/*
* Sizes of the data structures w/o checksum
*/
#define FFS_HDR_SIZE_CSUM (FFS_HDR_SIZE - sizeof(uint32_t))
#define FFS_ENTRY_SIZE_CSUM (FFS_ENTRY_SIZE - sizeof(uint32_t))

/* pid of logical partitions/containers */
#define FFS_PID_TOPLEVEL 0xFFFFFFFF

/*
* Type of image contained w/in partition
*/
enum type {
enum ffs_type {
FFS_TYPE_DATA = 1,
FFS_TYPE_LOGICAL = 2,
FFS_TYPE_PARTITION = 3,
};

/*
* Flag bit definitions
*/
#define FFS_FLAGS_PROTECTED 0x0001
#define FFS_FLAGS_U_BOOT_ENV 0x0002

/* Data integrity flags */
#define FFS_ENRY_INTEG_ECC 0x8000

/**
* struct ffs_entry_user - User data enties
* struct __ffs_entry_user - On flash user data entries
*
* Represents the on flash layout of FFS structures
*
* @chip: Chip Select (0,1)
* @compressType: Compression Indication/alg (0=not compressed)
Expand All @@ -84,18 +67,22 @@ enum type {
* @freeMisc[2]: Unused Miscellaneious Info
* @freeUser[14]: Unused User Data
*/
struct ffs_entry_user {
uint8_t chip;
uint8_t compresstype;
uint16_t datainteg;
uint8_t vercheck;
uint8_t miscflags;
uint8_t freemisc[2];
uint32_t reserved[14];
};
struct __ffs_entry_user {
uint8_t chip;
uint8_t compresstype;
be16 datainteg;
uint8_t vercheck;
uint8_t miscflags;
uint8_t freemisc[2];
be32 reserved[14];
} __attribute__ ((packed));

/**
* struct ffs_entry - Partition entry
* struct __ffs_entry - On flash partition entry
*
* Represents the on flash layout of FFS structures
* Note: Unlike the in memory structures base and size of the entry are in
* units of block_size and the actual size is in bytes
*
* @name: Opaque null terminated string
* @base: Starting offset of partition in flash (in hdr.block_size)
Expand All @@ -109,22 +96,54 @@ struct ffs_entry_user {
* @user: User data (optional)
* @checksum: Partition entry checksum (includes all above)
*/
struct __ffs_entry {
char name[FFS_PART_NAME_MAX + 1];
be32 base;
be32 size;
be32 pid;
be32 id;
be32 type;
be32 flags;
be32 actual;
be32 resvd[4];
struct __ffs_entry_user user;
/* The checksum is actually endian agnostic */
uint32_t checksum;
} __attribute__ ((packed));

/**
* struct ffs_entry - Partition entry
*
* Useable in memory representation of a struct __ffs_entry
* Note: Unlike the on flash structure, all sizes here are in bytes!
*
* @name: Opaque null terminated string
* @base: Starting offset of partition in flash (in bytes)
* @size: Partition size (in bytes)
* @actual: Actual partition size (in bytes)
* @pid: Parent partition entry (FFS_PID_TOPLEVEL for toplevel)
* @type: Describe type of partition
* @flags: Partition attributes (optional)
* @user: User data (optional)
*/
struct ffs_entry {
char name[PART_NAME_MAX + 1];
char name[FFS_PART_NAME_MAX + 1];
uint32_t base;
uint32_t size;
uint32_t actual;
uint32_t pid;
uint32_t id;
uint32_t type;
enum ffs_type type;
uint32_t flags;
uint32_t actual;
uint32_t resvd[4];
struct ffs_entry_user user;
uint32_t checksum;
} __attribute__ ((packed));
struct list_node list;
};


/**
* struct ffs_hdr - FSP Flash Structure header
* struct __ffs_hdr - On flash FSP Flash Structure header
*
* Represents the on flash layout of FFS structures
* Note: Beware that the size of the partition table is in units of block_size
*
* @magic: Eye catcher/corruption detector
* @version: Version of the structure
Expand All @@ -133,22 +152,44 @@ struct ffs_entry {
* @entry_count: Number of struct ffs_entry elements in @entries array
* @block_size: Size of block on device (in bytes)
* @block_count: Number of blocks on device
* @resvd: Reserved words for future use
* @resvd[4]: Reserved words for future use
* @checksum: Header checksum
* @entries: Pointer to array of partition entries
*/
struct ffs_hdr {
uint32_t magic;
uint32_t version;
uint32_t size;
uint32_t entry_size;
uint32_t entry_count;
uint32_t block_size;
uint32_t block_count;
uint32_t resvd[4];
uint32_t checksum;
struct ffs_entry entries[];
struct __ffs_hdr {
be32 magic;
be32 version;
be32 size;
be32 entry_size;
be32 entry_count;
be32 block_size;
be32 block_count;
be32 resvd[4];
/* The checksum is actually endian agnostic */
uint32_t checksum;
struct __ffs_entry entries[];
} __attribute__ ((packed));

/**
* struct ffs_hdr - FSP Flash Structure header
*
* Useable in memory representation of a struct __ffs_hdr
* Note: All sizes here are in bytes
*
* @version: Version of the structure
* @size: Size of partition table (in bytes)
* @block_size: Size of block on device (in bytes)
* @block_count: Number of blocks on device.
* @backup The backup partition
* @side The ffs header for the other side
* @entries: List of partition entries
*/
struct ffs_hdr {
uint32_t version;
uint32_t size;
uint32_t block_size;
uint32_t block_count;
struct list_head entries;
};

#endif /* __FFS_H__ */

0 comments on commit 602dee4

Please sign in to comment.