diff options
author | Andrew Jeffery <andrew@aj.id.au> | 2018-03-26 11:56:16 +1030 |
---|---|---|
committer | Andrew Jeffery <andrew@aj.id.au> | 2018-04-04 17:27:31 +0930 |
commit | 53c21aaa803e148c9c79cb3f5e0252d911506b10 (patch) | |
tree | 2c8e7482711617bc12a58022dd5839234a17f6a7 /vpnor/mboxd_pnor_partition_table.cpp | |
parent | 8b9102389718f639434253be3fa99f8f6d38d9a6 (diff) | |
download | phosphor-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.cpp | 132 |
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; + } +} |