// 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 <ipmid/api.hpp>
#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;

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;
};

SignalResponse sigtermResponse = SignalResponse::continueExecution;

/* 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;

    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)
    {
        sigtermResponse = SignalResponse::continueExecution;
        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;

    sigtermResponse = SignalResponse::breakExecution;
    if (!active_event_updates)
    {
        sigtermResponse = SignalResponse::breakExecution;
        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)
{
    // If this is running in signal context, ipmid will shutdown
    // the event queue as the last signal handler
    sigtermResponse = SignalResponse::continueExecution;
    return 0;
}

static int hiomap_protocol_reset(struct hiomap* ctx)
{
    if (ctx->bmc_events == BMC_EVENT_PROTOCOL_RESET)
    {
        // If this is running in signal context, ipmid will shutdown
        // the event queue as the last signal handler
        sigtermResponse = SignalResponse::continueExecution;
        return 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;

    struct hiomap* ctx = new hiomap();

    /* 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)));

    std::function<SignalResponse(int)> shutdownHandler =
        [ctx](int signalNumber) {
            hiomap_protocol_reset(ctx);
            return sigtermResponse;
        };
    registerSignalHandler(ipmi::prioMax, SIGTERM, shutdownHandler);

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