// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2018 IBM Corp.

#include "config.h"

#include "hiomap.hpp"

#include <endian.h>
#include <host-ipmid/ipmid-api.h>
#include <signal.h>
#include <string.h>
#include <systemd/sd-bus.h>
#include <systemd/sd-event.h>

#include <cassert>
#include <cstring>
#include <fstream>
#include <functional>
#include <host-ipmid/ipmid-host-cmd-utils.hpp>
#include <host-ipmid/ipmid-host-cmd.hpp>
#include <iostream>
#include <map>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/bus/match.hpp>
#include <sdbusplus/exception.hpp>
#include <string>
#include <tuple>
#include <utility>

/*

Design and integration notes
============================

The primary motivation of the Host I/O Mapping protocol (HIOMAP) is to mediate
host access to a BMC-controlled flash chip housing the host's boot firmware.

openpower-host-ipmi-flash facilitates the system design of transporting the
HIOMAP protocol[1] over IPMI. This is somewhat abusive of IPMI, basically
treating the BT interface as a mailbox with an interrupt each way between the
BMC and the host.

[1] https://github.com/openbmc/mboxbridge/blob/master/Documentation/protocol.md

Using IPMI in this way has a number of challenges, a lot of them on the host
side where we need to bring up the LPC and BT interfaces to enable IPMI before
accessing the flash, and before any interrupts are enabled. There are also
challenges on the BMC side with the design of the current implementation. We
will cover those here.

BMC-side System Design and Integration Issues
---------------------------------------------

The current design is that we have the HIOMAP daemon, mboxd (to be renamed),
exposing a set of DBus interfaces. Whilst the spec defines the IPMI transport
message packing, mboxd knows nothing of IPMI itself, instead relying on the
DBus interface to receive messages from ipmid. ipmid in-turn knows nothing of
the interfaces communicating with it, also relying on DBus to receive messages
from interface-specific daemons, e.g. btbridged[2].

[2] https://github.com/openbmc/btbridge

For this design to function correctly we must ensure that the daemons are
started and shut down in a reasonable order, however defining that order is
somewhat tricky:

1. systemd uses Wants=/Before=/After= relationships in units to define both
   start-up *and* shutdown order, in stack push / pop order respectively.
2. Clearly ipmid depends on btbridged to receive messages sent by signals and
   replied to by method calls, so it needs a Wants=/After= relationship on
   btbridged
3. mboxd depends on ipmid to receive messages sent by method call, and issues a
   PropertiesChanged signal to notify of state changes.

Point 3. suggests mboxd should have a Wants=/Before= relationship with ipmid to
ensure ipmid can call into mboxd as messages arrive. However, this causes some
grief with shutdown of the BMC, as mboxd needs to issue a state-change
notification when it is shut down to inform the host that will not repsond to
future requests and that the protocol state has been reset. If mboxd has a
Wants=/Before= relationship with ipmid this message will never propagate to the
host, as ipmid will be shut by systemd before mboxd.

The above leads to mboxd having a Wants=/After= relationship with ipmid. This
ensures that if mboxd is restarted on its own the correct state changes will be
propagated to the host. The case where ipmid attempts to call into mboxd's DBus
interface before mboxd is ready is mitigated by the ready bit in the protocol's
BMC status, which will not yet be set, preventing a conforming host from
attempting to contact mboxd.

While this ordering prevents mboxd from being terminated before ipmid, there is
no control over the *scheduling* of processes to ensure the PropertiesChanged
signal emitted by mboxd before mboxd is terminated is seen by ipmid before
*ipmid* is also terminated. This leads to our first implementation wart:

  On the basis that mboxd has a Wants=/After= relationship with ipmid,
  openpower-host-ipmi-flash will emit an HIOMAP BMC status event to the host
  with the value BMC_EVENT_PROTOCOL_RESET upon receiving SIGTERM iff the BMC
  state is not already set to BMC_EVENT_PROTOCOL_RESET.

If ipmid has received SIGTERM the assumption is that it is systemd that is
sending it, and that the Wants=/After= relationship requires that mboxd has
been terminated before ipmid receives SIGTERM. By ensuring
openpower-host-ipmi-flash emits the BMC event state we close the race where the
host is not informed of the termination of mboxd due to scheduling ipmid (to
deliver SIGTERM) prior to scheduling dbus-daemon, where the PropertiesChanged
event would be delivered from mboxd to ipmid.

Observations on the IPMI Specification and Design Details of ipmid
------------------------------------------------------------------

In addition to the system-level design problems with delivering
PropertiesChanged signals during shutdown, IPMI specification and ipmid design
issues exist that make it tedious to ensure that events will be correctly
delivered to the host.

The first necessary observation is that the mechanism for delivering BMC state
change events from mboxd to the host over IPMI uses the SMS ATN bit to indicate
a message is ready for delivery from the BMC to the host system. Retrieving the
BMC state data involves the host recognising that the SMS ATN bit is set,
performing Get Message Flags transaction with the BMC followed by a subsequent
Get Message transaction. Thus, delivery of the HIOMAP protocol's BMC status is
not an atomic event.

The second necessary observation is that the kernel delivers signals
asynchronously. This couples badly with IPMI's event delivery not being atomic:
ipmid can win the race against SIGTERM to receive the PropertiesChanged event
from mboxd, but lose the race to complete delivery to the host.

  On this basis, we need to block the delivery of SIGTERM to ipmid until ipmid
  has completed the set of `SMS ATN`/`Get Message Flags`/`Get Message`
  transactions with the host

One approach to this would be to configure a custom SIGTERM handler that sets
some global application state to indicate that SIGTERM has been delivered. A
better approach that avoids the need for global application state is to simply
block the signal until we are ready to handle it, which we can do via
sigprocmask(2).

The existing design of ipmid makes it feasible to block and unblock
asynchronous SIGTERM as we require. ipmid_send_cmd_to_host() takes a CallBack
function as an argument, which is invoked by
phosphor::host::command::Manager::getNextCommand(). The documentation for
phosphor::host::command::Manager::getNextCommand() says:

  @brief  Extracts the next entry in the queue and returns
          Command and data part of it.

  @detail Also calls into the registered handlers so that they can now
          send the CommandComplete signal since the interface contract
          is that we emit this signal once the message has been
          passed to the host (which is required when calling this)

          Also, if the queue has more commands, then it will alert the
          host

However, its description is not entirely accurate. The callback function is
invoked when ipmid *dequeues* the data to send to the host: Delivery of the
data to the host occurs at some *after* the callback has been invoked.

Invoking the callback before completion of delivery of the data to the host
nullifies the approach of unblocking asynchronous SIGTERM in the callback
associated with sending the HIOMAP BMC state event to the host, as the BMC
kernel can asynchronously terminate the process between the callback being
invoked and the host receiving the BMC state event data.

Overcoming this issue hinges on a significant implementation detail of ipmid:

  ipmid uses an sd_event loop in the main function to pump DBus events.

This leads to a third necessary observation:

  sd_event can be used to process UNIX signals as well as other events by way
  of Linux's signalfd(2) interface.

The fact that sd_event is used to pump DBus events means that ipmid can remain
a single-threaded process. By remaining single-threaded we know that events
processing is sequencial and no two events can be processed simultaneously. A
corollary of this is that DBus events and UNIX signals are serialised with
respect to eachother.

The fourth necessary observation is that we do not need to pump sd_event in
order to complete DBus method calls; sd_bus will handle the pumping independent
of the main loop in order to complete the method invocation.

Implementing Reliable HIOMAP BMC Status Event Delivery
------------------------------------------------------

We achieve reliable delivery of HIOMAP BMC status events in the following way:

1. During plugin initialisation, mask SIGTERM using sigprocmask(2)
2. Subsequent to masking SIGTERM, register
   openpower::flash::hiomap_protocol_reset() as the SIGTERM handler using
   sd_event_add_signal() to hook a signalfd(2) into sd_event
3. openpower::flash::hiomap_protocol_reset() implements the logic to send the
   BMC_EVENT_PROTOCOL_RESET state to the host if necessary, otherwise terminate
   the sd_event loop.
4. If it is necessary to send BMC_EVENT_PROTOCOL_RESET to the host in 3, assign
   a callback handler that terminates the sd_event loop, which is only
   processed after the current iteration is complete.

This process and its use of signalfd integration in the sd_event loop
eliminates the following three races:

1. The scheduler race between mboxd, dbus-daemon and ipmid, by having
   openpower-host-ipmi-flash conditionally deliver the protocol reset event if
   no such message has been received from mboxd
2. The race between delivering the BMC status event to the host and ipmid
   receiving asynchronous SIGTERM after receiving the PropertiesChanged event
   from mboxd
3. The race to deliver the BMC status data to the host after unblocking
   asynchronous SIGTERM in the host command callback and before receiving
   asynchronous SIGTERM.

Ultimately, ipmid could benefit from a redesign that fires the callback *after*
delivering the associated data to the host, but brief inspection determined
that this involved a non-trivial amount of effort.

*/

