summaryrefslogtreecommitdiffstats
path: root/mboxd_flash_virtual.cpp
diff options
context:
space:
mode:
authorAndrew Jeffery <andrew@aj.id.au>2018-02-28 00:35:50 +1030
committerAndrew Jeffery <andrew@aj.id.au>2018-04-04 00:31:37 +0930
commitad343101c59beb0c2b0c1033f031ff76ff2237d7 (patch)
tree28c21f3cbf47ce720dd1e006bfdff7c52e45eb8d /mboxd_flash_virtual.cpp
parentfc62158caeaef009cd0055ce8cc35586581840b8 (diff)
downloadphosphor-mboxd-ad343101c59beb0c2b0c1033f031ff76ff2237d7.tar.gz
phosphor-mboxd-ad343101c59beb0c2b0c1033f031ff76ff2237d7.zip
pnor_partition: Refactor to enforce stronger boundaries for abstractions
The RORequest and RWRequest classes did not provide a clear abstraction over the operation of populating a window or partition associated with a CREATE_{READ,WRITE}_WINDOW request. The role of the classes was to find the partition for the provided offset, locate and then open its backing file. However, the file-descriptor for the backing file was exposed outside of the class, as was the FFS partition struct, both of which were managed _internal_ to the class. Thus the classes provided no encapsulation of state and awkwardly split the tasks of managing and utilising the resources between the callee and caller. This commit inverts the behaviour in a fulfil() method handles the mechanics of locating, opening, manipulating and closing the backing file, requiring nothing of the caller. The pnor_partition reference is managed entirely inside the Request class, derived from the offset passed to the constructor. Unifying the mechanics into fulfil() results in a decent reduction in lines of code at the expense of some cyclomatic complexity. fulfil() is publicly exposed via read() and write() wrappers on the class, and the RORequest and RWRequest classes are removed as a result. Change-Id: Ie587ed31f1a6db97bcb490dbcc2e27ece0b1f82c Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Diffstat (limited to 'mboxd_flash_virtual.cpp')
-rw-r--r--mboxd_flash_virtual.cpp86
1 files changed, 19 insertions, 67 deletions
diff --git a/mboxd_flash_virtual.cpp b/mboxd_flash_virtual.cpp
index 1561396..ffe75c6 100644
--- a/mboxd_flash_virtual.cpp
+++ b/mboxd_flash_virtual.cpp
@@ -29,6 +29,7 @@ extern "C" {
#include <stdexcept>
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. */
@@ -119,10 +120,6 @@ int erase_flash(struct mbox_context* context, uint32_t offset, uint32_t count)
int64_t copy_flash(struct mbox_context* context, uint32_t offset, void* mem,
uint32_t size)
{
- using namespace phosphor::logging;
- using namespace sdbusplus::xyz::openbmc_project::Common::Error;
- using namespace std::string_literals;
-
vpnor::partition::Table* table;
int rc = size;
@@ -152,30 +149,8 @@ int64_t copy_flash(struct mbox_context* context, uint32_t offset, void* mem,
try
{
- openpower::virtual_pnor::RORequest roRequest;
- auto partitionInfo = roRequest.getPartitionInfo(context, offset);
-
- auto mapped_mem = mmap(NULL, partitionInfo->data.actual, PROT_READ,
- MAP_PRIVATE, roRequest.fd(), 0);
-
- if (mapped_mem == MAP_FAILED)
- {
- MSG_ERR("Failed to map partition=%s:Error=%s\n",
- partitionInfo->data.name, strerror(errno));
-
- elog<InternalFailure>();
- }
-
- // if the asked offset + no of bytes to read is greater
- // then size of the partition file then throw error.
-
- uint32_t baseOffset = partitionInfo->data.base
- << context->block_size_shift;
- // copy to the reserved memory area
- auto diffOffset = offset - baseOffset;
- rc = std::min(partitionInfo->data.actual - diffOffset, size);
- memcpy(mem, (char*)mapped_mem + diffOffset, rc);
- munmap(mapped_mem, partitionInfo->data.actual);
+ vpnor::Request req(context, offset);
+ rc = req.read(mem, size);
}
catch (vpnor::UnmappedOffset& e)
{
@@ -214,51 +189,28 @@ int64_t copy_flash(struct mbox_context* context, uint32_t offset, void* mem,
int write_flash(struct mbox_context* context, uint32_t offset, void* buf,
uint32_t count)
{
- using namespace phosphor::logging;
- using namespace sdbusplus::xyz::openbmc_project::Common::Error;
- using namespace std::string_literals;
- int rc = 0;
- MSG_DBG("Write flash @ 0x%.8x for 0x%.8x from %p\n", offset, count, buf);
- try
+ if (!(context && context->vpnor && context->vpnor->table))
{
- openpower::virtual_pnor::RWRequest rwRequest;
- auto partitionInfo = rwRequest.getPartitionInfo(context, offset);
-
- auto mapped_mem =
- mmap(NULL, partitionInfo->data.actual, PROT_READ | PROT_WRITE,
- MAP_SHARED, rwRequest.fd(), 0);
- if (mapped_mem == MAP_FAILED)
- {
- MSG_ERR("Failed to map partition=%s:Error=%s\n",
- partitionInfo->data.name, strerror(errno));
-
- elog<InternalFailure>();
- }
- // copy to the mapped memory.
+ MSG_ERR("Trying to write data with uninitialised context!\n");
+ return -MBOX_R_SYSTEM_ERROR;
+ }
- uint32_t baseOffset = partitionInfo->data.base
- << context->block_size_shift;
+ vpnor::partition::Table* table = context->vpnor->table;
- // if the asked offset + no of bytes to write is greater
- // then size of the partition file then throw error.
- //
- // FIXME: Don't use .actual, use (.size << ctx->block_size_shift),
- // otherwise we can't grow the size of the data to fill the partition
- if ((offset + count) > (baseOffset + partitionInfo->data.actual))
+ try
+ {
+ const struct pnor_partition& part = table->partition(offset);
+ if (part.data.user.data[1] & PARTITION_READONLY)
{
- munmap(mapped_mem, partitionInfo->data.actual);
- std::stringstream err;
- err << "Write extends beyond the partition length " << std::hex
- << partitionInfo->data.actual;
- throw vpnor::OutOfBoundsOffset(err.str());
+ /* FIXME: This should be done on CREATE_WRITE_WINDOW, not here */
+ return -MBOX_R_WRITE_ERROR;
}
- auto diffOffset = offset - baseOffset;
- memcpy((char*)mapped_mem + diffOffset, buf, count);
- munmap(mapped_mem, partitionInfo->data.actual);
-
- set_flash_bytemap(context, offset, count, FLASH_DIRTY);
+ MSG_DBG("Write flash @ 0x%.8x for 0x%.8x from %p\n", offset, count,
+ buf);
+ vpnor::Request req(context, offset);
+ req.write(buf, count);
}
catch (vpnor::UnmappedOffset& e)
{
@@ -279,5 +231,5 @@ int write_flash(struct mbox_context* context, uint32_t offset, void* buf,
phosphor::logging::commit<err::InternalFailure>();
return -MBOX_R_SYSTEM_ERROR;
}
- return rc;
+ return 0;
}
OpenPOWER on IntegriCloud