summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am8
-rw-r--r--mboxd.c26
-rw-r--r--mboxd_dbus.c8
-rw-r--r--mboxd_lpc.h9
-rw-r--r--mboxd_lpc_physical.c34
-rw-r--r--mboxd_lpc_virtual.cpp34
-rw-r--r--mboxd_msg.c5
-rw-r--r--mboxd_pnor_partition_table.cpp40
-rw-r--r--mboxd_pnor_partition_table.h7
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 \
diff --git a/mboxd.c b/mboxd.c
index ffd8c84..43d2aa1 100644
--- a/mboxd.c
+++ b/mboxd.c
@@ -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
OpenPOWER on IntegriCloud