using namespace sdbusplus;
using namespace phosphor::host::command;

static void register_openpower_hiomap_commands() __attribute__((constructor));

namespace openpower
{
namespace flash
{
constexpr auto BMC_EVENT_DAEMON_READY = 1 << 7;
constexpr auto BMC_EVENT_FLASH_CTRL_LOST = 1 << 6;
constexpr auto BMC_EVENT_WINDOW_RESET = 1 << 1;
constexpr auto BMC_EVENT_PROTOCOL_RESET = 1 << 0;

constexpr auto IPMI_CMD_HIOMAP_EVENT = 0x0f;

constexpr auto HIOMAPD_SERVICE = "xyz.openbmc_project.Hiomapd";
constexpr auto HIOMAPD_OBJECT = "/xyz/openbmc_project/Hiomapd";
constexpr auto HIOMAPD_IFACE = "xyz.openbmc_project.Hiomapd.Protocol";
constexpr auto HIOMAPD_IFACE_V2 = "xyz.openbmc_project.Hiomapd.Protocol.V2";

constexpr auto DBUS_IFACE_PROPERTIES = "org.freedesktop.DBus.Properties";

/* XXX: ipmid is currently single-threaded, pumping dbus events in sequence
 * via the main event loop. Thus the code is not forced to be re-entrant. We
 * also know that the callback and DBus event handling will not be running
 * concurrently.
 *
 * ipmid_send_cmd_to_host() takes a callback that doesn't define a context
 * pointer, so instead use a global. active_event_updates gates manipulation of
 * process state, so its definition as a global at least aligns with its use.
 */
static int active_event_updates;
static struct sd_event_source* event_source;

struct hiomap
{
    bus::bus* bus;

