diff options
author | Andrew Jeffery <andrew@aj.id.au> | 2019-03-18 13:02:01 +1030 |
---|---|---|
committer | Andrew Jeffery <andrew@aj.id.au> | 2019-03-19 16:41:12 +1030 |
commit | 035ad76b8b45a01cc7fcc184e7e72eed69c0ece5 (patch) | |
tree | c95082574c65841246e901d4eb910e3e598e15c6 | |
parent | f4bc335b4fc899509c92c230f746fe90a5aa43d2 (diff) | |
download | phosphor-mboxbridge-035ad76b8b45a01cc7fcc184e7e72eed69c0ece5.tar.gz phosphor-mboxbridge-035ad76b8b45a01cc7fcc184e7e72eed69c0ece5.zip |
vpnor: Consolidate backend and mboxd_pnor_partition_table sources
Change-Id: Ibf66c3a86c2a50e2304fb968f8c912ede84cf719
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
-rw-r--r-- | vpnor/Makefile.am.include | 1 | ||||
-rw-r--r-- | vpnor/backend.cpp | 159 | ||||
-rw-r--r-- | vpnor/backend.h | 38 | ||||
-rw-r--r-- | vpnor/mboxd_pnor_partition_table.cpp | 153 | ||||
-rw-r--r-- | vpnor/pnor_partition_table.cpp | 13 | ||||
-rw-r--r-- | vpnor/pnor_partition_table.hpp | 4 | ||||
-rw-r--r-- | vpnor/test/Makefile.am.include | 1 | ||||
-rw-r--r-- | vpnor/test/create_pnor_partition_table.cpp | 11 | ||||
-rw-r--r-- | vpnor/test/create_read_window_toc.cpp | 14 | ||||
-rw-r--r-- | vpnor/test/force_readonly_toc.cpp | 16 | ||||
-rw-r--r-- | vpnor/test/toc_lookup_failed.cpp | 12 | ||||
-rw-r--r-- | vpnor/test/toc_lookup_found.cpp | 10 | ||||
-rw-r--r-- | vpnor/test/toc_missing_file.cpp | 10 | ||||
-rw-r--r-- | vpnor/test/write_toc.cpp | 14 |
14 files changed, 207 insertions, 249 deletions
diff --git a/vpnor/Makefile.am.include b/vpnor/Makefile.am.include index d69a94b..188e69f 100644 --- a/vpnor/Makefile.am.include +++ b/vpnor/Makefile.am.include @@ -1,5 +1,4 @@ mboxd_SOURCES += %reldir%/pnor_partition_table.cpp \ - %reldir%/mboxd_pnor_partition_table.cpp \ %reldir%/backend.cpp \ %reldir%/pnor_partition.cpp diff --git a/vpnor/backend.cpp b/vpnor/backend.cpp index 06aed57..006104f 100644 --- a/vpnor/backend.cpp +++ b/vpnor/backend.cpp @@ -1,6 +1,8 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (C) 2018 IBM Corp. +#include "config.h" + #include <fcntl.h> #include <stdint.h> #include <stdlib.h> @@ -12,19 +14,21 @@ #include <algorithm> extern "C" { +#include "backend.h" #include "common.h" #include "lpc.h" #include "mboxd.h" #include "protocol.h" +#include "vpnor/backend.h" } -#include "config.h" - #include "pnor_partition.hpp" #include "pnor_partition_table.hpp" #include "xyz/openbmc_project/Common/error.hpp" +#include <cassert> #include <exception> +#include <experimental/filesystem> #include <memory> #include <phosphor-logging/elog-errors.hpp> #include <phosphor-logging/log.hpp> @@ -39,6 +43,143 @@ namespace vpnor = openpower::virtual_pnor; static constexpr uint32_t VPNOR_ERASE_SIZE = 4 * 1024; +void vpnor_default_paths(vpnor_partition_paths* paths) +{ + 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'; +} + +/** @brief Create a virtual PNOR partition table. + * + * @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. + * + * 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. + */ +static 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; + + 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 + { + phosphor::logging::commit<err::InternalFailure>(); + } + catch (const std::exception& e) + { + MSG_ERR("Failed to commit InternalFailure: %s\n", e.what()); + } + return -EINVAL; + } + + return 0; +} + +/** @brief Copy bootloader partition (alongwith TOC) to LPC memory + * + * @param[in] backend - The backend context pointer + * + * @returns 0 on success, negative error code on failure + */ +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. + // 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 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); + + vtbl.table = &blTable; + + size_t tocOffset = 0; + + const pnor_partition& partition = blTable.partition(blPartitionName); + size_t hbbOffset = partition.data.base * eraseSize; + uint32_t hbbSize = partition.data.actual; + + 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*>(buf); + backend_copy(&local, tocOffset, buf8 + tocStart, blTable.capacity()); + backend_copy(&local, hbbOffset, buf8 + hbbOffset, hbbSize); + } + catch (err::InternalFailure& e) + { + phosphor::logging::commit<err::InternalFailure>(); + return -EIO; + } + catch (vpnor::ReasonedError& e) + { + MSG_ERR("%s\n", e.what()); + phosphor::logging::commit<err::InternalFailure>(); + return -EIO; + } + + return 0; +} + int vpnor_dev_init(struct backend* backend, void* data) { vpnor_partition_paths* paths = (vpnor_partition_paths*)data; @@ -111,7 +252,17 @@ cleanup_filename: static void vpnor_free(struct backend* backend) { - vpnor_destroy(backend); + struct vpnor_data* priv = (struct vpnor_data*)backend->priv; + + if (priv) + { + if (priv->vpnor) + { + delete priv->vpnor->table; + } + delete priv->vpnor; + } + delete priv; } /* @@ -298,7 +449,7 @@ static int vpnor_reset(struct backend* backend, void* buf, uint32_t count) vpnor_partition_paths paths = priv->paths; - vpnor_destroy(backend); + vpnor_free(backend); rc = vpnor_init(backend, &paths); if (rc < 0) diff --git a/vpnor/backend.h b/vpnor/backend.h index b76aa98..0102238 100644 --- a/vpnor/backend.h +++ b/vpnor/backend.h @@ -3,8 +3,6 @@ #pragma once #include <limits.h> -#include "pnor_partition_defs.h" -#include "backend.h" struct mbox_context; struct vpnor_partition_table; @@ -41,42 +39,6 @@ static inline void vpnor_default_paths(struct vpnor_partition_paths *paths) } #endif -#ifdef VIRTUAL_PNOR_ENABLED -/** @brief Create a virtual PNOR partition table. - * - * @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. - * - * 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 vpnor_init(struct backend *backend, - const struct vpnor_partition_paths *paths); - -/** @brief Copy bootloader partition (alongwith TOC) to LPC memory - * - * @param[in] backend - The backend context pointer - * - * @returns 0 on success, negative error code on failure - */ -int vpnor_copy_bootloader_partition(const struct backend *backend, void *buf, - uint32_t count); - -/** @brief Destroy partition table, if it exists. - * - * @param[in] backend - The backend context pointer - */ -void vpnor_destroy(struct backend *backend); - #ifdef __cplusplus } #endif - -#endif diff --git a/vpnor/mboxd_pnor_partition_table.cpp b/vpnor/mboxd_pnor_partition_table.cpp deleted file mode 100644 index e5f7458..0000000 --- a/vpnor/mboxd_pnor_partition_table.cpp +++ /dev/null @@ -1,153 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright (C) 2018 IBM Corp. -#include "config.h" - -#include <assert.h> - -extern "C" { -#include "backend.h" -} - -#include "pnor_partition_table.hpp" -#include "xyz/openbmc_project/Common/error.hpp" - -#include <experimental/filesystem> -#include <phosphor-logging/elog-errors.hpp> - -#include "common.h" -#include "mboxd.h" -#include "vpnor/backend.h" - -void vpnor_default_paths(vpnor_partition_paths* paths) -{ - 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 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 (!(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 - { - phosphor::logging::commit<err::InternalFailure>(); - } - catch (const std::exception& e) - { - MSG_ERR("Failed to commit InternalFailure: %s\n", e.what()); - } - return -EINVAL; - } - - return 0; -} - -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. - // 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 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); - - vtbl.table = &blTable; - - size_t tocOffset = 0; - - const pnor_partition& partition = blTable.partition(blPartitionName); - size_t hbbOffset = partition.data.base * eraseSize; - uint32_t hbbSize = partition.data.actual; - - 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*>(buf); - backend_copy(&local, tocOffset, buf8 + tocStart, blTable.capacity()); - backend_copy(&local, hbbOffset, buf8 + hbbOffset, hbbSize); - } - catch (err::InternalFailure& e) - { - phosphor::logging::commit<err::InternalFailure>(); - return -EIO; - } - catch (vpnor::ReasonedError& e) - { - MSG_ERR("%s\n", e.what()); - phosphor::logging::commit<err::InternalFailure>(); - return -EIO; - } - - return 0; -} - -void vpnor_destroy(struct backend* backend) -{ - struct vpnor_data* priv = (struct vpnor_data*)backend->priv; - - if (priv) - { - if (priv->vpnor) - { - delete priv->vpnor->table; - } - delete priv->vpnor; - } - delete priv; -} diff --git a/vpnor/pnor_partition_table.cpp b/vpnor/pnor_partition_table.cpp index 2a9442b..64a7872 100644 --- a/vpnor/pnor_partition_table.cpp +++ b/vpnor/pnor_partition_table.cpp @@ -2,8 +2,13 @@ // Copyright (C) 2018 IBM Corp. #include "config.h" -#include "pnor_partition_table.hpp" +extern "C" { +#include "backend.h" +#include "common.h" +#include "mboxd.h" +} +#include "pnor_partition_table.hpp" #include "xyz/openbmc_project/Common/error.hpp" #include <endian.h> @@ -14,12 +19,6 @@ #include <phosphor-logging/elog-errors.hpp> #include <regex> -extern "C" { -#include "backend.h" -#include "common.h" -#include "mboxd.h" -} - namespace openpower { namespace virtual_pnor diff --git a/vpnor/pnor_partition_table.hpp b/vpnor/pnor_partition_table.hpp index cfd47b5..4309ad5 100644 --- a/vpnor/pnor_partition_table.hpp +++ b/vpnor/pnor_partition_table.hpp @@ -10,8 +10,8 @@ extern "C" { #include "backend.h" #include "common.h" -#include "pnor_partition_defs.h" #include "vpnor/backend.h" +#include "vpnor/pnor_partition_defs.h" } struct mbox_context; @@ -97,7 +97,7 @@ class Table /** @brief Constructor accepting the path of the directory * that houses the PNOR partition files. * - * @param[in] ctx - Acquire sizes and paths relevant to the table + * @param[in] be - Acquire sizes and paths relevant to the table * * Throws MalformedTocEntry, InvalidTocEntry */ diff --git a/vpnor/test/Makefile.am.include b/vpnor/test/Makefile.am.include index 0600969..0b93747 100644 --- a/vpnor/test/Makefile.am.include +++ b/vpnor/test/Makefile.am.include @@ -7,7 +7,6 @@ TEST_MBOX_VPNOR_INTEG_SRCS = \ windows.c \ lpc.c \ vpnor/backend.cpp \ - vpnor/mboxd_pnor_partition_table.cpp \ vpnor/pnor_partition.cpp \ vpnor/pnor_partition_table.cpp \ %reldir%/tmpd.cpp diff --git a/vpnor/test/create_pnor_partition_table.cpp b/vpnor/test/create_pnor_partition_table.cpp index f198f29..7af61b7 100644 --- a/vpnor/test/create_pnor_partition_table.cpp +++ b/vpnor/test/create_pnor_partition_table.cpp @@ -1,19 +1,20 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (C) 2018 IBM Corp. -#include "config.h" - -#include "vpnor/pnor_partition_table.hpp" -#include <cassert> -#include <cstring> +#include "config.h" extern "C" { +#include "backend.h" #include "test/mbox.h" #include "test/system.h" } +#include "vpnor/pnor_partition_table.hpp" #include "vpnor/test/tmpd.hpp" +#include <cassert> +#include <cstring> + static const auto BLOCK_SIZE = 4 * 1024; static const auto ERASE_SIZE = BLOCK_SIZE; static const auto PNOR_SIZE = 64 * 1024 * 1024; diff --git a/vpnor/test/create_read_window_toc.cpp b/vpnor/test/create_read_window_toc.cpp index 7571f37..1eda6c2 100644 --- a/vpnor/test/create_read_window_toc.cpp +++ b/vpnor/test/create_read_window_toc.cpp @@ -2,20 +2,20 @@ // Copyright (C) 2018 IBM Corp. #include "config.h" -#include "vpnor/pnor_partition_table.hpp" - -#include <sys/mman.h> - -#include <cassert> -#include <cstring> - extern "C" { +#include "backend.h" #include "test/mbox.h" #include "test/system.h" } +#include "vpnor/pnor_partition_table.hpp" #include "vpnor/test/tmpd.hpp" +#include <sys/mman.h> + +#include <cassert> +#include <cstring> + static constexpr auto BLOCK_SIZE = 4 * 1024; static constexpr auto PNOR_SIZE = 64 * 1024 * 1024; static constexpr auto MEM_SIZE = BLOCK_SIZE * 2; diff --git a/vpnor/test/force_readonly_toc.cpp b/vpnor/test/force_readonly_toc.cpp index 465adad..026c976 100644 --- a/vpnor/test/force_readonly_toc.cpp +++ b/vpnor/test/force_readonly_toc.cpp @@ -2,22 +2,22 @@ // Copyright (C) 2018 IBM Corp. #include "config.h" -#include "vpnor/pnor_partition_table.hpp" - -#include <endian.h> -#include <sys/mman.h> - -#include <cassert> -#include <cstring> - extern "C" { +#include "backend.h" #include "test/mbox.h" #include "test/system.h" #include "vpnor/pnor_partition_defs.h" } +#include "vpnor/pnor_partition_table.hpp" #include "vpnor/test/tmpd.hpp" +#include <endian.h> +#include <sys/mman.h> + +#include <cassert> +#include <cstring> + static constexpr auto BLOCK_SIZE = 4 * 1024; static constexpr auto PNOR_SIZE = BLOCK_SIZE; static constexpr auto MEM_SIZE = BLOCK_SIZE; diff --git a/vpnor/test/toc_lookup_failed.cpp b/vpnor/test/toc_lookup_failed.cpp index cb56e51..b92cdff 100644 --- a/vpnor/test/toc_lookup_failed.cpp +++ b/vpnor/test/toc_lookup_failed.cpp @@ -2,18 +2,18 @@ // Copyright (C) 2018 IBM Corp. #include "config.h" -#include "vpnor/pnor_partition_table.hpp" -#include "xyz/openbmc_project/Common/error.hpp" - -#include <cassert> -#include <cstring> - extern "C" { +#include "backend.h" #include "test/mbox.h" #include "test/system.h" } +#include "vpnor/pnor_partition_table.hpp" #include "vpnor/test/tmpd.hpp" +#include "xyz/openbmc_project/Common/error.hpp" + +#include <cassert> +#include <cstring> static constexpr auto BLOCK_SIZE = 0x1000; static constexpr auto ERASE_SIZE = BLOCK_SIZE; diff --git a/vpnor/test/toc_lookup_found.cpp b/vpnor/test/toc_lookup_found.cpp index b8c879c..efe4ea4 100644 --- a/vpnor/test/toc_lookup_found.cpp +++ b/vpnor/test/toc_lookup_found.cpp @@ -2,18 +2,18 @@ // Copyright (C) 2018 IBM Corp. #include "config.h" -#include "vpnor/pnor_partition_table.hpp" - -#include <cassert> -#include <cstring> - extern "C" { +#include "backend.h" #include "test/mbox.h" #include "test/system.h" } +#include "vpnor/pnor_partition_table.hpp" #include "vpnor/test/tmpd.hpp" +#include <cassert> +#include <cstring> + static constexpr auto BLOCK_SIZE = 0x1000; static constexpr auto ERASE_SIZE = BLOCK_SIZE; static constexpr auto PNOR_SIZE = 64 * 1024 * 1024; diff --git a/vpnor/test/toc_missing_file.cpp b/vpnor/test/toc_missing_file.cpp index 95147c0..b19bfd8 100644 --- a/vpnor/test/toc_missing_file.cpp +++ b/vpnor/test/toc_missing_file.cpp @@ -2,18 +2,18 @@ // Copyright (C) 2018 IBM Corp. #include "config.h" -#include "vpnor/pnor_partition_table.hpp" - -#include <cassert> -#include <cstring> - extern "C" { +#include "backend.h" #include "test/mbox.h" #include "test/system.h" } +#include "vpnor/pnor_partition_table.hpp" #include "vpnor/test/tmpd.hpp" +#include <cassert> +#include <cstring> + static constexpr auto BLOCK_SIZE = 0x1000; static constexpr auto ERASE_SIZE = BLOCK_SIZE; static constexpr auto PNOR_SIZE = 64 * 1024 * 1024; diff --git a/vpnor/test/write_toc.cpp b/vpnor/test/write_toc.cpp index 8b690a1..d8b63ce 100644 --- a/vpnor/test/write_toc.cpp +++ b/vpnor/test/write_toc.cpp @@ -2,20 +2,20 @@ // Copyright (C) 2018 IBM Corp. #include "config.h" -#include "vpnor/pnor_partition_table.hpp" - -#include <sys/mman.h> - -#include <cassert> -#include <cstring> - extern "C" { +#include "backend.h" #include "test/mbox.h" #include "test/system.h" } +#include "vpnor/pnor_partition_table.hpp" #include "vpnor/test/tmpd.hpp" +#include <sys/mman.h> + +#include <cassert> +#include <cstring> + static constexpr auto BLOCK_SIZE = 4 * 1024; static constexpr auto PNOR_SIZE = 2 * BLOCK_SIZE; static constexpr auto MEM_SIZE = BLOCK_SIZE; |