summaryrefslogtreecommitdiffstats
path: root/common/recipes-lib
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-lib')
-rw-r--r--common/recipes-lib/fruid/files/Makefile27
-rw-r--r--common/recipes-lib/fruid/files/fruid.c682
-rw-r--r--common/recipes-lib/fruid/files/fruid.h192
-rw-r--r--common/recipes-lib/fruid/libfruid_0.1.bb43
-rw-r--r--common/recipes-lib/gpio/files/src/Makefile27
-rw-r--r--common/recipes-lib/gpio/files/src/gpio.c107
-rw-r--r--common/recipes-lib/gpio/files/src/gpio.h42
-rw-r--r--common/recipes-lib/gpio/libgpio_0.1.bb40
-rw-r--r--common/recipes-lib/ipmb/files/Makefile11
-rw-r--r--common/recipes-lib/ipmb/files/ipmb.c82
-rw-r--r--common/recipes-lib/ipmb/files/ipmb.h75
-rw-r--r--common/recipes-lib/ipmb/libipmb_0.1.bb26
-rw-r--r--common/recipes-lib/ipmi/files/Makefile27
-rw-r--r--common/recipes-lib/ipmi/files/ipmi.c80
-rw-r--r--common/recipes-lib/ipmi/files/ipmi.h453
-rw-r--r--common/recipes-lib/ipmi/libipmi_0.2.bb41
-rw-r--r--common/recipes-lib/log/files/src/log.h59
-rw-r--r--common/recipes-lib/log/liblog_0.1.bb36
-rw-r--r--common/recipes-lib/sdr/files/Makefile11
-rw-r--r--common/recipes-lib/sdr/files/sdr.c210
-rw-r--r--common/recipes-lib/sdr/files/sdr.h163
-rw-r--r--common/recipes-lib/sdr/libsdr_0.1.bb30
22 files changed, 2464 insertions, 0 deletions
diff --git a/common/recipes-lib/fruid/files/Makefile b/common/recipes-lib/fruid/files/Makefile
new file mode 100644
index 0000000..225d5f7
--- /dev/null
+++ b/common/recipes-lib/fruid/files/Makefile
@@ -0,0 +1,27 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+#
+# This program file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program in a file named COPYING; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+lib: libfruid.so
+
+libfruid.so: fruid.c
+ $(CC) $(CFLAGS) -fPIC -c -o fruid.o fruid.c
+ $(CC) -shared -o libfruid.so fruid.o -lc
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libfruid.so
diff --git a/common/recipes-lib/fruid/files/fruid.c b/common/recipes-lib/fruid/files/fruid.c
new file mode 100644
index 0000000..dc71ac8
--- /dev/null
+++ b/common/recipes-lib/fruid/files/fruid.c
@@ -0,0 +1,682 @@
+/*
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <syslog.h>
+#include <time.h>
+#include "fruid.h"
+
+#define FIELD_TYPE(x) ((x & (0x03 << 6)) >> 6)
+#define FIELD_LEN(x) (x & ~(0x03 << 6))
+#define FIELD_EMPTY "N/A"
+
+/* Unix time difference between 1970 and 1996. */
+#define UNIX_TIMESTAMP_1996 820454400
+
+/* Array for BCD Plus definition. */
+const char bcd_plus_array[] = "0123456789 -.XXX";
+
+/* Array for 6-Bit ASCII definition. */
+const char * ascii_6bit[4] = {
+ " !\"#$%&'()*+,-./",
+ "0123456789:;<=>?",
+ "@ABCDEFGHIJKLMNO",
+ "PQRSTUVWXYZ[\\]^_"
+};
+
+/*
+ * calculate_time - calculate time from the unix time stamp stored
+ *
+ * @mfg_time : Unix timestamp since 1996
+ *
+ * returns char * for mfg_time_str
+ * returns NULL for memory allocation failure
+ */
+static char * calculate_time(uint8_t * mfg_time)
+{
+ int len;
+ struct tm * local;
+ time_t unix_time = 0;
+ unix_time = ((mfg_time[2] << 16) + (mfg_time[1] << 8) + mfg_time[0]) * 60;
+ unix_time += UNIX_TIMESTAMP_1996;
+
+ local = localtime(&unix_time);
+ char * str = asctime(local);
+
+ len = strlen(str);
+
+ char * mfg_time_str = (char *) malloc(len);
+ if (!mfg_time_str) {
+ syslog(LOG_ALERT, "fruid: malloc: memory allocation failed\n");
+ return NULL;
+ }
+
+ memset(mfg_time_str, 0, len);
+
+ memcpy(mfg_time_str, str, len);
+
+ mfg_time_str[len - 1] = '\0';
+
+ return mfg_time_str;
+}
+
+/*
+ * verify_chksum - verify the zero checksum of the data
+ *
+ * @area : offset of the area
+ * @len : len of the area in bytes
+ * @chksum_read : stored checksum in the data.
+ *
+ * returns 0 if chksum is verified
+ * returns -1 if there exist a mismatch
+ */
+static int verify_chksum(uint8_t * area, uint8_t len, uint8_t chksum_read)
+{
+ int i;
+ uint8_t chksum = 0;
+
+ for (i = 0; i < len - 1; i++)
+ chksum += area[i];
+
+ /* Zero checksum calculation */
+ chksum = ~(chksum) + 1;
+
+ return (chksum == chksum_read) ? 0 : -1;
+}
+
+/*
+ * get_chassis_type - get the Chassis type
+ *
+ * @type_hex : type stored in the data
+ *
+ * returns char ptr for chassis type string
+ * returns NULL if type not in the list
+ */
+static char * get_chassis_type(uint8_t type_hex)
+{
+ int type, ret;
+ char type_int[4];
+
+ ret = sprintf(type_int, "%u", type_hex);
+ type = atoi(type_int) - 1;
+
+ /* If the type is not in the list defined.*/
+ if (type > FRUID_CHASSIS_TYPECODE_MAX || type < FRUID_CHASSIS_TYPECODE_MIN) {
+ syslog(LOG_INFO, "fruid: chassis area: invalid chassis type\n");
+ return NULL;
+ }
+
+ char * type_str = (char *) malloc(strlen(fruid_chassis_type[type]));
+ if (!type_str) {
+ syslog(LOG_ALERT, "fruid: malloc: memory allocation failed\n");
+ return NULL;
+ }
+
+ memcpy(type_str, fruid_chassis_type[type], strlen(fruid_chassis_type[type]));
+
+ return type_str;
+}
+
+/*
+ * _fruid_area_field_read - read the field data
+ *
+ * @offset : offset of the field
+ *
+ * returns char ptr for the field data string
+ */
+static char * _fruid_area_field_read(uint8_t *offset)
+{
+ int field_type, field_len, field_len_eff;
+ int idx, idx_eff, val;
+ char * field;
+
+ /* Bits 7:6 */
+ field_type = FIELD_TYPE(offset[0]);
+ /* Bits 5:0 */
+ field_len = FIELD_LEN(offset[0]);
+
+ /* Calculate the effective length of the field data based on type stored. */
+ switch (field_type) {
+
+ case TYPE_BINARY:
+ /* TODO: Need to add support to read data stored in binary type. */
+ field_len_eff = 1;
+ break;
+
+ case TYPE_ASCII_6BIT:
+ /*
+ * Every 3 bytes have four 6-bit packed values
+ * + 6-bit values from the remaining field bytes.
+ */
+ field_len_eff = (field_len / 3) * 4 + (field_len % 3);
+ break;
+
+ case TYPE_BCD_PLUS:
+ case TYPE_ASCII_8BIT:
+ field_len_eff = field_len;
+ break;
+ }
+
+ /* If field data is zero, store 'N/A' for that field. */
+ field_len_eff > 0 ? (field = (char *) malloc(field_len_eff + 1)) :
+ (field = (char *) malloc(strlen(FIELD_EMPTY)));
+ if (!field) {
+ syslog(LOG_ALERT, "fruid: malloc: memory allocation failed\n");
+ return NULL;
+ }
+
+ memset(field, 0, field_len + 1);
+
+ if (field_len_eff < 1) {
+ strcpy(field, FIELD_EMPTY);
+ return field;
+ }
+
+ /* Retrieve field data depending on the type it was stored. */
+ switch (field_type) {
+ case TYPE_BINARY:
+ /* TODO: Need to add support to read data stored in binary type. */
+ break;
+
+ case TYPE_BCD_PLUS:
+
+ idx = 0;
+ while (idx != field_len) {
+ field[idx] = bcd_plus_array[offset[idx + 1] & 0x0F];
+ idx++;
+ }
+ field[idx] = '\0';
+ break;
+
+ case TYPE_ASCII_6BIT:
+
+ idx_eff = 0, idx = 1;
+
+ while (field_len > 0) {
+
+ /* 6-Bits => Bits 5:0 of the first byte */
+ val = offset[idx] & 0x3F;
+ field[idx_eff++] = ascii_6bit[(val & 0xF0) >> 4][val & 0x0F];
+ field_len--;
+
+ if (field_len > 0) {
+ /* 6-Bits => Bits 3:0 of second byte + Bits 7:6 of first byte. */
+ val = ((offset[idx] & 0xC0) >> 6) |
+ ((offset[idx + 1] & 0x0F) << 2);
+ field[idx_eff++] = ascii_6bit[(val & 0xF0) >> 4][val & 0x0F];
+ field_len--;
+ }
+
+ if (field_len > 0) {
+ /* 6-Bits => Bits 1:0 of third byte + Bits 7:4 of second byte. */
+ val = ((offset[idx + 1] & 0xF0) >> 4) |
+ ((offset[idx + 2] & 0x03) << 4);
+ field[idx_eff++] = ascii_6bit[(val & 0xF0) >> 4][val & 0x0F];
+
+ /* 6-Bits => Bits 7:2 of third byte. */
+ val = ((offset[idx + 2] & 0xFC) >> 2);
+ field[idx_eff++] = ascii_6bit[(val & 0xF0) >> 4][val & 0x0F];
+
+ field_len--;
+ idx += 3;
+ }
+ }
+ /* Add Null terminator */
+ field[idx_eff] = '\0';
+ break;
+
+ case TYPE_ASCII_8BIT:
+
+ memcpy(field, offset + 1, field_len);
+ /* Add Null terminator */
+ field[field_len] = '\0';
+ break;
+ }
+
+ return field;
+}
+
+/* Free all the memory allocated for fruid information */
+void free_fruid_info(fruid_info_t * fruid)
+{
+ if (fruid->chassis.flag) {
+ free(fruid->chassis.type_str);
+ free(fruid->chassis.part);
+ free(fruid->chassis.serial);
+ free(fruid->chassis.custom);
+ }
+
+ if (fruid->board.flag) {
+ free(fruid->board.mfg_time_str);
+ free(fruid->board.mfg);
+ free(fruid->board.name);
+ free(fruid->board.serial);
+ free(fruid->board.part);
+ free(fruid->board.fruid);
+ }
+
+ if (fruid->product.flag) {
+ free(fruid->board.custom);
+ free(fruid->product.mfg);
+ free(fruid->product.name);
+ free(fruid->product.part);
+ free(fruid->product.version);
+ free(fruid->product.serial);
+ free(fruid->product.asset_tag);
+ free(fruid->product.fruid);
+ free(fruid->product.custom);
+ }
+}
+
+/* Initialize the fruid information struct */
+static void init_fruid_info(fruid_info_t * fruid)
+{
+ fruid->chassis.flag = 0;
+ fruid->board.flag = 0;
+ fruid->product.flag = 0;
+ fruid->chassis.type_str = NULL;
+ fruid->chassis.part = NULL;
+ fruid->chassis.serial = NULL;
+ fruid->chassis.custom = NULL;
+ fruid->board.mfg_time_str = NULL;
+ fruid->board.mfg = NULL;
+ fruid->board.name = NULL;
+ fruid->board.serial = NULL;
+ fruid->board.part = NULL;
+ fruid->board.fruid = NULL;
+ fruid->board.custom = NULL;
+ fruid->product.mfg = NULL;
+ fruid->product.name = NULL;
+ fruid->product.part = NULL;
+ fruid->product.version = NULL;
+ fruid->product.serial = NULL;
+ fruid->product.asset_tag = NULL;
+ fruid->product.fruid = NULL;
+ fruid->product.custom = NULL;
+}
+
+/* Parse the Product area data */
+int parse_fruid_area_product(uint8_t * product,
+ fruid_area_product_t * fruid_product)
+{
+ int ret, index;
+
+ index = 0;
+
+ /* Reset the struct to zero */
+ memset(fruid_product, 0, sizeof(fruid_area_product_t));
+
+ /* Check if the format version is as per IPMI FRUID v1.0 format spec */
+ fruid_product->format_ver = product[index++];
+ if (fruid_product->format_ver != FRUID_FORMAT_VER) {
+ syslog(LOG_ERR, "fruid: product_area: format version not supported");
+ return EPROTONOSUPPORT;
+ }
+
+ fruid_product->area_len = product[index++] * FRUID_AREA_LEN_MULTIPLIER;
+ fruid_product->lang_code = product[index++];
+
+ fruid_product->chksum = product[fruid_product->area_len - 1];
+ ret = verify_chksum((uint8_t *) product,
+ fruid_product->area_len, fruid_product->chksum);
+
+ if (ret) {
+ syslog(LOG_ERR, "fruid: product_area: chksum not verified.");
+ return EBADF;
+ }
+
+ fruid_product->mfg = _fruid_area_field_read(&product[index]);
+ if (fruid_product->mfg == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(product[index]) + 1;
+
+ fruid_product->name = _fruid_area_field_read(&product[index]);
+ if (fruid_product->name == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(product[index]) + 1;
+
+ fruid_product->part = _fruid_area_field_read(&product[index]);
+ if (fruid_product->part == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(product[index]) + 1;
+
+ fruid_product->version = _fruid_area_field_read(&product[index]);
+ if (fruid_product->version == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(product[index]) + 1;
+
+ fruid_product->serial = _fruid_area_field_read(&product[index]);
+ if (fruid_product->serial == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(product[index]) + 1;
+
+ fruid_product->asset_tag = _fruid_area_field_read(&product[index]);
+ if (fruid_product->asset_tag == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(product[index]) + 1;
+
+ fruid_product->fruid = _fruid_area_field_read(&product[index]);
+ if (fruid_product->fruid == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(product[index]) + 1;
+
+ fruid_product->custom = _fruid_area_field_read(&product[index]);
+ if (fruid_product->custom == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(product[index]) + 1;
+
+ return 0;
+}
+
+/* Parse the Board area data */
+int parse_fruid_area_board(uint8_t * board,
+ fruid_area_board_t * fruid_board)
+{
+ int ret, index, i;
+ time_t unix_time;
+
+ index = 0;
+
+ /* Reset the struct to zero */
+ memset(fruid_board, 0, sizeof(fruid_area_board_t));
+
+ /* Check if the format version is as per IPMI FRUID v1.0 format spec */
+ fruid_board->format_ver = board[index++];
+ if (fruid_board->format_ver != FRUID_FORMAT_VER) {
+ syslog(LOG_ERR, "fruid: board_area: format version not supported");
+ return EPROTONOSUPPORT;
+ }
+ fruid_board->area_len = board[index++] * FRUID_AREA_LEN_MULTIPLIER;
+ fruid_board->lang_code = board[index++];
+
+ fruid_board->chksum = board[fruid_board->area_len - 1];
+ ret = verify_chksum((uint8_t *) board,
+ fruid_board->area_len, fruid_board->chksum);
+
+ if (ret) {
+ syslog(LOG_ERR, "fruid: board_area: chksum not verified.");
+ return EBADF;
+ }
+
+ for (i = 0; i < 3; i++) {
+ fruid_board->mfg_time[i] = board[index++];
+ }
+
+ fruid_board->mfg_time_str = calculate_time(fruid_board->mfg_time);
+ if (fruid_board->mfg_time_str == NULL)
+ return ENOMEM;
+
+ fruid_board->mfg = _fruid_area_field_read(&board[index]);
+ if (fruid_board->mfg == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(board[index]) + 1;
+
+ fruid_board->name = _fruid_area_field_read(&board[index]);
+ if (fruid_board->name == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(board[index]) + 1;
+
+ fruid_board->serial = _fruid_area_field_read(&board[index]);
+ if (fruid_board->serial == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(board[index]) + 1;
+
+ fruid_board->part = _fruid_area_field_read(&board[index]);
+ if (fruid_board->part == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(board[index]) + 1;
+
+ fruid_board->fruid = _fruid_area_field_read(&board[index]);
+ if (fruid_board->fruid == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(board[index]) + 1;
+
+ fruid_board->custom = _fruid_area_field_read(&board[index]);
+ if (fruid_board->custom == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(board[index]) + 1;
+
+ return 0;
+}
+
+/* Parse the Chassis area data */
+int parse_fruid_area_chassis(uint8_t * chassis,
+ fruid_area_chassis_t * fruid_chassis)
+{
+ int ret, index;
+
+ index = 0;
+
+ /* Reset the struct to zero */
+ memset(fruid_chassis, 0, sizeof(fruid_area_chassis_t));
+
+ /* Check if the format version is as per IPMI FRUID v1.0 format spec */
+ fruid_chassis->format_ver = chassis[index++];
+ if (fruid_chassis->format_ver != FRUID_FORMAT_VER) {
+ syslog(LOG_ERR, "fruid: chassis_area: format version not supported");
+ return EPROTONOSUPPORT;
+ }
+
+ fruid_chassis->area_len = chassis[index++] * FRUID_AREA_LEN_MULTIPLIER;
+ fruid_chassis->type = chassis[index++];
+
+ fruid_chassis->chksum = chassis[fruid_chassis->area_len - 1];
+ ret = verify_chksum((uint8_t *) chassis,
+ fruid_chassis->area_len, fruid_chassis->chksum);
+ if (ret) {
+ syslog(LOG_ERR, "fruid: chassis_area: chksum not verified.");
+ return EBADF;
+ }
+
+ fruid_chassis->type_str = get_chassis_type(fruid_chassis->type);
+ if (fruid_chassis->type_str == NULL)
+ return ENOMSG;
+
+ fruid_chassis->part = _fruid_area_field_read(&chassis[index]);
+ if (fruid_chassis->part == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(chassis[index]) + 1;
+
+ fruid_chassis->serial = _fruid_area_field_read(&chassis[index]);
+ if (fruid_chassis->serial == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(chassis[index]) + 1;
+
+ fruid_chassis->custom = _fruid_area_field_read(&chassis[index]);
+ if (fruid_chassis->custom == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(chassis[index]) + 1;
+
+ return 0;
+}
+
+/* Calculate the area offsets and populate the fruid_eeprom_t struct */
+void set_fruid_eeprom_offsets(uint8_t * eeprom, fruid_header_t * header,
+ fruid_eeprom_t * fruid_eeprom)
+{
+ fruid_eeprom->header = eeprom + 0x00;
+
+ header->offset_area.chassis ? (fruid_eeprom->chassis = eeprom + \
+ (header->offset_area.chassis * FRUID_OFFSET_MULTIPLIER)) : \
+ (fruid_eeprom->chassis = NULL);
+
+ header->offset_area.board ? (fruid_eeprom->board = eeprom + \
+ (header->offset_area.board * FRUID_OFFSET_MULTIPLIER)) : \
+ (fruid_eeprom->board = NULL);
+
+ header->offset_area.product ? (fruid_eeprom->product = eeprom + \
+ (header->offset_area.product * FRUID_OFFSET_MULTIPLIER)) : \
+ (fruid_eeprom->product = NULL);
+
+ header->offset_area.multirecord ? (fruid_eeprom->multirecord = eeprom + \
+ (header->offset_area.multirecord * FRUID_OFFSET_MULTIPLIER)) : \
+ (fruid_eeprom->multirecord = NULL);
+}
+
+/* Populate the common header struct */
+int parse_fruid_header(uint8_t * eeprom, fruid_header_t * header)
+{
+ int ret;
+
+ memcpy((uint8_t *)header, (uint8_t *)eeprom, sizeof(fruid_header_t));
+ ret = verify_chksum((uint8_t *) header,
+ sizeof(fruid_header_t), header->chksum);
+ if (ret) {
+ syslog(LOG_ERR, "fruid: common_header: chksum not verified.");
+ return EBADF;
+ }
+
+ return ret;
+}
+
+/* Parse the eeprom dump and populate the fruid info in struct */
+int populate_fruid_info(fruid_eeprom_t * fruid_eeprom, fruid_info_t * fruid)
+{
+ int ret;
+
+ /* Initial all the required fruid structures */
+ fruid_area_chassis_t fruid_chassis;
+ fruid_area_board_t fruid_board;
+ fruid_area_product_t fruid_product;
+
+ /* If Chassis area is present, parse and print it */
+ if (fruid_eeprom->chassis) {
+ ret = parse_fruid_area_chassis(fruid_eeprom->chassis, &fruid_chassis);
+ if (!ret) {
+ fruid->chassis.flag = 1;
+ fruid->chassis.type_str = fruid_chassis.type_str;
+ fruid->chassis.part = fruid_chassis.part;
+ fruid->chassis.serial = fruid_chassis.serial;
+ fruid->chassis.custom = fruid_chassis.custom;
+ } else
+ return ret;
+ }
+
+ /* If Board area is present, parse and print it */
+ if (fruid_eeprom->board) {
+ ret = parse_fruid_area_board(fruid_eeprom->board, &fruid_board);
+ if (!ret) {
+ fruid->board.flag = 1;
+ fruid->board.mfg_time_str = fruid_board.mfg_time_str;
+ fruid->board.mfg = fruid_board.mfg;
+ fruid->board.name = fruid_board.name;
+ fruid->board.serial = fruid_board.serial;
+ fruid->board.part = fruid_board.part;
+ fruid->board.fruid = fruid_board.fruid;
+ fruid->board.custom = fruid_board.custom;
+ } else
+ return ret;
+ }
+
+ /* If Product area is present, parse and print it */
+ if (fruid_eeprom->product) {
+ ret = parse_fruid_area_product(fruid_eeprom->product, &fruid_product);
+ if (!ret) {
+ fruid->product.flag = 1;
+ fruid->product.mfg = fruid_product.mfg;
+ fruid->product.name = fruid_product.name;
+ fruid->product.part = fruid_product.part;
+ fruid->product.version = fruid_product.version;
+ fruid->product.serial = fruid_product.serial;
+ fruid->product.asset_tag = fruid_product.asset_tag;
+ fruid->product.fruid = fruid_product.fruid;
+ fruid->product.custom = fruid_product.custom;
+ } else
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * fruid_parse - To parse the bin file (eeprom) and populate
+ * the fruid information in the struct
+ * @bin : Eeprom binary file
+ * @fruid : ptr to the struct that holds the fruid information
+ *
+ * returns 0 on success
+ * returns non-zero errno value on error
+ */
+int fruid_parse(const char * bin, fruid_info_t * fruid)
+{
+ int fruid_len, ret;
+ FILE *fruid_fd;
+ uint8_t * eeprom;
+
+ /* Initial all the required fruid structures */
+ fruid_header_t fruid_header;
+ fruid_eeprom_t fruid_eeprom;
+
+ memset(&fruid_header, 0, sizeof(fruid_header_t));
+ memset(&fruid_eeprom, 0, sizeof(fruid_eeprom_t));
+
+ /* Reset parser return value */
+ ret = 0;
+
+ /* Open the FRUID binary file */
+ fruid_fd = fopen(bin, "rb");
+ if (!fruid_fd) {
+ syslog(LOG_ERR, "fruid: unable to open the file");
+ return ENOENT;
+ }
+
+ /* Get the size of the binary file */
+ fseek(fruid_fd, 0, SEEK_END);
+ fruid_len = (uint32_t) ftell(fruid_fd);
+
+ fseek(fruid_fd, 0, SEEK_SET);
+
+ eeprom = (uint8_t *) malloc(fruid_len);
+ if (!eeprom) {
+ syslog(LOG_ALERT, "fruid: malloc: memory allocation failed\n");
+ return ENOMEM;
+ }
+
+ /* Read the binary file */
+ fread(eeprom, sizeof(uint8_t), fruid_len, fruid_fd);
+
+ /* Close the FRUID binary file */
+ fclose(fruid_fd);
+
+ /* Parse the common header data */
+ ret = parse_fruid_header(eeprom, &fruid_header);
+ if (ret) {
+ /* Free the eeprom malloc'ed memory */
+ free(eeprom);
+ return ret;
+ }
+
+ /* Calculate all the area offsets */
+ set_fruid_eeprom_offsets(eeprom, &fruid_header, &fruid_eeprom);
+
+ init_fruid_info(fruid);
+ /* Parse the eeprom and populate the fruid information */
+ ret = populate_fruid_info(&fruid_eeprom, fruid);
+ if (ret) {
+ /* Free the malloced memory for the fruid information */
+ free_fruid_info(fruid);
+ }
+
+ /* Free the eeprom malloced memory */
+ free(eeprom);
+
+ return ret;
+}
diff --git a/common/recipes-lib/fruid/files/fruid.h b/common/recipes-lib/fruid/files/fruid.h
new file mode 100644
index 0000000..713658d
--- /dev/null
+++ b/common/recipes-lib/fruid/files/fruid.h
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __FRUID_H__
+#define __FRUID_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <openbmc/ipmi.h>
+
+#define FRUID_FORMAT_VER 0x01
+#define FRUID_OFFSET_MULTIPLIER 8
+#define FRUID_AREA_LEN_MULTIPLIER 8
+
+#define FRUID_OFFSET_AREA_INTERNAL 0
+#define FRUID_OFFSET_AREA_CHASSIS 1
+#define FRUID_OFFSET_AREA_BOARD 2
+#define FRUID_OFFSET_AREA_PRODUCT 3
+#define FRUID_OFFSET_AREA_MULTIRECORD 4
+
+#define FRUID_CHASSIS_TYPECODE_MIN 1
+#define FRUID_CHASSIS_TYPECODE_MAX 32
+
+/* To hold the common header information. */
+typedef struct fruid_header_t {
+ uint8_t format_ver : 4;
+ struct {
+ uint8_t internal;
+ uint8_t chassis;
+ uint8_t board;
+ uint8_t product;
+ uint8_t multirecord;
+ } offset_area;
+ uint8_t pad;
+ uint8_t chksum;
+} fruid_header_t;
+
+/* To hold the Chassis area information. */
+typedef struct fruid_area_chassis_t {
+ uint8_t format_ver : 4;
+ uint8_t area_len;
+ uint8_t type;
+ char * type_str;
+ char * part;
+ char * serial;
+ char * custom;
+ uint8_t chksum;
+} fruid_area_chassis_t;
+
+/* To hold the Board area information. */
+typedef struct fruid_area_board_t {
+ uint8_t format_ver : 4;
+ uint8_t area_len;
+ uint8_t lang_code;
+ uint8_t mfg_time[3];
+ char * mfg_time_str;
+ char * mfg;
+ char * name;
+ char * serial;
+ char * part;
+ char * fruid;
+ char * custom;
+ uint8_t chksum;
+} fruid_area_board_t;
+
+/* To hold the Product area information. */
+typedef struct fruid_area_product_t {
+ uint8_t format_ver : 4;
+ uint8_t area_len;
+ uint8_t lang_code;
+ char * mfg;
+ char * name;
+ char * part;
+ char * version;
+ char * serial;
+ char * asset_tag;
+ char * fruid;
+ char * custom;
+ uint8_t chksum;
+} fruid_area_product_t;
+
+/* To hold the Multirecord area information. */
+typedef struct fruid_area_multirecord_t {
+ uint8_t format_ver : 4;
+ uint8_t area_len;
+ /* TODO: Add more fields to support Multirecord area. */
+} fruid_area_multirecord_t;
+
+/* To hold all the fruid information */
+typedef struct fruid_info_t {
+ struct {
+ uint8_t flag;
+ char * type_str;
+ char * part;
+ char * serial;
+ char * custom;
+ } chassis;
+ struct {
+ uint8_t flag;
+ char * mfg_time_str;
+ char * mfg;
+ char * name;
+ char * serial;
+ char * part;
+ char * fruid;
+ char * custom;
+ } board;
+ struct {
+ uint8_t flag;
+ char * mfg;
+ char * name;
+ char * part;
+ char * version;
+ char * serial;
+ char * asset_tag;
+ char * fruid;
+ char * custom;
+ } product;
+} fruid_info_t;
+
+/* To hold the different area offsets. */
+typedef struct fruid_eeprom_t {
+ uint8_t * header;
+ uint8_t * chassis;
+ uint8_t * board;
+ uint8_t * product;
+ uint8_t * multirecord;
+} fruid_eeprom_t;
+
+/* List of all the Chassis types. */
+const char * fruid_chassis_type [] = {
+ "Other", /* 0x01 */
+ "Unknown", /* 0x02 */
+ "Desktop", /* 0x03 */
+ "Low Profile Desktop", /* 0x04 */
+ "Pizza Box", /* 0x05 */
+ "Mini Tower", /* 0x06 */
+ "Tower", /* 0x07 */
+ "Portable", /* 0x08 */
+ "Laptop", /* 0x09 */
+ "Notebook", /* 0x0A */
+ "Hand Held", /* 0x0B */
+ "Docking Station", /* 0x0C */
+ "All in One", /* 0x0D */
+ "Sub Notebook", /* 0x0E */
+ "Space-saving", /* 0x0F */
+ "Lunch Box", /* 0x10 */
+ "Main Server Chassis", /* 0x11 */
+ "Expansion Chassis", /* 0x12 */
+ "SubChassis", /* 0x13 */
+ "Bus Expansion Chassis", /* 0x14 */
+ "Peripheral Chassis", /* 0x15 */
+ "RAID Chassis", /* 0x16 */
+ "Rack Mount Chassis", /* 0x17 */
+ "Sealed-case PC", /* 0x18 */
+ "Multi-system Chassis", /* 0x19 */
+ "Compact PCI", /* 0x1A */
+ "Advanced TCA", /* 0x1B */
+ "Blade", /* 0x1C */
+ "Blade Enclosure", /* 0x1D */
+ "Tablet", /* 0x1E */
+ "Convertible", /* 0x1F */
+ "Detachable" /* 0x20 */
+};
+
+int fruid_parse(const char * bin, fruid_info_t * fruid);
+void free_fruid_info(fruid_info_t * fruid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __FRUID_H__ */
diff --git a/common/recipes-lib/fruid/libfruid_0.1.bb b/common/recipes-lib/fruid/libfruid_0.1.bb
new file mode 100644
index 0000000..7984d3b
--- /dev/null
+++ b/common/recipes-lib/fruid/libfruid_0.1.bb
@@ -0,0 +1,43 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+#
+# This program file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program in a file named COPYING; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+SUMMARY = "IPMI FRUID Library"
+DESCRIPTION = "library for ipmi fruid"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://fruid.c;beginline=4;endline=16;md5=da35978751a9d71b73679307c4d296ec"
+
+SRC_URI = "file://Makefile \
+ file://fruid.c \
+ file://fruid.h \
+ "
+
+S = "${WORKDIR}"
+
+DEPENDS += " libipmi "
+
+do_install() {
+ install -d ${D}${libdir}
+ install -m 0644 libfruid.so ${D}${libdir}/libfruid.so
+
+ install -d ${D}${includedir}/openbmc
+ install -m 0644 fruid.h ${D}${includedir}/openbmc/fruid.h
+}
+
+FILES_${PN} = "${libdir}/libfruid.so"
+FILES_${PN}-dev = "${includedir}/openbmc/fruid.h"
diff --git a/common/recipes-lib/gpio/files/src/Makefile b/common/recipes-lib/gpio/files/src/Makefile
new file mode 100644
index 0000000..0b605fc
--- /dev/null
+++ b/common/recipes-lib/gpio/files/src/Makefile
@@ -0,0 +1,27 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+#
+# This program file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program in a file named COPYING; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+lib: libgpio.so
+
+libgpio.so: gpio.c
+ $(CC) $(CFLAGS) -fPIC -c -o gpio.o gpio.c
+ $(CC) -shared -o libgpio.so gpio.o -lc
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libgpio.so
diff --git a/common/recipes-lib/gpio/files/src/gpio.c b/common/recipes-lib/gpio/files/src/gpio.c
new file mode 100644
index 0000000..9c1f7a2
--- /dev/null
+++ b/common/recipes-lib/gpio/files/src/gpio.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+//#define DEBUG
+//#define VERBOSE
+
+#include "gpio.h"
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/errno.h>
+
+#include <openbmc/log.h>
+
+void gpio_init_default(gpio_st *g) {
+ g->gs_gpio = -1;
+ g->gs_fd = -1;
+}
+
+int gpio_open(gpio_st *g, int gpio)
+{
+ char buf[128];
+ int rc;
+
+ snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%u/value", gpio);
+ rc = open(buf, O_RDWR);
+ if (rc == -1) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to open %s", buf);
+ return -rc;
+ }
+ g->gs_fd = rc;
+ g->gs_gpio = gpio;
+ return 0;
+}
+
+void gpio_close(gpio_st *g)
+{
+ if (g && g->gs_fd != -1) {
+ close(g->gs_fd);
+ }
+ gpio_init_default(g);
+}
+
+gpio_value_en gpio_read(gpio_st *g)
+{
+ char buf[32] = {0};
+ gpio_value_en v;
+ lseek(g->gs_fd, 0, SEEK_SET);
+ read(g->gs_fd, buf, sizeof(buf));
+ v = atoi(buf) ? GPIO_VALUE_HIGH : GPIO_VALUE_LOW;
+ LOG_VER("read gpio=%d value=%d %d", g->gs_gpio, atoi(buf), v);
+ return v;
+}
+
+void gpio_write(gpio_st *g, gpio_value_en v)
+{
+ lseek(g->gs_fd, 0, SEEK_SET);
+ write(g->gs_fd, (v == GPIO_VALUE_HIGH) ? "1" : "0", 1);
+ LOG_VER("write gpio=%d value=%d", g->gs_gpio, v);
+}
+
+int gpio_change_direction(gpio_st *g, gpio_direction_en dir)
+{
+ char buf[128];
+ char *val;
+ int fd = -1;
+ int rc = 0;
+
+ snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%u/direction", g->gs_gpio);
+ fd = open(buf, O_WRONLY);
+ if (fd == -1) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to open %s", buf);
+ return -rc;
+ }
+
+ val = (dir == GPIO_DIRECTION_IN) ? "in" : "out";
+ write(fd, val, strlen(val));
+
+ LOG_VER("change gpio=%d direction=%s", g->gs_gpio, val);
+
+ out:
+ if (fd != -1) {
+ close(fd);
+ }
+ return -rc;
+}
diff --git a/common/recipes-lib/gpio/files/src/gpio.h b/common/recipes-lib/gpio/files/src/gpio.h
new file mode 100644
index 0000000..3303986
--- /dev/null
+++ b/common/recipes-lib/gpio/files/src/gpio.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef GPIO_H
+#define GPIO_H
+
+typedef struct {
+ int gs_gpio;
+ int gs_fd;
+} gpio_st;
+
+typedef enum {
+ GPIO_DIRECTION_IN,
+ GPIO_DIRECTION_OUT,
+} gpio_direction_en;
+
+typedef enum {
+ GPIO_VALUE_LOW = 0,
+ GPIO_VALUE_HIGH = 1,
+} gpio_value_en;
+
+int gpio_open(gpio_st* g, int gpio);
+void gpio_close(gpio_st *g);
+gpio_value_en gpio_read(gpio_st *g);
+void gpio_write(gpio_st *g, gpio_value_en v);
+int gpio_change_direction(gpio_st *g, gpio_direction_en dir);
+
+#endif
diff --git a/common/recipes-lib/gpio/libgpio_0.1.bb b/common/recipes-lib/gpio/libgpio_0.1.bb
new file mode 100644
index 0000000..cd32ac0
--- /dev/null
+++ b/common/recipes-lib/gpio/libgpio_0.1.bb
@@ -0,0 +1,40 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+#
+# This program file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program in a file named COPYING; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
+SUMMARY = "GPIO access library"
+DESCRIPTION = "library to access GPIO"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://gpio.c;beginline=4;endline=16;md5=da35978751a9d71b73679307c4d296ec"
+
+SRC_URI = "file://src \
+ "
+
+DEPENDS += "liblog"
+
+S = "${WORKDIR}/src"
+
+do_install() {
+ install -d ${D}${libdir}
+ install -m 0644 libgpio.so ${D}${libdir}/libgpio.so
+
+ install -d ${D}${includedir}/openbmc
+ install -m 0644 gpio.h ${D}${includedir}/openbmc/gpio.h
+}
+
+FILES_${PN} = "${libdir}/libgpio.so"
+FILES_${PN}-dev = "${includedir}/openbmc/gpio.h"
diff --git a/common/recipes-lib/ipmb/files/Makefile b/common/recipes-lib/ipmb/files/Makefile
new file mode 100644
index 0000000..c09b325
--- /dev/null
+++ b/common/recipes-lib/ipmb/files/Makefile
@@ -0,0 +1,11 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+lib: libipmb.so
+
+libipmb.so: ipmb.c
+ $(CC) $(CFLAGS) -fPIC -c -o ipmb.o ipmb.c
+ $(CC) -shared -o libipmb.so ipmb.o -lc
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libipmb.so
diff --git a/common/recipes-lib/ipmb/files/ipmb.c b/common/recipes-lib/ipmb/files/ipmb.c
new file mode 100644
index 0000000..731eeba
--- /dev/null
+++ b/common/recipes-lib/ipmb/files/ipmb.c
@@ -0,0 +1,82 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * This file contains code to support IPMI2.0 Specificaton available @
+ * http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-specifications.html
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include "ipmb.h"
+
+/*
+ * Function to handle IPMB messages
+ */
+void
+lib_ipmb_handle(unsigned char bus_id,
+ unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len) {
+
+ int s, t, len;
+ struct sockaddr_un remote;
+ char sock_path[64] = {0};
+
+ sprintf(sock_path, "%s_%d", SOCK_PATH_IPMB, bus_id);
+
+ // TODO: Need to update to reuse the socket instead of creating new
+ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ syslog(LOG_ALERT, "lib_ipmb_handle: socket() failed\n");
+ return;
+ }
+
+ remote.sun_family = AF_UNIX;
+ strcpy(remote.sun_path, sock_path);
+ len = strlen(remote.sun_path) + sizeof(remote.sun_family);
+
+ if (connect(s, (struct sockaddr *)&remote, len) == -1) {
+ syslog(LOG_ALERT, "ipmb_handle: connect() failed\n");
+ goto clean_exit;
+ }
+
+ if (send(s, request, req_len, 0) == -1) {
+ syslog(LOG_ALERT, "ipmb_handle: send() failed\n");
+ goto clean_exit;
+ }
+
+ if ((t=recv(s, response, MAX_IPMB_RES_LEN, 0)) > 0) {
+ *res_len = t;
+ } else {
+ if (t < 0) {
+ syslog(LOG_ALERT, "lib_ipmb_handle: recv() failed\n");
+ } else {
+ printf("Server closed connection\n");
+ }
+ }
+
+clean_exit:
+ close(s);
+
+ return;
+}
diff --git a/common/recipes-lib/ipmb/files/ipmb.h b/common/recipes-lib/ipmb/files/ipmb.h
new file mode 100644
index 0000000..d9bc16b
--- /dev/null
+++ b/common/recipes-lib/ipmb/files/ipmb.h
@@ -0,0 +1,75 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __IPMB_H__
+#define __IPMB_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SOCK_PATH_IPMB "/tmp/ipmb_socket"
+
+#define BMC_SLAVE_ADDR 0x10
+#define BRIDGE_SLAVE_ADDR 0x20
+#define ZERO_CKSUM_CONST 0x100
+
+// rqSA, rsSA, rqSeq, hdrCksum, dataCksum
+#define IPMB_HDR_SIZE 5
+
+// rqSA, NetFn, hdrCksum
+#define IPMB_DATA_OFFSET 3
+
+// Slot#0 is on I2C Bus1
+#define IPMB_BUS_SLOT0 1
+
+#define TIMEOUT_IPMI 4
+#define MAX_IPMB_RES_LEN 255
+
+typedef struct _ipmb_req_t {
+ uint8_t res_slave_addr;
+ uint8_t netfn_lun;
+ uint8_t hdr_cksum;
+ uint8_t req_slave_addr;
+ uint8_t seq_lun;
+ uint8_t cmd;
+ uint8_t data[];
+} ipmb_req_t;
+
+typedef struct _ipmb_res_t {
+ uint8_t req_slave_addr;
+ uint8_t netfn_lun;
+ uint8_t hdr_cksum;
+ uint8_t res_slave_addr;
+ uint8_t seq_lun;
+ uint8_t cmd;
+ uint8_t cc;
+ uint8_t data[];
+} ipmb_res_t;
+
+void lib_ipmb_handle(unsigned char bus_id,
+ unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* __IPMB_H__ */
diff --git a/common/recipes-lib/ipmb/libipmb_0.1.bb b/common/recipes-lib/ipmb/libipmb_0.1.bb
new file mode 100644
index 0000000..81eed9c
--- /dev/null
+++ b/common/recipes-lib/ipmb/libipmb_0.1.bb
@@ -0,0 +1,26 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+SUMMARY = "IPMB Client Library"
+DESCRIPTION = "library for IPMB Client"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://ipmb.c;beginline=8;endline=20;md5=da35978751a9d71b73679307c4d296ec"
+
+
+SRC_URI = "file://Makefile \
+ file://ipmb.c \
+ file://ipmb.h \
+ "
+
+S = "${WORKDIR}"
+
+do_install() {
+ install -d ${D}${libdir}
+ install -m 0644 libipmb.so ${D}${libdir}/libipmb.so
+
+ install -d ${D}${includedir}/openbmc
+ install -m 0644 ipmb.h ${D}${includedir}/openbmc/ipmb.h
+}
+
+FILES_${PN} = "${libdir}/libipmb.so"
+FILES_${PN}-dev = "${includedir}/openbmc/ipmb.h"
diff --git a/common/recipes-lib/ipmi/files/Makefile b/common/recipes-lib/ipmi/files/Makefile
new file mode 100644
index 0000000..369819c
--- /dev/null
+++ b/common/recipes-lib/ipmi/files/Makefile
@@ -0,0 +1,27 @@
+# Copyright 2014-present Facebook. All Rights Reserved.
+#
+# This program file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program in a file named COPYING; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+lib: libipmi.so
+
+libipmi.so: ipmi.c
+ $(CC) $(CFLAGS) -fPIC -c -o ipmi.o ipmi.c
+ $(CC) -shared -o libipmi.so ipmi.o -lc
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libipmi.so
diff --git a/common/recipes-lib/ipmi/files/ipmi.c b/common/recipes-lib/ipmi/files/ipmi.c
new file mode 100644
index 0000000..3579eca
--- /dev/null
+++ b/common/recipes-lib/ipmi/files/ipmi.c
@@ -0,0 +1,80 @@
+/*
+ *
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * This file contains code to support IPMI2.0 Specificaton available @
+ * http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-specifications.html
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "ipmi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#define MAX_IPMI_RES_LEN 100
+
+/*
+ * Function to handle IPMI messages
+ */
+void
+lib_ipmi_handle(unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len) {
+
+ int s, t, len;
+ struct sockaddr_un remote;
+
+ // TODO: Need to update to reuse the socket instead of creating new
+ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ syslog(LOG_ALERT, "lib_ipmi_handle: socket() failed\n");
+ return;
+ }
+
+ remote.sun_family = AF_UNIX;
+ strcpy(remote.sun_path, SOCK_PATH_IPMI);
+ len = strlen(remote.sun_path) + sizeof(remote.sun_family);
+
+ if (connect(s, (struct sockaddr *)&remote, len) == -1) {
+ syslog(LOG_ALERT, "lib_ipmi_handle: connect() failed\n");
+ return;
+ }
+
+ if (send(s, request, req_len, 0) == -1) {
+ syslog(LOG_ALERT, "lib_ipmi_handle: send() failed\n");
+ return;
+ }
+
+ if ((t=recv(s, response, MAX_IPMI_RES_LEN, 0)) > 0) {
+ *res_len = t;
+ } else {
+ if (t < 0) {
+ syslog(LOG_ALERT, "lib_ipmi_handle: recv() failed\n");
+ } else {
+ printf("Server closed connection");
+ }
+
+ return;
+ }
+
+ close(s);
+
+ return;
+}
diff --git a/common/recipes-lib/ipmi/files/ipmi.h b/common/recipes-lib/ipmi/files/ipmi.h
new file mode 100644
index 0000000..2ae7f1c
--- /dev/null
+++ b/common/recipes-lib/ipmi/files/ipmi.h
@@ -0,0 +1,453 @@
+/*
+ *
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __IPMI_H__
+#define __IPMI_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define SOCK_PATH_IPMI "/tmp/ipmi_socket"
+
+#define IPMI_SEL_VERSION 0x51
+#define IPMI_SDR_VERSION 0x51
+
+#define MAX_NUM_DIMMS 4
+
+#define SIZE_AUTH_ENABLES 5
+#define SIZE_IP_ADDR 4
+#define SIZE_MAC_ADDR 6
+#define SIZE_NET_MASK 4
+#define SIZE_IP_HDR 3
+#define SIZE_RMCP_PORT 2
+#define SIZE_COMMUNITY_STR 18
+#define SIZE_DEST_TYPE 4
+#define SIZE_DEST_ADDR 18
+#define SIZE_TIME_STAMP 4
+
+#define SIZE_PROC_FREQ 2
+#define SIZE_DIMM_SPEED 2
+#define SIZE_DIMM_SIZE 2
+
+#define SIZE_SYSFW_VER 17
+#define SIZE_SYS_NAME 17
+#define SIZE_OS_NAME 17
+#define SIZE_OS_VER 17
+#define SIZE_BMC_URL 17
+#define SIZE_OS_HV_URL 17
+
+#define SIZE_SEL_REC 16
+
+#define BIC_INTF_HDR_SIZE 3
+
+#define LUN_OFFSET 2
+
+//NetFn, Cmd
+#define IPMI_REQ_HDR_SIZE 2
+
+// NetFn, Cmd, CC
+#define IPMI_RESP_HDR_SIZE 3
+
+#define MAX_IPMI_MSG_SIZE 100
+
+// Type Definition
+#define TYPE_BINARY 0
+#define TYPE_BCD_PLUS 1
+#define TYPE_ASCII_6BIT 2
+#define TYPE_ASCII_8BIT 3
+
+// IPMI request Structure (IPMI/Section 9.2)
+typedef struct
+{
+ unsigned char netfn_lun;
+ unsigned char cmd;
+ unsigned char data[];
+} ipmi_req_t;
+
+// IPMI Multi Node request Structure
+// Supports additional member to identify the node#
+typedef struct
+{
+ unsigned char payload_id;
+ unsigned char netfn_lun;
+ unsigned char cmd;
+ unsigned char data[];
+} ipmi_mn_req_t;
+
+// IPMI response Structure (IPMI/Section 9.3)
+typedef struct
+{
+ unsigned char netfn_lun;
+ unsigned char cmd;
+ unsigned char cc;
+ unsigned char data[];
+} ipmi_res_t;
+
+// IPMI/Spec Table 20-2
+typedef struct _ipmi_dev_id_t {
+ uint8_t dev_id;
+ uint8_t dev_rev;
+ uint8_t fw_rev1;
+ uint8_t fw_rev2;
+ uint8_t ipmi_ver;
+ uint8_t dev_support;
+ uint8_t mfg_id[3];
+ uint8_t prod_id[2];
+ uint8_t aux_fw_rev[4];
+} ipmi_dev_id_t;
+
+
+typedef struct _ipmi_fruid_info_t {
+ uint8_t size_lsb;
+ uint8_t size_msb;
+ uint8_t bytes_words;
+} ipmi_fruid_info_t;
+
+#pragma pack(push, 1)
+
+// Full Sensor SDR record; IPMI/Section 43.1
+typedef struct {
+ // Sensor Record Header
+ unsigned char rec_id[2];
+ unsigned char ver;
+ unsigned char type;
+ unsigned char len;
+ // Record Key Bytes
+ unsigned char owner;
+ unsigned char lun;
+ unsigned char sensor_num;
+ // Record Body Bytes
+ unsigned char ent_id;
+ unsigned char ent_inst;
+ unsigned char sensor_init;
+ unsigned char sensor_caps;
+ unsigned char sensor_type;
+ unsigned char evt_read_type;
+ union {
+ unsigned char assert_evt_mask[2];
+ unsigned char lt_read_mask[2];
+ };
+ union {
+ unsigned char deassert_evt_mask[2];
+ unsigned char ut_read_mask[2];
+ };
+ union {
+ unsigned char read_evt_mask[2];
+ unsigned char set_thresh_mask[2];
+ };
+ unsigned char sensor_units1;
+ unsigned char sensor_units2;
+ unsigned char sensor_units3;
+ unsigned char linear;
+ unsigned char m_val;
+ unsigned char m_tolerance;
+ unsigned char b_val;
+ unsigned char b_accuracy;
+ unsigned char accuracy_dir;
+ unsigned char rb_exp;
+ unsigned char analog_flags;
+ unsigned char nominal;
+ unsigned char normal_max;
+ unsigned char normal_min;
+ unsigned char max_reading;
+ unsigned char min_reading;
+ unsigned char unr_thresh;
+ unsigned char uc_thresh;
+ unsigned char unc_thresh;
+ unsigned char lnr_thresh;
+ unsigned char lc_thresh;
+ unsigned char lnc_thresh;
+ unsigned char pos_hyst;
+ unsigned char neg_hyst;
+ unsigned char rsvd[2];
+ unsigned char oem;
+ unsigned char str_type_len;
+ char str[16];
+} sdr_full_t;
+
+typedef struct _ipmi_sel_sdr_info_t {
+ uint8_t ver;
+ uint16_t rec_count;
+ uint16_t free_space;
+ uint8_t add_ts[4];
+ uint8_t erase_ts[4];
+ uint8_t oper;
+} ipmi_sel_sdr_info_t;
+
+typedef struct _ipmi_sel_sdr_req_t {
+ uint16_t rsv_id;
+ uint16_t rec_id;
+ uint8_t offset;
+ uint8_t nbytes;
+} ipmi_sel_sdr_req_t;
+
+typedef struct _ipmi_sel_sdr_res_t {
+ uint16_t next_rec_id;
+ uint8_t data[];
+} ipmi_sel_sdr_res_t;
+
+#pragma pack(pop)
+
+// LAN Configuration Structure (IPMI/Table 23.4)
+typedef struct
+{
+ unsigned char set_in_prog;
+ unsigned char auth_support;
+ unsigned char auth_enables[SIZE_AUTH_ENABLES];
+ unsigned char ip_addr[SIZE_IP_ADDR];
+ unsigned char ip_src;
+ unsigned char mac_addr[SIZE_MAC_ADDR];
+ unsigned char net_mask[SIZE_NET_MASK];
+ unsigned char ip_hdr[SIZE_IP_HDR];
+ unsigned char pri_rmcp_port[SIZE_RMCP_PORT];
+ unsigned char sec_rmcp_port[SIZE_RMCP_PORT];
+ unsigned char arp_ctrl;
+ unsigned char garp_interval;
+ unsigned char df_gw_ip_addr[SIZE_IP_ADDR];
+ unsigned char df_gw_mac_addr[SIZE_MAC_ADDR];
+ unsigned char back_gw_ip_addr[SIZE_IP_ADDR];
+ unsigned char back_gw_mac_addr[SIZE_MAC_ADDR];
+ unsigned char community_str[SIZE_COMMUNITY_STR];
+ unsigned char no_of_dest;
+ unsigned char dest_type[SIZE_DEST_TYPE];
+ unsigned char dest_addr[SIZE_DEST_ADDR];
+} lan_config_t;
+
+// Structure to store Processor Information
+typedef struct
+{
+ unsigned char type;
+ unsigned char freq[SIZE_PROC_FREQ];
+} proc_info_t;
+
+// Structure to store DIMM Information
+typedef struct
+{
+ unsigned char type;
+ unsigned char speed[SIZE_DIMM_SPEED];
+ unsigned char size[SIZE_DIMM_SIZE];
+} dimm_info_t;
+
+
+// Structure for System Info Params (IPMI/Section 22.14a)
+typedef struct
+{
+ unsigned char set_in_prog;
+ unsigned char sysfw_ver[SIZE_SYSFW_VER];
+ unsigned char sys_name[SIZE_SYS_NAME];
+ unsigned char pri_os_name[SIZE_OS_NAME];
+ unsigned char present_os_name[SIZE_OS_NAME];
+ unsigned char present_os_ver[SIZE_OS_VER];
+ unsigned char bmc_url[SIZE_BMC_URL];
+ unsigned char os_hv_url[SIZE_OS_HV_URL];
+} sys_info_param_t;
+
+// Structure for Sensor Reading (IPMI/Section 35.14)
+typedef struct
+{
+ uint8_t value;
+ uint8_t flags;
+ uint8_t status;
+ uint8_t ext_status;
+} ipmi_sensor_reading_t;
+
+// Network Function Codes (IPMI/Section 5.1)
+enum
+{
+ NETFN_CHASSIS_REQ = 0x00,
+ NETFN_CHASSIS_RES,
+ NETFN_BRIDGE_REQ,
+ NETFN_BRIDGE_RES,
+ NETFN_SENSOR_REQ,
+ NETFN_SENSOR_RES,
+ NETFN_APP_REQ,
+ NETFN_APP_RES,
+ NETFN_FIRMWARE_REQ,
+ NETFN_FIRMWARE_RES,
+ NETFN_STORAGE_REQ,
+ NETFN_STORAGE_RES,
+ NETFN_TRANSPORT_REQ,
+ NETFN_TRANSPORT_RES,
+ NETFN_OEM_REQ = 0x30,
+ NETFN_OEM_RES = 0x31,
+ NETFN_OEM_1S_REQ = 0x38,
+ NETFN_OEM_1S_RES = 0x39,
+};
+
+// Chassis Command Codes (IPMI/Table H-1)
+enum
+{
+ CMD_CHASSIS_GET_STATUS = 0x01,
+ CMD_CHASSIS_GET_BOOT_OPTIONS = 0x09,
+};
+
+
+// Application Command Codes (IPMI/Table H-1)
+enum
+{
+ CMD_APP_GET_DEVICE_ID = 0x01,
+ CMD_APP_GET_SELFTEST_RESULTS = 0x04,
+ CMD_APP_GET_DEVICE_GUID = 0x08,
+ CMD_APP_RESET_WDT = 0x22,
+ CMD_APP_SET_WDT = 0x24,
+ CMD_APP_GET_WDT = 0x25,
+ CMD_APP_GET_GLOBAL_ENABLES = 0x2F,
+ CMD_APP_GET_SYSTEM_GUID = 0x37,
+ CMD_APP_SET_SYS_INFO_PARAMS = 0x58,
+ CMD_APP_GET_SYS_INFO_PARAMS = 0x59,
+};
+
+// Storage Command Codes (IPMI/Table H-1)
+enum
+{
+ CMD_STORAGE_GET_FRUID_INFO = 0x10,
+ CMD_STORAGE_READ_FRUID_DATA = 0x11,
+ CMD_STORAGE_GET_SDR_INFO = 0x20,
+ CMD_STORAGE_RSV_SDR = 0x22,
+ CMD_STORAGE_GET_SDR = 0x23,
+ CMD_STORAGE_GET_SEL_INFO = 0x40,
+ CMD_STORAGE_RSV_SEL = 0x42,
+ CMD_STORAGE_GET_SEL = 0x43,
+ CMD_STORAGE_ADD_SEL = 0x44,
+ CMD_STORAGE_CLR_SEL = 0x47,
+ CMD_STORAGE_GET_SEL_TIME = 0x48,
+ CMD_STORAGE_GET_SEL_UTC = 0x5C,
+};
+
+// Sensor Command Codes (IPMI/Table H-1)
+enum
+{
+ CMD_SENSOR_GET_SENSOR_READING = 0x2D,
+};
+
+// Transport Command Codes (IPMI/Table H-1)
+enum
+{
+ CMD_TRANSPORT_SET_LAN_CONFIG = 0x01,
+ CMD_TRANSPORT_GET_LAN_CONFIG = 0x02,
+};
+
+// OEM Command Codes (Quanta/FB defined commands)
+enum
+{
+ CMD_OEM_SET_PROC_INFO = 0x1A,
+ CMD_OEM_SET_DIMM_INFO = 0x1C,
+ CMD_OEM_SET_POST_START = 0x73,
+ CMD_OEM_SET_POST_END = 0x74,
+};
+
+// OEM 1S Command Codes (Quanta/FB defined commands)
+enum
+{
+ CMD_OEM_1S_MSG_IN = 0x1,
+ CMD_OEM_1S_GET_GPIO = 0x3,
+ CMD_OEM_1S_GET_GPIO_CONFIG = 0x5,
+ CMD_OEM_1S_SET_GPIO_CONFIG = 0x6,
+ CMD_OEM_1S_INTR = 0x7,
+ CMD_OEM_1S_POST_BUF = 0x8,
+ CMD_OEM_1S_GET_CONFIG = 0xE,
+ CMD_OEM_1S_PLAT_DISC = 0xF,
+ CMD_OEM_1S_SET_CONFIG = 0x10,
+ CMD_OEM_1S_BIC_RESET = 0x11,
+ CMD_OEM_1S_GET_POST_BUF = 0x12,
+ CMD_OEM_1S_BIC_UPDATE_MODE = 0x13,
+};
+
+
+// IPMI command Completion Codes (IPMI/Section 5.2)
+enum
+{
+ CC_SUCCESS = 0x00,
+ CC_INVALID_PARAM = 0x80,
+ CC_SEL_ERASE_PROG = 0x81,
+ CC_INVALID_CMD = 0xC1,
+ CC_PARAM_OUT_OF_RANGE = 0xC9,
+ CC_UNSPECIFIED_ERROR = 0xFF,
+};
+
+// LAN Configuration parameters (IPMI/Table 23-4)
+enum
+{
+ LAN_PARAM_SET_IN_PROG,
+ LAN_PARAM_AUTH_SUPPORT,
+ LAN_PARAM_AUTH_ENABLES,
+ LAN_PARAM_IP_ADDR,
+ LAN_PARAM_IP_SRC,
+ LAN_PARAM_MAC_ADDR,
+ LAN_PARAM_NET_MASK,
+ LAN_PARAM_IP_HDR,
+ LAN_PARAM_PRI_RMCP_PORT,
+ LAN_PARAM_SEC_RMCP_PORT,
+ LAN_PARAM_ARP_CTRL,
+ LAN_PARAM_GARP_INTERVAL,
+ LAN_PARAM_DF_GW_IP_ADDR,
+ LAN_PARAM_DF_GW_MAC_ADDR,
+ LAN_PARAM_BACK_GW_IP_ADDR,
+ LAN_PARAM_BACK_GW_MAC_ADDR,
+ LAN_PARAM_COMMUNITY_STR,
+ LAN_PARAM_NO_OF_DEST,
+ LAN_PARAM_DEST_TYPE,
+ LAN_PARAM_DEST_ADDR,
+};
+
+// Boot Option Parameters (IPMI/Table 28-14)
+enum
+{
+ PARAM_SET_IN_PROG = 0x00,
+ PARAM_SVC_PART_SELECT,
+ PARAM_SVC_PART_SCAN,
+ PARAM_BOOT_FLAG_CLR,
+ PARAM_BOOT_INFO_ACK,
+ PARAM_BOOT_FLAGS,
+ PARAM_BOOT_INIT_INFO,
+};
+
+//System Info Parameters (IPMI/Table 22-16c)
+enum
+{
+ SYS_INFO_PARAM_SET_IN_PROG,
+ SYS_INFO_PARAM_SYSFW_VER,
+ SYS_INFO_PARAM_SYS_NAME,
+ SYS_INFO_PARAM_PRI_OS_NAME,
+ SYS_INFO_PARAM_PRESENT_OS_NAME,
+ SYS_INFO_PARAM_PRESENT_OS_VER,
+ SYS_INFO_PARAM_BMC_URL,
+ SYS_INFO_PARAM_OS_HV_URL,
+};
+
+// Bridge-IC interface on which this command initiated
+enum
+{
+ BIC_INTF_ME = 0x01,
+ BIC_INTF_SOL = 0x02,
+ BIC_INTF_KCS = 0x03,
+};
+
+void lib_ipmi_handle(unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* __IPMI_H__ */
diff --git a/common/recipes-lib/ipmi/libipmi_0.2.bb b/common/recipes-lib/ipmi/libipmi_0.2.bb
new file mode 100644
index 0000000..c5bca76
--- /dev/null
+++ b/common/recipes-lib/ipmi/libipmi_0.2.bb
@@ -0,0 +1,41 @@
+# Copyright 2014-present Facebook. All Rights Reserved.
+#
+# This program file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program in a file named COPYING; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
+SUMMARY = "IPMI Client Library"
+DESCRIPTION = "library for IPMI Client"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://ipmi.c;beginline=8;endline=20;md5=da35978751a9d71b73679307c4d296ec"
+
+
+SRC_URI = "file://Makefile \
+ file://ipmi.c \
+ file://ipmi.h \
+ "
+
+S = "${WORKDIR}"
+
+do_install() {
+ install -d ${D}${libdir}
+ install -m 0644 libipmi.so ${D}${libdir}/libipmi.so
+
+ install -d ${D}${includedir}/openbmc
+ install -m 0644 ipmi.h ${D}${includedir}/openbmc/ipmi.h
+}
+
+FILES_${PN} = "${libdir}/libipmi.so"
+FILES_${PN}-dev = "${includedir}/openbmc/ipmi.h"
diff --git a/common/recipes-lib/log/files/src/log.h b/common/recipes-lib/log/files/src/log.h
new file mode 100644
index 0000000..a69d69e
--- /dev/null
+++ b/common/recipes-lib/log/files/src/log.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef LOG_H
+#define LOG_H
+
+#include <stdio.h>
+#include <string.h>
+
+//#define DEBUG
+//#define VERBOSE
+
+#define _LOG(dst, fmt, ...) do { \
+ fprintf(dst, "%s:%d " fmt "\n", \
+ __FUNCTION__, __LINE__, ##__VA_ARGS__); \
+ fflush(dst); \
+} while(0)
+
+#define LOG_ERR(err, fmt, ...) do { \
+ char buf[128]; \
+ strerror_r(err, buf, sizeof(buf)); \
+ _LOG(stderr, "ERROR " fmt ": %s", ##__VA_ARGS__, buf); \
+} while(0)
+
+#define LOG_INFO(fmt, ...) do { \
+ _LOG(stdout, fmt, ##__VA_ARGS__); \
+} while(0)
+
+#ifdef DEBUG
+#define LOG_DBG(fmt, ...) do { \
+ _LOG(stdout, fmt, ##__VA_ARGS__); \
+} while(0)
+#else
+#define LOG_DBG(fmt, ...)
+#endif
+
+#ifdef VERBOSE
+#define LOG_VER(fmt, ...) do { \
+ _LOG(stdout, fmt, ##__VA_ARGS__); \
+} while(0)
+#else
+#define LOG_VER(fmt, ...)
+#endif
+
+#endif
diff --git a/common/recipes-lib/log/liblog_0.1.bb b/common/recipes-lib/log/liblog_0.1.bb
new file mode 100644
index 0000000..8034c0d
--- /dev/null
+++ b/common/recipes-lib/log/liblog_0.1.bb
@@ -0,0 +1,36 @@
+# Copyright 2014-present Facebook. All Rights Reserved.
+#
+# This program file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program in a file named COPYING; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+SUMMARY = "Log util functions"
+DESCRIPTION = "some macros to log"
+SECTION = "dev"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://log.h;beginline=4;endline=16;md5=da35978751a9d71b73679307c4d296ec"
+
+SRC_URI += "file://src \
+ "
+
+S = "${WORKDIR}/src"
+
+do_install() {
+ # common lib and include files
+ install -d ${D}${includedir}/openbmc
+ install -m 0644 log.h ${D}${includedir}/openbmc/log.h
+}
+
+FILES_${PN}-dev = "${includedir}/openbmc/log.h"
diff --git a/common/recipes-lib/sdr/files/Makefile b/common/recipes-lib/sdr/files/Makefile
new file mode 100644
index 0000000..11fe3ee
--- /dev/null
+++ b/common/recipes-lib/sdr/files/Makefile
@@ -0,0 +1,11 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+lib: libsdr.so
+
+libsdr.so: sdr.c
+ $(CC) $(CFLAGS) -fPIC -c -o sdr.o sdr.c
+ $(CC) -lm -shared -o libsdr.so sdr.o -lc
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libsdr.so
diff --git a/common/recipes-lib/sdr/files/sdr.c b/common/recipes-lib/sdr/files/sdr.c
new file mode 100644
index 0000000..208b10f
--- /dev/null
+++ b/common/recipes-lib/sdr/files/sdr.c
@@ -0,0 +1,210 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * This file contains code to support IPMI2.0 Specificaton available @
+ * http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-specifications.html
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <math.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <syslog.h>
+#include "sdr.h"
+
+#define FIELD_RATE_UNIT(x) ((x & (0x07 << 3)) >> 3)
+#define FIELD_OP(x) ((x & (0x03 << 1)) >> 1)
+#define FIELD_PERCENTAGE(x) (x & 0x01)
+
+#define FIELD_TYPE(x) ((x & (0x03 << 6)) >> 6)
+#define FIELD_LEN(x) (x & 0xF)
+
+/* Array for BCD Plus definition. */
+const char bcd_plus_array[] = "0123456789 -.XXX";
+
+/* Array for 6-Bit ASCII definition. */
+const char * ascii_6bit[4] = {
+ " !\"#$%&'()*+,-./",
+ "0123456789:;<=>?",
+ "@ABCDEFGHIJKLMNO",
+ "PQRSTUVWXYZ[\\]^_"
+};
+
+/* Get the units of the sensor from the SDR */
+int
+sdr_get_sensor_units(sdr_full_t *sdr, uint8_t *op, uint8_t *modifier,
+ char *units) {
+
+ uint8_t percent;
+ uint8_t rate_idx;
+ uint8_t base_idx;
+
+ /* Bits 5:3 */
+ rate_idx = FIELD_RATE_UNIT(sdr->sensor_units1);
+
+ /* Bits 2:1 */
+ *op = FIELD_OP(sdr->sensor_units1);
+
+ /* Bit 0 */
+ percent = FIELD_PERCENTAGE(sdr->sensor_units1);
+
+ base_idx = sdr->sensor_units2;
+
+ if (*op == 0x0 || *op == 0x3)
+ *modifier = 0;
+ else
+ *modifier = sdr->sensor_units3;
+
+ if (percent) {
+ sprintf(units, "%");
+ } else {
+ if (base_idx > 0 && base_idx <= MAX_SENSOR_BASE_UNIT) {
+ if (rate_idx > 0 && rate_idx < MAX_SENSOR_RATE_UNIT) {
+ sprintf(units, "%s %s", sensor_base_units[base_idx],
+ sensor_rate_units[rate_idx]);
+ } else {
+ sprintf(units, "%s", sensor_base_units[base_idx]);
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+/* Get the name of the sensor from the SDR */
+int
+sdr_get_sensor_name(sdr_full_t *sdr, char *name) {
+ int field_type, field_len;
+ int idx, idx_eff, val;
+ char *str;
+
+ /* Bits 7:6 */
+ field_type = FIELD_TYPE(sdr->str_type_len);
+ /* Bits 4:0 */
+ field_len = FIELD_LEN(sdr->str_type_len) + 1;
+
+ str = sdr->str;
+
+ /* Case: length is zero */
+ if (field_len == 1) {
+ syslog(LOG_ALERT, "get_sensor_name: str length is 0\n");
+ // TODO: Fix this hack later
+ sprintf(name, "%s", str);
+ return -1;
+ }
+
+ /* Retrieve field data depending on the type it was stored. */
+ switch (field_type) {
+ case TYPE_BINARY:
+ /* TODO: Need to add support to read data stored in binary type. */
+ break;
+
+ case TYPE_BCD_PLUS:
+
+ idx = 0;
+ while (idx != field_len) {
+ name[idx] = bcd_plus_array[str[idx] & 0x0F];
+ idx++;
+ }
+ name[idx] = '\0';
+ break;
+
+ case TYPE_ASCII_6BIT:
+
+ idx_eff = idx = 0;
+
+ while (field_len > 0) {
+
+ /* 6-Bits => Bits 5:0 of the first byte */
+ val = str[idx] & 0x3F;
+ name[idx_eff++] = ascii_6bit[(val & 0xF0) >> 4][val & 0x0F];
+ field_len--;
+
+ if (field_len > 0) {
+ /* 6-Bits => Bits 3:0 of second byte + Bits 7:6 of first byte. */
+ val = ((str[idx] & 0xC0) >> 6) |
+ ((str[idx + 1] & 0x0F) << 2);
+ name[idx_eff++] = ascii_6bit[(val & 0xF0) >> 4][val & 0x0F];
+ field_len--;
+ }
+
+ if (field_len > 0) {
+ /* 6-Bits => Bits 1:0 of third byte + Bits 7:4 of second byte. */
+ val = ((str[idx + 1] & 0xF0) >> 4) |
+ ((str[idx + 2] & 0x03) << 4);
+ name[idx_eff++] = ascii_6bit[(val & 0xF0) >> 4][val & 0x0F];
+
+ /* 6-Bits => Bits 7:2 of third byte. */
+ val = ((str[idx + 2] & 0xFC) >> 2);
+ name[idx_eff++] = ascii_6bit[(val & 0xF0) >> 4][val & 0x0F];
+
+ field_len--;
+ idx += 3;
+ }
+ }
+ /* Add Null terminator */
+ name[idx_eff] = '\0';
+ break;
+
+ case TYPE_ASCII_8BIT:
+ snprintf(name, field_len, str);
+ /* Add Null terminator */
+ name[field_len] = '\0';
+ break;
+ }
+
+ return 0;
+}
+
+/* Populates all sensor_info_t struct using the path to SDR dump */
+int
+sdr_init(char *path, sensor_info_t *sinfo) {
+ int fd;
+ uint8_t buf[MAX_SDR_LEN] = {0};
+ uint8_t bytes_rd = 0;
+ uint8_t snr_num = 0;
+ sdr_full_t *sdr;
+
+ while (access(path, F_OK) == -1) {
+ sleep(5);
+ }
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ syslog(LOG_ERR, "sdr_init: open failed for %s\n", path);
+ return -1;
+ }
+
+ while ((bytes_rd = read(fd, buf, sizeof(sdr_full_t))) > 0) {
+ if (bytes_rd != sizeof(sdr_full_t)) {
+ syslog(LOG_ERR, "sdr_init: read returns %d bytes\n", bytes_rd);
+ return -1;
+ }
+
+ sdr = (sdr_full_t *) buf;
+ snr_num = sdr->sensor_num;
+ sinfo[snr_num].valid = true;
+ memcpy(&sinfo[snr_num].sdr, sdr, sizeof(sdr_full_t));
+ }
+
+ return 0;
+}
+
diff --git a/common/recipes-lib/sdr/files/sdr.h b/common/recipes-lib/sdr/files/sdr.h
new file mode 100644
index 0000000..c474fb1
--- /dev/null
+++ b/common/recipes-lib/sdr/files/sdr.h
@@ -0,0 +1,163 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __SDR_H__
+#define __SDR_H__
+
+#include <stdbool.h>
+#include <openbmc/ipmi.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_SDR_LEN 64
+
+
+#define MAX_SENSOR_RATE_UNIT 7
+#define MAX_SENSOR_BASE_UNIT 92
+
+typedef struct _sensor_info_t {
+ bool valid;
+ sdr_full_t sdr;
+} sensor_info_t;
+
+/* List of all the Sensor Rate Units types. */
+const char * sensor_rate_units[] = {
+ "", /* 0x00 */
+ "per \xC2\xB5s", /* 0x01 */
+ "per ms", /* 0x02 */
+ "per s", /* 0x03 */
+ "per min", /* 0x04 */
+ "per hour", /* 0x05 */
+ "per day", /* 0x06 */
+ "reserved", /* 0x07 */
+};
+
+
+/* List of all the Sensor Base Units types. */
+const char * sensor_base_units[] = {
+ "", /* 000 */
+ "C", /* 001 */
+ "F", /* 002 */
+ "K", /* 003 */
+ "Volts", /* 004 */
+ "Amps", /* 005 */
+ "Watts", /* 006 */
+ "Joules", /* 007 */
+ "Coulombs", /* 008 */
+ "VA", /* 009 */
+ "Nits", /* 010 */
+ "lumen", /* 011 */
+ "lux", /* 012 */
+ "Candela", /* 013 */
+ "kPa", /* 014 */
+ "PSI", /* 015 */
+ "Newton", /* 016 */
+ "CFM", /* 017 */
+ "RPM", /* 018 */
+ "Hz", /* 019 */
+ "\xC2\xB5s", /* 020 */
+ "ms", /* 021 */
+ "sec", /* 022 */
+ "min", /* 023 */
+ "hour", /* 024 */
+ "day", /* 025 */
+ "week", /* 026 */
+ "mil", /* 027 */
+ "inches", /* 028 */
+ "feet", /* 029 */
+ "cu in", /* 030 */
+ "cu feet", /* 031 */
+ "mm", /* 032 */
+ "cm", /* 033 */
+ "m", /* 034 */
+ "cu cm", /* 035 */
+ "cu m", /* 036 */
+ "liters", /* 037 */
+ "fluid ounce", /* 038 */
+ "radians", /* 039 */
+ "steradians", /* 040 */
+ "revolutions", /* 041 */
+ "cycles", /* 042 */
+ "gravities", /* 043 */
+ "ounce", /* 044 */
+ "pound", /* 045 */
+ "ft-lb", /* 046 */
+ "oz-in", /* 047 */
+ "gauss", /* 048 */
+ "gilberts", /* 049 */
+ "henry", /* 050 */
+ "millihenry", /* 051 */
+ "farad", /* 052 */
+ "microfarad", /* 053 */
+ "ohms", /* 054 */
+ "siemens", /* 055 */
+ "mole", /* 056 */
+ "becquerel", /* 057 */
+ "PPM", /* 058 */
+ "reserved", /* 059 */
+ "Db", /* 060 */
+ "DbA", /* 061 */
+ "DbC", /* 062 */
+ "gray", /* 063 */
+ "sievert", /* 064 */
+ "color temp deg K", /* 065 */
+ "bit", /* 066 */
+ "kilobit", /* 067 */
+ "megabit", /* 068 */
+ "gigabit", /* 069 */
+ "B", /* 070 */
+ "KB", /* 071 */
+ "MB", /* 072 */
+ "GB", /* 073 */
+ "word", /* 074 */
+ "dword", /* 075 */
+ "qword", /* 076 */
+ "line", /* 077 */
+ "hit", /* 078 */
+ "miss", /* 079 */
+ "retry", /* 080 */
+ "reset", /* 081 */
+ "overflow", /* 082 */
+ "underrun", /* 083 */
+ "collision", /* 084 */
+ "packets", /* 085 */
+ "messages", /* 086 */
+ "characters", /* 087 */
+ "error", /* 088 */
+ "correctable error", /* 089 */
+ "uncorrectable error", /* 090 */
+ "fatal error", /* 091 */
+ "grams", /* 092 */
+ "", /* 093 */
+};
+
+int sdr_init(char *path, sensor_info_t *sinfo);
+
+int sdr_get_sensor_units(sdr_full_t *sdr, uint8_t *op, uint8_t *modifier,
+ char *units);
+int sdr_get_sensor_name(sdr_full_t *sdr, char *name);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* __SDR_H__ */
diff --git a/common/recipes-lib/sdr/libsdr_0.1.bb b/common/recipes-lib/sdr/libsdr_0.1.bb
new file mode 100644
index 0000000..958e0c6
--- /dev/null
+++ b/common/recipes-lib/sdr/libsdr_0.1.bb
@@ -0,0 +1,30 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+SUMMARY = "SDR Library"
+DESCRIPTION = "library for extracting information from SDR"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+
+
+LIC_FILES_CHKSUM = "file://sdr.c;beginline=8;endline=20;md5=da35978751a9d71b73679307c4d296ec"
+
+
+SRC_URI = "file://Makefile \
+ file://sdr.c \
+ file://sdr.h \
+ "
+
+S = "${WORKDIR}"
+
+DEPENDS += " libipmi "
+
+do_install() {
+ install -d ${D}${libdir}
+ install -m 0644 libsdr.so ${D}${libdir}/libsdr.so
+
+ install -d ${D}${includedir}/openbmc
+ install -m 0644 sdr.h ${D}${includedir}/openbmc/sdr.h
+}
+
+FILES_${PN} = "${libdir}/libsdr.so"
+FILES_${PN}-dev = "${includedir}/openbmc/sdr.h"
OpenPOWER on IntegriCloud