aboutsummaryrefslogtreecommitdiff
path: root/libflash/libffs.h
blob: 4c74aed80faa7b978e45bb67880ee7f2c07e93eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/* Copyright 2013-2014 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef __LIBFFS_H
#define __LIBFFS_H

#include <libflash/libflash.h>
#include <libflash/blocklevel.h>

/* FFS handle, opaque */
struct ffs_handle;
struct ffs_hdr;
struct ffs_entry;
struct ffs_entry_user;

/**
 * struct ffs_entry_user - User data entries
 *
 * Usable in memory representation of a struct __ffs_entry_user
 *
 *  @chip:		Chip Select (0,1)
 *  @compressType:	Compression Indication/alg (0=not compressed)
 *  @dataInteg:		Indicates Data Integrity mechanism
 *  @verCheck:		Indicates Version check type
 *  @miscFlags:		Misc Partition related Flags
 */
struct ffs_entry_user {
	uint8_t chip;
	uint8_t compresstype;
	uint16_t datainteg;
	uint8_t vercheck;
	uint8_t miscflags;
};

/* Error codes:
 *
 * < 0 = flash controller errors
 *   0 = success
 * > 0 = libffs / libflash errors
 */
#define FFS_ERR_BAD_MAGIC	100
#define FFS_ERR_BAD_VERSION	101
#define FFS_ERR_BAD_CKSUM	102
#define FFS_ERR_PART_NOT_FOUND	103
#define FFS_ERR_BAD_ECC		104
#define FFS_ERR_BAD_SIZE	105
#define FFS_ERR_BAD_PART_NAME	106
#define FFS_ERR_BAD_PART_BASE	107
#define FFS_ERR_BAD_PART_SIZE	108
#define FFS_ERR_BAD_PART_PID	109

/* The maximum length of the partition name */
#define FFS_PART_NAME_MAX   15
/* Old version of the name DEPRECATED */
#define PART_NAME_MAX   15

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

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

/*
 * User verCheck definitions
 */
#define FFS_VERCHECK_SHA512V 0x80
#define FFS_VERCHECK_SHA512EC 0x40

/*
 * User miscFlags
 */
#define FFS_MISCFLAGS_PRESERVED 0x80
#define FFS_MISCFLAGS_READONLY 0x40
#define FFS_MISCFLAGS_BACKUP 0x20
#define FFS_MISCFLAGS_REPROVISION 0x10
#define FFS_MISCFLAGS_VOLATILE 0x08
#define FFS_MISCFLAGS_CLEARECC 0x04
#define FFS_MISCFLAGS_GOLDEN 0x01


int ffs_string_to_entry_user(const char *flags, int nflags,
		struct ffs_entry_user *user);
char *ffs_entry_user_to_string(struct ffs_entry_user *user);

bool has_ecc(struct ffs_entry *ent);

bool has_flag(struct ffs_entry *ent, uint16_t flag);

/* Init */

int ffs_init(uint32_t offset, uint32_t max_size, struct blocklevel_device *bl,
		struct ffs_handle **ffs, bool mark_ecc);

/*
 * Initialise a new ffs_handle to the "OTHER SIDE".
 * Reuses the underlying blocklevel_device.
 */
int ffs_next_side(struct ffs_handle *ffs, struct ffs_handle **new_ffs,
		bool mark_ecc);

/*
 * There are quite a few ways one might consider two ffs_handles to be the
 * same. For the purposes of this function we are trying to detect a fairly
 * specific scenario:
 * Consecutive calls to ffs_next_side() may succeed but have gone circular.
 * It is possible that the OTHER_SIDE partition in one TOC actually points
 * back to the TOC of the first ffs_handle.
 * This function compares for this case, therefore the requirements are
 * simple, the underlying blocklevel_devices must be the same along with
 * the toc_offset and the max_size.
 */
bool ffs_equal(struct ffs_handle *one, struct ffs_handle *two);

void ffs_close(struct ffs_handle *ffs);

int ffs_lookup_part(struct ffs_handle *ffs, const char *name,
		    uint32_t *part_idx);

int ffs_part_info(struct ffs_handle *ffs, uint32_t part_idx,
		  char **name, uint32_t *start,
		  uint32_t *total_size, uint32_t *act_size, bool *ecc);

struct ffs_entry *ffs_entry_get(struct ffs_handle *ffs, uint32_t index);

int ffs_update_act_size(struct ffs_handle *ffs, uint32_t part_idx,
			uint32_t act_size);

int ffs_hdr_new(uint32_t block_size, uint32_t block_count,
		struct ffs_hdr **r);

int ffs_hdr_add_side(struct ffs_hdr *hdr);

int ffs_entry_new(const char *name, uint32_t base, uint32_t size, struct ffs_entry **r);

int ffs_entry_user_set(struct ffs_entry *ent, struct ffs_entry_user *user);

int ffs_entry_set_act_size(struct ffs_entry *ent, uint32_t actual_size);

int ffs_entry_add(struct ffs_hdr *hdr, struct ffs_entry *entry, unsigned int side);

struct ffs_entry_user ffs_entry_user_get(struct ffs_entry *ent);

int ffs_hdr_create_backup(struct ffs_hdr *hdr);

int ffs_hdr_finalise(struct blocklevel_device *bl, struct ffs_hdr *hdr);

int ffs_hdr_free(struct ffs_hdr *hdr);
#endif /* __LIBFFS_H */