meta-yosemitev2: add system get/set guid support

Added get/set system GUID command for multi host YosemiteV2,
it reads/writes guid to the corresponding hosts Bridge IC(BIC).

Tested:

Verified this with host reboot(BIOS automatically
sends get GUID command to BMC).

Verified this ipmitool.
 Get System GUID:
 ipmitool raw 60x37

 Set System GUID:
 ipmitool raw 0x30 0xEF 0 252 109 1 0 135 236 73 26
 54 249 84 1 1 80 7 8

Signed-off-by: Manikandan Elumalai <manikandan.hcl.ers.epl@gmail.com>
Change-Id: I4d24a2fb4bf98f38afd7c0d07df0005c22535d48
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b01f6cb..93a7847 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -65,6 +65,7 @@
 
 if(BIC)
    SET(bicFile "src/biccommands.cpp")
+   add_definitions (-DBIC_ENABLED)
 endif()
 
 add_library (zfboemcmds
diff --git a/src/appcommands.cpp b/src/appcommands.cpp
index 52eceb3..e8571ce 100644
--- a/src/appcommands.cpp
+++ b/src/appcommands.cpp
@@ -25,6 +25,8 @@
 #include <nlohmann/json.hpp>
 #include <phosphor-logging/log.hpp>
 #include <sdbusplus/message/types.hpp>
+#include <ipmid/api.hpp>
+#include <ipmid/api-types.hpp>
 
 #include <fstream>
 #include <iomanip>
@@ -46,6 +48,9 @@
 static SysInfoParam sysInfoParams;
 nlohmann::json appData __attribute__((init_priority(101)));
 
+int sendBicCmd(uint8_t, uint8_t, uint8_t, std::vector<uint8_t>&,
+               std::vector<uint8_t>&);
+
 void printGUID(uint8_t* guid, off_t offset)
 {
     std::cout << "Read GUID from offset : " << offset << " :\n";
@@ -200,6 +205,22 @@
 //----------------------------------------------------------------------
 // Get System GUID (CMD_APP_GET_SYS_GUID)
 //----------------------------------------------------------------------
+#if BIC_ENABLED
+ipmi::RspType<std::vector<uint8_t>>
+    ipmiAppGetSysGUID(ipmi::Context::ptr ctx, std::vector<uint8_t> reqData)
+
+{
+    std::vector<uint8_t> respData;
+
+    uint8_t bicAddr = (uint8_t)ctx->hostIdx << 2;
+
+    if (sendBicCmd(ctx->netFn, ctx->cmd, bicAddr, reqData, respData))
+        return ipmi::responseUnspecifiedError();
+
+    return ipmi::responseSuccess(respData);
+}
+
+#else
 ipmi_ret_t ipmiAppGetSysGUID(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)
@@ -213,6 +234,8 @@
     return IPMI_CC_OK;
 }
 
+#endif
+
 //----------------------------------------------------------------------
 // Platform specific functions for storing app data
 //----------------------------------------------------------------------
@@ -442,9 +465,15 @@
     ipmiPrintAndRegister(NETFUN_APP, CMD_APP_CLEAR_MESSAGE_FLAGS, NULL,
                          ipmiAppClearMsgFlags,
                          PRIVILEGE_USER); // Clear Message flags
+#if BIC_ENABLED
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnApp,
+                          ipmi::app::cmdGetSystemGuid, ipmi::Privilege::User,
+                          ipmiAppGetSysGUID);
+#else
     ipmiPrintAndRegister(NETFUN_APP, CMD_APP_GET_SYS_GUID, NULL,
                          ipmiAppGetSysGUID,
                          PRIVILEGE_USER); // Get System GUID
+#endif
     ipmiPrintAndRegister(NETFUN_APP, CMD_APP_SET_SYS_INFO_PARAMS, NULL,
                          ipmiAppSetSysInfoParams,
                          PRIVILEGE_USER); // Set Sys Info Params
diff --git a/src/oemcommands.cpp b/src/oemcommands.cpp
index be03ca3..e700d11 100644
--- a/src/oemcommands.cpp
+++ b/src/oemcommands.cpp
@@ -25,6 +25,9 @@
 #include <phosphor-logging/log.hpp>
 #include <sdbusplus/bus.hpp>
 
+#include <ipmid/api.hpp>
+#include <ipmid/api-types.hpp>
+
 #include <array>
 #include <cstring>
 #include <fstream>
