]> rtime.felk.cvut.cz Git - lincan.git/blob - embedded/libs4c/keyval/keyvalpb.h
Embedded code-base updated to actual version from uLan repository.
[lincan.git] / embedded / libs4c / keyval / keyvalpb.h
1 /*******************************************************************
2   Key Value Persistent Storage
3
4   keyvalpb.h    - key value parameters block
5
6   (C) Copyright 2003-2005 by Pavel Pisa - Originator
7   (C) Copyright 2004-2005 by Petr Smolik - Originator
8
9   The uLan utilities library can be used, copied and modified under
10   next licenses
11     - GPL - GNU General Public License
12     - LGPL - GNU Lesser General Public License
13     - MPL - Mozilla Public License
14     - and other licenses added by project originators
15   Code can be modified and re-distributed under any combination
16   of the above listed licenses. If contributor does not agree with
17   some of the licenses, he/she can delete appropriate line.
18   Warning, if you delete all lines, you are not allowed to
19   distribute source code and/or binaries utilizing code.
20
21   See files COPYING and README for details.
22
23  *******************************************************************/
24
25 #ifndef _KEYVALPB_H_
26 #define _KEYVALPB_H_
27
28 //#include <inttypes.h>
29 #include <types.h>
30 #include <system_def.h>
31 #include <cpu_def.h>
32
33 #ifdef  KVPB_MINIMALIZED
34 #define KVPB_WITHOUT_HADLE
35 #define KVPB_DPTRTYPE  CODE
36 #define KVPB_LOCALDATA DATA
37 #endif  /*KVPB_MINIMALIZED*/
38
39 #ifndef KVPB_DPTRTYPE
40 #define KVPB_DPTRTYPE
41 #endif  /*KVPB_DPTRTYPE*/
42
43 #ifndef KVPB_LOCALDATA
44 #define KVPB_LOCALDATA
45 #endif  /*KVPB_DPTRTYPE*/
46
47 #ifndef KVPB_BLOCK_LOC
48 #define KVPB_BLOCK_LOC
49 #endif  /*KVPB_BLOCK_LOC*/
50
51 #define KVPB_EMPTY         ((kvpb_size_t)~0)
52
53 #define KVPB_KEYID_INVALID      0
54 #define KVPB_KEYID_DUPLIC       ((((kvpb_keyid_t)~0)>>1)+1)
55 #define KBPB_KEYID_INVALID_BIT  (KVPB_KEYID_DUPLIC>>1)
56
57 #define KVPB_SUM_MASK      (((kvpb_sum_t)~0)>>2)
58 #define KVPB_SUM_OKVAL     (KVPB_SUM_MASK+1)
59
60 #define KVPB_DESC_DOUBLE  0x01
61 #define KVPB_DESC_USE2ND  0x02
62 #define KVPB_DESC_VALID   0x04
63 #define KVPB_DESC_RO      0x08
64 #define KVPB_DESC_CHUNKWO 0x10
65 #define KVPB_DESC_ALIGN4  0x40
66 #define KVPB_DESC_FLASH   0x80
67
68 #ifdef  KVPB_MINIMALIZED
69 typedef uint16_t kvpb_sum_t;
70 typedef uint16_t kvpb_size_t;
71 typedef uint8_t kvpb_keyid_t;
72 #else  /*KVPB_MINIMALIZED*/
73 typedef uint32_t kvpb_sum_t;
74 typedef uint32_t kvpb_size_t;
75 typedef uint32_t kvpb_keyid_t;
76 #endif  /*KVPB_MINIMALIZED*/
77
78 /**
79  * struct kvpb_block - Key-value parameter block access information
80  * @base: Pointer to the start of physically mapped key-value block data
81  * @size: Size of one region (one data copy) of parameter block
82  * @flags: Block state flags:
83  *      %KVPB_DESC_DOUBLE - the information is stored in two consecutive redundant copies/regions;
84  *      %KVPB_DESC_USE2ND - data will be read from the second copy because first one is damaged;
85  *      %KVPB_DESC_VALID - at least one region is valid;
86  *      %KVPB_DESC_RO - because of some problems, only read access is allowed
87  *      %KVPB_DESC_CHUNKWO - chunk can be written only once between erase operations
88  *      %KVPB_DESC_ALIGN4 - data has to be aligned to four bytes
89  *      %KVPB_DESC_FLASH - flash memory is used for data storage
90  * @psum1: Pointer to the control checksum of the first data region
91  * @psum2: Pointer to the control checksum of the second data region
92  * @erase: Function to erase some range of the storage region
93  * @copy: Function to copy data into or between storage regions
94  * @flush: Function to finish pending copy operations
95  * @chunk_size: Minimal store chunk size which can be independently modified
96  *
97  * File: keyvalpb.h
98  */
99 typedef struct kvpb_block {
100   KVPB_DPTRTYPE uint8_t *base;
101   kvpb_size_t size;
102   short flags;
103   KVPB_DPTRTYPE kvpb_sum_t *psum1;
104   KVPB_DPTRTYPE kvpb_sum_t *psum2;
105  #ifndef  KVPB_MINIMALIZED
106   int (*erase)(struct kvpb_block *store, void *base,int size);
107   int (*copy)(struct kvpb_block *store, void *des,const void *src,int len);
108   int (*flush)(struct kvpb_block *store);
109   unsigned chunk_size;
110  #endif  /* KVPB_MINIMALIZED */
111 } kvpb_block_t;
112
113
114 #define kvpb_region_base(block,regidx) \
115         ((((KVPB_DPTRTYPE uint8_t *)(block)->base)+(regidx*(block)->size)))
116
117 #ifndef  KVPB_MINIMALIZED
118  #ifndef kvpb_chunk_size
119    #define kvpb_chunk_size(store) ((store)->chunk_size<4?4:(store)->chunk_size)
120  #endif /*kvpb_chunk_size*/
121  #define kvpb_chunk_size_mask(store) (kvpb_chunk_size(store)-1)
122
123 /**
124  * kvpb_chunk_align - Round up KVPB size to minimal store chunk size multiple
125  * @store: Pointer to the KVPB access information/state structure
126  * @size: Unaligned size
127  *
128  * Return Value: Minimal aligned size to hold unaligned size.
129  * File: keyvalpb.h
130  */
131  static inline unsigned kvpb_chunk_align(struct kvpb_block *store, unsigned size)
132  {
133    return ((size)+kvpb_chunk_size_mask(store))&~kvpb_chunk_size_mask(store);
134  }
135
136 /**
137  * kvpb_psum_align - Round up KVPB size to minimal store chunk size multiple
138  * @store: Pointer to the KVPB access information/state structure
139  * @psum: Pointer to proposed location of next check sum location
140  *
141  * Return Value: Pointer to next check sum location rounded down to next slot.
142  * File: keyvalpb.h
143  */
144  static inline kvpb_sum_t* kvpb_psum_align(struct kvpb_block *store, kvpb_sum_t *psum)
145  {
146    unsigned long mask=~kvpb_chunk_size_mask(store);
147    if(store->flags&KVPB_DESC_CHUNKWO)
148      mask<<=1;
149    return (kvpb_sum_t*)(((unsigned long)(psum))&mask);
150  }
151
152 /**
153  * kvpb_psum_valid_loc - Return pointer to check sum validity info location
154  * @store: Pointer to the KVPB access information/state structure
155  * @psum: Pointer to corectly aligned check sum location
156  *
157  * Return Value: Pointer to location which indicates by zero value, that check sum
158  *               is invalidated.
159  * File: keyvalpb.h
160  */
161  static inline kvpb_sum_t* kvpb_psum_valid_loc(struct kvpb_block *store, kvpb_sum_t *psum)
162  {
163    if(!(store->flags&KVPB_DESC_CHUNKWO))
164      return psum;
165    else
166      return (kvpb_sum_t*)(((char *)(psum))+kvpb_chunk_size(store));
167  }
168
169 /**
170  * kvpb_block_erase - Wrapper function to call KVPB specific data erase function
171  * @store: Pointer to the KVPB access information/state structure
172  * @base: Base address of erased region inside parameter block data region
173  * @size: Number of bytes to erase
174  *
175  * The KVPB mechanism is intended for FLASH type memories and it expect
176  * that only whole data region can be erased at time. The expected erase state
177  * is all bits set to the ones.
178  *
179  * Return Value: Negative value indicates operation fault.
180  * File: keyvalpb.h
181  */
182  static inline int kvpb_block_erase(struct kvpb_block *store, void *base,int size)
183  {
184    return store->erase(store, base,size) ;
185  }
186
187 /**
188  * kvpb_block_copy - Wrapper function to call KVPB specific data copy function
189  * @store: Pointer to the KVPB access information/state structure
190  * @des: Address of data destination pointing inside mapped parameter block data region
191  * @src: Address of data source pointing inside mapped parameter block data or RAM memory
192  * @len: Number of bytes to transfer
193  *
194  * Return Value: Negative value indicates operation fault.
195  * File: keyvalpb.h
196  */
197  static inline int kvpb_block_copy(struct kvpb_block *store, void *des,const void *src,int len)
198  {
199    return store->copy(store, des, src, len);
200  }
201
202 /**
203  * kvpb_block_flush - Wrapper function to call KVPB specific flush function
204  * @store: Pointer to the KVPB access information/state structure
205  *
206  * Return Value: Negative value indicates operation fault.
207  * File: keyvalpb.h
208  */
209  static inline int kvpb_block_flush(struct kvpb_block *store)
210  {
211    if(!(store->flush)) return 0;
212    return store->flush(store);
213  }
214
215 #else /* KVPB_MINIMALIZED */
216  #ifndef kvpb_chunk_size
217   #define kvpb_chunk_size(store) 1
218  #endif /*kvpb_chunk_size*/
219  #define kvpb_chunk_size_mask(store) (kvpb_chunk_size(store)-1)
220  #define kvpb_chunk_align(store,x) \
221                 (((x)+kvpb_chunk_size_mask(store))&~kvpb_chunk_size_mask(store))
222  #define kvpb_psum_align(store,x) \
223                 ((KVPB_DPTRTYPE kvpb_sum_t*)((unsigned)(x)&~kvpb_chunk_size_mask(store)))
224  #define kvpb_psum_valid_loc(store,x) \
225                 ((kvpb_sum_t*)((char*)(x)+0*kvpb_chunk_size(store)))
226 #ifndef kvpb_block_copy
227  #define kvpb_block_erase(store, base, size) flash_erase(base, size)
228  #define kvpb_block_copy(store, des, src, len) flash_copy(des, src, len)
229  #define kvpb_block_flush(store) flash_flush()
230
231  /* forward declarations for external procedures */
232  int flash_erase(void *base,int size);
233  int flash_copy(void *des,const void *src,int len);
234 #ifndef flash_flush
235  int flash_flush(void);
236 #endif /* flash_flush */
237 #endif /* kvpb_block_copy */
238 #endif /* KVPB_MINIMALIZED */
239
240 /**
241  * struct kvpb_key - Header of stored key value pair and structure for iteration over KVPB
242  * @size: Non-aligned byte size of the stored value
243  * @keyid: Ordinal value representing stored data key
244  *
245  * The header structure is followed by @size data bytes in the KVPB storage block.
246  * Because only word aligned write accesses are possible on some architectures
247  * and memory types the whole size of space occupied by one key-value pair is
248  * sum of rounded-up data size kvpb_chunk_align(@size)  and size of header sizeof(kvpb_key_t).
249  */
250 typedef struct kvpb_key {
251   kvpb_size_t size;
252   kvpb_keyid_t keyid;
253 } kvpb_key_t;
254
255 #ifndef KVPB_WITHOUT_HADLE
256  static inline kvpb_keyid_t* kvpb_keyid_valid(struct kvpb_block *store, kvpb_key_t *key)
257  {
258    if(store->flags&KVPB_DESC_CHUNKWO)
259      return (kvpb_keyid_t*)((uint8_t*)key+(kvpb_chunk_align(store,key->size+sizeof(kvpb_key_t))));
260    return &(key->keyid);
261  }
262 #else
263   #define kvpb_keyid_valid(store,key) (&((key)->keyid))
264 #endif /*KVPB_WITHOUT_HADLE*/
265
266
267 #ifndef KVPB_WITHOUT_HADLE
268 KVPB_DPTRTYPE kvpb_key_t *kvpb_first(kvpb_block_t *block, uint8_t mode);
269 KVPB_DPTRTYPE kvpb_key_t *kvpb_next(kvpb_block_t *block, KVPB_DPTRTYPE kvpb_key_t *key);
270 KVPB_DPTRTYPE kvpb_key_t *kvpb_find(kvpb_block_t *block, kvpb_keyid_t keyid, uint8_t mode, KVPB_DPTRTYPE kvpb_key_t *key);
271 int kvpb_get_key(kvpb_block_t *kvpb_block, kvpb_keyid_t keyid, kvpb_size_t size, void *buf);
272 int kvpb_set_key(kvpb_block_t *kvpb_block, kvpb_keyid_t keyid, kvpb_size_t size, const void *buf);
273 int kvpb_err_keys(kvpb_block_t *kvpb_block, kvpb_keyid_t keyid);
274 int kvpb_check(kvpb_block_t *kvpb_block, uint8_t mode);
275 #else
276 extern KVPB_BLOCK_LOC kvpb_block_t kvpb_block_global;
277 #define kvpb_block (&kvpb_block_global)
278 KVPB_DPTRTYPE kvpb_sum_t *__kvpb_get_psum(KVPB_DPTRTYPE uint8_t *base, kvpb_size_t size);
279 KVPB_DPTRTYPE kvpb_key_t *__kvpb_first(uint8_t mode);
280 KVPB_DPTRTYPE kvpb_key_t *__kvpb_next(KVPB_DPTRTYPE kvpb_key_t *key);
281 KVPB_DPTRTYPE kvpb_key_t *__kvpb_find(kvpb_keyid_t keyid, uint8_t mode, KVPB_DPTRTYPE kvpb_key_t *key);
282 int __kvpb_get_key(kvpb_keyid_t keyid, kvpb_size_t size, void *buf);
283 int __kvpb_set_key(kvpb_keyid_t keyid, kvpb_size_t size, const void *buf);
284 int __kvpb_check(uint8_t mode);
285 #define kvpb_get_psum(block, base, size) __kvpb_get_psum(base, size)
286 #define kvpb_first(block, mode) __kvpb_first(mode)
287 #define kvpb_next(block, key) __kvpb_next(key)
288 #define kvpb_find(block, keyid, mode, key) __kvpb_find(keyid, mode, key)
289 #define kvpb_get_key(block, keyid, size, buf) __kvpb_get_key(keyid, size, buf)
290 #define kvpb_set_key(block, keyid, size, buf) __kvpb_set_key(keyid, size, buf)
291 #define kvpb_err_keys(block,keyid) kvpb_set_key(block,keyid,0,NULL)
292 #define kvpb_check(block, mode) __kvpb_check(mode)
293 #define kvpb_compact_region(block, mode, keyid) __kvpb_compact_region(mode, keyid)
294 #define kvpb_get_cfk(block,mode,size) __kvpb_get_cfk(mode,size)
295 #endif
296
297 /**
298  * kvpb_for_each - Iterate over all key value pairs
299  * @root: Pointer to the KVPB access information/state structure
300  * @key: Iterator of kvpb_key_t* type
301  * @mode: iteration mode modifier: 0 .. iterate over active/valid data region;
302  *      1 .. iterate over first copy, 2 .. iterate over second copy
303  *
304  * File: keyvalpb.h
305  */
306 #define kvpb_for_each(root, key,mode) \
307         for(key=kvpb_first(root,mode);key;\
308             key=kvpb_next(root, key))
309
310 /**
311  * kvpb_for_each - Iterate over all key value pairs matching given key ID
312  * @root: Pointer to the KVPB access information/state structure
313  * @keyid: Ordinal value representing key ID
314  * @key: Iterator of kvpb_key_t* type
315  * @mode: iteration mode modifier: 0 .. iterate over active/valid data region;
316  *      1 .. iterate over first copy, 2 .. iterate over second copy
317  *
318  * File: keyvalpb.h
319  */
320 #define kvpb_each_from(root, keyid, mode, key) \
321         for(key=kvpb_find(root,keyid,mode,NULL);key;\
322             key=kvpb_find(root,keyid,mode,key))
323
324 #ifdef  KVPB_MINIMALIZED
325 #define kvpb_key2data(key) ((void*)(key+1))
326 #else  /*KVPB_MINIMALIZED*/
327 static inline void* kvpb_key2data(kvpb_key_t *key) { return key+1; }
328 #endif  /*KVPB_MINIMALIZED*/
329
330 #endif /* _KEYVALPB_H_ */
331