blob: 05c549842b83322abb49a346abf3e234e2a69bee [file] [log] [blame]
Evan Lojewskif1e547c2019-03-14 14:34:33 +10301/* 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
19struct backend backend_get_mtd(void);
20struct backend backend_get_vpnor(void);
21
22enum backend_reset_mode { reset_lpc_flash, reset_lpc_memory };
23
24struct backend_ops;
25
26struct 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
41struct 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 */
131static 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
160static inline void backend_free(struct backend *backend)
161{
162 assert(backend);
163
164 if (backend->ops->free)
165 backend->ops->free(backend);
166}
167
168static 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
177static 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
189static 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
199static 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
207static 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
218static 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
226int backend_probe_mtd(struct backend *master, const char *path);
227/* Avoid dependency on vpnor/mboxd_pnor_partition_table.h */
228struct vpnor_partition_paths;
229int backend_probe_vpnor(struct backend *master,
230 const struct vpnor_partition_paths *paths);
231
232#endif /* BACKEND_H */