Adding app command for fb
Added GUID and global enables commands.
On Tiogapass the GUID is stored in the EEPROM (the same EEPROM which
is used to store the FRUID) at a specific offset (towards the end)
which is known not to conflict with the FRUID. This change adds support
to read the device and system GUID from these locations.
Change-Id: If999349b3a6e90bf5884bfc1f25340eb231661bf
Signed-off-by: Vijay Khemka <vijaykhemka@fb.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6fadd46..a475a78 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -67,7 +67,7 @@
include_directories (${CMAKE_CURRENT_SOURCE_DIR}/include)
add_library (zfboemcmds
- SHARED src/oemcommands.cpp
+ SHARED src/oemcommands.cpp src/appcommands.cpp
src/storagecommands.cpp src/usb-dbg.cpp)
set_target_properties (zfboemcmds PROPERTIES VERSION "0.1.0")
set_target_properties (zfboemcmds PROPERTIES SOVERSION "0")
diff --git a/include/appcommands.hpp b/include/appcommands.hpp
new file mode 100644
index 0000000..b0ef418
--- /dev/null
+++ b/include/appcommands.hpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018-present Facebook. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+enum fb_app_cmds
+{
+ CMD_APP_SET_ACPI = 0x06,
+ CMD_APP_GET_ACPI = 0x07,
+ CMD_APP_GET_DEV_GUID = 0x08,
+ CMD_APP_RESET_WD = 0x22,
+ CMD_APP_SET_WD = 0x24,
+ CMD_APP_GET_WD = 0x25,
+ CMD_APP_SET_GLOBAL_ENABLES = 0x2E,
+ CMD_APP_GET_GLOBAL_ENABLES = 0x2F,
+ CMD_APP_GET_MSG_FLAGS = 0x31,
+ CMD_APP_READ_EVENT = 0x35,
+ CMD_APP_GET_CAP_BIT = 0x36,
+ CMD_APP_GET_SYS_GUID = 0x37,
+ CMD_APP_SET_CHAN_ACCESS = 0x40,
+ CMD_APP_GET_CHANNEL_ACCESS = 0x41,
+ CMD_APP_GET_CHAN_INFO = 0x42,
+
+};
diff --git a/src/appcommands.cpp b/src/appcommands.cpp
new file mode 100644
index 0000000..63995d9
--- /dev/null
+++ b/src/appcommands.cpp
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2018 Intel Corporation.
+ * Copyright (c) 2018-present Facebook.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ipmid/api.h>
+
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <commandutils.hpp>
+#include <iostream>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/message/types.hpp>
+#include <appcommands.hpp>
+
+namespace ipmi
+{
+
+static void registerAPPFunctions() __attribute__((constructor));
+static constexpr size_t GUID_SIZE = 16;
+// TODO Make offset and location runtime configurable to ensure we
+// can make each define their own locations.
+static constexpr off_t OFFSET_SYS_GUID = 0x17F0;
+static constexpr off_t OFFSET_DEV_GUID = 0x1800;
+static constexpr const char *FRU_EEPROM = "/sys/bus/i2c/devices/6-0054/eeprom";
+static uint8_t globEna = 0x09;
+
+void printGUID(uint8_t *guid, off_t offset)
+{
+ std::cout << "Read GUID from offset : " << offset << " :\n";
+ for (int i = 0; i < GUID_SIZE; i++)
+ {
+ int data = guid[i];
+ std::cout << std::hex << data << " ";
+ }
+ std::cout << std::endl;
+}
+
+int getGUID(off_t offset, uint8_t *guid)
+{
+ int fd = -1;
+ ssize_t bytes_rd;
+ int ret = 0;
+
+ errno = 0;
+
+ // Check if file is present
+ if (access(FRU_EEPROM, F_OK) == -1)
+ {
+ std::cerr << "Unable to access: " << FRU_EEPROM << std::endl;
+ return errno;
+ }
+
+ // Open the file
+ fd = open(FRU_EEPROM, O_RDONLY);
+ if (fd == -1)
+ {
+ std::cerr << "Unable to open: " << FRU_EEPROM << std::endl;
+ return errno;
+ }
+
+ // seek to the offset
+ lseek(fd, offset, SEEK_SET);
+
+ // Read bytes from location
+ bytes_rd = read(fd, guid, GUID_SIZE);
+ if (bytes_rd != GUID_SIZE)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "GUID read data from EEPROM failed");
+ ret = errno;
+ }
+ else
+ {
+ printGUID(guid, offset);
+ }
+ close(fd);
+ return ret;
+}
+
+int getSystemGUID(uint8_t *guid)
+{
+ return getGUID(OFFSET_SYS_GUID, guid);
+}
+
+int getDeviceGUID(uint8_t *guid)
+{
+ return getGUID(OFFSET_DEV_GUID, guid);
+}
+
+//----------------------------------------------------------------------
+// Get Device GUID (CMD_APP_GET_DEV_GUID)
+//----------------------------------------------------------------------
+ipmi_ret_t ipmiAppGetDevGUID(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)
+{
+ uint8_t *res = reinterpret_cast<uint8_t *>(response);
+
+ if (getDeviceGUID(res))
+ {
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+ *data_len = GUID_SIZE;
+
+ return IPMI_CC_OK;
+}
+
+//----------------------------------------------------------------------
+// Set Global Enables (CMD_APP_SET_GLOBAL_ENABLES)
+//----------------------------------------------------------------------
+ipmi_ret_t ipmiAppSetGlobalEnables(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)
+{
+ uint8_t *req = reinterpret_cast<uint8_t *>(request);
+
+ globEna = *req;
+ *data_len = 0;
+
+ return IPMI_CC_OK;
+}
+
+//----------------------------------------------------------------------
+// Get Global Enables (CMD_APP_GET_GLOBAL_ENABLES)
+//----------------------------------------------------------------------
+ipmi_ret_t ipmiAppGetGlobalEnables(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)
+{
+ uint8_t *res = reinterpret_cast<uint8_t *>(response);
+
+ *data_len = 1;
+ *res++ = globEna;
+
+ return IPMI_CC_OK;
+}
+
+//----------------------------------------------------------------------
+// Get System GUID (CMD_APP_GET_SYS_GUID)
+//----------------------------------------------------------------------
+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)
+{
+ uint8_t *res = reinterpret_cast<uint8_t *>(response);
+ if (getSystemGUID(res))
+ {
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+ *data_len = GUID_SIZE;
+ return IPMI_CC_OK;
+}
+
+void registerAPPFunctions()
+{
+ ipmiPrintAndRegister(NETFUN_APP, CMD_APP_GET_DEV_GUID, NULL,
+ ipmiAppGetDevGUID,
+ PRIVILEGE_USER); // Get Device GUID
+ ipmiPrintAndRegister(NETFUN_APP, CMD_APP_SET_GLOBAL_ENABLES, NULL,
+ ipmiAppSetGlobalEnables,
+ PRIVILEGE_USER); // Get Global Enables
+ ipmiPrintAndRegister(NETFUN_APP, CMD_APP_GET_GLOBAL_ENABLES, NULL,
+ ipmiAppGetGlobalEnables,
+ PRIVILEGE_USER); // Get Global Enables
+ ipmiPrintAndRegister(NETFUN_APP, CMD_APP_GET_SYS_GUID, NULL,
+ ipmiAppGetSysGUID,
+ PRIVILEGE_USER); // Get System GUID
+
+ return;
+}
+
+} // namespace ipmi