summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apphandler.cpp128
-rw-r--r--docs/configuration.md24
2 files changed, 93 insertions, 59 deletions
diff --git a/apphandler.cpp b/apphandler.cpp
index 048219e..4b00065 100644
--- a/apphandler.cpp
+++ b/apphandler.cpp
@@ -3,9 +3,11 @@
#include "app/watchdog.hpp"
#include "host-ipmid/ipmid-api.h"
#include "ipmid.hpp"
+#include "nlohmann/json.hpp"
#include "types.hpp"
#include "utils.hpp"
+#include <fstream>
#include <stdio.h>
#include <stdint.h>
#include <systemd/sd-bus.h>
@@ -59,7 +61,6 @@ ipmi_ret_t ipmi_app_set_acpi_power_state(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
return rc;
}
-
typedef struct
{
char major;
@@ -164,73 +165,82 @@ ipmi_ret_t ipmi_app_get_device_id(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
char *busname = NULL;
int r;
rev_t rev = {0};
- ipmi_device_id_t dev_id{};
+ static ipmi_device_id_t dev_id{};
+ static bool dev_id_initialized = false;
+ const char* filename = "/usr/share/ipmi-providers/dev_id.json";
// Data length
*data_len = sizeof(dev_id);
- // From IPMI spec, controller that have different application commands, or different
- // definitions of OEM fields, are expected to have different Device ID values.
- // Set to 0 now.
+ if (!dev_id_initialized)
+ {
+ // Firmware revision is already implemented,
+ // so get it from appropriate position.
+ r = mapper_get_service(bus, objname, &busname);
+ if (r < 0) {
+ fprintf(stderr, "Failed to get %s bus name: %s\n",
+ objname, strerror(-r));
+ goto finish;
+ }
+ r = sd_bus_get_property_string(bus,busname,objname,iface,"version",
+ NULL, &ver);
+ if ( r < 0 ) {
+ fprintf(stderr, "Failed to obtain version property: %s\n",
+ strerror(-r));
+ } else {
+ r = convert_version(ver, &rev);
+ if( r >= 0 ) {
+ // bit7 identifies if the device is available
+ // 0=normal operation
+ // 1=device firmware, SDR update,
+ // or self-initialization in progress.
+ // our SDR is normal working condition, so mask:
+ dev_id.fw[0] = 0x7F & rev.major;
+
+ rev.minor = (rev.minor > 99 ? 99 : rev.minor);
+ dev_id.fw[1] = rev.minor % 10 + (rev.minor / 10) * 16;
+ memcpy(&dev_id.aux, rev.d, 4);
+ }
+ }
- // Device Revision is set to 0 now.
- // Bit7 identifies if device provide Device SDRs, obmc don't have SDR,we use ipmi to
- // simulate SDR, hence the value:
- dev_id.revision = 0x80;
+ // IPMI Spec version 2.0
+ dev_id.ipmi_ver = 2;
- // Firmware revision is already implemented, so get it from appropriate position.
- r = mapper_get_service(bus, objname, &busname);
- if (r < 0) {
- fprintf(stderr, "Failed to get %s bus name: %s\n",
- objname, strerror(-r));
- goto finish;
- }
- r = sd_bus_get_property_string(bus,busname,objname,iface,"version", NULL, &ver);
- if ( r < 0 ) {
- fprintf(stderr, "Failed to obtain version property: %s\n", strerror(-r));
- } else {
- r = convert_version(ver, &rev);
- if( r >= 0 ) {
- // bit7 identifies if the device is available, 0=normal operation,
- // 1=device firmware, SDR update or self-initialization in progress.
- // our SDR is normal working condition, so mask:
- dev_id.fw[0] = 0x7F & rev.major;
-
- rev.minor = (rev.minor > 99 ? 99 : rev.minor);
- dev_id.fw[1] = rev.minor % 10 + (rev.minor / 10) * 16;
- memcpy(&dev_id.aux, rev.d, 4);
+ std::ifstream dev_id_file(filename);
+ if (dev_id_file.is_open())
+ {
+ auto data = nlohmann::json::parse(dev_id_file, nullptr, false);
+ if (!data.is_discarded())
+ {
+ dev_id.id = data.value("id", 0);
+ dev_id.revision = data.value("revision", 0);
+ dev_id.addn_dev_support = data.value("addn_dev_support", 0);
+ dev_id.manuf_id[2] = data.value("manuf_id", 0) >> 16;
+ dev_id.manuf_id[1] = data.value("manuf_id", 0) >> 8;
+ dev_id.manuf_id[0] = data.value("manuf_id", 0);
+ dev_id.prod_id[1] = data.value("prod_id", 0) >> 8;
+ dev_id.prod_id[0] = data.value("prod_id", 0);
+ dev_id.aux[3] = data.value("aux", 0) >> 24;
+ dev_id.aux[2] = data.value("aux", 0) >> 16;
+ dev_id.aux[1] = data.value("aux", 0) >> 8;
+ dev_id.aux[0] = data.value("aux", 0);
+
+ //Don't read the file every time if successful
+ dev_id_initialized = true;
+ }
+ else
+ {
+ log<level::ERR>("Device ID JSON parser failure");
+ rc = IPMI_CC_UNSPECIFIED_ERROR;
+ }
+ }
+ else
+ {
+ log<level::ERR>("Device ID file not found");
+ rc = IPMI_CC_UNSPECIFIED_ERROR;
}
}
- // IPMI Spec version 2.0
- dev_id.ipmi_ver = 2;
-
- // Additional device Support.
- // List the 'logical device' commands and functions that the controller supports
- // that are in addition to the mandatory IPM and Application commands.
- // [7] Chassis Device (device functions as chassis device per ICMB spec.)
- // [6] Bridge (device responds to Bridge NetFn commands)
- // [5] IPMB Event Generator
- // [4] IPMB Event Receiver
- // [3] FRU Inventory Device
- // [2] SEL Device
- // [1] SDR Repository Device
- // [0] Sensor Device
- // We support FRU/SEL/Sensor now:
- dev_id.addn_dev_support = 0x8D;
-
- // This value is the IANA number assigned to "IBM Platform Firmware
- // Division", which is also used by our service processor. We may want
- // a different number or at least a different version?
- dev_id.manuf_id[0] = 0x41;
- dev_id.manuf_id[1] = 0xA7;
- dev_id.manuf_id[2] = 0x00;
-
- // Witherspoon's product ID is hardcoded to 4F42(ASCII 'OB').
- // TODO: openbmc/openbmc#495
- dev_id.prod_id[0] = 0x4F;
- dev_id.prod_id[1] = 0x42;
-
// Pack the actual response
memcpy(response, &dev_id, *data_len);
finish:
diff --git a/docs/configuration.md b/docs/configuration.md
new file mode 100644
index 0000000..61caaf1
--- /dev/null
+++ b/docs/configuration.md
@@ -0,0 +1,24 @@
+#Device ID Configuration#
+
+There is a default dev_id.json file provided by
+meta-phosphor/common/recipes-phosphor/ipmi/phosphor-ipmi-host.bb
+
+Any target can override the default json file by providing a
+phosphor-ipmi-host.bbappend with an ODM or platform customizable configuration.
+
+For a specific example, see:
+[Witherspoon](https://github.com/openbmc/openbmc/blob/master/
+meta-openbmc-machines/meta-openpower/meta-ibm/meta-witherspoon/
+recipes-phosphor/ipmi/phosphor-ipmi-host.bbappend)
+
+The JSON format for get_device_id:
+
+ {"id": 0, "revision": 0, "addn_dev_support": 0,
+ "manuf_id": 0, "prod_id": 0, "aux": 0}
+
+
+Each value in this JSON object should be an integer. The file is placed in
+/usr/share/ipmi-providers/ by Yocto, and will be parsed upon the first call to
+get_device_id. The data is then cached for future use. If you change the data
+at runtime, simply restart the service to see the new data fetched by a call to
+get_device_id.
OpenPOWER on IntegriCloud