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