blob: 5b043eca3b9ab653ddc2a028a8dc402dadda57a5 [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);
Evan Lojewskia0429782019-03-13 15:25:44 +103020struct backend backend_get_file(void);
Evan Lojewskif1e547c2019-03-14 14:34:33 +103021struct backend backend_get_vpnor(void);
22
23enum backend_reset_mode { reset_lpc_flash, reset_lpc_memory };
24
25struct backend_ops;
26
27struct 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
42struct 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 */
132static 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
161static inline void backend_free(struct backend *backend)
162{
163 assert(backend);
164
165 if (backend->ops->free)
166 backend->ops->free(backend);
167}
168
169static 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
178static 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
190static 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
200static 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
208static 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
219static 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
227int backend_probe_mtd(struct backend *master, const char *path);
Evan Lojewskia0429782019-03-13 15:25:44 +1030228int backend_probe_file(struct backend *master, const char *path);
Evan Lojewskif1e547c2019-03-14 14:34:33 +1030229/* Avoid dependency on vpnor/mboxd_pnor_partition_table.h */
230struct vpnor_partition_paths;
231int backend_probe_vpnor(struct backend *master,
232 const struct vpnor_partition_paths *paths);
233
234#endif /* BACKEND_H */