summaryrefslogtreecommitdiffstats
path: root/vpnor/mboxd_pnor_partition_table.cpp
diff options
context:
space:
mode:
authorAndrew Jeffery <andrew@aj.id.au>2018-03-26 11:56:16 +1030
committerAndrew Jeffery <andrew@aj.id.au>2018-04-04 17:27:31 +0930
commit53c21aaa803e148c9c79cb3f5e0252d911506b10 (patch)
tree2c8e7482711617bc12a58022dd5839234a17f6a7 /vpnor/mboxd_pnor_partition_table.cpp
parent8b9102389718f639434253be3fa99f8f6d38d9a6 (diff)
downloadphosphor-mboxd-53c21aaa803e148c9c79cb3f5e0252d911506b10.tar.gz
phosphor-mboxd-53c21aaa803e148c9c79cb3f5e0252d911506b10.zip
vpnor: Isolate relevant code in vpnor directory
This is prepatory work for introducing more vpnor-specific behaviours to window handling. We will be introducing more objects to link, in order to hook some of the window command handlers. This change takes the opportunity to revert back to the upstream names for some of the original C files. Change-Id: I6b67ae466a2695054035e65ba752881be9c32d1a Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Diffstat (limited to 'vpnor/mboxd_pnor_partition_table.cpp')
-rw-r--r--vpnor/mboxd_pnor_partition_table.cpp132
1 files changed, 132 insertions, 0 deletions
diff --git a/vpnor/mboxd_pnor_partition_table.cpp b/vpnor/mboxd_pnor_partition_table.cpp
new file mode 100644
index 0000000..db53dc8
--- /dev/null
+++ b/vpnor/mboxd_pnor_partition_table.cpp
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (C) 2018 IBM Corp.
+#include "mboxd_pnor_partition_table.h"
+#include "pnor_partition_table.hpp"
+#include "common.h"
+#include "mbox.h"
+#include "mboxd_flash.h"
+#include "pnor_partition_table.hpp"
+#include "config.h"
+#include "xyz/openbmc_project/Common/error.hpp"
+#include <phosphor-logging/elog-errors.hpp>
+#include <experimental/filesystem>
+
+int init_vpnor(struct mbox_context *context)
+{
+ 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;
+}
+
+int init_vpnor_from_paths(struct mbox_context *context)
+{
+ namespace err = sdbusplus::xyz::openbmc_project::Common::Error;
+ namespace fs = std::experimental::filesystem;
+ namespace vpnor = openpower::virtual_pnor;
+
+ if (context && !context->vpnor)
+ {
+ try
+ {
+ context->vpnor = new vpnor_partition_table;
+ context->vpnor->table =
+ new openpower::virtual_pnor::partition::Table(context);
+ }
+ catch (vpnor::TocEntryError &e)
+ {
+ MSG_ERR("%s\n", e.what());
+ phosphor::logging::commit<err::InternalFailure>();
+ return -MBOX_R_SYSTEM_ERROR;
+ }
+ }
+
+ return 0;
+}
+
+int vpnor_copy_bootloader_partition(const struct mbox_context *context)
+{
+ // The hostboot bootloader has certain size/offset assumptions, so
+ // we need a special partition table here.
+ // It assumes the PNOR is 64M, the TOC size is 32K, the erase block is
+ // 4K, the page size is 4K.
+ // It also assumes the TOC is at the 'end of pnor - toc size - 1 page size'
+ // offset, and first looks for the TOC here, before proceeding to move up
+ // page by page looking for the TOC. So it is optimal to place the TOC at
+ // this offset.
+ constexpr size_t eraseSize = 0x1000;
+ constexpr size_t pageSize = 0x1000;
+ constexpr size_t pnorSize = 0x4000000;
+ constexpr size_t tocMaxSize = 0x8000;
+ constexpr size_t tocStart = pnorSize - tocMaxSize - pageSize;
+ constexpr auto blPartitionName = "HBB";
+
+ namespace err = sdbusplus::xyz::openbmc_project::Common::Error;
+ namespace fs = std::experimental::filesystem;
+ namespace vpnor = openpower::virtual_pnor;
+
+ try
+ {
+ vpnor_partition_table vtbl{};
+ struct mbox_context local = *context;
+ local.vpnor = &vtbl;
+ local.block_size_shift = log_2(eraseSize);
+
+ openpower::virtual_pnor::partition::Table blTable(&local);
+
+ vtbl.table = &blTable;
+
+ size_t tocOffset = 0;
+
+ // Copy TOC
+ copy_flash(&local, tocOffset,
+ static_cast<uint8_t *>(context->mem) + tocStart,
+ blTable.capacity());
+ const pnor_partition &partition = blTable.partition(blPartitionName);
+ size_t hbbOffset = partition.data.base * eraseSize;
+ uint32_t hbbSize = partition.data.actual;
+ // Copy HBB
+ copy_flash(&local, hbbOffset,
+ static_cast<uint8_t *>(context->mem) + hbbOffset, hbbSize);
+ }
+ catch (err::InternalFailure &e)
+ {
+ phosphor::logging::commit<err::InternalFailure>();
+ return -MBOX_R_SYSTEM_ERROR;
+ }
+ catch (vpnor::TocEntryError &e)
+ {
+ MSG_ERR("%s\n", e.what());
+ phosphor::logging::commit<err::InternalFailure>();
+ return -MBOX_R_SYSTEM_ERROR;
+ }
+
+ return 0;
+}
+
+void destroy_vpnor(struct mbox_context *context)
+{
+ if (context && context->vpnor)
+ {
+ delete context->vpnor->table;
+ delete context->vpnor;
+ context->vpnor = nullptr;
+ }
+}
OpenPOWER on IntegriCloud