]> rtime.felk.cvut.cz Git - lincan.git/blob - embedded/libs4c/keyval/keyvalpb.h
Included ARM LPC21xx related code from uLan project. The snapshot date is 2008-07-05
[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) (((block)->base+(regidx*(block)->size)))
115
116 #ifndef  KVPB_MINIMALIZED
117  #ifndef kvpb_chunk_size
118    #define kvpb_chunk_size(store) ((store)->chunk_size<4?4:(store)->chunk_size)
119  #endif /*kvpb_chunk_size*/
120  #define kvpb_chunk_size_mask(store) (kvpb_chunk_size(store)-1)
121  
122 /**
123  * kvpb_chunk_align - Round up KVPB size to minimal store chunk size multiple
124  * @store: Pointer to the KVPB access information/state structure
125  * @size: Unaligned size
126  *
127  * Return Value: Minimal aligned size to hold unaligned size.
128  * File: keyvalpb.h
129  */
130  static inline unsigned kvpb_chunk_align(struct kvpb_block *store, unsigned size)
131  {
132    return ((size)+kvpb_chunk_size_mask(store))&~kvpb_chunk_size_mask(store);
133  }
134
135 /**
136  * kvpb_psum_align - Round up KVPB size to minimal store chunk size multiple
137  * @store: Pointer to the KVPB access information/state structure
138  * @psum: Pointer to proposed location of next check sum location 
139  *
140  * Return Value: Pointer to next check sum location rounded down to next slot.
141  * File: keyvalpb.h
142  */
143  static inline kvpb_sum_t* kvpb_psum_align(struct kvpb_block *store, kvpb_sum_t *psum)
144  {
145    unsigned long mask=~kvpb_chunk_size_mask(store);
146    if(store->flags&KVPB_DESC_CHUNKWO)
147      mask<<=1;
148    return (kvpb_sum_t*)(((unsigned long)(psum))&mask);
149  }
150
151 /**
152  * kvpb_psum_valid_loc - Return pointer to check sum validity info location
153  * @store: Pointer to the KVPB access information/state structure
154  * @psum: Pointer to corectly aligned check sum location
155  *
156  * Return Value: Pointer to location which indicates by zero value, that check sum
157  *               is invalidated.
158  * File: keyvalpb.h
159  */
160  static inline kvpb_sum_t* kvpb_psum_valid_loc(struct kvpb_block *store, kvpb_sum_t *psum)
161  {
162    if(!(store->flags&KVPB_DESC_CHUNKWO))
163      return psum;
164    else
165      return (kvpb_sum_t*)(((char *)(psum))+kvpb_chunk_size(store));
166  }
167
168 /**
169  * kvpb_block_erase - Wrapper function to call KVPB specific data erase function
170  * @store: Pointer to the KVPB access information/state structure
171  * @base: Base address of erased region inside parameter block data region
172  * @size: Number of bytes to erase
173  *
174  * The KVPB mechanism is intended for FLASH type memories and it expect
175  * that only whole data region can be erased at time. The expected erase state
176  * is all bits set to the ones.
177  *
178  * Return Value: Negative value indicates operation fault.
179  * File: keyvalpb.h
180  */
181  static inline int kvpb_block_erase(struct kvpb_block *store, void *base,int size)
182  {
183    return store->erase(store, base,size) ; 
184  }
185
186 /**
187  * kvpb_block_copy - Wrapper function to call KVPB specific data copy function
188  * @store: Pointer to the KVPB access information/state structure
189  * @des: Address of data destination pointing inside mapped parameter block data region
190  * @src: Address of data source pointing inside mapped parameter block data or RAM memory
191  * @len: Number of bytes to transfer
192  *
193  * Return Value: Negative value indicates operation fault.
194  * File: keyvalpb.h
195  */
196  static inline int kvpb_block_copy(struct kvpb_block *store, void *des,const void *src,int len)
197  {
198    return store->copy(store, des, src, len);
199  }
200
201 /**
202  * kvpb_block_flush - Wrapper function to call KVPB specific flush function
203  * @store: Pointer to the KVPB access information/state structure
204  *
205  * Return Value: Negative value indicates operation fault.
206  * File: keyvalpb.h
207  */
208  static inline int kvpb_block_flush(struct kvpb_block *store)
209  {
210    if(!(store->flush)) return 0;
211    return store->flush(store);
212  }
213
214 #else /* KVPB_MINIMALIZED */
215  #ifndef kvpb_chunk_size
216   #define kvpb_chunk_size(store) 1
217  #endif /*kvpb_chunk_size*/
218  #define kvpb_chunk_size_mask(store) (kvpb_chunk_size(store)-1)
219  #define kvpb_chunk_align(store,x) \
220                 (((x)+kvpb_chunk_size_mask(store))&~kvpb_chunk_size_mask(store))
221  #define kvpb_psum_align(store,x) \
222                 ((KVPB_DPTRTYPE kvpb_sum_t*)((unsigned)(x)&~kvpb_chunk_size_mask(store)))
223  #define kvpb_psum_valid_loc(store,x) \
224                 ((kvpb_sum_t*)((char*)(x)+0*kvpb_chunk_size(store)))
225  #define kvpb_block_erase(store, base, size) flash_erase(base, size)
226  #define kvpb_block_copy(store, des, src, len) flash_copy(des, src, len) 
227  #define kvpb_block_flush(store) flash_flush() 
228  /* forward declarations for external procedures */
229  int flash_erase(void *base,int size);
230  int flash_copy(void *des,const void *src,int len);
231 #ifndef flash_flush
232  int flash_flush(void);
233 #endif /* flash_flush */
234 #endif /* KVPB_MINIMALIZED */
235
236 /**
237  * struct kvpb_key - Header of stored key value pair and structure for iteration over KVPB
238  * @size: Non-aligned byte size of the stored value
239  * @keyid: Ordinal value representing stored data key
240  *
241  * The header structure is followed by @size data bytes in the KVPB storage block.
242  * Because only word aligned write accesses are possible on some architectures
243  * and memory types the whole size of space occupied by one key-value pair is
244  * sum of rounded-up data size kvpb_chunk_align(@size)  and size of header sizeof(kvpb_key_t).
245  */
246 typedef struct kvpb_key {
247   kvpb_size_t size;
248   kvpb_keyid_t keyid;
249 } kvpb_key_t;
250
251 #ifndef KVPB_WITHOUT_HADLE
252  static inline kvpb_keyid_t* kvpb_keyid_valid(struct kvpb_block *store, kvpb_key_t *key)
253  {
254    if(store->flags&KVPB_DESC_CHUNKWO)
255      return (kvpb_keyid_t*)((uint8_t*)key+(kvpb_chunk_align(store,key->size+sizeof(kvpb_key_t))));
256    return &(key->keyid);
257  }
258 #else
259   #define kvpb_keyid_valid(store,key) (&((key)->keyid))
260 #endif /*KVPB_WITHOUT_HADLE*/
261
262
263 #ifndef KVPB_WITHOUT_HADLE
264 KVPB_DPTRTYPE kvpb_key_t *kvpb_first(kvpb_block_t *block, uint8_t mode);
265 KVPB_DPTRTYPE kvpb_key_t *kvpb_next(kvpb_block_t *block, KVPB_DPTRTYPE kvpb_key_t *key);
266 KVPB_DPTRTYPE kvpb_key_t *kvpb_find(kvpb_block_t *block, kvpb_keyid_t keyid, uint8_t mode, KVPB_DPTRTYPE kvpb_key_t *key);
267 int kvpb_get_key(kvpb_block_t *kvpb_block, kvpb_keyid_t keyid, kvpb_size_t size, void *buf);
268 int kvpb_set_key(kvpb_block_t *kvpb_block, kvpb_keyid_t keyid, kvpb_size_t size, const void *buf);
269 int kvpb_err_keys(kvpb_block_t *kvpb_block, kvpb_keyid_t keyid);
270 int kvpb_check(kvpb_block_t *kvpb_block, uint8_t mode);
271 #else
272 extern KVPB_BLOCK_LOC kvpb_block_t kvpb_block_global;
273 #define kvpb_block (&kvpb_block_global)
274 KVPB_DPTRTYPE kvpb_sum_t *__kvpb_get_psum(KVPB_DPTRTYPE uint8_t *base, kvpb_size_t size);
275 KVPB_DPTRTYPE kvpb_key_t *__kvpb_first(uint8_t mode);
276 KVPB_DPTRTYPE kvpb_key_t *__kvpb_next(KVPB_DPTRTYPE kvpb_key_t *key);
277 KVPB_DPTRTYPE kvpb_key_t *__kvpb_find(kvpb_keyid_t keyid, uint8_t mode, KVPB_DPTRTYPE kvpb_key_t *key);
278 int __kvpb_get_key(kvpb_keyid_t keyid, kvpb_size_t size, void *buf);
279 int __kvpb_set_key(kvpb_keyid_t keyid, kvpb_size_t size, const void *buf);
280 int __kvpb_check(uint8_t mode);
281 #define kvpb_get_psum(block, base, size) __kvpb_get_psum(base, size)
282 #define kvpb_first(block, mode) __kvpb_first(mode)
283 #define kvpb_next(block, key) __kvpb_next(key)
284 #define kvpb_find(block, keyid, mode, key) __kvpb_find(keyid, mode, key)
285 #define kvpb_get_key(block, keyid, size, buf) __kvpb_get_key(keyid, size, buf)
286 #define kvpb_set_key(block, keyid, size, buf) __kvpb_set_key(keyid, size, buf)
287 #define kvpb_err_keys(block,keyid) kvpb_set_key(block,keyid,0,NULL) 
288 #define kvpb_check(block, mode) __kvpb_check(mode)
289 #define kvpb_compact_region(block, mode, keyid) __kvpb_compact_region(mode, keyid)
290 #define kvpb_get_cfk(block,mode,size) __kvpb_get_cfk(mode,size)
291 #endif
292
293 /**
294  * kvpb_for_each - Iterate over all key value pairs
295  * @root: Pointer to the KVPB access information/state structure
296  * @key: Iterator of kvpb_key_t* type
297  * @mode: iteration mode modifier: 0 .. iterate over active/valid data region;
298  *      1 .. iterate over first copy, 2 .. iterate over second copy
299  *
300  * File: keyvalpb.h
301  */
302 #define kvpb_for_each(root, key,mode) \
303         for(key=kvpb_first(root,mode);key;\
304             key=kvpb_next(key))
305
306 /**
307  * kvpb_for_each - Iterate over all key value pairs matching given key ID
308  * @root: Pointer to the KVPB access information/state structure
309  * @keyid: Ordinal value representing key ID
310  * @key: Iterator of kvpb_key_t* type
311  * @mode: iteration mode modifier: 0 .. iterate over active/valid data region;
312  *      1 .. iterate over first copy, 2 .. iterate over second copy
313  *
314  * File: keyvalpb.h
315  */
316 #define kvpb_each_from(root, keyid, mode, key) \
317         for(key=kvpb_find(root,keyid,mode,NULL);key;\
318             key=kvpb_find(root,keyid,mode,key))
319
320 #ifdef  KVPB_MINIMALIZED
321 #define kvpb_key2data(key) ((void*)(key+1))
322 #else  /*KVPB_MINIMALIZED*/
323 static inline void* kvpb_key2data(kvpb_key_t *key) { return key+1; }
324 #endif  /*KVPB_MINIMALIZED*/
325
326 #endif /* _KEYVALPB_H_ */
327