    /* Signals */
    bus::match::match* properties;

    /* Protocol state */
    std::map<std::string, int> event_lookup;
    uint8_t bmc_events;
    uint8_t seq;
};

/* TODO: Replace get/put with packed structs and direct assignment */
template <typename T>
static inline T get(void* buf)
{
    T t;
    std::memcpy(&t, buf, sizeof(t));
    return t;
}

template <typename T>
static inline void put(void* buf, T&& t)
{
    std::memcpy(buf, &t, sizeof(t));
}

typedef ipmi_ret_t (*hiomap_command)(ipmi_request_t req, ipmi_response_t resp,
                                     ipmi_data_len_t data_len,
                                     ipmi_context_t context);

struct errno_cc_entry
{
    int err;
    int cc;
};

static const errno_cc_entry errno_cc_map[] = {
    {0, IPMI_CC_OK},
    {EBUSY, IPMI_CC_BUSY},
    {ENOTSUP, IPMI_CC_INVALID},
    {ETIMEDOUT, 0xc3}, /* FIXME: Replace when defined in ipmid-api.h */
    {ENOSPC, 0xc4},    /* FIXME: Replace when defined in ipmid-api.h */
    {EINVAL, IPMI_CC_PARM_OUT_OF_RANGE},
    {ENODEV, IPMI_CC_SENSOR_INVALID},
    {EPERM, IPMI_CC_INSUFFICIENT_PRIVILEGE},
    {EACCES, IPMI_CC_INSUFFICIENT_PRIVILEGE},
    {-1, IPMI_CC_UNSPECIFIED_ERROR},
};

static int hiomap_xlate_errno(int err)
{
    const errno_cc_entry* entry = &errno_cc_map[0];

    while (!(entry->err == err || entry->err == -1))
    {
        entry++;
    }

    return entry->cc;
}

static void ipmi_hiomap_event_response(IpmiCmdData cmd, bool status)
{
    using namespace phosphor::logging;
    int rc;

    if (!status)
    {
        log<level::ERR>("Failed to deliver host command",
                        entry("SEL_COMMAND=%x:%x", cmd.first, cmd.second));
    }

    assert(active_event_updates);
    active_event_updates--;
    if (!active_event_updates)
    {
        rc = sd_event_source_set_enabled(event_source, SD_EVENT_ON);
        if (rc < 0)
        {
            log<level::WARNING>("Failed to unblock SIGTERM delivery",
                                entry("RC=%d", rc));
        }
        else
        {
            log<level::DEBUG>("Unblocked SIGTERM");
        }
    }
}

static int hiomap_handle_property_update(struct hiomap* ctx,
                                         sdbusplus::message::message& msg)
{
    using namespace phosphor::logging;

    std::map<std::string, sdbusplus::message::variant<bool>> msgData;
    int rc;

    if (!active_event_updates)
    {
        rc = sd_event_source_set_enabled(event_source, SD_EVENT_OFF);
        if (rc < 0)
        {
            log<level::WARNING>("Failed to block SIGTERM delivery",
                                entry("RC=%d", rc));
        }
        else
        {
            log<level::DEBUG>("Blocked SIGTERM");
        }
    }
    active_event_updates++;

    std::string iface;
    msg.read(iface, msgData);

    for (auto const& x : msgData)
    {
        if (!ctx->event_lookup.count(x.first))
        {
            /* Unsupported event? */
            continue;
        }

        uint8_t mask = ctx->event_lookup[x.first];
        auto value = sdbusplus::message::variant_ns::get<bool>(x.second);

        if (value)
        {
            ctx->bmc_events |= mask;
        }
        else
        {
            ctx->bmc_events &= ~mask;
        }
    }

    auto cmd = std::make_pair(IPMI_CMD_HIOMAP_EVENT, ctx->bmc_events);

    ipmid_send_cmd_to_host(std::make_tuple(cmd, ipmi_hiomap_event_response));

    return 0;
}

static int hiomap_protocol_reset_response(IpmiCmdData cmd, bool status)
{
    return sd_event_exit(ipmid_get_sd_event_connection(), status ? 0 : EIO);
}

static int hiomap_protocol_reset(sd_event_source* source,
                                 const struct signalfd_siginfo* si,
                                 void* userdata)
{
    struct hiomap* ctx = static_cast<struct hiomap*>(userdata);

    if (ctx->bmc_events == BMC_EVENT_PROTOCOL_RESET)
    {
        return sd_event_exit(ipmid_get_sd_event_connection(), 0);
    }

    /*
     * Send an attention indicating the hiomapd has died
     * (BMC_EVENT_DAEMON_READY cleared) and that the protocol has been reset
     * (BMC_EVENT_PROTOCOL_RESET set) to indicate to the host that it needs to
     * wait for the BMC to come back and renegotiate the protocol.
     *
     * We know this to be the case in systems that integrate
     * openpower-host-ipmi-flash, as hiomapd's unit depends on
     * phosphor-ipmi-host, and thus hiomapd has been terminated before ipmid
     * receives SIGTERM.
     */
    auto cmd = std::make_pair(IPMI_CMD_HIOMAP_EVENT, BMC_EVENT_PROTOCOL_RESET);

    auto cmdHandler = std::make_tuple(cmd, hiomap_protocol_reset_response);
    ipmid_send_cmd_to_host(cmdHandler);

    return 0;
}

static bus::match::match hiomap_match_properties(struct hiomap* ctx)
{
    auto properties =
        bus::match::rules::propertiesChanged(HIOMAPD_OBJECT, HIOMAPD_IFACE_V2);

    bus::match::match match(
        *ctx->bus, properties,
        std::bind(hiomap_handle_property_update, ctx, std::placeholders::_1));

    return match;
}

static ipmi_ret_t hiomap_reset(ipmi_request_t request, ipmi_response_t response,
                               ipmi_data_len_t data_len, ipmi_context_t context)
{
    struct hiomap* ctx = static_cast<struct hiomap*>(context);

    auto m = ctx->bus->new_method_call(HIOMAPD_SERVICE, HIOMAPD_OBJECT,
                                       HIOMAPD_IFACE, "Reset");
    try
    {
        ctx->bus->call(m);

        *data_len = 0;
    }
    catch (const exception::SdBusError& e)
    {
        return hiomap_xlate_errno(e.get_errno());
    }

    return IPMI_CC_OK;
}

static ipmi_ret_t hiomap_get_info(ipmi_request_t request,
                                  ipmi_response_t response,
                                  ipmi_data_len_t data_len,
                                  ipmi_context_t context)
{
    struct hiomap* ctx = static_cast<struct hiomap*>(context);

    if (*data_len < 1)
    {
        return IPMI_CC_REQ_DATA_LEN_INVALID;
    }

    uint8_t* reqdata = (uint8_t*)request;
    auto m = ctx->bus->new_method_call(HIOMAPD_SERVICE, HIOMAPD_OBJECT,
                                       HIOMAPD_IFACE, "GetInfo");
    m.append(reqdata[0]);

    try
    {
        auto reply = ctx->bus->call(m);

        uint8_t version;
        uint8_t blockSizeShift;
        uint16_t timeout;
        reply.read(version, blockSizeShift, timeout);

        uint8_t* respdata = (uint8_t*)response;

        /* FIXME: Assumes v2! */
        put(&respdata[0], version);
        put(&respdata[1], blockSizeShift);
        put(&respdata[2], htole16(timeout));

        *data_len = 4;
    }
    catch (const exception::SdBusError& e)
    {
        return hiomap_xlate_errno(e.get_errno());
    }

    return IPMI_CC_OK;
}

static ipmi_ret_t hiomap_get_flash_info(ipmi_request_t request,
                                        ipmi_response_t response,
                                        ipmi_data_len_t data_len,
                                        ipmi_context_t context)
{
    struct hiomap* ctx = static_cast<struct hiomap*>(context);

    auto m = ctx->bus->new_method_call(HIOMAPD_SERVICE, HIOMAPD_OBJECT,
                                       HIOMAPD_IFACE_V2, "GetFlashInfo");
    try
    {
        auto reply = ctx->bus->call(m);

        uint16_t flashSize, eraseSize;
        reply.read(flashSize, eraseSize);

        uint8_t* respdata = (uint8_t*)response;
        put(&respdata[0], htole16(flashSize));
        put(&respdata[2], htole16(eraseSize));

        *data_len = 4;
    }
    catch (const exception::SdBusError& e)
    {
        return hiomap_xlate_errno(e.get_errno());
    }

    return IPMI_CC_OK;
}

static ipmi_ret_t hiomap_create_window(struct hiomap* ctx, bool ro,
                                       ipmi_request_t request,
                                       ipmi_response_t response,
                                       ipmi_data_len_t data_len)
{
    if (*data_len < 4)
    {
        return IPMI_CC_REQ_DATA_LEN_INVALID;
    }

    uint8_t* reqdata = (uint8_t*)request;
    auto windowType = ro ? "CreateReadWindow" : "CreateWriteWindow";

    auto m = ctx->bus->new_method_call(HIOMAPD_SERVICE, HIOMAPD_OBJECT,
                                       HIOMAPD_IFACE_V2, windowType);
    m.append(le16toh(get<uint16_t>(&reqdata[0])));
    m.append(le16toh(get<uint16_t>(&reqdata[2])));

    try
    {
        auto reply = ctx->bus->call(m);

        uint16_t lpcAddress, size, offset;
        reply.read(lpcAddress, size, offset);

        uint8_t* respdata = (uint8_t*)response;

        /* FIXME: Assumes v2! */
        put(&respdata[0], htole16(lpcAddress));
        put(&respdata[2], htole16(size));
        put(&respdata[4], htole16(offset));

        *data_len = 6;
    }
    catch (const exception::SdBusError& e)
    {
        return hiomap_xlate_errno(e.get_errno());
    }

    return IPMI_CC_OK;
}

static ipmi_ret_t hiomap_create_read_window(ipmi_request_t request,
                                            ipmi_response_t response,
                                            ipmi_data_len_t data_len,
                                            ipmi_context_t context)
{
    struct hiomap* ctx = static_cast<struct hiomap*>(context);

    return hiomap_create_window(ctx, true, request, response, data_len);
}

static ipmi_ret_t hiomap_create_write_window(ipmi_request_t request,
                                             ipmi_response_t response,
                                             ipmi_data_len_t data_len,
                                             ipmi_context_t context)
{
    struct hiomap* ctx = static_cast<struct hiomap*>(context);

    return hiomap_create_window(ctx, false, request, response, data_len);
}

static ipmi_ret_t hiomap_close_window(ipmi_request_t request,
                                      ipmi_response_t response,
                                      ipmi_data_len_t data_len,
                                      ipmi_context_t context)
{
    struct hiomap* ctx = static_cast<struct hiomap*>(context);

    if (*data_len < 1)
    {
        return IPMI_CC_REQ_DATA_LEN_INVALID;
    }

    uint8_t* reqdata = (uint8_t*)request;
    auto m = ctx->bus->new_method_call(HIOMAPD_SERVICE, HIOMAPD_OBJECT,
                                       HIOMAPD_IFACE_V2, "CloseWindow");
    m.append(reqdata[0]);

    try
    {
        auto reply = ctx->bus->call(m);

        *data_len = 0;
    }
    catch (const exception::SdBusError& e)
    {
        return hiomap_xlate_errno(e.get_errno());
    }

    return IPMI_CC_OK;
}

static ipmi_ret_t hiomap_mark_dirty(ipmi_request_t request,
                                    ipmi_response_t response,
                                    ipmi_data_len_t data_len,
                                    ipmi_context_t context)
{
    struct hiomap* ctx = static_cast<struct hiomap*>(context);

    if (*data_len < 4)
    {
        return IPMI_CC_REQ_DATA_LEN_INVALID;
    }

    uint8_t* reqdata = (uint8_t*)request;
    auto m = ctx->bus->new_method_call(HIOMAPD_SERVICE, HIOMAPD_OBJECT,
                                       HIOMAPD_IFACE_V2, "MarkDirty");
    /* FIXME: Assumes v2 */
    m.append(le16toh(get<uint16_t>(&reqdata[0]))); /* offset */
    m.append(le16toh(get<uint16_t>(&reqdata[2]))); /* size */

    try
    {
        auto reply = ctx->bus->call(m);

        *data_len = 0;
    }
    catch (const exception::SdBusError& e)
    {
        return hiomap_xlate_errno(e.get_errno());
    }

    return IPMI_CC_OK;
}

static ipmi_ret_t hiomap_flush(ipmi_request_t request, ipmi_response_t response,
                               ipmi_data_len_t data_len, ipmi_context_t context)
{
    struct hiomap* ctx = static_cast<struct hiomap*>(context);

    auto m = ctx->bus->new_method_call(HIOMAPD_SERVICE, HIOMAPD_OBJECT,
                                       HIOMAPD_IFACE_V2, "Flush");

    try
    {
        /* FIXME: No argument call assumes v2 */
        auto reply = ctx->bus->call(m);

        *data_len = 0;
    }
    catch (const exception::SdBusError& e)
    {
        return hiomap_xlate_errno(e.get_errno());
    }

    return IPMI_CC_OK;
}

static ipmi_ret_t hiomap_ack(ipmi_request_t request, ipmi_response_t response,
                             ipmi_data_len_t data_len, ipmi_context_t context)
{
    struct hiomap* ctx = static_cast<struct hiomap*>(context);

    if (*data_len < 1)
    {
        return IPMI_CC_REQ_DATA_LEN_INVALID;
    }

    uint8_t* reqdata = (uint8_t*)request;
    auto m = ctx->bus->new_method_call(HIOMAPD_SERVICE, HIOMAPD_OBJECT,
                                       HIOMAPD_IFACE_V2, "Ack");
    auto acked = reqdata[0];
    m.append(acked);

    try
    {
        auto reply = ctx->bus->call(m);

        *data_len = 0;
    }
    catch (const exception::SdBusError& e)
    {
        return hiomap_xlate_errno(e.get_errno());
    }

    return IPMI_CC_OK;
}

static ipmi_ret_t hiomap_erase(ipmi_request_t request, ipmi_response_t response,
                               ipmi_data_len_t data_len, ipmi_context_t context)
{
    struct hiomap* ctx = static_cast<struct hiomap*>(context);

    if (*data_len < 4)
    {
        return IPMI_CC_REQ_DATA_LEN_INVALID;
    }

    uint8_t* reqdata = (uint8_t*)request;
    auto m = ctx->bus->new_method_call(HIOMAPD_SERVICE, HIOMAPD_OBJECT,
                                       HIOMAPD_IFACE_V2, "Erase");
    /* FIXME: Assumes v2 */
    m.append(le16toh(get<uint16_t>(&reqdata[0]))); /* offset */
    m.append(le16toh(get<uint16_t>(&reqdata[2]))); /* size */

    try
    {
        auto reply = ctx->bus->call(m);

        *data_len = 0;
    }
    catch (const exception::SdBusError& e)
    {
        return hiomap_xlate_errno(e.get_errno());
    }

    return IPMI_CC_OK;
}

#define HIOMAP_C_RESET 1
#define HIOMAP_C_GET_INFO 2
#define HIOMAP_C_GET_FLASH_INFO 3
#define HIOMAP_C_CREATE_READ_WINDOW 4
#define HIOMAP_C_CLOSE_WINDOW 5
#define HIOMAP_C_CREATE_WRITE_WINDOW 6
#define HIOMAP_C_MARK_DIRTY 7
#define HIOMAP_C_FLUSH 8
#define HIOMAP_C_ACK 9
#define HIOMAP_C_ERASE 10

static const hiomap_command hiomap_commands[] = {
    [0] = NULL, /* Invalid command ID */
    [HIOMAP_C_RESET] = hiomap_reset,
    [HIOMAP_C_GET_INFO] = hiomap_get_info,
    [HIOMAP_C_GET_FLASH_INFO] = hiomap_get_flash_info,
    [HIOMAP_C_CREATE_READ_WINDOW] = hiomap_create_read_window,
    [HIOMAP_C_CLOSE_WINDOW] = hiomap_close_window,
    [HIOMAP_C_CREATE_WRITE_WINDOW] = hiomap_create_write_window,
    [HIOMAP_C_MARK_DIRTY] = hiomap_mark_dirty,
    [HIOMAP_C_FLUSH] = hiomap_flush,
    [HIOMAP_C_ACK] = hiomap_ack,
    [HIOMAP_C_ERASE] = hiomap_erase,
};

/* FIXME: Define this in the "right" place, wherever that is */
/* FIXME: Double evaluation */
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

static ipmi_ret_t hiomap_dispatch(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                                  ipmi_request_t request,
                                  ipmi_response_t response,
                                  ipmi_data_len_t data_len,
                                  ipmi_context_t context)
{
    struct hiomap* ctx = static_cast<struct hiomap*>(context);

    if (*data_len < 2)
    {
        *data_len = 0;
        return IPMI_CC_REQ_DATA_LEN_INVALID;
    }

    uint8_t* ipmi_req = (uint8_t*)request;
    uint8_t* ipmi_resp = (uint8_t*)response;
    uint8_t hiomap_cmd = ipmi_req[0];

    if (hiomap_cmd == 0 || hiomap_cmd > ARRAY_SIZE(hiomap_commands) - 1)
    {
        *data_len = 0;
        return IPMI_CC_PARM_OUT_OF_RANGE;
    }

    bool is_unversioned =
        (hiomap_cmd == HIOMAP_C_RESET || hiomap_cmd == HIOMAP_C_GET_INFO ||
         hiomap_cmd == HIOMAP_C_ACK);
    if (!is_unversioned && ctx->seq == ipmi_req[1])
    {
        *data_len = 0;
        return IPMI_CC_INVALID_FIELD_REQUEST;
    }

    ctx->seq = ipmi_req[1];

    uint8_t* flash_req = ipmi_req + 2;
    size_t flash_len = *data_len - 2;
    uint8_t* flash_resp = ipmi_resp + 2;

    ipmi_ret_t cc =
        hiomap_commands[hiomap_cmd](flash_req, flash_resp, &flash_len, context);
    if (cc != IPMI_CC_OK)
    {
        *data_len = 0;
        return cc;
    }

    /* Populate the response command and sequence */
    ipmi_resp[0] = hiomap_cmd;
    ipmi_resp[1] = ctx->seq;

    *data_len = flash_len + 2;

    return cc;
}
} // namespace flash
} // namespace openpower

