diff options
| author | Evan Lojewski <github@meklort.com> | 2019-03-14 14:34:33 +1030 |
|---|---|---|
| committer | Andrew Jeffery <andrew@aj.id.au> | 2019-03-18 10:46:11 +1030 |
| commit | f1e547c74563d59f60d918c6fa673bb8cee6e669 (patch) | |
| tree | 9ac7e157de69b3163b289f1f2f01f2a5c5c31861 | |
| parent | cb93504ed0fefa23186415accca6c0812174f274 (diff) | |
| download | phosphor-mboxbridge-f1e547c74563d59f60d918c6fa673bb8cee6e669.tar.gz phosphor-mboxbridge-f1e547c74563d59f60d918c6fa673bb8cee6e669.zip | |
mboxd: Add a backend abstraction layer to mboxd.
Introduce a backend abstraction, enabling multiple implementations to be
compiled in at once. This change formally abstracts the two existing
backends, mtd and vpnor.
With the backend abstraction in place, subsequent backends are easier to
implement.
This change is based of Evan's work and he retains authorship credit. I
(AJ) have reworked the patch to pass the vpnor tests, refactored some
parts to enable broader use of const structures and others to clarify
the initialisation sequences.
Due to the existing lack of abstraction the patch has unfortunately
wide-ranging impacts. I've whittled it down as much as I consider
reasonable.
Change-Id: I29984a36dae4ea86ec00b853d2a756f0b9afb3ec
Signed-off-by: Evan Lojewski <github@meklort.com>
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
62 files changed, 1009 insertions, 637 deletions
diff --git a/Makefile.am b/Makefile.am index fb21633..0ce5242 100644 --- a/Makefile.am +++ b/Makefile.am @@ -16,11 +16,12 @@ mboxd_SOURCES = \ mboxd_LDFLAGS = $(LIBSYSTEMD_LIBS) mboxd_CFLAGS = $(LIBSYSTEMD_CFLAGS) +# MTD Backing storage +include mtd/Makefile.am.include + if VIRTUAL_PNOR_ENABLED +# VPNOR Backing storage include vpnor/Makefile.am.include -else -mboxd_SOURCES += flash.c \ - lpc_reset.c endif mboxctl_SOURCES = mboxctl.c diff --git a/backend.h b/backend.h new file mode 100644 index 0000000..05c5498 --- /dev/null +++ b/backend.h @@ -0,0 +1,232 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright (C) 2018 IBM Corp. */ +/* Copyright (C) 2018 Evan Lojewski. */ + +#ifndef BACKEND_H +#define BACKEND_H + +#include <assert.h> +#include <stdbool.h> +#include <stdint.h> +#include <mtd/mtd-abi.h> + +#define FLASH_DIRTY 0x00 +#define FLASH_ERASED 0x01 + +/* Estimate as to how long (milliseconds) it takes to access a MB from flash */ +#define FLASH_ACCESS_MS_PER_MB 8000 + +struct backend backend_get_mtd(void); +struct backend backend_get_vpnor(void); + +enum backend_reset_mode { reset_lpc_flash, reset_lpc_memory }; + +struct backend_ops; + +struct backend { + const struct backend_ops *ops; + + /* Backend private data */ + void *priv; + + /* Flash size from command line (bytes) */ + uint32_t flash_size; + + /* Erase size (as a shift) */ + uint32_t erase_size_shift; + /* Block size (as a shift) */ + uint32_t block_size_shift; +}; + +struct backend_ops { + /* + * init() - Main initialization function for backing device + * @context: The backend context pointer + * @data: Additional backend-implementation-specifc data + * Return: Zero on success, otherwise negative error + */ + int (*init)(struct backend *backend, void *data); + + /* + * free() - Main teardown function for backing device + * @context: The backend context pointer + */ + void (*free)(struct backend *backend); + + /* + * copy() - Copy data from the flash device into a provided buffer + * @context: The mbox context pointer + * @offset: The flash offset to copy from (bytes) + * @mem: The buffer to copy into (must be of atleast 'size' bytes) + * @size: The number of bytes to copy + * Return: Number of bytes copied on success, otherwise negative error + * code. flash_copy will copy at most 'size' bytes, but it may + * copy less. + */ + int64_t (*copy)(struct backend *backend, uint32_t offset, void *mem, + uint32_t size); + + /* + * set_bytemap() - Set the flash erased bytemap + * @context: The mbox context pointer + * @offset: The flash offset to set (bytes) + * @count: Number of bytes to set + * @val: Value to set the bytemap to + * + * The flash bytemap only tracks the erased status at the erase block level so + * this will update the erased state for an (or many) erase blocks + * + * Return: 0 if success otherwise negative error code + */ + int (*set_bytemap)(struct backend *backend, uint32_t offset, + uint32_t count, uint8_t val); + + /* + * erase() - Erase the flash + * @context: The backend context pointer + * @offset: The flash offset to erase (bytes) + * @size: The number of bytes to erase + * + * Return: 0 on success otherwise negative error code + */ + int (*erase)(struct backend *backend, uint32_t offset, + uint32_t count); + /* + * write() - Write the flash from a provided buffer + * @context: The backend context pointer + * @offset: The flash offset to write to (bytes) + * @buf: The buffer to write from (must be of atleast size) + * @size: The number of bytes to write + * + * Return: 0 on success otherwise negative error code + */ + int (*write)(struct backend *backend, uint32_t offset, void *buf, + uint32_t count); + + /* + * validate() - Validates a requested window + * @context: The backend context pointer + * @offset: The requested flash offset + * @size: The requested region size + * @ro: The requested access type: True for read-only, false + * for read-write + * + * Return: 0 on valid otherwise negative error code + */ + int (*validate)(struct backend *backend, + uint32_t offset, uint32_t size, bool ro); + + /* + * reset() - Ready the reserved memory for host startup + * @context: The backend context pointer + * @buf: The LPC reserved memory pointer + * @count The size of the LPC reserved memory region + * + * Return: 0 on success otherwise negative error code + */ + int (*reset)(struct backend *backend, void *buf, uint32_t count); +}; + +/* Make this better */ +static inline int backend_init(struct backend *master, struct backend *with, + void *data) +{ + int rc; + + assert(master); + + /* FIXME: A bit hacky? */ + with->flash_size = master->flash_size; + *master = *with; + +#ifndef NDEBUG + /* Set some poison values to ensure backends init properly */ + master->erase_size_shift = 33; + master->block_size_shift = 34; +#endif + + assert(master->ops->init); + + rc = master->ops->init(master, data); + if (rc < 0) + return rc; + + assert(master->erase_size_shift < 32); + assert(master->block_size_shift < 32); + + return 0; +} + +static inline void backend_free(struct backend *backend) +{ + assert(backend); + + if (backend->ops->free) + backend->ops->free(backend); +} + +static inline int64_t backend_copy(struct backend *backend, + uint32_t offset, void *mem, uint32_t size) +{ + assert(backend); + assert(backend->ops->copy); + return backend->ops->copy(backend, offset, mem, size); + +} + +static inline int backend_set_bytemap(struct backend *backend, + uint32_t offset, uint32_t count, + uint8_t val) +{ + assert(backend); + + if (backend->ops->set_bytemap) + return backend->ops->set_bytemap(backend, offset, count, val); + + return 0; +} + +static inline int backend_erase(struct backend *backend, uint32_t offset, + uint32_t count) +{ + assert(backend); + if (backend->ops->erase) + return backend->ops->erase(backend, offset, count); + + return 0; +} + +static inline int backend_write(struct backend *backend, uint32_t offset, + void *buf, uint32_t count) +{ + assert(backend); + assert(backend->ops->write); + return backend->ops->write(backend, offset, buf, count); +} + +static inline int backend_validate(struct backend *backend, + uint32_t offset, uint32_t size, bool ro) +{ + assert(backend); + + if (backend->ops->validate) + return backend->ops->validate(backend, offset, size, ro); + + return 0; +} + +static inline int backend_reset(struct backend *backend, void *buf, + uint32_t count) +{ + assert(backend); + assert(backend->ops->reset); + return backend->ops->reset(backend, buf, count); +} + +int backend_probe_mtd(struct backend *master, const char *path); +/* Avoid dependency on vpnor/mboxd_pnor_partition_table.h */ +struct vpnor_partition_paths; +int backend_probe_vpnor(struct backend *master, + const struct vpnor_partition_paths *paths); + +#endif /* BACKEND_H */ @@ -6,7 +6,7 @@ #include "common.h" #include "dbus.h" #include "mboxd.h" -#include "flash.h" +#include "backend.h" #include "lpc.h" #include "transport_mbox.h" #include "windows.h" @@ -62,7 +62,8 @@ int control_kill(struct mbox_context *context) int control_modified(struct mbox_context *context) { /* Flash has been modified - can no longer trust our erased bytemap */ - flash_set_bytemap(context, 0, context->flash_size, FLASH_DIRTY); + flash_set_bytemap(context, 0, context->backend.flash_size, + FLASH_DIRTY); /* Force daemon to reload all windows -> Set BMC event to notify host */ if (windows_reset_all(context)) { diff --git a/flash.h b/flash.h deleted file mode 100644 index 2760563..0000000 --- a/flash.h +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* Copyright (C) 2018 IBM Corp. */ - -#ifndef FLASH_H -#define FLASH_H - -#include <stdbool.h> -#include <stdint.h> - -#define FLASH_DIRTY 0x00 -#define FLASH_ERASED 0x01 - -/* Estimate as to how long (milliseconds) it takes to access a MB from flash */ -#define FLASH_ACCESS_MS_PER_MB 8000 - -struct mbox_context; - -int flash_dev_init(struct mbox_context *context); -void flash_dev_free(struct mbox_context *context); -int flash_validate(struct mbox_context *context, uint32_t offset, - uint32_t size, bool ro); -int64_t flash_copy(struct mbox_context *context, uint32_t offset, void *mem, - uint32_t size); -int flash_set_bytemap(struct mbox_context *context, uint32_t offset, - uint32_t count, uint8_t val); -int flash_erase(struct mbox_context *context, uint32_t offset, uint32_t count); -int flash_write(struct mbox_context *context, uint32_t offset, void *buf, - uint32_t count); - -#endif /* FLASH_H */ @@ -27,7 +27,7 @@ #include "mboxd.h" #include "common.h" #include "lpc.h" -#include "flash.h" +#include "backend.h" #include <linux/aspeed-lpc-ctrl.h> #define LPC_CTRL_PATH "/dev/aspeed-lpc-ctrl" @@ -108,9 +108,9 @@ int lpc_map_flash(struct mbox_context *context) * The mask is because the top nibble is the host LPC FW space, * we want space 0. */ - .addr = 0x0FFFFFFF & -context->flash_size, + .addr = 0x0FFFFFFF & -context->backend.flash_size, .offset = 0, - .size = context->flash_size + .size = context->backend.flash_size }; if (context->state & MAPS_FLASH) { @@ -124,7 +124,7 @@ int lpc_map_flash(struct mbox_context *context) MSG_INFO("Pointing HOST LPC bus at the flash\n"); MSG_INFO("Assuming %dMB of flash: HOST LPC 0x%08x\n", - context->flash_size >> 20, map.addr); + context->backend.flash_size >> 20, map.addr); if (ioctl(context->fds[LPC_CTRL_FD].fd, ASPEED_LPC_CTRL_IOCTL_MAP, &map) == -1) { @@ -138,7 +138,8 @@ int lpc_map_flash(struct mbox_context *context) * Since the host now has access to the flash it can change it out from * under us */ - return flash_set_bytemap(context, 0, context->flash_size, FLASH_DIRTY); + return flash_set_bytemap(context, 0, context->backend.flash_size, + FLASH_DIRTY); } /* @@ -10,6 +10,5 @@ int lpc_dev_init(struct mbox_context *context); void lpc_dev_free(struct mbox_context *context); int lpc_map_flash(struct mbox_context *context); int lpc_map_memory(struct mbox_context *context); -int lpc_reset(struct mbox_context *context); #endif /* LPC_H */ diff --git a/lpc_reset.c b/lpc_reset.c deleted file mode 100644 index 9b64aa7..0000000 --- a/lpc_reset.c +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright (C) 2018 IBM Corp. - -#define _GNU_SOURCE - -#include "lpc.h" - -struct mbox_context; - -/* - * lpc_reset() - Reset the lpc bus mapping - * @context: The mbox context pointer - * - * Return: 0 on success otherwise negative error code - */ -int lpc_reset(struct mbox_context *context) -{ - return lpc_map_flash(context); -} @@ -31,7 +31,7 @@ #include "common.h" #include "dbus.h" #include "control_dbus.h" -#include "flash.h" +#include "backend.h" #include "lpc.h" #include "transport_mbox.h" #include "transport_dbus.h" @@ -246,7 +246,7 @@ static bool parse_cmdline(int argc, char **argv, case 0: break; case 'f': - context->flash_size = strtol(optarg, &endptr, 10); + context->backend.flash_size = strtol(optarg, &endptr, 10); if (optarg == endptr) { fprintf(stderr, "Unparseable flash size\n"); return false; @@ -255,9 +255,9 @@ static bool parse_cmdline(int argc, char **argv, case '\0': break; case 'M': - context->flash_size <<= 10; + context->backend.flash_size <<= 10; case 'K': - context->flash_size <<= 10; + context->backend.flash_size <<= 10; break; default: fprintf(stderr, "Unknown units '%c'\n", @@ -307,12 +307,15 @@ static bool parse_cmdline(int argc, char **argv, } } - if (!context->flash_size) { + if (!context->path) { + context->path = get_dev_mtd(); + } + if (!context->backend.flash_size) { fprintf(stderr, "Must specify a non-zero flash size\n"); return false; } - MSG_INFO("Flash size: 0x%.8x\n", context->flash_size); + MSG_INFO("Flash size: 0x%.8x\n", context->backend.flash_size); if (verbosity) { MSG_INFO("%s logging\n", verbosity == MBOX_LOG_DEBUG ? "Debug" : @@ -322,6 +325,24 @@ static bool parse_cmdline(int argc, char **argv, return true; } +static int mboxd_backend_init(struct mbox_context *context) +{ + int rc; + +#ifdef VIRTUAL_PNOR_ENABLED + struct vpnor_partition_paths paths; + vpnor_default_paths(&paths); + + rc = backend_probe_vpnor(&context->backend, &paths); + if(rc) +#endif + { + rc = backend_probe_mtd(&context->backend, context->path); + } + + return rc; +} + int main(int argc, char **argv) { const struct transport_ops *mbox_ops, *dbus_ops; @@ -353,6 +374,11 @@ int main(int argc, char **argv) goto finish; } + rc = mboxd_backend_init(context); + if (rc) { + goto finish; + } + rc = protocol_init(context); if (rc) { goto finish; @@ -374,20 +400,11 @@ int main(int argc, char **argv) goto finish; } - rc = flash_dev_init(context); - if (rc) { - goto finish; - } - rc = dbus_init(context, &dbus_ops); if (rc) { goto finish; } -#ifdef VIRTUAL_PNOR_ENABLED - init_vpnor(context); -#endif - /* Set the LPC bus mapping */ __protocol_reset(context); @@ -421,10 +438,10 @@ finish: protocol_events_put(context, dbus_ops); #ifdef VIRTUAL_PNOR_ENABLED - destroy_vpnor(context); + vpnor_destroy(&context->backend); #endif dbus_free(context); - flash_dev_free(context); + backend_free(&context->backend); lpc_dev_free(context); transport_mbox_free(context); windows_free(context); @@ -4,11 +4,13 @@ #ifndef MBOX_H #define MBOX_H +#include <assert.h> #include <mtd/mtd-abi.h> #include <systemd/sd-bus.h> #include <poll.h> #include <stdbool.h> +#include "backend.h" #include "protocol.h" #include "transport.h" #include "vpnor/mboxd_pnor_partition_table.h" @@ -48,8 +50,7 @@ enum api_version { #define SIG_FD 2 #define POLL_FDS 3 /* Number of FDs we poll on */ #define LPC_CTRL_FD 3 -#define MTD_FD 4 -#define TOTAL_FDS 5 +#define TOTAL_FDS 4 #define MAPS_FLASH (1 << 0) #define MAPS_MEM (1 << 1) @@ -72,6 +73,10 @@ struct mbox_context { enum api_version version; const struct protocol_ops *protocol; const struct transport_ops *transport; + struct backend backend; + + /* Commandline parameters */ + const char *path; /* System State */ enum mbox_state state; @@ -96,21 +101,32 @@ struct mbox_context { uint32_t mem_size; /* LPC Bus Base Address (bytes) */ uint32_t lpc_base; - /* Flash size from command line (bytes) */ - uint32_t flash_size; - /* Bytemap of the erased state of the entire flash */ - uint8_t *flash_bmap; - /* Erase size (as a shift) */ - uint32_t erase_size_shift; - /* Block size (as a shift) */ - uint32_t block_size_shift; - /* Actual Flash Info */ - struct mtd_info_user mtd_info; -#ifdef VIRTUAL_PNOR_ENABLED - /* Virtual PNOR partition table */ - struct vpnor_partition_table *vpnor; - struct vpnor_partition_paths paths; -#endif }; +/* Temporary flash API compatibility */ +static inline int64_t flash_copy(struct mbox_context *context, uint32_t offset, + void *mem, uint32_t size) +{ + return backend_copy(&context->backend, offset, mem, size); +} + +static inline int flash_set_bytemap(struct mbox_context *context, + uint32_t offset, uint32_t count, + uint8_t val) +{ + return backend_set_bytemap(&context->backend, offset, count, val); +} + +static inline int flash_erase(struct mbox_context *context, uint32_t offset, + uint32_t count) +{ + return backend_erase(&context->backend, offset, count); +} + +static inline int flash_write(struct mbox_context *context, uint32_t offset, + void *buf, uint32_t count) +{ + return backend_write(&context->backend, offset, buf, count); +} + #endif /* MBOX_H */ diff --git a/mtd/Makefile.am.include b/mtd/Makefile.am.include new file mode 100644 index 0000000..155db50 --- /dev/null +++ b/mtd/Makefile.am.include @@ -0,0 +1 @@ +mboxd_SOURCES += %reldir%/backend.c @@ -6,61 +6,66 @@ #include <errno.h> #include <fcntl.h> #include <getopt.h> +#include <inttypes.h> #include <limits.h> +#include <mtd/mtd-abi.h> #include <poll.h> +#include <signal.h> #include <stdbool.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <syslog.h> -#include <signal.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/timerfd.h> #include <sys/types.h> +#include <syslog.h> #include <time.h> #include <unistd.h> -#include <inttypes.h> -#include <errno.h> -#include <mtd/mtd-abi.h> -#include "mboxd.h" #include "common.h" -#include "flash.h" +#include "backend.h" +#include "lpc.h" +#include "mboxd.h" +#include "mtd/backend.h" -int flash_dev_init(struct mbox_context *context) +static int mtd_dev_init(struct backend *backend, void *data) { - char *filename = get_dev_mtd(); - int fd, rc = 0; + const char *path = data; + struct mtd_data *priv; + int rc = 0; - if (!filename) { - MSG_ERR("Couldn't find the PNOR /dev/mtd partition\n"); - return -1; + if (!path) { + MSG_INFO("Discovering PNOR MTD\n"); + path = get_dev_mtd(); } - MSG_DBG("Opening %s\n", filename); - - /* Open Flash Device */ - fd = open(filename, O_RDWR); - if (fd < 0) { - MSG_ERR("Couldn't open %s with flags O_RDWR: %s\n", - filename, strerror(errno)); + priv = malloc(sizeof(*priv)); + if (!priv) { rc = -errno; goto out; } - context->fds[MTD_FD].fd = fd; - /* Read the Flash Info */ - if (ioctl(fd, MEMGETINFO, &context->mtd_info) == -1) { - MSG_ERR("Couldn't get information about MTD: %s\n", + MSG_DBG("Opening %s\n", path); + + priv->fd = open(path, O_RDWR); + if (priv->fd < 0) { + MSG_ERR("Couldn't open %s with flags O_RDWR: %s\n", path, strerror(errno)); - rc = -1; - goto out; + rc = -errno; + goto cleanup_priv; } - if (context->flash_size == 0) { + /* If the file does not support MEMGETINFO it's not an mtd device */ + if (ioctl(priv->fd, MEMGETINFO, &priv->mtd_info) == -1) { + rc = -errno; + close(priv->fd); + goto cleanup_priv; + } + + if (backend->flash_size == 0) { /* * PNOR images for current OpenPOWER systems are at most 64MB * despite the PNOR itself sometimes being as big as 128MB. To @@ -80,27 +85,38 @@ int flash_dev_init(struct mbox_context *context) * the test environment), log an error. As a consequence, this * error is expected in the test case output. */ - MSG_ERR("Flash size MUST be supplied on the commandline. However, continuing by assuming flash is %u bytes\n", - context->mtd_info.size); - context->flash_size = context->mtd_info.size; + MSG_ERR( + "Flash size MUST be supplied on the commandline. However, " + "continuing by assuming flash is %u bytes\n", + priv->mtd_info.size); + backend->flash_size = priv->mtd_info.size; } /* We know the erase size so we can allocate the flash_erased bytemap */ - context->erase_size_shift = log_2(context->mtd_info.erasesize); - context->flash_bmap = calloc(context->flash_size >> - context->erase_size_shift, - sizeof(*context->flash_bmap)); - MSG_DBG("Flash erase size: 0x%.8x\n", context->mtd_info.erasesize); + backend->erase_size_shift = log_2(priv->mtd_info.erasesize); + backend->block_size_shift = backend->erase_size_shift; + priv->flash_bmap = calloc(backend->flash_size + >> backend->erase_size_shift, + sizeof(*priv->flash_bmap)); + MSG_DBG("Flash erase size: 0x%.8x\n", priv->mtd_info.erasesize); + + backend->priv = priv; out: - free(filename); + return rc; + +cleanup_priv: + free(priv); return rc; } -void flash_dev_free(struct mbox_context *context) +static void mtd_dev_free(struct backend *backend) { - free(context->flash_bmap); - close(context->fds[MTD_FD].fd); + struct mtd_data *priv = backend->priv; + + free(priv->flash_bmap); + close(priv->fd); + free(priv); } /* Flash Functions */ @@ -113,22 +129,23 @@ int flash_validate(struct mbox_context *context, uint32_t offset, } /* - * flash_is_erased() - Check if an offset into flash is erased + * mtd_is_erased() - Check if an offset into flash is erased * @context: The mbox context pointer * @offset: The flash offset to check (bytes) * * Return: true if erased otherwise false */ -static inline bool flash_is_erased(struct mbox_context *context, - uint32_t offset) +static inline bool mtd_is_erased(struct backend *backend, uint32_t offset) { - return context->flash_bmap[offset >> context->erase_size_shift] - == FLASH_ERASED; + const off_t index = offset >> backend->erase_size_shift; + struct mtd_data *priv = backend->priv; + + return priv->flash_bmap[index] == FLASH_ERASED; } /* - * flash_set_bytemap() - Set the flash erased bytemap - * @context: The mbox context pointer + * mtd_set_bytemap() - Set the flash erased bytemap + * @context: The backend context pointer * @offset: The flash offset to set (bytes) * @count: Number of bytes to set * @val: Value to set the bytemap to @@ -138,35 +155,38 @@ static inline bool flash_is_erased(struct mbox_context *context, * * Return: 0 if success otherwise negative error code */ -int flash_set_bytemap(struct mbox_context *context, uint32_t offset, - uint32_t count, uint8_t val) +static int mtd_set_bytemap(struct backend *backend, uint32_t offset, + uint32_t count, uint8_t val) { - if ((offset + count) > context->flash_size) { + struct mtd_data *priv = backend->priv; + + if ((offset + count) > backend->flash_size) { return -EINVAL; } - MSG_DBG("Set flash bytemap @ 0x%.8x for 0x%.8x to %s\n", - offset, count, val ? "ERASED" : "DIRTY"); - memset(context->flash_bmap + (offset >> context->erase_size_shift), + MSG_DBG("Set flash bytemap @ 0x%.8x for 0x%.8x to %s\n", offset, count, + val ? "ERASED" : "DIRTY"); + memset(priv->flash_bmap + (offset >> backend->erase_size_shift), val, - align_up(count, 1 << context->erase_size_shift) >> - context->erase_size_shift); + align_up(count, 1 << backend->erase_size_shift) >> + backend->erase_size_shift); return 0; } /* - * flash_erase() - Erase the flash + * mtd_erase() - Erase the flash * @context: The mbox context pointer * @offset: The flash offset to erase (bytes) * @size: The number of bytes to erase * * Return: 0 on success otherwise negative error code */ -int flash_erase(struct mbox_context *context, uint32_t offset, uint32_t count) +static int mtd_erase(struct backend *backend, uint32_t offset, uint32_t count) { - const uint32_t erase_size = 1 << context->erase_size_shift; - struct erase_info_user erase_info = { 0 }; + const uint32_t erase_size = 1 << backend->erase_size_shift; + struct mtd_data *priv = backend->priv; + struct erase_info_user erase_info = {0}; int rc; MSG_DBG("Erase flash @ 0x%.8x for 0x%.8x\n", offset, count); @@ -179,7 +199,7 @@ int flash_erase(struct mbox_context *context, uint32_t offset, uint32_t count) * erased then there's nothing we need to do. */ while (count) { - if (!flash_is_erased(context, offset)) { /* Need to erase */ + if (!mtd_is_erased(backend, offset)) { /* Need to erase */ if (!erase_info.length) { /* Start of not-erased run */ erase_info.start = offset; } @@ -188,16 +208,15 @@ int flash_erase(struct mbox_context *context, uint32_t offset, uint32_t count) /* Erase the previous run which just ended */ MSG_DBG("Erase flash @ 0x%.8x for 0x%.8x\n", erase_info.start, erase_info.length); - rc = ioctl(context->fds[MTD_FD].fd, MEMERASE, - &erase_info); + rc = ioctl(priv->fd, MEMERASE, &erase_info); if (rc < 0) { MSG_ERR("Couldn't erase flash at 0x%.8x\n", - erase_info.start); + erase_info.start); return -errno; } /* Mark ERASED where we just erased */ - flash_set_bytemap(context, erase_info.start, - erase_info.length, FLASH_ERASED); + mtd_set_bytemap(backend, erase_info.start, + erase_info.length, FLASH_ERASED); erase_info.start = 0; erase_info.length = 0; } @@ -207,17 +226,17 @@ int flash_erase(struct mbox_context *context, uint32_t offset, uint32_t count) } if (erase_info.length) { - MSG_DBG("Erase flash @ 0x%.8x for 0x%.8x\n", - erase_info.start, erase_info.length); - rc = ioctl(context->fds[MTD_FD].fd, MEMERASE, &erase_info); + MSG_DBG("Erase flash @ 0x%.8x for 0x%.8x\n", erase_info.start, + erase_info.length); + rc = ioctl(priv->fd, MEMERASE, &erase_info); if (rc < 0) { MSG_ERR("Couldn't erase flash at 0x%.8x\n", - erase_info.start); + erase_info.start); return -errno; } /* Mark ERASED where we just erased */ - flash_set_bytemap(context, erase_info.start, erase_info.length, - FLASH_ERASED); + mtd_set_bytemap(backend, erase_info.start, erase_info.length, + FLASH_ERASED); } return 0; @@ -226,32 +245,33 @@ int flash_erase(struct mbox_context *context, uint32_t offset, uint32_t count) #define CHUNKSIZE (64 * 1024) /* - * flash_copy() - Copy data from the flash device into a provided buffer - * @context: The mbox context pointer + * mtd_copy() - Copy data from the flash device into a provided buffer + * @context: The backend context pointer * @offset: The flash offset to copy from (bytes) * @mem: The buffer to copy into (must be of atleast 'size' bytes) * @size: The number of bytes to copy * Return: Number of bytes copied on success, otherwise negative error - * code. flash_copy will copy at most 'size' bytes, but it may + * code. mtd_copy will copy at most 'size' bytes, but it may * copy less. */ -int64_t flash_copy(struct mbox_context *context, uint32_t offset, void *mem, - uint32_t size) +static int64_t mtd_copy(struct backend *backend, uint32_t offset, + void *mem, uint32_t size) { + struct mtd_data *priv = backend->priv; int32_t size_read; void *start = mem; - MSG_DBG("Copy flash to %p for size 0x%.8x from offset 0x%.8x\n", - mem, size, offset); - if (lseek(context->fds[MTD_FD].fd, offset, SEEK_SET) != offset) { + MSG_DBG("Copy flash to %p for size 0x%.8x from offset 0x%.8x\n", mem, + size, offset); + if (lseek(priv->fd, offset, SEEK_SET) != offset) { MSG_ERR("Couldn't seek flash at pos: %u %s\n", offset, strerror(errno)); return -errno; } do { - size_read = read(context->fds[MTD_FD].fd, mem, - min_u32(CHUNKSIZE, size)); + size_read = read(priv->fd, mem, + min_u32(CHUNKSIZE, size)); if (size_read < 0) { MSG_ERR("Couldn't copy mtd into ram: %s\n", strerror(errno)); @@ -266,7 +286,7 @@ int64_t flash_copy(struct mbox_context *context, uint32_t offset, void *mem, } /* - * flash_write() - Write the flash from a provided buffer + * mtd_write() - Write the flash from a provided buffer * @context: The mbox context pointer * @offset: The flash offset to write to (bytes) * @buf: The buffer to write from (must be of atleast size) @@ -274,33 +294,78 @@ int64_t flash_copy(struct mbox_context *context, uint32_t offset, void *mem, * * Return: 0 on success otherwise negative error code */ -int flash_write(struct mbox_context *context, uint32_t offset, void *buf, - uint32_t count) +static int mtd_write(struct backend *backend, uint32_t offset, void *buf, + uint32_t count) { + struct mtd_data *priv = backend->priv; uint32_t buf_offset = 0; int rc; - MSG_DBG("Write flash @ 0x%.8x for 0x%.8x from %p\n", offset, count, buf); + MSG_DBG("Write flash @ 0x%.8x for 0x%.8x from %p\n", offset, count, + buf); - if (lseek(context->fds[MTD_FD].fd, offset, SEEK_SET) != offset) { + if (lseek(priv->fd, offset, SEEK_SET) != offset) { MSG_ERR("Couldn't seek flash at pos: %u %s\n", offset, strerror(errno)); return -errno; } while (count) { - rc = write(context->fds[MTD_FD].fd, buf + buf_offset, count); + rc = write(priv->fd, buf + buf_offset, count); if (rc < 0) { MSG_ERR("Couldn't write to flash, write lost: %s\n", strerror(errno)); return -errno; } /* Mark *NOT* erased where we just wrote */ - flash_set_bytemap(context, offset + buf_offset, rc, - FLASH_DIRTY); + mtd_set_bytemap(backend, offset + buf_offset, rc, FLASH_DIRTY); count -= rc; buf_offset += rc; } return 0; } + +/* + * mtd_reset() - Reset the lpc bus mapping + * @context: The mbox context pointer + * + * Return: A value from enum backend_reset_mode, otherwise a negative + * error code + */ +static int mtd_reset(struct backend *backend, + void *buf __attribute__((unused)), + uint32_t count __attribute__((unused))) +{ + return reset_lpc_flash; +} + +static const struct backend_ops mtd_ops = { + .init = mtd_dev_init, + .free = mtd_dev_free, + .copy = mtd_copy, + .set_bytemap = mtd_set_bytemap, + .erase = mtd_erase, + .write = mtd_write, + .validate = NULL, + .reset = mtd_reset, +}; + +struct backend backend_get_mtd(void) +{ + struct backend be = {0}; + + be.ops = &mtd_ops; + + return be; +} + +int backend_probe_mtd(struct backend *master, const char *path) +{ + struct backend with; + + assert(master); + with = backend_get_mtd(); + + return backend_init(master, &with, (void *)path); +} diff --git a/mtd/backend.h b/mtd/backend.h new file mode 100644 index 0000000..0f64215 --- /dev/null +++ b/mtd/backend.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright (C) 2019 IBM Corp. */ + +#ifndef MTD_BACKEND_H +#define MTD_BACKEND_H + +struct mtd_data { + int fd; + uint8_t *flash_bmap; + struct mtd_info_user mtd_info; +}; + +#endif @@ -4,9 +4,10 @@ #include <errno.h> #include <stdint.h> +#include <stdio.h> +#include "backend.h" #include "common.h" -#include "flash.h" #include "lpc.h" #include "mboxd.h" #include "protocol.h" @@ -77,11 +78,12 @@ int protocol_events_clear(struct mbox_context *context, uint8_t bmc_event) return context->transport->clear_events(context, bmc_event, mask); } +static int protocol_negotiate_version(struct mbox_context *context, + uint8_t requested); + static int protocol_v1_reset(struct mbox_context *context) { - /* Host requested it -> No BMC Event */ - windows_reset_all(context); - return lpc_reset(context); + return __protocol_reset(context); } static int protocol_negotiate_version(struct mbox_context *context, @@ -109,26 +111,26 @@ static int protocol_v1_get_info(struct mbox_context *context, io->resp.api_version = rc; /* Now do all required intialisation for v1 */ - context->block_size_shift = BLOCK_SIZE_SHIFT_V1; + context->backend.block_size_shift = BLOCK_SIZE_SHIFT_V1; MSG_INFO("Block Size: 0x%.8x (shift: %u)\n", - 1 << context->block_size_shift, context->block_size_shift); + 1 << context->backend.block_size_shift, context->backend.block_size_shift); /* Knowing blocksize we can allocate the window dirty_bytemap */ windows_alloc_dirty_bytemap(context); io->resp.v1.read_window_size = - context->windows.default_size >> context->block_size_shift; + context->windows.default_size >> context->backend.block_size_shift; io->resp.v1.write_window_size = - context->windows.default_size >> context->block_size_shift; + context->windows.default_size >> context->backend.block_size_shift; return lpc_map_memory(context); } static int protocol_v1_get_flash_info(struct mbox_context *context, - struct protocol_get_flash_info *io) + struct protocol_get_flash_info *io) { - io->resp.v1.flash_size = context->flash_size; - io->resp.v1.erase_size = context->mtd_info.erasesize; + io->resp.v1.flash_size = context->backend.flash_size; + io->resp.v1.erase_size = 1 << context->backend.erase_size_shift; return 0; } @@ -150,17 +152,20 @@ static inline uint16_t get_lpc_addr_shifted(struct mbox_context *context) MSG_DBG("LPC address of current window: 0x%.8x\n", lpc_addr); - return lpc_addr >> context->block_size_shift; + return lpc_addr >> context->backend.block_size_shift; } static int protocol_v1_create_window(struct mbox_context *context, struct protocol_create_window *io) { - uint32_t offset = io->req.offset << context->block_size_shift; - uint32_t size = io->req.size << context->block_size_shift; + struct backend *backend = &context->backend; + uint32_t offset; + uint32_t size; int rc; - rc = flash_validate(context, offset, size, io->req.ro); + offset = io->req.offset << backend->block_size_shift; + size = io->req.size << backend->block_size_shift; + rc = backend_validate(backend, offset, size, io->req.ro); if (rc < 0) { /* Backend does not allow window to be created. */ return rc; @@ -227,11 +232,11 @@ static int protocol_v1_mark_dirty(struct mbox_context *context, /* For V1 offset given relative to flash - we want the window */ off = offset - ((context->current->flash_offset) >> - context->block_size_shift); + context->backend.block_size_shift); if (off > offset) { /* Underflow - before current window */ MSG_ERR("Tried to mark dirty before start of window\n"); MSG_ERR("requested offset: 0x%x window start: 0x%x\n", - offset << context->block_size_shift, + offset << context->backend.block_size_shift, context->current->flash_offset); return -EINVAL; } @@ -241,12 +246,12 @@ static int protocol_v1_mark_dirty(struct mbox_context *context, * For protocol V1 we can get away with just marking the whole * block dirty. */ - size = align_up(size, 1 << context->block_size_shift); - size >>= context->block_size_shift; + size = align_up(size, 1 << context->backend.block_size_shift); + size >>= context->backend.block_size_shift; MSG_INFO("Dirty window @ 0x%.8x for 0x%.8x\n", - offset << context->block_size_shift, - size << context->block_size_shift); + offset << context->backend.block_size_shift, + size << context->backend.block_size_shift); return window_set_bytemap(context, context->current, offset, size, WINDOW_DIRTY); @@ -270,7 +275,7 @@ static int generic_flush(struct mbox_context *context) * (dirty/erased) changes we perform the required action on the backing * store and update the current streak-type */ - for (i = 0; i < (context->current->size >> context->block_size_shift); + for (i = 0; i < (context->current->size >> context->backend.block_size_shift); i++) { uint8_t cur = context->current->dirty_bmap[i]; if (cur != WINDOW_CLEAN) { @@ -312,7 +317,7 @@ static int generic_flush(struct mbox_context *context) /* Clear the dirty bytemap since we have written back all changes */ return window_set_bytemap(context, context->current, 0, context->current->size >> - context->block_size_shift, + context->backend.block_size_shift, WINDOW_CLEAN); } @@ -416,14 +421,14 @@ static int protocol_v2_get_info(struct mbox_context *context, io->resp.api_version = rc; /* Now do all required intialisation for v2 */ - context->block_size_shift = log_2(context->mtd_info.erasesize); - MSG_INFO("Block Size: 0x%.8x (shift: %u)\n", - 1 << context->block_size_shift, context->block_size_shift); /* Knowing blocksize we can allocate the window dirty_bytemap */ windows_alloc_dirty_bytemap(context); - io->resp.v2.block_size_shift = context->block_size_shift; + io->resp.v2.block_size_shift = context->backend.block_size_shift; + MSG_INFO("Block Size: 0x%.8x (shift: %u)\n", + 1 << context->backend.block_size_shift, context->backend.block_size_shift); + io->resp.v2.timeout = get_suggested_timeout(context); return lpc_map_memory(context); @@ -432,10 +437,12 @@ static int protocol_v2_get_info(struct mbox_context *context, static int protocol_v2_get_flash_info(struct mbox_context *context, struct protocol_get_flash_info *io) { + struct backend *backend = &context->backend; + io->resp.v2.flash_size = - context->flash_size >> context->block_size_shift; + backend->flash_size >> backend->block_size_shift; io->resp.v2.erase_size = - context->mtd_info.erasesize >> context->block_size_shift; + ((1 << backend->erase_size_shift) >> backend->block_size_shift); return 0; } @@ -449,9 +456,9 @@ static int protocol_v2_create_window(struct mbox_context *context, if (rc < 0) return rc; - io->resp.size = context->current->size >> context->block_size_shift; + io->resp.size = context->current->size >> context->backend.block_size_shift; io->resp.offset = context->current->flash_offset >> - context->block_size_shift; + context->backend.block_size_shift; return 0; } @@ -465,8 +472,8 @@ static int protocol_v2_mark_dirty(struct mbox_context *context, } MSG_INFO("Dirty window @ 0x%.8x for 0x%.8x\n", - io->req.v2.offset << context->block_size_shift, - io->req.v2.size << context->block_size_shift); + io->req.v2.offset << context->backend.block_size_shift, + io->req.v2.size << context->backend.block_size_shift); return window_set_bytemap(context, context->current, io->req.v2.offset, io->req.v2.size, WINDOW_DIRTY); @@ -484,8 +491,8 @@ static int protocol_v2_erase(struct mbox_context *context, } MSG_INFO("Erase window @ 0x%.8x for 0x%.8x\n", - io->req.offset << context->block_size_shift, - io->req.size << context->block_size_shift); + io->req.offset << context->backend.block_size_shift, + io->req.size << context->backend.block_size_shift); rc = window_set_bytemap(context, context->current, io->req.offset, io->req.size, WINDOW_ERASED); @@ -494,8 +501,8 @@ static int protocol_v2_erase(struct mbox_context *context, } /* Write 0xFF to mem -> This ensures consistency between flash & ram */ - start = io->req.offset << context->block_size_shift; - len = io->req.size << context->block_size_shift; + start = io->req.offset << context->backend.block_size_shift; + len = io->req.size << context->backend.block_size_shift; memset(context->current->mem + start, 0xFF, len); return 0; @@ -597,9 +604,24 @@ void protocol_free(struct mbox_context *context) /* Don't do any state manipulation, just perform the reset */ int __protocol_reset(struct mbox_context *context) { + enum backend_reset_mode mode; + int rc; + windows_reset_all(context); - return lpc_reset(context); + rc = backend_reset(&context->backend, context->mem, context->mem_size); + if (rc < 0) + return rc; + + mode = rc; + if (!(mode == reset_lpc_flash || mode == reset_lpc_memory)) + return -EINVAL; + + if (mode == reset_lpc_flash) + return lpc_map_flash(context); + + assert(mode == reset_lpc_memory); + return lpc_map_memory(context); } /* Prevent the host from performing actions whilst reset takes place */ diff --git a/test/Makefile.am.include b/test/Makefile.am.include index 195e451..2b7ba75 100644 --- a/test/Makefile.am.include +++ b/test/Makefile.am.include @@ -2,20 +2,23 @@ test_sanity_SOURCES = %reldir%/sanity.c test_flash_copy_SOURCES = \ %reldir%/flash_copy.c \ - flash.c \ + mtd/backend.c \ + lpc.c \ common.c mtd.c \ %reldir%/tmpf.c \ %reldir%/system.c test_flash_erase_SOURCES = \ %reldir%/flash_erase.c \ - flash.c \ + mtd/backend.c \ + lpc.c \ common.c \ %reldir%/tmpf.c test_flash_write_SOURCES = \ %reldir%/flash_write.c \ - flash.c \ + mtd/backend.c \ + lpc.c \ common.c \ %reldir%/tmpf.c @@ -23,12 +26,16 @@ TEST_MBOX_SRCS = \ transport_mbox.c \ windows.c \ lpc.c \ - lpc_reset.c \ common.c \ - flash.c \ protocol.c -TEST_MOCK_SRCS = %reldir%/tmpf.c %reldir%/mbox.c %reldir%/system.c +TEST_MOCK_CORE = \ + %reldir%/tmpf.c \ + mtd/backend.c \ + %reldir%/mbox.c \ + %reldir%/system.c + +TEST_MOCK_SRCS = %reldir%/backend.c $(TEST_MOCK_CORE) test_get_mbox_info_v2_SOURCES = %reldir%/get_mbox_info_v2.c \ $(TEST_MBOX_SRCS) $(TEST_MOCK_SRCS) diff --git a/test/backend.c b/test/backend.c new file mode 100644 index 0000000..7b9fec8 --- /dev/null +++ b/test/backend.c @@ -0,0 +1,11 @@ +#include "backend.h" +#include "mboxd.h" + +#include <errno.h> + +struct backend backend_get_vpnor(void) +{ + struct backend be = {0}; + + return be; +} diff --git a/test/flash_copy.c b/test/flash_copy.c index 3b88b76..472315b 100644 --- a/test/flash_copy.c +++ b/test/flash_copy.c @@ -11,7 +11,7 @@ #include "common.h" #include "mboxd.h" -#include "flash.h" +#include "backend.h" #include "test/system.h" #include "test/tmpf.h" @@ -69,12 +69,15 @@ int main(void) goto free; } - context.fds[MTD_FD].fd = tmp.fd; + assert(!backend_probe_mtd(&context.backend, tmp.path)); flash_copy(&context, 0, dst, TEST_SIZE); assert(0 == memcmp(src, dst, TEST_SIZE)); + backend_free(&context.backend); + free: + free(src); free(dst); diff --git a/test/flash_erase.c b/test/flash_erase.c index 3d299dd..ad4e535 100644 --- a/test/flash_erase.c +++ b/test/flash_erase.c @@ -13,7 +13,7 @@ #include "common.h" #include "mboxd.h" -#include "flash.h" +#include "backend.h" #include "test/tmpf.h" @@ -32,7 +32,7 @@ char *get_dev_mtd(void) if (rc < 0) return NULL; - return strdup(mtd.path); + return mtd.path; } struct erase_info_user *recorded; @@ -98,10 +98,13 @@ void dump_ioctls(void) int main(void) { - struct mbox_context context; + struct mbox_context context = {0}; + struct backend *backend; char data[MEM_SIZE]; int rc; + backend = &context.backend; + rc = atexit(cleanup_mtd); if (rc) return rc; @@ -111,7 +114,7 @@ int main(void) n_ioctls = 0; recorded = NULL; - flash_dev_init(&context); + assert(!backend_probe_mtd(backend, get_dev_mtd())); /* Erase from an unknown state */ rc = flash_erase(&context, 0, sizeof(data)); @@ -206,7 +209,7 @@ int main(void) recorded = NULL; n_ioctls = 0; - flash_dev_free(&context); + backend_free(backend); return rc; } diff --git a/test/flash_write.c b/test/flash_write.c index 1b55dbe..168b2aa 100644 --- a/test/flash_write.c +++ b/test/flash_write.c @@ -12,7 +12,7 @@ #include "common.h" #include "mboxd.h" -#include "flash.h" +#include "backend.h" #include "test/tmpf.h" @@ -31,7 +31,7 @@ char *get_dev_mtd(void) if (rc < 0) return NULL; - return strdup(tmp->path); + return tmp->path; } #define MEM_SIZE 3 @@ -58,6 +58,7 @@ int ioctl(int fd, unsigned long request, ...) int main(void) { struct mbox_context _context, *context = &_context; + struct backend *backend = &context->backend; char src[MEM_SIZE]; uint8_t *map; int rc; @@ -66,7 +67,7 @@ int main(void) mbox_vlog = &mbox_log_console; - rc = flash_dev_init(context); + rc = backend_probe_mtd(backend, get_dev_mtd()); assert(rc == 0); map = mmap(NULL, MEM_SIZE, PROT_READ, MAP_PRIVATE, tmp->fd, 0); @@ -102,7 +103,7 @@ int main(void) rc = memcmp(src, map, sizeof(src)); assert(rc == 0); - flash_dev_free(context); + backend_free(backend); return rc; } diff --git a/test/implicit_flush.c b/test/implicit_flush.c index 74275e4..f186d19 100644 --- a/test/implicit_flush.c +++ b/test/implicit_flush.c @@ -5,6 +5,7 @@ #include <sys/mman.h> #include "mboxd.h" +#include "mtd/backend.h" #include "transport_mbox.h" #include "test/mbox.h" @@ -92,7 +93,7 @@ int flush_on_close(struct mbox_context *ctx) assert(rc == 0); map = mmap(NULL, MEM_SIZE, PROT_READ, MAP_PRIVATE, - ctx->fds[MTD_FD].fd, 0); + ((struct mtd_data *)ctx->backend.priv)->fd, 0); assert(map != MAP_FAILED); rc = memcmp(finish_data, map, sizeof(finish_data)); @@ -124,7 +125,7 @@ int flush_on_create(struct mbox_context *ctx) assert(rc == 0); map = mmap(NULL, MEM_SIZE, PROT_READ, MAP_PRIVATE, - ctx->fds[MTD_FD].fd, 0); + ((struct mtd_data *)ctx->backend.priv)->fd, 0); assert(map != MAP_FAILED); rc = memcmp(finish_data, map, sizeof(finish_data)); diff --git a/test/mark_write_erased_v2.c b/test/mark_write_erased_v2.c index 9c0f172..95cff4b 100644 --- a/test/mark_write_erased_v2.c +++ b/test/mark_write_erased_v2.c @@ -5,6 +5,7 @@ #include <sys/mman.h> #include "mboxd.h" +#include "mtd/backend.h" #include "transport_mbox.h" #include "test/mbox.h" @@ -74,7 +75,7 @@ int main(void) assert(rc == 0); map = mmap(NULL, MEM_SIZE, PROT_READ, MAP_PRIVATE, - ctx->fds[MTD_FD].fd, 0); + ((struct mtd_data *)ctx->backend.priv)->fd, 0); assert(map != MAP_FAILED); rc = memcmp(start_data, map, sizeof(start_data)); diff --git a/test/mbox.c b/test/mbox.c index a351250..55af00c 100644 --- a/test/mbox.c +++ b/test/mbox.c @@ -8,13 +8,15 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/ioctl.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> +#include "config.h" #include "mboxd.h" -#include "flash.h" +#include "backend.h" #include "lpc.h" #include "transport_mbox.h" #include "windows.h" @@ -212,8 +214,9 @@ void cleanup(void) int __transport_mbox_init(struct mbox_context *context, const char *path); int __lpc_dev_init(struct mbox_context *context, const char *path); -struct mbox_context *mbox_create_test_context(int n_windows, size_t len) +struct mbox_context *mbox_create_frontend_context(int n_windows, size_t len) { + struct mtd_info_user mtd_info; int rc; mbox_vlog = &mbox_log_console; @@ -224,9 +227,6 @@ struct mbox_context *mbox_create_test_context(int n_windows, size_t len) rc = tmpf_init(&test.mbox, "mbox-store.XXXXXX"); assert(rc == 0); - rc = tmpf_init(&test.flash, "flash-store.XXXXXX"); - assert(rc == 0); - rc = tmpf_init(&test.lpc, "lpc-store.XXXXXX"); assert(rc == 0); @@ -247,12 +247,18 @@ struct mbox_context *mbox_create_test_context(int n_windows, size_t len) assert(rc == 0); test.context.fds[MBOX_FD].fd = test.mbox.fd; - rc = flash_dev_init(&test.context); + /* Instantiate the mtd backend */ + rc = tmpf_init(&test.flash, "flash-store.XXXXXX"); assert(rc == 0); - rc = fallocate(test.flash.fd, 0, 0, test.context.mtd_info.size); + rc = ioctl(test.flash.fd, MEMGETINFO, &mtd_info); assert(rc == 0); + rc = fallocate(test.flash.fd, 0, 0, mtd_info.size); + assert(rc == 0); + + test.context.backend.flash_size = mtd_info.size; + rc = __lpc_dev_init(&test.context, test.lpc.path); assert(rc == 0); @@ -265,6 +271,20 @@ struct mbox_context *mbox_create_test_context(int n_windows, size_t len) return rc ? NULL : &test.context; } +struct mbox_context *mbox_create_test_context(int n_windows, size_t len) +{ + struct mbox_context *ctx; + int rc; + + ctx = mbox_create_frontend_context(n_windows, len); + assert(ctx); + + rc = backend_probe_mtd(&ctx->backend, test.flash.path); + assert(rc == 0); + + return ctx; +} + /* From ccan's container_of module, CC0 license */ #define container_of(member_ptr, containing_type, member) \ ((containing_type *) \ @@ -295,13 +315,13 @@ int mbox_set_mtd_data(struct mbox_context *context, const void *data, /* Sanity check */ arg = container_of(context, struct mbox_test_context, context); assert(&test == arg); - assert(len <= test.context.flash_size); + assert(len <= test.context.backend.flash_size); - map = mmap(NULL, test.context.mtd_info.size, PROT_WRITE, MAP_SHARED, - test.flash.fd, 0); + map = mmap(NULL, test.context.backend.flash_size, + PROT_WRITE, MAP_SHARED, test.flash.fd, 0); assert(map != MAP_FAILED); memcpy(map, data, len); - munmap(map, test.context.mtd_info.size); + munmap(map, test.context.backend.flash_size); return 0; } diff --git a/test/mbox.h b/test/mbox.h index 8c1bff9..a030b7d 100644 --- a/test/mbox.h +++ b/test/mbox.h @@ -14,6 +14,7 @@ #include "tmpf.h" struct mbox_context *mbox_create_test_context(int n_windows, size_t len); +struct mbox_context *mbox_create_frontend_context(int n_windows, size_t len); int mbox_set_mtd_data(struct mbox_context *context, const void *data, size_t len); diff --git a/test/write_flush_v2.c b/test/write_flush_v2.c index fafa7d0..b53550d 100644 --- a/test/write_flush_v2.c +++ b/test/write_flush_v2.c @@ -5,6 +5,7 @@ #include <sys/mman.h> #include "mboxd.h" +#include "mtd/backend.h" #include "transport_mbox.h" #include "test/mbox.h" @@ -95,7 +96,7 @@ int main(void) assert(rc == 0); map = mmap(NULL, MEM_SIZE, PROT_READ, MAP_PRIVATE, - ctx->fds[MTD_FD].fd, 0); + ((struct mtd_data *)ctx->backend.priv)->fd, 0); assert(map != MAP_FAILED); rc = memcmp(flush_middle_data, map, sizeof(flush_middle_data)); diff --git a/test/write_window_dirty_erase.c b/test/write_window_dirty_erase.c index e839890..15f0bc3 100644 --- a/test/write_window_dirty_erase.c +++ b/test/write_window_dirty_erase.c @@ -5,6 +5,7 @@ #include <sys/mman.h> #include "mboxd.h" +#include "mtd/backend.h" #include "transport_mbox.h" #include "test/mbox.h" @@ -114,7 +115,7 @@ int main(void) assert(rc == 0); map = mmap(NULL, MEM_SIZE, PROT_READ, MAP_PRIVATE, - ctx->fds[MTD_FD].fd, 0); + ((struct mtd_data *)ctx->backend.priv)->fd, 0); assert(map != MAP_FAILED); rc = memcmp(flush_dirty_erased_dirty_data, map, diff --git a/transport_mbox.c b/transport_mbox.c index 852c0a4..3d71820 100644 --- a/transport_mbox.c +++ b/transport_mbox.c @@ -264,7 +264,7 @@ static inline uint16_t get_lpc_addr_shifted(struct mbox_context *context) MSG_DBG("LPC address of current window: 0x%.8x\n", lpc_addr); - return lpc_addr >> context->block_size_shift; + return lpc_addr >> context->backend.block_size_shift; } static int mbox_handle_create_window(struct mbox_context *context, bool ro, diff --git a/vpnor/Makefile.am.include b/vpnor/Makefile.am.include index 36e3c50..d69a94b 100644 --- a/vpnor/Makefile.am.include +++ b/vpnor/Makefile.am.include @@ -1,8 +1,7 @@ mboxd_SOURCES += %reldir%/pnor_partition_table.cpp \ %reldir%/mboxd_pnor_partition_table.cpp \ - %reldir%/flash.cpp \ - %reldir%/pnor_partition.cpp \ - %reldir%/lpc_reset.cpp + %reldir%/backend.cpp \ + %reldir%/pnor_partition.cpp mboxd_LDFLAGS += -lstdc++fs \ $(SDBUSPLUS_LIBS) \ diff --git a/vpnor/flash.cpp b/vpnor/backend.cpp index 847e6a5..ccda4ec 100644 --- a/vpnor/flash.cpp +++ b/vpnor/backend.cpp @@ -13,7 +13,9 @@ extern "C" { #include "common.h" -#include "flash.h" +#include "lpc.h" +#include "mboxd.h" +#include "protocol.h" } #include "config.h" @@ -35,104 +37,107 @@ namespace err = sdbusplus::xyz::openbmc_project::Common::Error; namespace fs = std::experimental::filesystem; namespace vpnor = openpower::virtual_pnor; -/** @brief unique_ptr functor to release a char* reference. */ -struct StringDeleter -{ - void operator()(char* ptr) const - { - free(ptr); - } -}; -using StringPtr = std::unique_ptr<char, StringDeleter>; +static constexpr uint32_t VPNOR_ERASE_SIZE = 4 * 1024; -int flash_dev_init(struct mbox_context* context) +int vpnor_dev_init(struct backend* backend, void* data) { - StringPtr filename(get_dev_mtd()); - int fd = 0; + vpnor_partition_paths* paths = (vpnor_partition_paths*)data; + struct mtd_info_user mtd_info; + const char* filename = NULL; + int fd; int rc = 0; - if (!filename) + if (!(fs::is_directory(fs::status(paths->ro_loc)) && + fs::is_directory(fs::status(paths->rw_loc)) && + fs::is_directory(fs::status(paths->prsv_loc)))) { - MSG_ERR("Couldn't find the flash /dev/mtd partition\n"); - return -1; + return -EINVAL; } - MSG_DBG("Opening %s\n", filename.get()); - - fd = open(filename.get(), O_RDWR); - if (fd < 0) + if (backend->flash_size == 0) { - MSG_ERR("Couldn't open %s with flags O_RDWR: %s\n", filename.get(), - strerror(errno)); - return -errno; - } + filename = get_dev_mtd(); + + MSG_INFO("No flash size provided, using PNOR MTD size\n"); + + if (!filename) + { + MSG_ERR("Couldn't find the flash /dev/mtd partition\n"); + return -errno; + } + + MSG_DBG("Opening %s\n", filename); + + fd = open(filename, O_RDWR); + if (fd < 0) + { + MSG_ERR("Couldn't open %s with flags O_RDWR: %s\n", filename, + strerror(errno)); + rc = -errno; + goto cleanup_filename; + } + + // Read the Flash Info + if (ioctl(fd, MEMGETINFO, &mtd_info) == -1) + { + MSG_ERR("Couldn't get information about MTD: %s\n", + strerror(errno)); + rc = -errno; + goto cleanup_fd; + } - // Read the Flash Info - if (ioctl(fd, MEMGETINFO, &context->mtd_info) == -1) - { - MSG_ERR("Couldn't get information about MTD: %s\n", strerror(errno)); close(fd); - return -errno; - } + free((void*)filename); - if (context->flash_size == 0) - { - // See comment in mboxd_flash_physical.c on why + // See comment in flash.c on why // this is needed. - context->flash_size = context->mtd_info.size; + backend->flash_size = mtd_info.size; } // Hostboot requires a 4K block-size to be used in the FFS flash structure - context->mtd_info.erasesize = 4096; - context->erase_size_shift = log_2(context->mtd_info.erasesize); - context->flash_bmap = NULL; - context->fds[MTD_FD].fd = -1; + backend->erase_size_shift = log_2(VPNOR_ERASE_SIZE); + backend->block_size_shift = backend->erase_size_shift; + + return vpnor_init(backend, paths); +cleanup_fd: close(fd); - return rc; -} -void flash_dev_free(struct mbox_context* context) -{ - // No-op -} +cleanup_filename: + free((void*)filename); -int flash_set_bytemap(struct mbox_context* context, uint32_t offset, - uint32_t count, uint8_t val) -{ - // No-op - return 0; + return rc; } -int flash_erase(struct mbox_context* context, uint32_t offset, uint32_t count) +static void vpnor_free(struct backend* backend) { - // No-op - return 0; + vpnor_destroy(backend); } /* - * flash_copy() - Copy data from the virtual pnor into a provided buffer - * @context: The mbox context pointer + * vpnor_copy() - Copy data from the virtual pnor into a provided buffer + * @context: The backend context pointer * @offset: The pnor offset to copy from (bytes) * @mem: The buffer to copy into (must be of atleast 'size' bytes) * @size: The number of bytes to copy * Return: Number of bytes copied on success, otherwise negative error - * code. flash_copy will copy at most 'size' bytes, but it may + * code. vpnor_copy will copy at most 'size' bytes, but it may * copy less. */ -int64_t flash_copy(struct mbox_context* context, uint32_t offset, void* mem, - uint32_t size) +static int64_t vpnor_copy(struct backend* backend, uint32_t offset, void* mem, + uint32_t size) { + struct vpnor_data* priv = (struct vpnor_data*)backend->priv; vpnor::partition::Table* table; int rc = size; - if (!(context && context->vpnor && context->vpnor->table)) + if (!(priv->vpnor && priv->vpnor->table)) { MSG_ERR("Trying to copy data with uninitialised context!\n"); return -EINVAL; } - table = context->vpnor->table; + table = priv->vpnor->table; MSG_DBG("Copy virtual pnor to %p for size 0x%.8x from offset 0x%.8x\n", mem, size, offset); @@ -152,7 +157,7 @@ int64_t flash_copy(struct mbox_context* context, uint32_t offset, void* mem, try { - vpnor::Request req(context, offset); + vpnor::Request req(backend, offset); rc = req.read(mem, size); } catch (vpnor::UnmappedOffset& e) @@ -161,7 +166,7 @@ int64_t flash_copy(struct mbox_context* context, uint32_t offset, void* mem, * Hooo boy. Pretend that this is valid flash so we don't have * discontiguous regions presented to the host. Instead, fill a window * with 0xff so the 'flash' looks erased. Writes to such regions are - * dropped on the floor, see the implementation of flash_write() below. + * dropped on the floor, see the implementation of vpnor_write() below. */ MSG_INFO("Host requested unmapped region of %" PRId32 " bytes at offset 0x%" PRIx32 "\n", @@ -180,8 +185,8 @@ int64_t flash_copy(struct mbox_context* context, uint32_t offset, void* mem, } /* - * flash_write() - Write to the virtual pnor from a provided buffer - * @context: The mbox context pointer + * vpnor_write() - Write to the virtual pnor from a provided buffer + * @context: The backend context pointer * @offset: The flash offset to write to (bytes) * @buf: The buffer to write from (must be of atleast size) * @size: The number of bytes to write @@ -189,17 +194,20 @@ int64_t flash_copy(struct mbox_context* context, uint32_t offset, void* mem, * Return: 0 on success otherwise negative error code */ -int flash_write(struct mbox_context* context, uint32_t offset, void* buf, - uint32_t count) +static int vpnor_write(struct backend* backend, uint32_t offset, void* buf, + uint32_t count) { + assert(backend); + + struct vpnor_data* priv = (struct vpnor_data*)backend->priv; - if (!(context && context->vpnor && context->vpnor->table)) + if (!(priv && priv->vpnor && priv->vpnor->table)) { MSG_ERR("Trying to write data with uninitialised context!\n"); return -EINVAL; } - vpnor::partition::Table* table = context->vpnor->table; + vpnor::partition::Table* table = priv->vpnor->table; try { @@ -214,7 +222,7 @@ int flash_write(struct mbox_context* context, uint32_t offset, void* buf, MSG_DBG("Write flash @ 0x%.8x for 0x%.8x from %p\n", offset, count, buf); - vpnor::Request req(context, offset); + vpnor::Request req(backend, offset); req.write(buf, count); } catch (vpnor::UnmappedOffset& e) @@ -243,9 +251,11 @@ static bool vpnor_partition_is_readonly(const pnor_partition& part) return part.data.user.data[1] & PARTITION_READONLY; } -int flash_validate(struct mbox_context* context, uint32_t offset, - uint32_t size __attribute__((unused)), bool ro) +static int vpnor_validate(struct backend* backend, uint32_t offset, + uint32_t size __attribute__((unused)), bool ro) { + struct vpnor_data* priv = (struct vpnor_data*)backend->priv; + /* All reads are allowed */ if (ro) { @@ -255,7 +265,7 @@ int flash_validate(struct mbox_context* context, uint32_t offset, /* Only allow write windows on regions mapped by the ToC as writeable */ try { - const pnor_partition& part = context->vpnor->table->partition(offset); + const pnor_partition& part = priv->vpnor->table->partition(offset); if (vpnor_partition_is_readonly(part)) { return -EPERM; @@ -271,5 +281,63 @@ int flash_validate(struct mbox_context* context, uint32_t offset, return -EACCES; } + // Allowed. return 0; } + +/* + * vpnor_reset() - Reset the lpc bus mapping + * @context: The mbox context pointer + * + * Return 0 on success otherwise negative error code + */ +static int vpnor_reset(struct backend* backend, void* buf, uint32_t count) +{ + const struct vpnor_data* priv = (const struct vpnor_data*)backend->priv; + int rc; + + vpnor_partition_paths paths = priv->paths; + + vpnor_destroy(backend); + + rc = vpnor_init(backend, &paths); + if (rc < 0) + return rc; + + rc = vpnor_copy_bootloader_partition(backend, buf, count); + if (rc < 0) + return rc; + + return reset_lpc_memory; +} + +static const struct backend_ops vpnor_ops = { + .init = vpnor_dev_init, + .free = vpnor_free, + .copy = vpnor_copy, + .set_bytemap = NULL, + .erase = NULL, + .write = vpnor_write, + .validate = vpnor_validate, + .reset = vpnor_reset, +}; + +struct backend backend_get_vpnor(void) +{ + struct backend be = {0}; + + be.ops = &vpnor_ops; + + return be; +} + +int backend_probe_vpnor(struct backend* master, + const struct vpnor_partition_paths* paths) +{ + struct backend with; + + assert(master); + with = backend_get_vpnor(); + + return backend_init(master, &with, (void*)paths); +} diff --git a/vpnor/lpc_reset.cpp b/vpnor/lpc_reset.cpp deleted file mode 100644 index 80ec6ac..0000000 --- a/vpnor/lpc_reset.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Mailbox Daemon LPC Helpers - * - * Copyright 2017 IBM - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -extern "C" { -#include "lpc.h" -#include "mboxd.h" -} - -#include "mboxd_pnor_partition_table.h" - -/* - * lpc_reset() - Reset the lpc bus mapping - * @context: The mbox context pointer - * - * Return 0 on success otherwise negative error code - */ -int lpc_reset(struct mbox_context* context) -{ - int rc; - - destroy_vpnor(context); - - rc = init_vpnor(context); - if (rc < 0) - return rc; - - rc = vpnor_copy_bootloader_partition(context); - if (rc < 0) - return rc; - - return lpc_map_memory(context); -} diff --git a/vpnor/mboxd_pnor_partition_table.cpp b/vpnor/mboxd_pnor_partition_table.cpp index a6ebd4e..394cc18 100644 --- a/vpnor/mboxd_pnor_partition_table.cpp +++ b/vpnor/mboxd_pnor_partition_table.cpp @@ -1,11 +1,13 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (C) 2018 IBM Corp. +#include "config.h" + +#include <assert.h> + extern "C" { -#include "flash.h" +#include "backend.h" } -#include "config.h" - #include "pnor_partition_table.hpp" #include "xyz/openbmc_project/Common/error.hpp" @@ -16,57 +18,58 @@ extern "C" { #include "mboxd.h" #include "mboxd_pnor_partition_table.h" -int init_vpnor(struct mbox_context* context) +void vpnor_default_paths(vpnor_partition_paths* paths) { - if (context && !context->vpnor) - { - int rc; - - strncpy(context->paths.ro_loc, PARTITION_FILES_RO_LOC, PATH_MAX); - context->paths.ro_loc[PATH_MAX - 1] = '\0'; - strncpy(context->paths.rw_loc, PARTITION_FILES_RW_LOC, PATH_MAX); - context->paths.rw_loc[PATH_MAX - 1] = '\0'; - strncpy(context->paths.prsv_loc, PARTITION_FILES_PRSV_LOC, PATH_MAX); - context->paths.prsv_loc[PATH_MAX - 1] = '\0'; - strncpy(context->paths.patch_loc, PARTITION_FILES_PATCH_LOC, PATH_MAX); - context->paths.prsv_loc[PATH_MAX - 1] = '\0'; - - rc = init_vpnor_from_paths(context); - if (rc < 0) - { - return rc; - } - } - - return 0; + strncpy(paths->ro_loc, PARTITION_FILES_RO_LOC, PATH_MAX); + paths->ro_loc[PATH_MAX - 1] = '\0'; + strncpy(paths->rw_loc, PARTITION_FILES_RW_LOC, PATH_MAX); + paths->rw_loc[PATH_MAX - 1] = '\0'; + strncpy(paths->prsv_loc, PARTITION_FILES_PRSV_LOC, PATH_MAX); + paths->prsv_loc[PATH_MAX - 1] = '\0'; + strncpy(paths->patch_loc, PARTITION_FILES_PATCH_LOC, PATH_MAX); + paths->prsv_loc[PATH_MAX - 1] = '\0'; } -int init_vpnor_from_paths(struct mbox_context* context) +int vpnor_init(struct backend* backend, const vpnor_partition_paths* paths) { namespace err = sdbusplus::xyz::openbmc_project::Common::Error; namespace fs = std::experimental::filesystem; namespace vpnor = openpower::virtual_pnor; - if (context && !context->vpnor) + if (!(backend && paths)) + return -EINVAL; + + vpnor_data* priv = new vpnor_data; + assert(priv); + + priv->paths = *paths; + backend->priv = priv; + + try + { + priv->vpnor = new vpnor_partition_table; + priv->vpnor->table = + new openpower::virtual_pnor::partition::Table(backend); + } + catch (vpnor::TocEntryError& e) { + MSG_ERR("%s\n", e.what()); try { - context->vpnor = new vpnor_partition_table; - context->vpnor->table = - new openpower::virtual_pnor::partition::Table(context); + phosphor::logging::commit<err::InternalFailure>(); } - catch (vpnor::TocEntryError& e) + catch (const std::exception& e) { - MSG_ERR("%s\n", e.what()); - phosphor::logging::commit<err::InternalFailure>(); - return -EINVAL; + MSG_ERR("Failed to commit InternalFailure: %s\n", e.what()); } + return -EINVAL; } return 0; } -int vpnor_copy_bootloader_partition(const struct mbox_context* context) +int vpnor_copy_bootloader_partition(const struct backend* backend, void* buf, + uint32_t count) { // The hostboot bootloader has certain size/offset assumptions, so // we need a special partition table here. @@ -90,8 +93,12 @@ int vpnor_copy_bootloader_partition(const struct mbox_context* context) try { vpnor_partition_table vtbl{}; - struct mbox_context local = *context; - local.vpnor = &vtbl; + struct vpnor_data priv; + struct backend local = *backend; + + priv.vpnor = &vtbl; + priv.paths = ((struct vpnor_data*)backend->priv)->paths; + local.priv = &priv; local.block_size_shift = log_2(eraseSize); openpower::virtual_pnor::partition::Table blTable(&local); @@ -104,16 +111,16 @@ int vpnor_copy_bootloader_partition(const struct mbox_context* context) size_t hbbOffset = partition.data.base * eraseSize; uint32_t hbbSize = partition.data.actual; - if (context->mem_size < tocStart + blTable.capacity() || - context->mem_size < hbbOffset + hbbSize) + if (count < tocStart + blTable.capacity() || + count < hbbOffset + hbbSize) { MSG_ERR("Reserved memory too small for dumb bootstrap\n"); return -EINVAL; } - uint8_t* buf8 = static_cast<uint8_t*>(context->mem); - flash_copy(&local, tocOffset, buf8 + tocStart, blTable.capacity()); - flash_copy(&local, hbbOffset, buf8 + hbbOffset, hbbSize); + uint8_t* buf8 = static_cast<uint8_t*>(buf); + backend_copy(&local, tocOffset, buf8 + tocStart, blTable.capacity()); + backend_copy(&local, hbbOffset, buf8 + hbbOffset, hbbSize); } catch (err::InternalFailure& e) { @@ -130,12 +137,17 @@ int vpnor_copy_bootloader_partition(const struct mbox_context* context) return 0; } -void destroy_vpnor(struct mbox_context* context) +void vpnor_destroy(struct backend* backend) { - if (context && context->vpnor) + struct vpnor_data* priv = (struct vpnor_data*)backend->priv; + + if (priv) { - delete context->vpnor->table; - delete context->vpnor; - context->vpnor = nullptr; + if (priv->vpnor) + { + delete priv->vpnor->table; + } + delete priv->vpnor; } + delete priv; } diff --git a/vpnor/mboxd_pnor_partition_table.h b/vpnor/mboxd_pnor_partition_table.h index d13a2d2..e325775 100644 --- a/vpnor/mboxd_pnor_partition_table.h +++ b/vpnor/mboxd_pnor_partition_table.h @@ -6,6 +6,7 @@ #include <limits.h> #include "pnor_partition_defs.h" +#include "backend.h" struct mbox_context; struct vpnor_partition_table; @@ -18,47 +19,55 @@ struct vpnor_partition_paths char patch_loc[PATH_MAX]; }; +struct vpnor_data { + struct vpnor_partition_table *vpnor; + struct vpnor_partition_paths paths; +}; + #ifdef __cplusplus extern "C" { #endif -/** @brief Create a virtual PNOR partition table. +/** @brief Populate the path object with the default partition paths * - * @param[in] context - mbox context pointer - * - * This API should be called before calling any other APIs below. If a table - * already exists, this function will not do anything further. This function - * will not do anything if the context is NULL. + * @param[in/out] paths - A paths object in which to store the defaults * * Returns 0 if the call succeeds, else a negative error code. */ -int init_vpnor(struct mbox_context *context); +void vpnor_default_paths(struct vpnor_partition_paths *paths); /** @brief Create a virtual PNOR partition table. * - * @param[in] context - mbox context pointer + * @param[in] backend - The backend context pointer + * @param[in] paths - A paths object pointer to initialise vpnor + * + * This API should be called before calling any other APIs below. If a table + * already exists, this function will not do anything further. This function + * will not do anything if the context is NULL. * - * This API is same as above one but requires context->path is initialised - * with all the necessary paths. + * The content of the paths object is copied out, ownership is retained by the + * caller. * * Returns 0 if the call succeeds, else a negative error code. */ -int init_vpnor_from_paths(struct mbox_context *context); +int vpnor_init(struct backend *backend, + const struct vpnor_partition_paths *paths); /** @brief Copy bootloader partition (alongwith TOC) to LPC memory * - * @param[in] context - mbox context pointer + * @param[in] backend - The backend context pointer * * @returns 0 on success, negative error code on failure */ -int vpnor_copy_bootloader_partition(const struct mbox_context *context); +int vpnor_copy_bootloader_partition(const struct backend *backend, void *buf, + uint32_t count); /** @brief Destroy partition table, if it exists. * - * @param[in] context - mbox context pointer + * @param[in] backend - The backend context pointer */ -void destroy_vpnor(struct mbox_context *context); +void vpnor_destroy(struct backend *backend); #ifdef __cplusplus } diff --git a/vpnor/pnor_partition.cpp b/vpnor/pnor_partition.cpp index 613ee26..9854159 100644 --- a/vpnor/pnor_partition.cpp +++ b/vpnor/pnor_partition.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (C) 2018 IBM Corp. extern "C" { -#include "flash.h" +#include "mboxd.h" } #include "config.h" @@ -39,8 +39,10 @@ namespace fs = std::experimental::filesystem; fs::path Request::getPartitionFilePath(int flags) { + struct vpnor_data* priv = (struct vpnor_data*)backend->priv; + // Check if partition exists in patch location - auto dst = fs::path(ctx->paths.patch_loc) / partition.data.name; + auto dst = fs::path(priv->paths.patch_loc) / partition.data.name; if (fs::is_regular_file(dst)) { return dst; @@ -50,15 +52,15 @@ fs::path Request::getPartitionFilePath(int flags) (PARTITION_PRESERVED | PARTITION_READONLY)) { case PARTITION_PRESERVED: - dst = ctx->paths.prsv_loc; + dst = priv->paths.prsv_loc; break; case PARTITION_READONLY: - dst = ctx->paths.ro_loc; + dst = priv->paths.ro_loc; break; default: - dst = ctx->paths.rw_loc; + dst = priv->paths.rw_loc; } dst /= partition.data.name; @@ -69,22 +71,22 @@ fs::path Request::getPartitionFilePath(int flags) if (flags == O_RDONLY) { - dst = fs::path(ctx->paths.ro_loc) / partition.data.name; + dst = fs::path(priv->paths.ro_loc) / partition.data.name; assert(fs::exists(dst)); return dst; } assert(flags == O_RDWR); - auto src = fs::path(ctx->paths.ro_loc) / partition.data.name; + auto src = fs::path(priv->paths.ro_loc) / partition.data.name; assert(fs::exists(src)); MSG_DBG("RWRequest: Didn't find '%s' under '%s', copying from '%s'\n", partition.data.name, dst.c_str(), src.c_str()); - dst = ctx->paths.rw_loc; + dst = priv->paths.rw_loc; if (partition.data.user.data[1] & PARTITION_PRESERVED) { - dst = ctx->paths.prsv_loc; + dst = priv->paths.prsv_loc; } dst /= partition.data.name; @@ -96,7 +98,7 @@ fs::path Request::getPartitionFilePath(int flags) size_t Request::clamp(size_t len) { size_t maxAccess = offset + len; - size_t partSize = partition.data.size << ctx->block_size_shift; + size_t partSize = partition.data.size << backend->block_size_shift; return std::min(maxAccess, partSize) - offset; } @@ -168,7 +170,7 @@ size_t Request::fulfil(const fs::path& path, int flags, void* buf, size_t len) else { memcpy((char*)map + offset, buf, len); - flash_set_bytemap(ctx, base + offset, len, FLASH_DIRTY); + backend_set_bytemap(backend, base + offset, len, FLASH_DIRTY); } munmap(map, fileSize); close(fd); diff --git a/vpnor/pnor_partition.hpp b/vpnor/pnor_partition.hpp index 95d4309..c91f22e 100644 --- a/vpnor/pnor_partition.hpp +++ b/vpnor/pnor_partition.hpp @@ -3,7 +3,8 @@ #pragma once extern "C" { -#include "mboxd.h" +#include "backend.h" +#include "mboxd_pnor_partition_table.h" }; #include "pnor_partition_table.hpp" @@ -14,8 +15,6 @@ extern "C" { #include <experimental/filesystem> #include <string> -#include "mboxd_pnor_partition_table.h" - namespace openpower { namespace virtual_pnor @@ -28,7 +27,7 @@ class Request public: /** @brief Construct a flash access request * - * @param[in] ctx - The mbox context used to process the request + * @param[in] backend - The backend context used to process the request * @param[in] offset - The absolute offset into the flash device as * provided by the mbox message associated with the * request @@ -37,9 +36,10 @@ class Request * the ctx pointer must strictly exceed the lifetime of the class * instance. */ - Request(struct mbox_context* ctx, size_t offset) : - ctx(ctx), partition(ctx->vpnor->table->partition(offset)), - base(partition.data.base << ctx->block_size_shift), + Request(struct backend* backend, size_t offset) : + backend(backend), partition(((struct vpnor_data*)backend->priv) + ->vpnor->table->partition(offset)), + base(partition.data.base << backend->block_size_shift), offset(offset - base) { } @@ -64,7 +64,8 @@ class Request std::stringstream err; err << "Request size 0x" << std::hex << len << " from offset 0x" << std::hex << offset << " exceeds the partition size 0x" - << std::hex << (partition.data.size << ctx->block_size_shift); + << std::hex + << (partition.data.size << backend->block_size_shift); throw OutOfBoundsOffset(err.str()); } constexpr auto flags = O_RDWR; @@ -132,7 +133,7 @@ class Request size_t fulfil(const std::experimental::filesystem::path& path, int flags, void* dst, size_t len); - struct mbox_context* ctx; + struct backend* backend; const pnor_partition& partition; size_t base; size_t offset; diff --git a/vpnor/pnor_partition_table.cpp b/vpnor/pnor_partition_table.cpp index 7e99ae2..2a9442b 100644 --- a/vpnor/pnor_partition_table.cpp +++ b/vpnor/pnor_partition_table.cpp @@ -14,8 +14,11 @@ #include <phosphor-logging/elog-errors.hpp> #include <regex> +extern "C" { +#include "backend.h" #include "common.h" #include "mboxd.h" +} namespace openpower { @@ -28,11 +31,11 @@ using namespace sdbusplus::xyz::openbmc_project::Common::Error; namespace partition { -Table::Table(const struct mbox_context* ctx) : +Table::Table(const struct backend* be) : szBytes(sizeof(pnor_partition_table)), numParts(0), - blockSize(1 << ctx->erase_size_shift), pnorSize(ctx->flash_size) + blockSize(1 << be->erase_size_shift), pnorSize(be->flash_size) { - preparePartitions(ctx); + preparePartitions((const struct vpnor_data*)be->priv); prepareHeader(); hostTbl = endianFixup(tbl); } @@ -74,10 +77,10 @@ inline void Table::allocateMemory(const fs::path& tocFile) tbl.resize(capacity()); } -void Table::preparePartitions(const struct mbox_context* ctx) +void Table::preparePartitions(const struct vpnor_data* priv) { - const fs::path roDir = ctx->paths.ro_loc; - const fs::path patchDir = ctx->paths.patch_loc; + const fs::path roDir(priv->paths.ro_loc); + const fs::path patchDir(priv->paths.patch_loc); fs::path tocFile = roDir / PARTITION_TOC_FILE; allocateMemory(tocFile); diff --git a/vpnor/pnor_partition_table.hpp b/vpnor/pnor_partition_table.hpp index 8ba432a..90f014c 100644 --- a/vpnor/pnor_partition_table.hpp +++ b/vpnor/pnor_partition_table.hpp @@ -7,8 +7,12 @@ #include <numeric> #include <vector> +extern "C" { +#include "backend.h" #include "common.h" +#include "mboxd_pnor_partition_table.h" #include "pnor_partition_defs.h" +} struct mbox_context; @@ -97,7 +101,7 @@ class Table * * Throws MalformedTocEntry, InvalidTocEntry */ - Table(const struct mbox_context* ctx); + Table(const struct backend* be); Table(const Table&) = delete; Table& operator=(const Table&) = delete; @@ -186,7 +190,7 @@ class Table * * Throws: MalformedTocEntry, InvalidTocEntry */ - void preparePartitions(const struct mbox_context* ctx); + void preparePartitions(const struct vpnor_data* ctx); /** @brief Prepares the PNOR header. */ diff --git a/vpnor/protocol.h b/vpnor/protocol.h deleted file mode 100644 index 8cebda6..0000000 --- a/vpnor/protocol.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* Copyright (C) 2018 IBM Corp. */ -#ifndef VPNOR_PROTOCOL_H -#define VPNOR_PROTOCOL_H - -#include "protocol.h" - -/* Protocol v1 */ -int protocol_v1_vpnor_create_window(struct mbox_context *context, - struct protocol_create_window *io); - -/* Protocol v2 */ -int protocol_v2_vpnor_create_window(struct mbox_context *context, - struct protocol_create_window *io); - -#endif /* VPNOR_PROTOCOL_H */ diff --git a/vpnor/test/Makefile.am.include b/vpnor/test/Makefile.am.include index 5ff4dcc..0600969 100644 --- a/vpnor/test/Makefile.am.include +++ b/vpnor/test/Makefile.am.include @@ -1,7 +1,4 @@ -TEST_MBOX_VPNOR_SRCS = \ - common.c \ - vpnor/pnor_partition_table.cpp \ - %reldir%/tmpd.cpp +TEST_MOCK_VPNOR_SRCS = $(TEST_MOCK_CORE) TEST_MBOX_VPNOR_INTEG_SRCS = \ common.c \ @@ -9,9 +6,8 @@ TEST_MBOX_VPNOR_INTEG_SRCS = \ transport_mbox.c \ windows.c \ lpc.c \ - vpnor/lpc_reset.cpp \ + vpnor/backend.cpp \ vpnor/mboxd_pnor_partition_table.cpp \ - vpnor/flash.cpp \ vpnor/pnor_partition.cpp \ vpnor/pnor_partition_table.cpp \ %reldir%/tmpd.cpp @@ -22,14 +18,14 @@ VPNOR_LDADD = -lstdc++fs \ $(PHOSPHOR_DBUS_INTERFACES_LIBS) vpnor_test_create_pnor_partition_table_SOURCES = \ - $(TEST_MOCK_SRCS) \ + $(TEST_MOCK_VPNOR_SRCS) \ $(TEST_MBOX_VPNOR_INTEG_SRCS) \ %reldir%/create_pnor_partition_table.cpp vpnor_test_create_pnor_partition_table_LDFLAGS = $(OESDK_TESTCASE_FLAGS) vpnor_test_create_pnor_partition_table_LDADD = $(VPNOR_LDADD) vpnor_test_create_read_window_partition_exists_SOURCES = \ - $(TEST_MOCK_SRCS) \ + $(TEST_MOCK_VPNOR_SRCS) \ $(TEST_MBOX_VPNOR_INTEG_SRCS) \ %reldir%/create_read_window_partition_exists.cpp vpnor_test_create_read_window_partition_exists_LDFLAGS = $(OESDK_TESTCASE_FLAGS) @@ -106,63 +102,63 @@ vpnor_test_toc_flags_LDFLAGS = $(OESDK_TESTCASE_FLAGS) vpnor_test_toc_flags_LDADD = $(VPNOR_LDADD) vpnor_test_toc_overlap_SOURCES = \ - $(TEST_MOCK_SRCS) \ + $(TEST_MOCK_VPNOR_SRCS) \ $(TEST_MBOX_VPNOR_INTEG_SRCS) \ %reldir%/toc_overlap.cpp vpnor_test_toc_overlap_LDFLAGS = $(OESDK_TESTCASE_FLAGS) vpnor_test_toc_overlap_LDADD = $(VPNOR_LDADD) vpnor_test_toc_lookup_found_SOURCES = \ - $(TEST_MOCK_SRCS) \ + $(TEST_MOCK_VPNOR_SRCS) \ $(TEST_MBOX_VPNOR_INTEG_SRCS) \ %reldir%/toc_lookup_found.cpp vpnor_test_toc_lookup_found_LDFLAGS = $(OESDK_TESTCASE_FLAGS) vpnor_test_toc_lookup_found_LDADD = $(VPNOR_LDADD) vpnor_test_toc_lookup_failed_SOURCES = \ - $(TEST_MOCK_SRCS) \ + $(TEST_MOCK_VPNOR_SRCS) \ $(TEST_MBOX_VPNOR_INTEG_SRCS) \ %reldir%/toc_lookup_failed.cpp vpnor_test_toc_lookup_failed_LDFLAGS = $(OESDK_TESTCASE_FLAGS) vpnor_test_toc_lookup_failed_LDADD = $(VPNOR_LDADD) vpnor_test_toc_missing_file_SOURCES = \ - $(TEST_MOCK_SRCS) \ + $(TEST_MOCK_VPNOR_SRCS) \ $(TEST_MBOX_VPNOR_INTEG_SRCS) \ %reldir%/toc_missing_file.cpp vpnor_test_toc_missing_file_LDFLAGS = $(OESDK_TESTCASE_FLAGS) vpnor_test_toc_missing_file_LDADD = $(VPNOR_LDADD) vpnor_test_create_read_window_oob_SOURCES = \ - $(TEST_MOCK_SRCS) \ + $(TEST_MOCK_VPNOR_SRCS) \ $(TEST_MBOX_VPNOR_INTEG_SRCS) \ %reldir%/create_read_window_oob.cpp vpnor_test_create_read_window_oob_LDFLAGS = $(OESDK_TESTCASE_FLAGS) vpnor_test_create_read_window_oob_LDADD = $(VPNOR_LDADD) vpnor_test_create_read_window_toc_SOURCES = \ - $(TEST_MOCK_SRCS) \ + $(TEST_MOCK_VPNOR_SRCS) \ $(TEST_MBOX_VPNOR_INTEG_SRCS) \ %reldir%/create_read_window_toc.cpp vpnor_test_create_read_window_toc_LDFLAGS = $(OESDK_TESTCASE_FLAGS) vpnor_test_create_read_window_toc_LDADD = $(VPNOR_LDADD) vpnor_test_create_read_window_straddle_partitions_SOURCES = \ - $(TEST_MOCK_SRCS) \ + $(TEST_MOCK_VPNOR_SRCS) \ $(TEST_MBOX_VPNOR_INTEG_SRCS) \ %reldir%/create_read_window_straddle_partitions.cpp vpnor_test_create_read_window_straddle_partitions_LDFLAGS = $(OESDK_TESTCASE_FLAGS) vpnor_test_create_read_window_straddle_partitions_LDADD = $(VPNOR_LDADD) vpnor_test_create_read_window_partition_invalid_SOURCES = \ - $(TEST_MOCK_SRCS) \ + $(TEST_MOCK_VPNOR_SRCS) \ $(TEST_MBOX_VPNOR_INTEG_SRCS) \ %reldir%/create_read_window_partition_invalid.cpp vpnor_test_create_read_window_partition_invalid_LDFLAGS = $(OESDK_TESTCASE_FLAGS) vpnor_test_create_read_window_partition_invalid_LDADD = $(VPNOR_LDADD) vpnor_test_read_patch_SOURCES = \ - $(TEST_MOCK_SRCS) \ + $(TEST_MOCK_VPNOR_SRCS) \ $(TEST_MBOX_VPNOR_INTEG_SRCS) \ %reldir%/read_patch.cpp vpnor_test_read_patch_LDFLAGS = $(OESDK_TESTCASE_FLAGS) @@ -176,56 +172,56 @@ vpnor_test_write_patch_resize_LDFLAGS = $(OESDK_TESTCASE_FLAGS) vpnor_test_write_patch_resize_LDADD = $(VPNOR_LDADD) vpnor_test_dump_flash_SOURCES = \ - $(TEST_MOCK_SRCS) \ + $(TEST_MOCK_VPNOR_SRCS) \ $(TEST_MBOX_VPNOR_INTEG_SRCS) \ %reldir%/dump_flash.cpp vpnor_test_dump_flash_LDFLAGS = $(OESDK_TESTCASE_FLAGS) vpnor_test_dump_flash_LDADD = $(VPNOR_LDADD) vpnor_test_create_read_window_size_SOURCES = \ - $(TEST_MOCK_SRCS) \ + $(TEST_MOCK_VPNOR_SRCS) \ $(TEST_MBOX_VPNOR_INTEG_SRCS) \ %reldir%/create_read_window_size.cpp vpnor_test_create_read_window_size_LDFLAGS = $(OESDK_TESTCASE_FLAGS) vpnor_test_create_read_window_size_LDADD = $(VPNOR_LDADD) vpnor_test_create_read_window_remap_SOURCES = \ - $(TEST_MOCK_SRCS) \ + $(TEST_MOCK_VPNOR_SRCS) \ $(TEST_MBOX_VPNOR_INTEG_SRCS) \ %reldir%/create_read_window_remap.cpp vpnor_test_create_read_window_remap_LDFLAGS = $(OESDK_TESTCASE_FLAGS) vpnor_test_create_read_window_remap_LDADD = $(VPNOR_LDADD) vpnor_test_create_write_window_ro_partition_SOURCES = \ - $(TEST_MOCK_SRCS) \ + $(TEST_MOCK_VPNOR_SRCS) \ $(TEST_MBOX_VPNOR_INTEG_SRCS) \ %reldir%/create_write_window_ro_partition.cpp vpnor_test_create_write_window_ro_partition_LDFLAGS = $(OESDK_TESTCASE_FLAGS) vpnor_test_create_write_window_ro_partition_LDADD = $(VPNOR_LDADD) vpnor_test_create_write_window_rw_partition_SOURCES = \ - $(TEST_MOCK_SRCS) \ + $(TEST_MOCK_VPNOR_SRCS) \ $(TEST_MBOX_VPNOR_INTEG_SRCS) \ %reldir%/create_write_window_rw_partition.cpp vpnor_test_create_write_window_rw_partition_LDFLAGS = $(OESDK_TESTCASE_FLAGS) vpnor_test_create_write_window_rw_partition_LDADD = $(VPNOR_LDADD) vpnor_test_create_write_window_unmapped_SOURCES = \ - $(TEST_MOCK_SRCS) \ + $(TEST_MOCK_VPNOR_SRCS) \ $(TEST_MBOX_VPNOR_INTEG_SRCS) \ %reldir%/create_write_window_unmapped.cpp vpnor_test_create_write_window_unmapped_LDFLAGS = $(OESDK_TESTCASE_FLAGS) vpnor_test_create_write_window_unmapped_LDADD = $(VPNOR_LDADD) vpnor_test_write_toc_SOURCES = \ - $(TEST_MOCK_SRCS) \ + $(TEST_MOCK_VPNOR_SRCS) \ $(TEST_MBOX_VPNOR_INTEG_SRCS) \ %reldir%/write_toc.cpp vpnor_test_write_toc_LDFLAGS = $(OESDK_TESTCASE_FLAGS) vpnor_test_write_toc_LDADD = $(VPNOR_LDADD) vpnor_test_force_readonly_toc_SOURCES = \ - $(TEST_MOCK_SRCS) \ + $(TEST_MOCK_VPNOR_SRCS) \ $(TEST_MBOX_VPNOR_INTEG_SRCS) \ %reldir%/force_readonly_toc.cpp vpnor_test_force_readonly_toc_LDFLAGS = $(OESDK_TESTCASE_FLAGS) diff --git a/vpnor/test/create_pnor_partition_table.cpp b/vpnor/test/create_pnor_partition_table.cpp index cdbe8b6..f198f29 100644 --- a/vpnor/test/create_pnor_partition_table.cpp +++ b/vpnor/test/create_pnor_partition_table.cpp @@ -34,9 +34,9 @@ int main() system_set_reserved_size(MEM_SIZE); system_set_mtd_sizes(PNOR_SIZE, ERASE_SIZE); - ctx = mbox_create_test_context(N_WINDOWS, WINDOW_SIZE); - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); - const openpower::virtual_pnor::partition::Table table(ctx); + ctx = mbox_create_frontend_context(N_WINDOWS, WINDOW_SIZE); + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); + const openpower::virtual_pnor::partition::Table table(&ctx->backend); pnor_partition_table expectedTable{}; expectedTable.data.magic = PARTITION_HEADER_MAGIC; diff --git a/vpnor/test/create_read_window_oob.cpp b/vpnor/test/create_read_window_oob.cpp index 240c10e..d1e7e64 100644 --- a/vpnor/test/create_read_window_oob.cpp +++ b/vpnor/test/create_read_window_oob.cpp @@ -48,9 +48,8 @@ int main() system_set_reserved_size(MEM_SIZE); system_set_mtd_sizes(PNOR_SIZE, ERASE_SIZE); - ctx = mbox_create_test_context(N_WINDOWS, WINDOW_SIZE); - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); - init_vpnor_from_paths(ctx); + ctx = mbox_create_frontend_context(N_WINDOWS, WINDOW_SIZE); + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); rc = mbox_command_dispatch(ctx, get_info, sizeof(get_info)); assert(rc == 1); diff --git a/vpnor/test/create_read_window_partition_exists.cpp b/vpnor/test/create_read_window_partition_exists.cpp index d3532ec..7ff3018 100644 --- a/vpnor/test/create_read_window_partition_exists.cpp +++ b/vpnor/test/create_read_window_partition_exists.cpp @@ -53,13 +53,11 @@ int main() system_set_reserved_size(MEM_SIZE); system_set_mtd_sizes(MEM_SIZE, ERASE_SIZE); - ctx = mbox_create_test_context(N_WINDOWS, WINDOW_SIZE); + ctx = mbox_create_frontend_context(N_WINDOWS, WINDOW_SIZE); - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); root.write("HBB", data, sizeof(data)); - init_vpnor_from_paths(ctx); - int rc = mbox_command_dispatch(ctx, get_info, sizeof(get_info)); assert(rc == 1); diff --git a/vpnor/test/create_read_window_partition_invalid.cpp b/vpnor/test/create_read_window_partition_invalid.cpp index 36431d3..4d28b2c 100644 --- a/vpnor/test/create_read_window_partition_invalid.cpp +++ b/vpnor/test/create_read_window_partition_invalid.cpp @@ -44,14 +44,14 @@ int main() system_set_reserved_size(MEM_SIZE); system_set_mtd_sizes(MEM_SIZE, ERASE_SIZE); - ctx = mbox_create_test_context(N_WINDOWS, WINDOW_SIZE); - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); - init_vpnor_from_paths(ctx); + ctx = mbox_create_frontend_context(N_WINDOWS, WINDOW_SIZE); + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); rc = mbox_command_dispatch(ctx, get_info, sizeof(get_info)); assert(rc == 1); rc = mbox_command_dispatch(ctx, create_read_window, sizeof(create_read_window)); + return !(rc == 1); } diff --git a/vpnor/test/create_read_window_remap.cpp b/vpnor/test/create_read_window_remap.cpp index 7a11053..f81d1bc 100644 --- a/vpnor/test/create_read_window_remap.cpp +++ b/vpnor/test/create_read_window_remap.cpp @@ -47,9 +47,8 @@ int main() system_set_reserved_size(MEM_SIZE); system_set_mtd_sizes(MEM_SIZE, ERASE_SIZE); - ctx = mbox_create_test_context(N_WINDOWS, WINDOW_SIZE); - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); - init_vpnor_from_paths(ctx); + ctx = mbox_create_frontend_context(N_WINDOWS, WINDOW_SIZE); + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); int rc = mbox_command_dispatch(ctx, get_info, sizeof(get_info)); assert(rc == 1); diff --git a/vpnor/test/create_read_window_size.cpp b/vpnor/test/create_read_window_size.cpp index 6ea11f1..4e8cb5d 100644 --- a/vpnor/test/create_read_window_size.cpp +++ b/vpnor/test/create_read_window_size.cpp @@ -56,9 +56,8 @@ int main() system_set_reserved_size(MEM_SIZE); system_set_mtd_sizes(PNOR_SIZE, ERASE_SIZE); - ctx = mbox_create_test_context(N_WINDOWS, WINDOW_SIZE); - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); - init_vpnor_from_paths(ctx); + ctx = mbox_create_frontend_context(N_WINDOWS, WINDOW_SIZE); + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); int rc = mbox_command_dispatch(ctx, get_info, sizeof(get_info)); assert(rc == 1); diff --git a/vpnor/test/create_read_window_straddle_partitions.cpp b/vpnor/test/create_read_window_straddle_partitions.cpp index bc963dd..bdc3fa5 100644 --- a/vpnor/test/create_read_window_straddle_partitions.cpp +++ b/vpnor/test/create_read_window_straddle_partitions.cpp @@ -52,9 +52,8 @@ int main() system_set_reserved_size(MEM_SIZE); system_set_mtd_sizes(PNOR_SIZE, ERASE_SIZE); - ctx = mbox_create_test_context(N_WINDOWS, WINDOW_SIZE); - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); - init_vpnor_from_paths(ctx); + ctx = mbox_create_frontend_context(N_WINDOWS, WINDOW_SIZE); + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); int rc = mbox_command_dispatch(ctx, get_info, sizeof(get_info)); assert(rc == 1); diff --git a/vpnor/test/create_read_window_toc.cpp b/vpnor/test/create_read_window_toc.cpp index fee61ca..7571f37 100644 --- a/vpnor/test/create_read_window_toc.cpp +++ b/vpnor/test/create_read_window_toc.cpp @@ -55,15 +55,13 @@ int main() system_set_reserved_size(MEM_SIZE); system_set_mtd_sizes(PNOR_SIZE, ERASE_SIZE); - ctx = mbox_create_test_context(N_WINDOWS, WINDOW_SIZE); - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); - vpnor::partition::Table table(ctx); + ctx = mbox_create_frontend_context(N_WINDOWS, WINDOW_SIZE); + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); + vpnor::partition::Table table(&ctx->backend); /* Make sure the ToC exactly fits in the space allocated for it */ assert(table.capacity() == TOC_PART_SIZE); - init_vpnor_from_paths(ctx); - rc = mbox_command_dispatch(ctx, get_info, sizeof(get_info)); assert(rc == 1); diff --git a/vpnor/test/create_write_window_ro_partition.cpp b/vpnor/test/create_write_window_ro_partition.cpp index 5cc19ca..59d4a0d 100644 --- a/vpnor/test/create_write_window_ro_partition.cpp +++ b/vpnor/test/create_write_window_ro_partition.cpp @@ -45,11 +45,9 @@ int main() system_set_reserved_size(MEM_SIZE); system_set_mtd_sizes(MEM_SIZE, ERASE_SIZE); - ctx = mbox_create_test_context(N_WINDOWS, WINDOW_SIZE); + ctx = mbox_create_frontend_context(N_WINDOWS, WINDOW_SIZE); - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); - - init_vpnor_from_paths(ctx); + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); int rc = mbox_command_dispatch(ctx, get_info, sizeof(get_info)); assert(rc == 1); diff --git a/vpnor/test/create_write_window_rw_partition.cpp b/vpnor/test/create_write_window_rw_partition.cpp index 879fd85..ed6f3dd 100644 --- a/vpnor/test/create_write_window_rw_partition.cpp +++ b/vpnor/test/create_write_window_rw_partition.cpp @@ -45,11 +45,9 @@ int main() system_set_reserved_size(MEM_SIZE); system_set_mtd_sizes(MEM_SIZE, ERASE_SIZE); - ctx = mbox_create_test_context(N_WINDOWS, WINDOW_SIZE); + ctx = mbox_create_frontend_context(N_WINDOWS, WINDOW_SIZE); - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); - - init_vpnor_from_paths(ctx); + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); int rc = mbox_command_dispatch(ctx, get_info, sizeof(get_info)); assert(rc == 1); diff --git a/vpnor/test/create_write_window_unmapped.cpp b/vpnor/test/create_write_window_unmapped.cpp index 76694fc..d7f76fd 100644 --- a/vpnor/test/create_write_window_unmapped.cpp +++ b/vpnor/test/create_write_window_unmapped.cpp @@ -46,11 +46,9 @@ int main() system_set_reserved_size(MEM_SIZE); system_set_mtd_sizes(PNOR_SIZE, ERASE_SIZE); - ctx = mbox_create_test_context(N_WINDOWS, WINDOW_SIZE); + ctx = mbox_create_frontend_context(N_WINDOWS, WINDOW_SIZE); - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); - - init_vpnor_from_paths(ctx); + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); int rc = mbox_command_dispatch(ctx, get_info, sizeof(get_info)); assert(rc == MBOX_R_SUCCESS); diff --git a/vpnor/test/dump_flash.cpp b/vpnor/test/dump_flash.cpp index 5179b7c..f285a61 100644 --- a/vpnor/test/dump_flash.cpp +++ b/vpnor/test/dump_flash.cpp @@ -68,9 +68,8 @@ int main() system_set_reserved_size(MEM_SIZE); system_set_mtd_sizes(PNOR_SIZE, ERASE_SIZE); - tctx->ctx = mbox_create_test_context(N_WINDOWS, WINDOW_SIZE); - test::VpnorRoot root(tctx->ctx, toc, BLOCK_SIZE); - init_vpnor_from_paths(tctx->ctx); + tctx->ctx = mbox_create_frontend_context(N_WINDOWS, WINDOW_SIZE); + test::VpnorRoot root(&tctx->ctx->backend, toc, BLOCK_SIZE); rc = mbox_command_dispatch(tctx->ctx, get_info, sizeof(get_info)); assert(rc == 1); diff --git a/vpnor/test/force_readonly_toc.cpp b/vpnor/test/force_readonly_toc.cpp index 8d3bec1..465adad 100644 --- a/vpnor/test/force_readonly_toc.cpp +++ b/vpnor/test/force_readonly_toc.cpp @@ -52,14 +52,12 @@ int main() system_set_reserved_size(MEM_SIZE); system_set_mtd_sizes(PNOR_SIZE, ERASE_SIZE); - ctx = mbox_create_test_context(N_WINDOWS, WINDOW_SIZE); - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); - vpnor::partition::Table table(ctx); + ctx = mbox_create_frontend_context(N_WINDOWS, WINDOW_SIZE); + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); + vpnor::partition::Table table(&ctx->backend); assert(table.capacity() == TOC_PART_SIZE); - init_vpnor_from_paths(ctx); - rc = mbox_command_dispatch(ctx, get_info, sizeof(get_info)); assert(rc == MBOX_R_SUCCESS); diff --git a/vpnor/test/read_patch.cpp b/vpnor/test/read_patch.cpp index 631a23c..4d541f6 100644 --- a/vpnor/test/read_patch.cpp +++ b/vpnor/test/read_patch.cpp @@ -47,8 +47,8 @@ int main() system_set_reserved_size(MEM_SIZE); system_set_mtd_sizes(PNOR_SIZE, ERASE_SIZE); - ctx = mbox_create_test_context(N_WINDOWS, WINDOW_SIZE); - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); + ctx = mbox_create_frontend_context(N_WINDOWS, WINDOW_SIZE); + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); // PATCH_SIZE is smaller than the size of the partition we defined. This // test ensures that mboxd will behave correctly when we request an offset @@ -57,8 +57,6 @@ int main() std::vector<uint8_t> patch(PATCH_SIZE, 0xff); root.patch("ONE", patch.data(), patch.size()); - init_vpnor_from_paths(ctx); - int rc = mbox_command_dispatch(ctx, get_info, sizeof(get_info)); assert(rc == 1); diff --git a/vpnor/test/tmpd.hpp b/vpnor/test/tmpd.hpp index 7386f2f..f6ea7c9 100644 --- a/vpnor/test/tmpd.hpp +++ b/vpnor/test/tmpd.hpp @@ -4,6 +4,7 @@ #include "config.h" extern "C" { +#include "backend.h" #include "mboxd.h" } @@ -28,8 +29,9 @@ class VpnorRoot { public: template <std::size_t N> - VpnorRoot(struct mbox_context* ctx, const std::string (&toc)[N], - size_t blockSize) + VpnorRoot(struct backend* backend, const std::string (&toc)[N], + size_t blockSize) : + backend(backend) { char tmplt[] = "/tmp/vpnor_root.XXXXXX"; char* tmpdir = mkdtemp(tmplt); @@ -58,14 +60,21 @@ class VpnorRoot std::ofstream(tocFilePath, std::ofstream::app) << line << "\n"; } - strncpy(ctx->paths.ro_loc, ro().c_str(), PATH_MAX - 1); - ctx->paths.ro_loc[PATH_MAX - 1] = '\0'; - strncpy(ctx->paths.rw_loc, rw().c_str(), PATH_MAX - 1); - ctx->paths.rw_loc[PATH_MAX - 1] = '\0'; - strncpy(ctx->paths.prsv_loc, prsv().c_str(), PATH_MAX - 1); - ctx->paths.prsv_loc[PATH_MAX - 1] = '\0'; - strncpy(ctx->paths.patch_loc, patch().c_str(), PATH_MAX - 1); - ctx->paths.patch_loc[PATH_MAX - 1] = '\0'; + vpnor_partition_paths paths{}; + + snprintf(paths.ro_loc, PATH_MAX - 1, "%s/ro", root.c_str()); + paths.ro_loc[PATH_MAX - 1] = '\0'; + snprintf(paths.rw_loc, PATH_MAX - 1, "%s/rw", root.c_str()); + paths.rw_loc[PATH_MAX - 1] = '\0'; + snprintf(paths.prsv_loc, PATH_MAX - 1, "%s/prsv", root.c_str()); + paths.prsv_loc[PATH_MAX - 1] = '\0'; + snprintf(paths.patch_loc, PATH_MAX - 1, "%s/patch", root.c_str()); + paths.patch_loc[PATH_MAX - 1] = '\0'; + + if (backend_probe_vpnor(backend, &paths)) + { + throw std::system_error(errno, std::system_category()); + } } VpnorRoot(const VpnorRoot&) = delete; @@ -75,6 +84,7 @@ class VpnorRoot ~VpnorRoot() { + backend_free(backend); fs::remove_all(root); } fs::path ro() @@ -97,6 +107,7 @@ class VpnorRoot size_t patch(const std::string& name, const void* data, size_t len); private: + struct backend* backend; fs::path root; const std::string attributes[4] = {"ro", "rw", "prsv", "patch"}; }; diff --git a/vpnor/test/toc_lookup_failed.cpp b/vpnor/test/toc_lookup_failed.cpp index bb07725..cb56e51 100644 --- a/vpnor/test/toc_lookup_failed.cpp +++ b/vpnor/test/toc_lookup_failed.cpp @@ -37,10 +37,10 @@ int main() system_set_reserved_size(MEM_SIZE); system_set_mtd_sizes(MEM_SIZE, ERASE_SIZE); - ctx = mbox_create_test_context(N_WINDOWS, WINDOW_SIZE); + ctx = mbox_create_frontend_context(N_WINDOWS, WINDOW_SIZE); - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); - vpnor::partition::Table table(ctx); + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); + vpnor::partition::Table table(&ctx->backend); try { diff --git a/vpnor/test/toc_lookup_found.cpp b/vpnor/test/toc_lookup_found.cpp index fccee0c..b8c879c 100644 --- a/vpnor/test/toc_lookup_found.cpp +++ b/vpnor/test/toc_lookup_found.cpp @@ -37,10 +37,10 @@ int main() system_set_reserved_size(MEM_SIZE); system_set_mtd_sizes(MEM_SIZE, ERASE_SIZE); - ctx = mbox_create_test_context(N_WINDOWS, WINDOW_SIZE); + ctx = mbox_create_frontend_context(N_WINDOWS, WINDOW_SIZE); - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); - vpnor::partition::Table table(ctx); + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); + vpnor::partition::Table table(&ctx->backend); const struct pnor_partition& part = table.partition("TWO"); assert(part.data.id == 2); diff --git a/vpnor/test/toc_missing_file.cpp b/vpnor/test/toc_missing_file.cpp index 6b7e068..95147c0 100644 --- a/vpnor/test/toc_missing_file.cpp +++ b/vpnor/test/toc_missing_file.cpp @@ -37,15 +37,15 @@ int main() system_set_reserved_size(MEM_SIZE); system_set_mtd_sizes(MEM_SIZE, ERASE_SIZE); - ctx = mbox_create_test_context(N_WINDOWS, WINDOW_SIZE); + ctx = mbox_create_frontend_context(N_WINDOWS, WINDOW_SIZE); - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); fs::remove(root.ro() / "TWO"); try { - vpnor::partition::Table table(ctx); + vpnor::partition::Table table(&ctx->backend); } catch (vpnor::InvalidTocEntry& e) { diff --git a/vpnor/test/toc_overlap.cpp b/vpnor/test/toc_overlap.cpp index a7ac20d..18b7151 100644 --- a/vpnor/test/toc_overlap.cpp +++ b/vpnor/test/toc_overlap.cpp @@ -36,15 +36,13 @@ int main() system_set_reserved_size(MEM_SIZE); system_set_mtd_sizes(MEM_SIZE, ERASE_SIZE); - ctx = mbox_create_test_context(N_WINDOWS, WINDOW_SIZE); - - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); + ctx = mbox_create_frontend_context(N_WINDOWS, WINDOW_SIZE); try { - vpnor::partition::Table table(ctx); + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); } - catch (vpnor::InvalidTocEntry& e) + catch (std::system_error& e) { return 0; } diff --git a/vpnor/test/write_patch.cpp b/vpnor/test/write_patch.cpp index 1bf6ba9..4f59db5 100644 --- a/vpnor/test/write_patch.cpp +++ b/vpnor/test/write_patch.cpp @@ -4,8 +4,8 @@ #include "config.h" extern "C" { +#include "backend.h" #include "common.h" -#include "flash.h" #include "mboxd.h" } @@ -47,15 +47,14 @@ int main(void) mbox_vlog = &mbox_log_console; verbosity = (verbose)2; - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); + ctx->backend.flash_size = 0x2000; + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); root.write("TEST1", data, sizeof(data)); /* flash_write doesn't copy the file for us */ assert(fs::copy_file(root.ro() / "TEST1", root.rw() / "TEST1")); fs::path patch = root.patch() / "TEST1"; assert(fs::copy_file(root.ro() / "TEST1", patch)); - init_vpnor_from_paths(ctx); - /* Test */ memset(src, 0x33, sizeof(src)); rc = flash_write(ctx, 0x1000, src, sizeof(src)); @@ -79,8 +78,5 @@ int main(void) munmap(map, sizeof(src)); close(fd); - destroy_vpnor(ctx); - free(ctx->flash_bmap); - return rc; } diff --git a/vpnor/test/write_patch_resize.cpp b/vpnor/test/write_patch_resize.cpp index 9a6979f..ce128c8 100644 --- a/vpnor/test/write_patch_resize.cpp +++ b/vpnor/test/write_patch_resize.cpp @@ -4,8 +4,8 @@ #include "config.h" extern "C" { +#include "backend.h" #include "common.h" -#include "flash.h" #include "mboxd.h" } @@ -46,15 +46,14 @@ int main(void) mbox_vlog = &mbox_log_console; verbosity = (verbose)2; - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); + ctx->backend.flash_size = 0x2000; + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); std::vector<uint8_t> roContent(PART_SIZE, 0xff); root.write("TEST1", roContent.data(), roContent.size()); /* flash_write doesn't copy the file for us */ std::vector<uint8_t> patchContent(PATCH_SIZE, 0xaa); root.patch("TEST1", patchContent.data(), patchContent.size()); - init_vpnor_from_paths(ctx); - /* Test */ std::vector<uint8_t> update(UPDATE_SIZE, 0x55); rc = flash_write(ctx, 0x1000, update.data(), update.size()); @@ -71,8 +70,5 @@ int main(void) munmap(map, update.size()); close(fd); - destroy_vpnor(ctx); - free(ctx->flash_bmap); - return rc; } diff --git a/vpnor/test/write_prsv.cpp b/vpnor/test/write_prsv.cpp index 53f3cfe..9ee1fb3 100644 --- a/vpnor/test/write_prsv.cpp +++ b/vpnor/test/write_prsv.cpp @@ -2,8 +2,8 @@ // Copyright (C) 2018 IBM Corp. extern "C" { +#include "backend.h" #include "common.h" -#include "flash.h" #include "mboxd.h" } @@ -41,8 +41,8 @@ int main(void) mbox_vlog = &mbox_log_console; verbosity = (verbose)2; - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); - init_vpnor_from_paths(ctx); + ctx->backend.flash_size = 0x2000; + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); /* Test */ memset(src, 0xaa, sizeof(src)); @@ -60,8 +60,5 @@ int main(void) munmap(map, sizeof(src)); close(fd); - /* Cleanup */ - destroy_vpnor(ctx); - return 0; } diff --git a/vpnor/test/write_ro.cpp b/vpnor/test/write_ro.cpp index e5671b1..e6bedd3 100644 --- a/vpnor/test/write_ro.cpp +++ b/vpnor/test/write_ro.cpp @@ -3,8 +3,8 @@ #include "config.h" extern "C" { +#include "backend.h" #include "common.h" -#include "flash.h" #include "mboxd.h" } @@ -39,8 +39,8 @@ int main(void) mbox_vlog = &mbox_log_console; verbosity = (verbose)2; - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); - init_vpnor_from_paths(ctx); + ctx->backend.flash_size = 0x2000; + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); /* Test */ rc = flash_write(ctx, 0x1000, src, sizeof(src)); @@ -48,7 +48,5 @@ int main(void) /* Verify we can't write to RO partitions */ assert(rc != 0); - destroy_vpnor(ctx); - return 0; } diff --git a/vpnor/test/write_rw.cpp b/vpnor/test/write_rw.cpp index e64f01e..3b742a1 100644 --- a/vpnor/test/write_rw.cpp +++ b/vpnor/test/write_rw.cpp @@ -3,8 +3,8 @@ #include "config.h" extern "C" { +#include "backend.h" #include "common.h" -#include "flash.h" #include "mboxd.h" } @@ -41,10 +41,10 @@ int main(void) mbox_vlog = &mbox_log_console; verbosity = (verbose)2; - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); + ctx->backend.flash_size = 0x2000; + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); /* flash_write() doesn't copy the file for us */ assert(fs::copy_file(root.ro() / "TEST1", root.rw() / "TEST1")); - init_vpnor_from_paths(ctx); /* Test */ memset(src, 0xbb, sizeof(src)); @@ -95,7 +95,5 @@ int main(void) munmap(map, sizeof(src)); close(fd); - destroy_vpnor(ctx); - return 0; } diff --git a/vpnor/test/write_toc.cpp b/vpnor/test/write_toc.cpp index 6f6b101..8b690a1 100644 --- a/vpnor/test/write_toc.cpp +++ b/vpnor/test/write_toc.cpp @@ -67,14 +67,12 @@ int main() system_set_reserved_size(MEM_SIZE); system_set_mtd_sizes(PNOR_SIZE, ERASE_SIZE); - ctx = mbox_create_test_context(N_WINDOWS, WINDOW_SIZE); - test::VpnorRoot root(ctx, toc, BLOCK_SIZE); - vpnor::partition::Table table(ctx); + ctx = mbox_create_frontend_context(N_WINDOWS, WINDOW_SIZE); + test::VpnorRoot root(&ctx->backend, toc, BLOCK_SIZE); + vpnor::partition::Table table(&ctx->backend); assert(table.capacity() == TOC_PART_SIZE); - init_vpnor_from_paths(ctx); - rc = mbox_command_dispatch(ctx, get_info, sizeof(get_info)); assert(rc == MBOX_R_SUCCESS); @@ -29,7 +29,7 @@ #include "common.h" #include "transport_mbox.h" #include "windows.h" -#include "flash.h" +#include "backend.h" /* Initialisation Functions */ @@ -173,11 +173,11 @@ int window_flush_v1(struct mbox_context *context, * boundary */ low_mem.flash_offset = align_down(flash_offset, - context->mtd_info.erasesize); + 1 << context->backend.erase_size_shift); low_mem.size = flash_offset - low_mem.flash_offset; high_mem.flash_offset = flash_offset + count_bytes; high_mem.size = align_up(high_mem.flash_offset, - context->mtd_info.erasesize) - + 1 << context->backend.erase_size_shift) - high_mem.flash_offset; /* @@ -279,8 +279,8 @@ int window_flush(struct mbox_context *context, uint32_t offset, uint32_t count, uint8_t type) { int rc; - uint32_t flash_offset, count_bytes = count << context->block_size_shift; - uint32_t offset_bytes = offset << context->block_size_shift; + uint32_t flash_offset, count_bytes = count << context->backend.block_size_shift; + uint32_t offset_bytes = offset << context->backend.block_size_shift; switch (type) { case WINDOW_ERASED: /* >= V2 ONLY -> block_size == erasesize */ @@ -297,8 +297,8 @@ int window_flush(struct mbox_context *context, uint32_t offset, * so we have a special function to make sure that we do this * correctly without losing data. */ - if (log_2(context->mtd_info.erasesize) != - context->block_size_shift) { + if (context->backend.erase_size_shift != + context->backend.block_size_shift) { return window_flush_v1(context, offset_bytes, count_bytes); } @@ -345,7 +345,7 @@ void windows_alloc_dirty_bytemap(struct mbox_context *context) free(cur->dirty_bmap); /* Allocate the new one */ cur->dirty_bmap = calloc((context->windows.default_size >> - context->block_size_shift), + context->backend.block_size_shift), sizeof(*cur->dirty_bmap)); } } @@ -363,12 +363,12 @@ void windows_alloc_dirty_bytemap(struct mbox_context *context) int window_set_bytemap(struct mbox_context *context, struct window_context *cur, uint32_t offset, uint32_t size, uint8_t val) { - if (offset + size > (cur->size >> context->block_size_shift)) { + if (offset + size > (cur->size >> context->backend.block_size_shift)) { MSG_ERR("Tried to set window bytemap past end of window\n"); MSG_ERR("Requested offset: 0x%x size: 0x%x window size: 0x%x\n", - offset << context->block_size_shift, - size << context->block_size_shift, - cur->size << context->block_size_shift); + offset << context->backend.block_size_shift, + size << context->backend.block_size_shift, + cur->size << context->backend.block_size_shift); return -EACCES; } @@ -410,7 +410,7 @@ void window_reset(struct mbox_context *context, struct window_context *window) window->size = context->windows.default_size; if (window->dirty_bmap) { /* Might not have been allocated */ window_set_bytemap(context, window, 0, - window->size >> context->block_size_shift, + window->size >> context->backend.block_size_shift, WINDOW_CLEAN); } window->age = 0; @@ -593,10 +593,10 @@ int windows_create_map(struct mbox_context *context, } #endif - if (offset > context->flash_size) { + if (offset > context->backend.flash_size) { MSG_ERR("Tried to open read window past flash limit\n"); return -EINVAL; - } else if ((offset + cur->size) > context->flash_size) { + } else if ((offset + cur->size) > context->backend.flash_size) { /* * There is V1 skiboot implementations out there which don't * mask offset with window size, meaning when we have @@ -608,14 +608,14 @@ int windows_create_map(struct mbox_context *context, * this. */ if (context->version == API_VERSION_1) { - cur->size = align_down(context->flash_size - offset, - 1 << context->block_size_shift); + cur->size = align_down(context->backend.flash_size - offset, + 1 << context->backend.block_size_shift); } else { /* * Allow requests to exceed the flash size, but limit * the response to the size of the flash. */ - cur->size = context->flash_size - offset; + cur->size = context->backend.flash_size - offset; } } @@ -632,7 +632,7 @@ int windows_create_map(struct mbox_context *context, * FIXME: This should only be the case for the vpnor ToC now, so handle * it there */ - cur->size = align_up(rc, (1ULL << context->block_size_shift)); + cur->size = align_up(rc, (1ULL << context->backend.block_size_shift)); /* Would like a known value, pick 0xFF to it looks like erased flash */ memset(cur->mem + rc, 0xFF, cur->size - rc); @@ -662,7 +662,7 @@ int windows_create_map(struct mbox_context *context, /* Clear the bytemap of the window just loaded -> we know it's clean */ window_set_bytemap(context, cur, 0, - cur->size >> context->block_size_shift, + cur->size >> context->backend.block_size_shift, WINDOW_CLEAN); /* Update so we know what's in the window */ |

