summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Geissler <andrewg@us.ibm.com>2017-05-18 15:35:40 -0500
committerAndrew Geissler <andrewg@us.ibm.com>2017-06-01 18:35:52 -0500
commit2548c7a35ab2ac8d8d73b8b8f5145d64f248ebe1 (patch)
treef7e020ee7cbd6d42340d6a130f922c20e5f7c75f
parent7ce535cb8cb9e98e64eb307d060e9a6ebf428116 (diff)
downloadopenpower-proc-control-2548c7a35ab2ac8d8d73b8b8f5145d64f248ebe1.tar.gz
openpower-proc-control-2548c7a35ab2ac8d8d73b8b8f5145d64f248ebe1.zip
Set SBE seeprom boot side
The default side for the SBE to boot from is side 0, which is indicated by a 0 in bit 17 of cfam 0x2808. When the boot count goes to 1 (the last before giving up), the start_host logic will switch over to side 1 for the SBE to boot from. Resolves openbmc/openbmc#1467 Change-Id: I61aa22939baa4cde38c8716429b6ca55f7c850bd Signed-off-by: Andrew Geissler <andrewg@us.ibm.com>
-rw-r--r--Makefile.am13
-rw-r--r--ext_interface.cpp87
-rw-r--r--ext_interface.hpp11
-rw-r--r--p9_cfam.hpp1
-rw-r--r--procedures/p9/start_host.cpp21
5 files changed, 128 insertions, 5 deletions
diff --git a/Makefile.am b/Makefile.am
index 474e998..e76cfba 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,14 +9,19 @@ openpower_proc_control_SOURCES = \
filedescriptor.cpp \
registration.cpp \
targeting.cpp \
- openpower_procedures.cpp
+ openpower_procedures.cpp \
+ ext_interface.cpp
CLEANFILES = openpower_procedures.cpp
-openpower_proc_control_LDFLAGS = $(PHOSPHOR_LOGGING_LIBS) -lstdc++fs \
- $(PHOSPHOR_DBUS_INTERFACES_LIBS)
+openpower_proc_control_LDFLAGS = $(PHOSPHOR_LOGGING_LIBS) \
+ $(PHOSPHOR_DBUS_INTERFACES_LIBS) \
+ $(SDBUSPLUS_LIBS) \
+ -lstdc++fs
+
openpower_proc_control_CXXFLAGS = $(PHOSPHOR_LOGGING_CFLAGS) \
- $(PHOSPHOR_DBUS_INTERFACES_CFLAGS)
+ $(PHOSPHOR_DBUS_INTERFACES_CFLAGS) \
+ $(SDBUSPLUS_CFLAGS)
SUBDIRS = test
diff --git a/ext_interface.cpp b/ext_interface.cpp
new file mode 100644
index 0000000..d289e20
--- /dev/null
+++ b/ext_interface.cpp
@@ -0,0 +1,87 @@
+#include <string>
+#include <sdbusplus/server.hpp>
+#include <phosphor-logging/log.hpp>
+#include <ext_interface.hpp>
+
+// Mapper
+constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
+constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
+constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
+
+// Reboot count
+constexpr auto REBOOTCOUNTER_PATH("/org/openbmc/sensors/host/BootCount");
+constexpr auto REBOOTCOUNTER_INTERFACE("org.openbmc.SensorValue");
+
+using namespace phosphor::logging;
+
+/**
+ * @brief Get DBUS service for input interface via mapper call
+ *
+ * This is an internal function to be used only by functions within this
+ * file.
+ *
+ * @param[in] bus - DBUS Bus Object
+ * @param[in] intf - DBUS Interface
+ * @param[in] path - DBUS Object Path
+ *
+ * @return distinct dbus name for input interface/path
+ **/
+std::string getService(sdbusplus::bus::bus& bus,
+ const std::string& intf,
+ const std::string& path)
+{
+
+ auto mapper = bus.new_method_call(MAPPER_BUSNAME,
+ MAPPER_PATH,
+ MAPPER_INTERFACE,
+ "GetObject");
+
+ mapper.append(path);
+ mapper.append(std::vector<std::string>({intf}));
+
+ auto mapperResponseMsg = bus.call(mapper);
+
+ if (mapperResponseMsg.is_method_error())
+ {
+ // TODO openbmc/openbmc#851 - Once available, throw returned error
+ throw std::runtime_error("ERROR in mapper call");
+ }
+
+ std::map<std::string, std::vector<std::string>> mapperResponse;
+ mapperResponseMsg.read(mapperResponse);
+
+ if (mapperResponse.empty())
+ {
+ // TODO openbmc/openbmc#1712 - Handle empty mapper resp. consistently
+ throw std::runtime_error("ERROR in reading the mapper response");
+ }
+
+ return mapperResponse.begin()->first;
+}
+
+
+int getBootCount()
+{
+ auto bus = sdbusplus::bus::new_default();
+
+ auto rebootSvc = getService(bus,
+ REBOOTCOUNTER_INTERFACE,
+ REBOOTCOUNTER_PATH);
+
+ sdbusplus::message::variant<int> rebootCount = 0;
+ auto method = bus.new_method_call(rebootSvc.c_str(),
+ REBOOTCOUNTER_PATH,
+ REBOOTCOUNTER_INTERFACE,
+ "getValue");
+
+ auto reply = bus.call(method);
+ if (reply.is_method_error())
+ {
+ log<level::ERR>("Error in BOOTCOUNT getValue");
+ // TODO openbmc/openbmc#851 - Once available, throw returned error
+ throw std::runtime_error("ERROR in reading BOOTCOUNT");
+ }
+ reply.read(rebootCount);
+
+ return (sdbusplus::message::variant_ns::get<int>(rebootCount));
+}
diff --git a/ext_interface.hpp b/ext_interface.hpp
new file mode 100644
index 0000000..deb21d8
--- /dev/null
+++ b/ext_interface.hpp
@@ -0,0 +1,11 @@
+#include <stdint.h>
+
+/**
+ * @brief Get the current boot count for the host
+ *
+ * The boot count indicates how many more times the bmc will try to
+ * boot the host.
+ *
+ * @return Number of boot attempts left
+ **/
+int getBootCount();
diff --git a/p9_cfam.hpp b/p9_cfam.hpp
index d8fa5ff..07b251d 100644
--- a/p9_cfam.hpp
+++ b/p9_cfam.hpp
@@ -11,6 +11,7 @@ static constexpr uint16_t P9_LL_MODE_REG = 0x0840;
static constexpr uint16_t P9_FSI2PIB_INTERRUPT = 0x100B;
static constexpr uint16_t P9_FSI2PIB_TRUE_MASK = 0x100D;
static constexpr uint16_t P9_CBS_CS = 0x2801;
+static constexpr uint16_t P9_SBE_CTRL_STATUS = 0x2808;
static constexpr uint16_t P9_ROOT_CTRL0 = 0x2810;
static constexpr uint16_t P9_PERV_CTRL0 = 0x281A;
static constexpr uint16_t P9_SCRATCH_REGISTER_8 = 0x283F;
diff --git a/procedures/p9/start_host.cpp b/procedures/p9/start_host.cpp
index 6494086..3049eac 100644
--- a/procedures/p9/start_host.cpp
+++ b/procedures/p9/start_host.cpp
@@ -18,6 +18,7 @@
#include "p9_cfam.hpp"
#include "registration.hpp"
#include "targeting.hpp"
+#include "ext_interface.hpp"
namespace openpower
{
@@ -65,7 +66,25 @@ void startHost()
//Kick off the SBE to start the boot
- //First ensure ISTEP stepping isn't enabled
+ // Choose seeprom side to boot from
+ cfam_data_t sbeSide = 0;
+ if(getBootCount() > 1)
+ {
+ sbeSide = 0;
+ log<level::INFO>("Setting SBE seeprom side to 0",
+ entry("SBE_SIDE_SELECT=%d", 0));
+ }
+ else
+ {
+ sbeSide = 0x00004000;
+ log<level::INFO>("Setting SBE seeprom side to 1",
+ entry("SBE_SIDE_SELECT=%d", 1));
+ }
+ // Bit 17 of the ctrl status reg indicates sbe seeprom boot side
+ // 0 -> Side 0, 1 -> Side 1
+ writeRegWithMask(master, P9_SBE_CTRL_STATUS, sbeSide, 0x00004000);
+
+ //Ensure ISTEP stepping isn't enabled
writeRegWithMask(master, P9_SCRATCH_REGISTER_8, 0x20000000, 0x20000000);
//Start the SBE
OpenPOWER on IntegriCloud