Add GPIO pin description
Added functionality to read gpio pin code description from
gpio_desc.json file stored in /usr/share/ipmi-providers/.
This file is platform specific and can be overwritten for
different platforms. This gpio pin description will be
requested by lcd debug card for displaying in screen.
Tested: verified with lcd debug card screen.
Change-Id: I32275a5d218cbfdd20cd919768688ab6cc67b091
Signed-off-by: Vijay Khemka <vijaykhemka@fb.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d54c71d..62e3e4d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -74,7 +74,7 @@
target_link_libraries (zfboemcmds phosphor_logging)
set (PACKAGE_DIR /usr/share/ipmi-providers/)
-set (CONFIG_FILES post_desc.json)
+set (CONFIG_FILES post_desc.json gpio_desc.json)
install (TARGETS zfboemcmds DESTINATION lib/ipmid-providers)
install (FILES ${CONFIG_FILES} DESTINATION ${PACKAGE_DIR})
diff --git a/gpio_desc.json b/gpio_desc.json
new file mode 100644
index 0000000..97cf81b
--- /dev/null
+++ b/gpio_desc.json
@@ -0,0 +1,13 @@
+
+{
+ "GpioDesc": [
+ [ "0x10", 0, 2, "FM_DBG_RST_BTN" ],
+ [ "0x11", 0, 1, "FM_PWR_BTN" ],
+ [ "0x12", 1, 0, "SYS_PWROK" ],
+ [ "0x13", 0, 0, "RST_PLTRST" ],
+ [ "0x14", 1, 0, "DSW_PWROK" ],
+ [ "0x15", 0, 0, "FM_CATERR_MSMI" ],
+ [ "0x16", 0, 0, "FM_SLPS3" ],
+ [ "0x17", 0, 3, "FM_UART_SWITCH" ]
+]
+}
diff --git a/src/oemcommands.cpp b/src/oemcommands.cpp
index b628c7b..9fbcc90 100644
--- a/src/oemcommands.cpp
+++ b/src/oemcommands.cpp
@@ -46,6 +46,8 @@
int plat_udbg_get_post_desc(uint8_t, uint8_t *, uint8_t, uint8_t *, uint8_t *,
uint8_t *);
+int plat_udbg_get_gpio_desc(uint8_t, uint8_t *, uint8_t *, uint8_t *, uint8_t *,
+ uint8_t *);
ipmi_ret_t plat_udbg_get_frame_data(uint8_t, uint8_t, uint8_t *, uint8_t *,
uint8_t *);
ipmi_ret_t plat_udbg_control_panel(uint8_t, uint8_t, uint8_t, uint8_t *,
@@ -481,11 +483,31 @@
uint8_t *req = reinterpret_cast<uint8_t *>(request);
uint8_t *res = reinterpret_cast<uint8_t *>(response);
- phosphor::logging::log<phosphor::logging::level::INFO>(
- "Get GPIO Description Event");
+ uint8_t index = 0;
+ uint8_t next = 0;
+ uint8_t level = 0;
+ uint8_t pinDef = 0;
+ uint8_t descLen = 0;
+ int ret;
- std::memcpy(res, req, SIZE_IANA_ID + 1); // IANA ID
- *data_len = SIZE_IANA_ID + 1;
+ index = req[3];
+
+ ret = plat_udbg_get_gpio_desc(index, &next, &level, &pinDef, &descLen,
+ &res[8]);
+ if (ret)
+ {
+ memcpy(res, req, SIZE_IANA_ID); // IANA ID
+ *data_len = SIZE_IANA_ID;
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+
+ memcpy(res, req, SIZE_IANA_ID); // IANA ID
+ res[3] = index;
+ res[4] = next;
+ res[5] = level;
+ res[6] = pinDef;
+ res[7] = descLen;
+ *data_len = SIZE_IANA_ID + 5 + descLen;
return IPMI_CC_OK;
}
diff --git a/src/usb-dbg.cpp b/src/usb-dbg.cpp
index d61c9b2..630b7b7 100644
--- a/src/usb-dbg.cpp
+++ b/src/usb-dbg.cpp
@@ -29,6 +29,7 @@
{
#define JSON_POST_DATA_FILE "/usr/share/ipmi-providers/post_desc.json"
+#define JSON_GPIO_DATA_FILE "/usr/share/ipmi-providers/gpio_desc.json"
#define ETH_INTF_NAME "eth0"
#define ESCAPE "\x1B"
@@ -45,6 +46,13 @@
#define FRU_ALL 0
#define MAX_VALUE_LEN 64
+#define DEBUG_GPIO_KEY "GpioDesc"
+#define GPIO_ARRAY_SIZE 4
+#define GPIO_PIN_INDEX 0
+#define GPIO_LEVEL_INDEX 1
+#define GPIO_DEF_INDEX 2
+#define GPIO_DESC_INDEX 3
+
/* Used for systems which do not specifically have a
* phase, and we want to ignore the phase provided by the
* debug card */
@@ -53,14 +61,6 @@
ipmi_ret_t getNetworkData(uint8_t lan_param, char *data);
int8_t getFruData(std::string &serial, std::string &name);
-typedef struct _gpio_desc
-{
- uint8_t pin;
- uint8_t level;
- uint8_t def;
- char desc[32];
-} gpio_desc_t;
-
typedef struct _sensor_desc
{
char name[16];
@@ -587,9 +587,76 @@
/* Need to implement this */
int plat_udbg_get_gpio_desc(uint8_t index, uint8_t *next, uint8_t *level,
- uint8_t *def, uint8_t *count, uint8_t *buffer)
+ uint8_t *def, uint8_t *length, uint8_t *buffer)
{
- return 0;
+ nlohmann::json gpioObj;
+ std::string gpioPin;
+
+ /* Get gpio data stored in json file */
+ std::ifstream file(JSON_GPIO_DATA_FILE);
+ if (file)
+ {
+ file >> gpioObj;
+ file.close();
+ }
+ else
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "GPIO pin description file not found",
+ phosphor::logging::entry("GPIO_PIN_DETAILS_FILE=%s",
+ JSON_GPIO_DATA_FILE));
+ return -1;
+ }
+
+ if (gpioObj.find(DEBUG_GPIO_KEY) == gpioObj.end())
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "GPIO pin details not available",
+ phosphor::logging::entry("GPIO_JSON_KEY=%d", DEBUG_GPIO_KEY));
+ return -1;
+ }
+
+ auto obj = gpioObj[DEBUG_GPIO_KEY];
+ int objSize = obj.size();
+
+ for (int i = 0; i < objSize; i++)
+ {
+ if (obj[i].size() != GPIO_ARRAY_SIZE)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Size of gpio array is incorrect",
+ phosphor::logging::entry("EXPECTED_SIZE=%d", GPIO_ARRAY_SIZE));
+ return -1;
+ }
+
+ gpioPin = obj[i][GPIO_PIN_INDEX];
+ if (index == stoul(gpioPin, nullptr, 16))
+ {
+ if (objSize != i + 1)
+ {
+ gpioPin = obj[i + 1][GPIO_PIN_INDEX];
+ *next = stoul(gpioPin, nullptr, 16);
+ }
+ else
+ {
+ *next = 0xff;
+ }
+
+ *level = obj[i][GPIO_LEVEL_INDEX];
+ *def = obj[i][GPIO_DEF_INDEX];
+ std::string gpioDesc = obj[i][GPIO_DESC_INDEX];
+ *length = gpioDesc.size();
+ memcpy(buffer, gpioDesc.data(), *length);
+ buffer[*length] = '\0';
+
+ return 0;
+ }
+ }
+
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "GPIO pin description data not available",
+ phosphor::logging::entry("GPIO_PIN=0x%x", index));
+ return -1;
}
static int udbg_get_cri_sel(uint8_t frame, uint8_t page, uint8_t *next,