@@ -44,6 +47,7 @@
 static void registerOEMFunctions() __attribute__((constructor));
 sdbusplus::bus::bus dbus(ipmid_get_sd_bus_connection()); // from ipmid/api.h
 static constexpr size_t maxFRUStringLength = 0x3F;
+constexpr uint8_t cmdSetSystemGuid = 0xEF;
 
 int plat_udbg_get_post_desc(uint8_t, uint8_t*, uint8_t, uint8_t*, uint8_t*,
                             uint8_t*);
@@ -55,6 +59,9 @@
                                    uint8_t*);
 int sendMeCmd(uint8_t, uint8_t, std::vector<uint8_t>&, std::vector<uint8_t>&);
 
+int sendBicCmd(uint8_t, uint8_t, uint8_t, std::vector<uint8_t>&,
+               std::vector<uint8_t>&);
+
 nlohmann::json oemData __attribute__((init_priority(101)));
 
 static constexpr size_t GUID_SIZE = 16;
@@ -857,6 +864,29 @@
 //----------------------------------------------------------------------
 // Set System GUID (CMD_OEM_SET_SYSTEM_GUID)
 //----------------------------------------------------------------------
+#if BIC_ENABLED
+ipmi::RspType<> ipmiOemSetSystemGuid(ipmi::Context::ptr ctx, uint8_t cmdReq,
+                                     std::vector<uint8_t> reqData)
+{
+    std::vector<uint8_t> respData;
+
+    if (reqData.size() != GUID_SIZE) // 16bytes
+    {
+
+        return ipmi::responseReqDataLenInvalid();
+    }
+
+    auto ptrReqData = reqData.insert(reqData.begin(), reqData.size());
+
+    uint8_t bicAddr = (uint8_t)ctx->hostIdx << 2;
+
+    if (sendBicCmd(ctx->netFn, ctx->cmd, bicAddr, reqData, respData))
+        return ipmi::responseUnspecifiedError();
+
+    return ipmi::responseSuccess();
+}
+
+#else
 ipmi_ret_t ipmiOemSetSystemGuid(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
                                 ipmi_request_t request,
                                 ipmi_response_t response,
@@ -879,6 +909,7 @@
     }
     return IPMI_CC_OK;
 }
+#endif
 
 //----------------------------------------------------------------------
 // Set Bios Flash Info (CMD_OEM_SET_BIOS_FLASH_INFO)
@@ -1664,9 +1695,17 @@
     ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_PPIN_INFO, NULL,
                          ipmiOemSetPPINInfo,
                          PRIVILEGE_USER); // Set PPIN Info
+#if BIC_ENABLED
+
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemOne,
+                          ipmi::cmdSetSystemGuid, ipmi::Privilege::User,
+                          ipmiOemSetSystemGuid);
+#else
+
     ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_SYSTEM_GUID, NULL,
                          ipmiOemSetSystemGuid,
                          PRIVILEGE_USER); // Set System GUID
+#endif
     ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_ADR_TRIGGER, NULL,
                          ipmiOemSetAdrTrigger,
                          PRIVILEGE_USER); // Set ADR Trigger
diff --git a/src/usb-dbg.cpp b/src/usb-dbg.cpp
index 2588f81..965b564 100644
--- a/src/usb-dbg.cpp
+++ b/src/usb-dbg.cpp
@@ -880,6 +880,35 @@
     return -1;
 }
 
+int sendBicCmd(uint8_t netFn, uint8_t cmd, uint8_t bicAddr,
+               std::vector<uint8_t>& cmdData, std::vector<uint8_t>& respData)
+{
+    static constexpr uint8_t lun = 0;
+
+    auto bus = getSdBus();
+
+    auto method = bus->new_method_call("xyz.openbmc_project.Ipmi.Channel.Ipmb",
+                                       "/xyz/openbmc_project/Ipmi/Channel/Ipmb",
+                                       "org.openbmc.Ipmb", "sendRequest");
+    method.append(bicAddr, netFn, lun, cmd, cmdData);
+
+    auto reply = bus->call(method);
+    if (reply.is_method_error())
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error reading from BIC");
+        return -1;
+    }
+
+    IpmbMethodType resp;
+    reply.read(resp);
+
+    respData =
+        std::move(std::get<std::remove_reference_t<decltype(respData)>>(resp));
+
+    return 0;
+}
+
 int sendMeCmd(uint8_t netFn, uint8_t cmd, std::vector<uint8_t>& cmdData,
               std::vector<uint8_t>& respData)
 {