xref: /openbmc/hiomapd/backend.h (revision a042978b03c91ca3a716e99f313ef5cda42820ba)
1 /* SPDX-License-Identifier: Apache-2.0 */
2 /* Copyright (C) 2018 IBM Corp. */
3 /* Copyright (C) 2018 Evan Lojewski. */
4 
5 #ifndef BACKEND_H
6 #define BACKEND_H
7 
8 #include <assert.h>
9 #include <stdbool.h>
10 #include <stdint.h>
11 #include <mtd/mtd-abi.h>
12 
13 #define FLASH_DIRTY	0x00
14 #define FLASH_ERASED	0x01
15 
16 /* Estimate as to how long (milliseconds) it takes to access a MB from flash */
17 #define FLASH_ACCESS_MS_PER_MB		8000
18 
19 struct backend backend_get_mtd(void);
20 struct backend backend_get_file(void);
21 struct backend backend_get_vpnor(void);
22 
23 enum backend_reset_mode { reset_lpc_flash, reset_lpc_memory };
24 
25 struct backend_ops;
26 
27 struct backend {
28 	const struct backend_ops *ops;
29 
30 	/* Backend private data */
31 	void *priv;
32 
33 	/* Flash size from command line (bytes) */
34 	uint32_t flash_size;
35 
36 	/* Erase size (as a shift) */
37 	uint32_t erase_size_shift;
38 	/* Block size (as a shift) */
39 	uint32_t block_size_shift;
40 };
41 
42 struct backend_ops {
43 	/*
44 	 * init() - Main initialization function for backing device
45 	 * @context:	The backend context pointer
46 	 * @data:	Additional backend-implementation-specifc data
47 	 * Return:	Zero on success, otherwise negative error
48 	 */
49 	int 	(*init)(struct backend *backend, void *data);
50 
51 	/*
52 	 * free() - Main teardown function for backing device
53 	 * @context:	The backend context pointer
54 	 */
55 	void 	(*free)(struct backend *backend);
56 
57 	/*
58 	 * copy() - Copy data from the flash device into a provided buffer
59 	 * @context:	The mbox context pointer
60 	 * @offset:	The flash offset to copy from (bytes)
61 	 * @mem:	The buffer to copy into (must be of atleast 'size' bytes)
62 	 * @size:	The number of bytes to copy
63 	 * Return:	Number of bytes copied on success, otherwise negative error
64 	 *		code. flash_copy will copy at most 'size' bytes, but it may
65 	 *		copy less.
66 	 */
67 	int64_t (*copy)(struct backend *backend, uint32_t offset, void *mem,
68 			uint32_t size);
69 
70 	/*
71 	 * set_bytemap() - Set the flash erased bytemap
72 	 * @context:	The mbox context pointer
73 	 * @offset:	The flash offset to set (bytes)
74 	 * @count:	Number of bytes to set
75 	 * @val:	Value to set the bytemap to
76 	 *
77 	 * The flash bytemap only tracks the erased status at the erase block level so
78 	 * this will update the erased state for an (or many) erase blocks
79 	 *
80 	 * Return:	0 if success otherwise negative error code
81 	 */
82 	 int 	(*set_bytemap)(struct backend *backend, uint32_t offset,
83 			       uint32_t count, uint8_t val);
84 
85 	/*
86 	 * erase() - Erase the flash
87 	 * @context:	The backend context pointer
88 	 * @offset:	The flash offset to erase (bytes)
89 	 * @size:	The number of bytes to erase
90 	 *
91 	 * Return:	0 on success otherwise negative error code
92 	 */
93 	int 	(*erase)(struct backend *backend, uint32_t offset,
94 			 uint32_t count);
95 	/*
96 	 * write() - Write the flash from a provided buffer
97 	 * @context:	The backend context pointer
98 	 * @offset:	The flash offset to write to (bytes)
99 	 * @buf:	The buffer to write from (must be of atleast size)
100 	 * @size:	The number of bytes to write
101 	 *
102 	 * Return:	0 on success otherwise negative error code
103 	 */
104 	int 	(*write)(struct backend *backend, uint32_t offset, void *buf,
105 			 uint32_t count);
106 
107 	/*
108 	 * validate() - Validates a requested window
109 	 * @context:	The backend context pointer
110 	 * @offset:	The requested flash offset
111 	 * @size:	The requested region size
112 	 * @ro:		The requested access type: True for read-only, false
113 	 *		for read-write
114 	 *
115 	 * Return:	0 on valid otherwise negative error code
116 	 */
117 	int 	(*validate)(struct backend *backend,
118 			    uint32_t offset, uint32_t size, bool ro);
119 
120 	/*
121 	 * reset() - Ready the reserved memory for host startup
122 	 * @context:    The backend context pointer
123 	 * @buf:	The LPC reserved memory pointer
124 	 * @count	The size of the LPC reserved memory region
125 	 *
126 	 * Return:      0 on success otherwise negative error code
127 	 */
128 	int	(*reset)(struct backend *backend, void *buf, uint32_t count);
129 };
130 
131 /* Make this better */
132 static inline int backend_init(struct backend *master, struct backend *with,
133 			       void *data)
134 {
135 	int rc;
136 
137 	assert(master);
138 
139 	/* FIXME: A bit hacky? */
140 	with->flash_size = master->flash_size;
141 	*master = *with;
142 
143 #ifndef NDEBUG
144 	/* Set some poison values to ensure backends init properly */
145 	master->erase_size_shift = 33;
146 	master->block_size_shift = 34;
147 #endif
148 
149 	assert(master->ops->init);
150 
151 	rc = master->ops->init(master, data);
152 	if (rc < 0)
153 		return rc;
154 
155 	assert(master->erase_size_shift < 32);
156 	assert(master->block_size_shift < 32);
157 
158 	return 0;
159 }
160 
161 static inline void backend_free(struct backend *backend)
162 {
163 	assert(backend);
164 
165 	if (backend->ops->free)
166 		backend->ops->free(backend);
167 }
168 
169 static inline int64_t backend_copy(struct backend *backend,
170 				   uint32_t offset, void *mem, uint32_t size)
171 {
172 	assert(backend);
173 	assert(backend->ops->copy);
174 	return backend->ops->copy(backend, offset, mem, size);
175 
176 }
177 
178 static inline int backend_set_bytemap(struct backend *backend,
179 				      uint32_t offset, uint32_t count,
180 				      uint8_t val)
181 {
182 	assert(backend);
183 
184 	if (backend->ops->set_bytemap)
185 		return backend->ops->set_bytemap(backend, offset, count, val);
186 
187 	return 0;
188 }
189 
190 static inline int backend_erase(struct backend *backend, uint32_t offset,
191 				uint32_t count)
192 {
193 	assert(backend);
194 	if (backend->ops->erase)
195 		return backend->ops->erase(backend, offset, count);
196 
197 	return 0;
198 }
199 
200 static inline int backend_write(struct backend *backend, uint32_t offset,
201 				void *buf, uint32_t count)
202 {
203 	assert(backend);
204 	assert(backend->ops->write);
205 	return backend->ops->write(backend, offset, buf, count);
206 }
207 
208 static inline int backend_validate(struct backend *backend,
209 				   uint32_t offset, uint32_t size, bool ro)
210 {
211 	assert(backend);
212 
213 	if (backend->ops->validate)
214 		return backend->ops->validate(backend, offset, size, ro);
215 
216 	return 0;
217 }
218 
219 static inline int backend_reset(struct backend *backend, void *buf,
220 				uint32_t count)
221 {
222 	assert(backend);
223 	assert(backend->ops->reset);
224 	return backend->ops->reset(backend, buf, count);
225 }
226 
227 int backend_probe_mtd(struct backend *master, const char *path);
228 int backend_probe_file(struct backend *master, const char *path);
229 /* Avoid dependency on vpnor/mboxd_pnor_partition_table.h */
230 struct vpnor_partition_paths;
231 int backend_probe_vpnor(struct backend *master,
232                         const struct vpnor_partition_paths *paths);
233 
234 #endif /* BACKEND_H */
235