diff options
-rw-r--r-- | Makefile.am | 8 | ||||
-rw-r--r-- | mboxd.c | 26 | ||||
-rw-r--r-- | mboxd_dbus.c | 8 | ||||
-rw-r--r-- | mboxd_lpc.h | 9 | ||||
-rw-r--r-- | mboxd_lpc_physical.c | 34 | ||||
-rw-r--r-- | mboxd_lpc_virtual.cpp | 34 | ||||
-rw-r--r-- | mboxd_msg.c | 5 | ||||
-rw-r--r-- | mboxd_pnor_partition_table.cpp | 40 | ||||
-rw-r--r-- | mboxd_pnor_partition_table.h | 7 |
9 files changed, 149 insertions, 22 deletions
diff --git a/Makefile.am b/Makefile.am index af44432..f182f1a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -16,14 +16,16 @@ if VIRTUAL_PNOR_ENABLED mboxd_SOURCES += pnor_partition_table.cpp \ mboxd_pnor_partition_table.cpp \ mboxd_flash_virtual.cpp \ - pnor_partition.cpp + pnor_partition.cpp \ + mboxd_lpc_virtual.cpp mboxd_LDFLAGS += -lstdc++fs \ $(SDBUSPLUS_LIBS) \ $(PHOSPHOR_LOGGING_LIBS) \ $(PHOSPHOR_DBUS_INTERFACES_LIBS) else -mboxd_SOURCES += mboxd_flash_physical.c +mboxd_SOURCES += mboxd_flash_physical.c \ + mboxd_lpc_physical.c endif mboxctl_SOURCES = mboxctl.c @@ -61,6 +63,7 @@ TEST_MBOX_SRCS = \ mboxd_msg.c \ mboxd_windows.c \ mboxd_lpc.c \ + mboxd_lpc_physical.c \ common.c \ mboxd_flash_physical.c @@ -151,6 +154,7 @@ test_create_read_window_vpnor_SOURCES = \ mboxd_msg.c \ mboxd_windows.c \ mboxd_lpc.c \ + mboxd_lpc_virtual.cpp \ mboxd_pnor_partition_table.cpp \ mboxd_flash_virtual.cpp \ pnor_partition.cpp \ @@ -104,7 +104,7 @@ static int poll_loop(struct mbox_context *context) case SIGHUP: /* Host didn't request reset -> Notify it */ reset_all_windows(context, SET_BMC_EVENT); - rc = point_to_flash(context); + rc = reset_lpc(context); if (rc < 0) { MSG_ERR("WARNING: Failed to point the " "LPC bus back to flash on " @@ -139,10 +139,10 @@ static int poll_loop(struct mbox_context *context) } } - /* Best to reset windows and point back to flash for safety */ + /* Best to reset windows and the lpc mapping for safety */ /* Host didn't request reset -> Notify it */ reset_all_windows(context, SET_BMC_EVENT); - rc = point_to_flash(context); + rc = reset_lpc(context); /* Not much we can do if this fails */ if (rc < 0) { MSG_ERR("WARNING: Failed to point the LPC bus back to flash\n" @@ -343,8 +343,16 @@ int main(int argc, char **argv) goto finish; } - /* Set the LPC bus mapping to point to the physical flash device */ - rc = point_to_flash(context); +#ifdef VIRTUAL_PNOR_ENABLED + vpnor_create_partition_table(context); + + strcpy(context->paths.ro_loc, PARTITION_FILES_RO_LOC); + strcpy(context->paths.rw_loc, PARTITION_FILES_RW_LOC); + strcpy(context->paths.prsv_loc, PARTITION_FILES_PRSV_LOC); +#endif + + /* Set the LPC bus mapping */ + rc = reset_lpc(context); if (rc) { goto finish; } @@ -354,14 +362,6 @@ int main(int argc, char **argv) goto finish; } -#ifdef VIRTUAL_PNOR_ENABLED - vpnor_create_partition_table(context); - - strcpy(context->paths.ro_loc, PARTITION_FILES_RO_LOC); - strcpy(context->paths.rw_loc, PARTITION_FILES_RW_LOC); - strcpy(context->paths.prsv_loc, PARTITION_FILES_PRSV_LOC); -#endif - MSG_INFO("Entering Polling Loop\n"); rc = poll_loop(context); diff --git a/mboxd_dbus.c b/mboxd_dbus.c index 6673ca6..3f869fe 100644 --- a/mboxd_dbus.c +++ b/mboxd_dbus.c @@ -133,12 +133,12 @@ static int dbus_handle_reset(struct mbox_context *context, } /* - * This will close (and flush) the current window and point the lpc bus - * mapping back to flash. Better set the bmc event to notify the host - * of this. + * This will close (and flush) the current window and reset the lpc bus + * mapping back to flash, or memory in case we're using a virtual pnor. + * Better set the bmc event to notify the host of this. */ reset_all_windows(context, SET_BMC_EVENT); - rc = point_to_flash(context); + rc = reset_lpc(context); if (rc < 0) { return -E_DBUS_HARDWARE; } diff --git a/mboxd_lpc.h b/mboxd_lpc.h index bb288a9..2c38ab0 100644 --- a/mboxd_lpc.h +++ b/mboxd_lpc.h @@ -18,9 +18,18 @@ #ifndef MBOXD_LPC_H #define MBOXD_LPC_H +#ifdef __cplusplus +extern "C" { +#endif + int init_lpc_dev(struct mbox_context *context); void free_lpc_dev(struct mbox_context *context); int point_to_flash(struct mbox_context *context); int point_to_memory(struct mbox_context *context); +int reset_lpc(struct mbox_context *context); + +#ifdef __cplusplus +} +#endif #endif /* MBOXD_LPC_H */ diff --git a/mboxd_lpc_physical.c b/mboxd_lpc_physical.c new file mode 100644 index 0000000..5f5dc01 --- /dev/null +++ b/mboxd_lpc_physical.c @@ -0,0 +1,34 @@ +/* + * 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. + * + */ + +#define _GNU_SOURCE + +#include "mbox.h" +#include "mboxd_lpc.h" + +/* + * reset_lpc() - Reset the lpc bus mapping + * @context: The mbox context pointer + * + * Return: 0 on success otherwise negative error code + */ +int reset_lpc(struct mbox_context *context) +{ + return point_to_flash(context); +} diff --git a/mboxd_lpc_virtual.cpp b/mboxd_lpc_virtual.cpp new file mode 100644 index 0000000..802c761 --- /dev/null +++ b/mboxd_lpc_virtual.cpp @@ -0,0 +1,34 @@ +/* + * 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. + * + */ + +#include "mbox.h" +#include "mboxd_lpc.h" +#include "mboxd_pnor_partition_table.h" + +/* + * reset_lpc() - Reset the lpc bus mapping + * @context: The mbox context pointer + * + * Return 0 on success otherwise negative error code + */ +int reset_lpc(struct mbox_context *context) +{ + vpnor_copy_bootloader_partition(context); + return point_to_memory(context); +} diff --git a/mboxd_msg.c b/mboxd_msg.c index 65946e8..437c67d 100644 --- a/mboxd_msg.c +++ b/mboxd_msg.c @@ -138,14 +138,15 @@ int clr_bmc_events(struct mbox_context *context, uint8_t bmc_event, /* * Command: RESET_STATE - * Reset the LPC mapping to point back at the flash + * Reset the LPC mapping to point back at the flash, or memory in case we're + * using a virtual pnor. */ static int mbox_handle_reset(struct mbox_context *context, union mbox_regs *req, struct mbox_msg *resp) { /* Host requested it -> No BMC Event */ reset_all_windows(context, NO_BMC_EVENT); - return point_to_flash(context); + return reset_lpc(context); } /* diff --git a/mboxd_pnor_partition_table.cpp b/mboxd_pnor_partition_table.cpp index 2464e6c..d2fdba3 100644 --- a/mboxd_pnor_partition_table.cpp +++ b/mboxd_pnor_partition_table.cpp @@ -1,5 +1,7 @@ #include "mboxd_pnor_partition_table.h" +#include "common.h" #include "mbox.h" +#include "mboxd_flash.h" #include "pnor_partition_table.hpp" #include <experimental/filesystem> @@ -57,6 +59,44 @@ const struct pnor_partition* vpnor_get_partition( &(context->vpnor->table->partition(offset)) : nullptr; } +void 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"; + + openpower::virtual_pnor::partition::Table blTable(eraseSize, pnorSize); + vpnor_partition_table vtbl{}; + vtbl.table = &blTable; + struct mbox_context local{}; + local.vpnor = &vtbl; + local.block_size_shift = log_2(eraseSize); + memcpy(&local.paths, &context->paths, sizeof(local.paths)); + + size_t tocOffset = 0; + // Copy TOC + copy_flash(&local, tocOffset, + static_cast<uint8_t*>(context->mem) + tocStart, + blTable.size() * eraseSize); + const pnor_partition& partition = blTable.partition(blPartitionName); + size_t hbbOffset = partition.data.base * eraseSize; + size_t hbbSize = partition.data.actual; + // Copy HBB + copy_flash(&local, hbbOffset, + static_cast<uint8_t*>(context->mem) + hbbOffset, hbbSize); +} + void vpnor_destroy_partition_table(struct mbox_context *context) { if(context && context->vpnor) diff --git a/mboxd_pnor_partition_table.h b/mboxd_pnor_partition_table.h index e6c899b..df15d24 100644 --- a/mboxd_pnor_partition_table.h +++ b/mboxd_pnor_partition_table.h @@ -78,11 +78,16 @@ const struct pnor_partition* vpnor_get_partition( const size_t offset); -/** @brief Destroy partition table, if it exists. +/** @brief Copy bootloader partition (alongwith TOC) to LPC memory * * @param[in] context - mbox context pointer */ +void vpnor_copy_bootloader_partition(const struct mbox_context *context); +/** @brief Destroy partition table, if it exists. + * + * @param[in] context - mbox context pointer + */ void vpnor_destroy_partition_table(struct mbox_context *context); #ifdef __cplusplus |