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