// 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 <ipmid-host/cmd-utils.hpp>
#include <ipmid-host/cmd.hpp>
#include <ipmid/api.hpp>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/bus/match.hpp>
#include <sdbusplus/exception.hpp>

#include <cassert>
#include <cstring>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#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 respond 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 sequential and no two events can be processed simultaneously. A
corollary of this is that DBus events and UNIX signals are serialised with
respect to each other.

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 (const auto& 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);
}
