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

#include "hiomap.hpp"

#include <endian.h>
#include <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 <iostream>
#include <ipmid-host/cmd-utils.hpp>
#include <ipmid-host/cmd.hpp>
#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 <unordered_map>
#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_t* bus;

    /* Signals */
    bus::match_t* 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));
}

using hiomap_command =
    std::function<ipmi_ret_t(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_t& msg)
{
    using namespace phosphor::logging;

    std::map<std::string, std::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 = std::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([[maybe_unused]] IpmiCmdData cmd,
                                          [[maybe_unused]] 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_t hiomap_match_properties(struct hiomap* ctx)
{
    auto properties =
        bus::match::rules::propertiesChanged(HIOMAPD_OBJECT, HIOMAPD_IFACE_V2);

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

    return match;
}

static ipmi_ret_t hiomap_reset([[maybe_unused]] ipmi_request_t request,
                               [[maybe_unused]] 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_t& 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_t& e)
    {
        return hiomap_xlate_errno(e.get_errno());
    }

    return IPMI_CC_OK;
}

static ipmi_ret_t hiomap_get_flash_info([[maybe_unused]] 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_t& 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_t& 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,
                                      [[maybe_unused]] 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_t& e)
    {
        return hiomap_xlate_errno(e.get_errno());
    }

    return IPMI_CC_OK;
}

static ipmi_ret_t hiomap_mark_dirty(ipmi_request_t request,
                                    [[maybe_unused]] 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_t& e)
    {
        return hiomap_xlate_errno(e.get_errno());
    }

    return IPMI_CC_OK;
}

static ipmi_ret_t hiomap_flush([[maybe_unused]] ipmi_request_t request,
                               [[maybe_unused]] 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_t& e)
    {
        return hiomap_xlate_errno(e.get_errno());
    }

    return IPMI_CC_OK;
}

static ipmi_ret_t hiomap_ack(ipmi_request_t request,
                             [[maybe_unused]] 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_t& e)
    {
        return hiomap_xlate_errno(e.get_errno());
    }

    return IPMI_CC_OK;
}

static ipmi_ret_t hiomap_erase(ipmi_request_t request,
                               [[maybe_unused]] 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_t& 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 std::unordered_map<uint8_t, hiomap_command> hiomap_commands = {
    {0, nullptr}, /* 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([[maybe_unused]] ipmi_netfn_t netfn,
                                  [[maybe_unused]] 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 > hiomap_commands.size() - 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;

    auto command = hiomap_commands.find(hiomap_cmd);
    if (command == hiomap_commands.end())
    {
        *data_len = 0;
        return IPMI_CC_INVALID;
    }
    ipmi_ret_t cc = command->second(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_t(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_t(std::move(hiomap_match_properties(ctx)));

    std::function<SignalResponse(int)> shutdownHandler =
        [ctx]([[maybe_unused]] 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);
}