static void register_openpower_hiomap_commands()
{
    using namespace phosphor::logging;
    using namespace openpower::flash;

    sigset_t _sigset, *sigset = &_sigset;
    struct hiomap* ctx = new hiomap();
    struct sd_event* events;
    int rc;

    /* Initialise mapping from signal and property names to status bit */
    ctx->event_lookup["DaemonReady"] = BMC_EVENT_DAEMON_READY;
    ctx->event_lookup["FlashControlLost"] = BMC_EVENT_FLASH_CTRL_LOST;
    ctx->event_lookup["WindowReset"] = BMC_EVENT_WINDOW_RESET;
    ctx->event_lookup["ProtocolReset"] = BMC_EVENT_PROTOCOL_RESET;

    ctx->bus = new bus::bus(ipmid_get_sd_bus_connection());

    /* Initialise signal handling */

    /*
     * Can't use temporaries here because that causes SEGFAULTs due to slot
     * destruction (!?), so enjoy the weird wrapping.
     */
    ctx->properties =
        new bus::match::match(std::move(hiomap_match_properties(ctx)));

    rc = sigemptyset(sigset);
    if (rc < 0)
    {
        log<level::ERR>("sigemptyset() failed", entry("RC=%d", rc));
        return;
    }

    rc = sigaddset(sigset, SIGTERM);
    if (rc < 0)
    {
        log<level::ERR>("sigaddset() failed", entry("RC=%d", rc));
        return;
    }

    rc = sigprocmask(SIG_BLOCK, sigset, NULL);
    if (rc < 0)
    {
        log<level::ERR>("sigprocmask() failed", entry("RC=%d", rc));
        return;
    }

    events = ipmid_get_sd_event_connection();

    rc = sd_event_add_signal(events, &event_source, SIGTERM,
                             openpower::flash::hiomap_protocol_reset, ctx);
    if (rc < 0)
    {
        log<level::ERR>("sd_event_add_signal() failed", entry("RC=%d", rc));
        return;
    }

    ipmi_register_callback(NETFUN_IBM_OEM, IPMI_CMD_HIOMAP, ctx,
                           openpower::flash::hiomap_dispatch, SYSTEM_INTERFACE);
}
