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
|
/*
* This file is part of the coreboot project.
*
* Copyright 2015 Google, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc.
*/
#ifndef _IMD_H_
#define _IMD_H_
#include <stdint.h>
#include <stddef.h>
/*
* imd is an in-memory database/directory/datastore (whatever d word you
* desire). It grows downwards in memory from provided upper limit and
* root size. Each entry has a size alignment which is also provided by
* the caller.
*
* +----------------------+ <- upper_limit
* | +----| root pointer |
* | | +----------------------+
* | | | |--------+
* | +--->| root block |-----+ |
* | +----------------------+-----|--|--- root_size
* | | | | |
* | | | | |
* | | alloc N |<----+ |
* | +----------------------+ |
* | | | |
* | | | |
* \|/ | alloc N + 1 |<-------+
* v +----------------------+
*
* The root_size in imd_create_empty() encompasses the root pointer
* and root block. The root_size value, therefore, dictates the number
* of allocations maintained by the imd.
*/
/*
* NOTE: This API has the following calling conventions: all functions
* returning int supply 0 on success or < 0 on error.
*/
struct imd_entry;
struct imd;
/*
* Initialize handle to use for working with an imd. Upper limit is the
* exclusive address to start allocating down from. This function needs
* to be called at least once before any other imd related functions
* can be used.
*/
void imd_handle_init(struct imd *imd, void *upper_limit);
/*
* Initialize a handle with a shallow recovery. This function doesn't
* verify every entry, but it does set up the root pointer. Because of
* this behavior it's not very safe. However, the current CBMEM constraints
* demand having these semantics.
*/
void imd_handle_init_partial_recovery(struct imd *imd);
/*
* Create an empty imd with a specified root_size and each entry is aligned to
* the provided entry_align. As noted above the root size encompasses the
* root pointer and root block leading to the number of imd entries being a
* function of the root_size parameter.
*/
int imd_create_empty(struct imd *imd, size_t root_size, size_t entry_align);
/*
* Recover a previously created imd.
*/
int imd_recover(struct imd *imd);
/* Limit imd to provided max_size. */
int imd_limit_size(struct imd *imd, size_t max_size);
/* Lock down imd from further modifications. */
int imd_lockdown(struct imd *imd);
/* Fill in base address and size of region used by imd. */
int imd_region_used(struct imd *imd, void **base, size_t *size);
/* Add an entry to the imd. If id already exists NULL is returned. */
const struct imd_entry *imd_entry_add(const struct imd *imd, uint32_t id,
size_t size);
/* Locate an entry within the imd. NULL is returned when not found. */
const struct imd_entry *imd_entry_find(const struct imd *imd, uint32_t id);
/* Find an existing entry or add a new one. */
const struct imd_entry *imd_entry_find_or_add(const struct imd *imd,
uint32_t id, size_t size);
/* Returns size of entry or 0 on failure. */
size_t imd_entry_size(const struct imd *imd, const struct imd_entry *entry);
/* Returns pointer to region described by entry or NULL on failure. */
void *imd_entry_at(const struct imd *imd, const struct imd_entry *entry);
/* Attempt to remove entry from imd. */
int imd_entry_remove(const struct imd *imd, const struct imd_entry *entry);
/* Print the entry information provided by lookup with the specified size. */
struct imd_lookup {
uint32_t id;
const char *name;
};
int imd_print_entries(const struct imd *imd, const struct imd_lookup *lookup,
size_t size);
/*
* The struct imd is a handle for working with an in-memory directory.
*
* NOTE: Do not directly touch any fields within this structure. An imd pointer
* is meant to be opaque, but the fields are exposed for stack allocation.
*/
struct imd {
uintptr_t limit;
void *r;
};
#endif /* _IMD_H_ */
|