Commit e7d15475 authored by Manohar Vanga's avatar Manohar Vanga

add initial commit for libipmi and fmc_eeprom.py

Signed-off-by: 's avatarManohar Vanga <manohar.vanga@cern.ch>
parent debf0bb2
0000000000000000 00000001
0000000000000001 00000001
0000000000000010 00000000
0000000000000011 00000000
0000000000000100 00000000
0000000000000101 00001010
0000000000000110 00000000
0000000000000111 11110000
0000000000001000 00000001
0000000000001001 00001001
0000000000001010 00000001
0000000000001011 00000010
0000000000001100 01010101
0000000000001101 11000100
0000000000001110 01000011
0000000000001111 01000101
0000000000010000 01010010
0000000000010001 01001110
0000000000010010 11001110
0000000000010011 01000001
0000000000010100 01000100
0000000000010101 01000011
0000000000010110 00100000
0000000000010111 00110010
0000000000011000 00110000
0000000000011001 00110000
0000000000011010 01101011
0000000000011011 00100000
0000000000011100 00110001
0000000000011101 00110110
0000000000011110 01100010
0000000000011111 01101001
0000000000100000 01110100
0000000000100001 00000001
0000000000100010 00000000
0000000000100011 11001101
0000000000100100 01000100
0000000000100101 01100101
0000000000100110 01110011
0000000000100111 01101001
0000000000101000 01110010
0000000000101001 01100101
0000000000101010 01100100
0000000000101011 00100000
0000000000101100 01101001
0000000000101101 01101110
0000000000101110 01110000
0000000000101111 01110101
0000000000110000 01110100
0000000000110001 11001110
0000000000110010 01010101
0000000000110011 01110011
0000000000110100 01100101
0000000000110101 01110010
0000000000110110 00100000
0000000000110111 01100100
0000000000111000 01100101
0000000000111001 01110000
0000000000111010 01100101
0000000000111011 01101110
0000000000111100 01100100
0000000000111101 01100001
0000000000111110 01101110
0000000000111111 01110100
0000000001000000 11001101
0000000001000001 01010101
0000000001000010 01110011
0000000001000011 01100101
0000000001000100 01110010
0000000001000101 01100100
0000000001000110 01100101
0000000001000111 01110000
0000000001001000 01100101
0000000001001001 01101110
0000000001001010 01100100
0000000001001011 01100001
0000000001001100 01101110
0000000001001101 01110100
0000000001001110 11000001
0000000001001111 11110111
0000000001010000 00000010
0000000001010001 00000010
0000000001010010 00001101
0000000001010011 11110011
0000000001010100 11111011
0000000001010101 00000001
0000000001010110 00000000
0000000001010111 00000000
0000000001011000 00000000
0000000001011001 00000000
0000000001011010 00000000
0000000001011011 00000000
0000000001011100 00000000
0000000001011101 00000000
0000000001011110 00000000
0000000001011111 00000000
0000000001100000 00000000
0000000001100001 00000000
0000000001100010 00000010
0000000001100011 00000010
0000000001100100 00001101
0000000001100101 11110011
0000000001100110 11111011
0000000001100111 00000001
0000000001101000 00000000
0000000001101001 00000000
0000000001101010 00000000
0000000001101011 00000000
0000000001101100 00000000
0000000001101101 00000000
0000000001101110 00000000
0000000001101111 00000000
0000000001110000 00000000
0000000001110001 00000000
0000000001110010 00000000
0000000001110011 00000000
0000000001110100 00000010
0000000001110101 00000010
0000000001110110 00001101
0000000001110111 11110011
0000000001111000 11111011
0000000001111001 00000011
0000000001111010 00000000
0000000001111011 00000000
0000000001111100 00000000
0000000001111101 00000000
0000000001111110 00000000
0000000001111111 00000000
0000000010000000 00000000
0000000010000001 00000000
0000000010000010 00000000
0000000010000011 00000000
0000000010000100 00000000
0000000010000101 00000000
0000000010000110 00000001
0000000010000111 00000010
0000000010001000 00001101
0000000010001001 11110011
0000000010001010 11111011
0000000010001011 00000001
0000000010001100 00000000
0000000010001101 00000000
0000000010001110 00000000
0000000010001111 00000000
0000000010010000 00000000
0000000010010001 00000000
0000000010010010 00000000
0000000010010011 00000000
0000000010010100 00000000
0000000010010101 00000000
0000000010010110 00000000
0000000010010111 00000000
0000000010011000 00000001
0000000010011001 00000010
0000000010011010 00001101
0000000010011011 11110011
0000000010011100 11111011
0000000010011101 00000010
0000000010011110 00000000
0000000010011111 00000000
0000000010100000 00000000
0000000010100001 00000000
0000000010100010 00000000
0000000010100011 00000000
0000000010100100 00000000
0000000010100101 00000000
0000000010100110 00000000
0000000010100111 00000000
0000000010101000 00000000
0000000010101001 00000000
0000000010101010 00000001
0000000010101011 00000010
0000000010101100 00001101
0000000010101101 11110011
0000000010101110 11111011
0000000010101111 00000001
0000000010110000 00000000
0000000010110001 00000000
0000000010110010 00000000
0000000010110011 00000000
0000000010110100 00000000
0000000010110101 00000000
0000000010110110 00000000
0000000010110111 00000000
0000000010111000 00000000
0000000010111001 00000000
0000000010111010 00000000
0000000010111011 00000000
0000000010111100 11111111
0000000010111101 00000010
0000000010111110 00001000
0000000010111111 11111000
0000000011000000 11111011
0000000011000001 00000000
0000000011000010 00000000
0000000011000011 00000000
0000000011000100 00000000
0000000011000101 00000000
0000000011000110 00000000
0000000011000111 00000000
0000000011001000 00000000
#!/usr/bin/python
from ctypes import *
lib = cdll.LoadLibrary("libipmi/libipmi.so")
class c_CommonHeader(Structure):
_fields_ = [
("format", c_ubyte),
("internal_use_off", c_ubyte),
("chassis_info_off", c_ubyte),
("board_area_off", c_ubyte),
("product_area_off", c_ubyte),
("multirecord_off", c_ubyte),
("pad", c_ubyte),
("checksum", c_ubyte)
]
class c_BoardInfoArea(Structure):
_fields_ = [
("format", c_ubyte),
("area_len", c_ubyte),
("language", c_ubyte),
("mfg_date0", c_ubyte),
("mfg_date1", c_ubyte),
("mfg_date2", c_ubyte),
("mfgr_typelen", c_ubyte),
("mfgr_data", c_char_p),
("product_typelen", c_ubyte),
("product_data", c_char_p),
("serial_typelen", c_ubyte),
("serial_data", c_char_p),
("partnum_typelen", c_ubyte),
("partnum_data", c_char_p),
("fru_fid_typelen", c_ubyte),
("fru_fid_data", c_char_p),
("typelen_end", c_ubyte),
("pad_len", c_ubyte),
("checksum", c_ubyte),
]
class c_DCLoadRecord(Structure):
_fields_ = [
("voltage_required", c_ubyte),
("nominal_voltage", c_ushort),
("min_voltage", c_ushort),
("max_voltage", c_ushort),
("spec_ripple", c_ushort),
("min_current", c_ushort),
("max_current", c_ushort),
]
class c_DCOutputRecord(Structure):
_fields_ = [
("output_info", c_ubyte),
("nominal_voltage", c_ushort),
("max_neg_voltage_dev", c_ushort),
("max_pos_voltage_dev", c_ushort),
("ripple", c_ushort),
("min_current_draw", c_ushort),
("max_current_draw", c_ushort),
]
class CommonHeader:
def __init__(self):
self.struct = c_CommonHeader()
self._as_parameter_ = byref(self.struct)
self.struct.format = 0x1
self.struct.chassis_info_off = 0
self.struct.product_area_off = 0
self.struct.pad = 0
def set_internal_use_offset(self, off):
self.struct.internal_use_off = off
def set_board_info_area_offset(self, off):
self.struct.board_area_off = off
def set_multirecord_area_offset(self, off):
self.multirecord_off = off
class BoardInfoArea:
def __init__(self):
self.struct = c_BoardInfoArea()
self._as_parameter_ = byref(self.struct)
self.struct.format = 0x1
self.struct.area_len = 25 # English
self.struct.language = 0
def set_manufacturer(self, data):
self.struct.mfgr_data = c_char_p(data)
self.struct.mfgr_typelen = (len(bytearray(data)) & 0x1f) | (0x3 << 6)
def set_product(self, data):
self.struct.product_data = c_char_p(data)
self.struct.product_typelen = (len(bytearray(data)) & 0x1f) | (0x3 << 6)
def set_serial_number(self, data):
self.struct.serial_data = c_char_p(data)
self.struct.serial_typelen = (len(bytearray(data)) & 0x1f) | (0x3 << 6)
def set_part_number(self, data):
self.struct.partnum_data = c_char_p(data)
self.struct.partnum_typelen = (len(bytearray(data)) & 0x1f) | (0x3 << 6)
def set_fru_file_id(self, data):
self.struct.fru_fid_data = c_char_p(data)
self.struct.fru_fid_typelen = (len(bytearray(data)) & 0x1f) | (0x3 << 6)
class DCLoadRecord:
def __init__(self):
self.struct = c_DCLoadRecord()
self._as_parameter_ = byref(self.struct)
self.struct.voltage_required = 0
self.struct.nominal_voltage = 0
self.struct.min_voltage = 0
self.struct.max_voltage = 0
self.struct.spec_ripple = 0
self.struct.min_current = 0
self.struct.max_current = 0
def set_voltage_required(self, val):
self.struct.voltage_required = val
def set_nominal_voltage(self, val):
self.struct.nominal_voltage = val
def set_min_voltage(self, val):
self.struct.min_voltage = val
def set_max_voltage(self, val):
self.struct.max_voltage = val
def set_spec_ripple(self, val):
self.struct.spec_ripple = val
def set_min_current(self, val):
self.struct.min_current = val
def set_max_current(self, val):
self.struct.max_current = val
class DCOutputRecord:
def __init__(self):
self.struct = c_DCOutputRecord()
self._as_parameter_ = byref(self.struct)
self.struct.output_info = 0
self.struct.nominal_voltage = 0
self.struct.max_net_voltage_dev = 0
self.struct.max_pos_voltage_dev = 0
self.struct.ripple = 0
self.struct.min_current_draw = 0
self.struct.max_current_draw = 0
def set_output_info(self, val):
self.struct.output_info = val
def set_nominal_voltage(self, val):
self.struct.nominal_voltage = val
def set_max_negative_voltage_deviation(self, val):
self.struct.max_neg_voltage_dev = val
def set_max_positive_voltage_deviation(self, val):
self.struct.max_pos_voltage_dev = val
def set_ripple(self, val):
self.struct.ripple = val
def set_min_current_draw(self, val):
self.struct.min_current_draw = val
def set_max_current_draw(self, val):
self.struct.max_current_draw = val
class c_FMCOEMData(Structure):
_fields_ = [
("subtype_version", c_ubyte),
("other", c_ubyte),
("p1_a_nsig", c_ubyte),
("p1_b_nsig", c_ubyte),
("p2_a_nsig", c_ubyte),
("p2_b_nsig", c_ubyte),
("p1_gbt_ntran", c_ubyte),
("p2_gbt_ntran", c_ubyte),
("max_clock", c_ubyte),
]
class c_OEMRecord(Structure):
_fields_ = [
("mfg_id0", c_ubyte),
("mfg_id1", c_ubyte),
("mfg_id2", c_ubyte),
("data", c_FMCOEMData),
]
class OEMRecord:
def __init__(self):
self.struct = c_OEMRecord()
self._as_parameter_ = byref(self.struct)
self.struct.data.subtype_version = 0
self.struct.data.other = 0
self.struct.data.p1_a_nsig = 0
self.struct.data.p1_b_nsig = 0
self.struct.data.p2_a_nsig = 0
self.struct.data.p2_b_nsig = 0
self.struct.data.p1_gbt_ntran = 0
self.struct.data.p2_gbt_ntran = 0
self.struct.data.max_clock = 0
def set_module_size(self, val):
self.struct.data.other &= ~(0x3)
self.struct.data.other |= val & 0x3
def set_p1_connector_size(self, val):
self.struct.data.other &= ~(0xc)
self.struct.data.other |= (val << 2) & 0xc
def set_p2_connector_size(self, val):
self.struct.data.other &= ~(0x30)
self.struct.data.other |= (val << 4) & 0x30
def set_clock_direction(self, val):
self.struct.data.other |= (val & 0x1) << 4
def set_nsignals(self, port, bank, num):
if (port == 1):
if (bank == 1):
self.struct.data.p1_a_nsig = num
elif (bank == 2):
self.struct.data.p1_b_nsig = num
elif (port == 2):
if (bank == 1):
self.struct.data.p2_a_nsig = num
elif (bank == 2):
self.struct.data.p2_b_nsig = num
def set_num_gbt_transceivers(self, port, num):
if (port == 1):
self.struct.data.p1_gbt_ntran = num
elif (port == 2):
self.struct.data.p2_gbt_ntran = num
def set_max_clock(self, clock):
self.struct.data.max_clock = clock
def ipmi_open_file(name):
lib.ipmi_file_open(c_char_p(name))
def ipmi_close_file():
lib.ipmi_file_close()
def ipmi_set(bia, dcload, dcout, oem):
lib.ipmi_set_board_info_area(bia)
lib.ipmi_set_dc_load_record(dcload)
lib.ipmi_set_dc_output_record(dcout)
lib.ipmi_set_oem_record(oem)
def ipmi_write():
lib.ipmi_write()
def main():
bia = BoardInfoArea()
# Set Board Info Area stuff here
bia.set_manufacturer("CERN")
dcload = DCLoadRecord()
# Set DC Load information here
dcout = DCOutputRecord()
# Set DC Output information here
oem = OEMRecord()
# Set OEM record information here
# Open, set, write, close!
ipmi_open_file("test.out")
ipmi_set(bia, dcload, dcout, oem)
ipmi_write()
ipmi_close_file()
if __name__ == "__main__":
main()
OBJ=ipmi.o
OUT=libipmi.a
OUT_SO=libipmi.so
CFLAGS+=-fPIC -shared -Wall -Wextra
all: $(OUT) $(OUT_SO)
$(OUT): $(OBJ)
ar rcs $(OUT) $(OBJ)
$(OUT_SO): $(OBJ)
$(CC) $< $(CFLAGS) -shared -fPIC -L. -Wl,-soname,$@ -o $@
clean:
rm -rf $(OBJ) $(OUT) $(OUT_SO)
#include "ipmi.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static FILE *f = NULL;
struct common_header *ch;
struct board_info_area *bia;
struct dc_load_record *dcl;
struct dc_output_record *dco;
struct oem_record *oem;
int ipmi_file_open(const char *name)
{
if (f)
fclose(f);
f = fopen(name, "w");
if (!f)
return -1;
return 0;
}
void ipmi_file_close(void)
{
if (f)
fclose(f);
}
uint8_t checksum(uint8_t *data, int len)
{
int i;
int sum = 0;
for (i = 0; i < len; i++)
sum += data[i];
return (-sum)&0xff;
}
int ipmi_common_header_write(void)
{
int ret;
if (!ch || !f)
return -1;
ch->checksum = checksum((uint8_t *)ch, sizeof(struct common_header) - 1);
ret = fwrite(ch, 1, sizeof(struct common_header), f);
return 0;
}
void ipmi_set_board_info_area(struct board_info_area *d)
{
bia = d;
}
void ipmi_set_dc_load_record(struct dc_load_record *d)
{
dcl = d;
}
void ipmi_set_dc_output_record(struct dc_output_record *d)
{
dco = d;
}
void ipmi_set_oem_record(struct oem_record *d)
{
oem = d;
}
int ipmi_board_info_area_write(void)
{
int i;
int len;
int sum;
int ret;
uint8_t pad = 0;
uint8_t checksum;
if (!bia || !f)
return -1;
/* Write upto the mfgr_data */
ret = fwrite(bia, 1, 6, f);
len = bia->mfgr_typelen & 0x1f;
ret = fwrite(&bia->mfgr_typelen, 1, sizeof(uint8_t), f);
ret = fwrite(bia->mfgr_data, len, 1, f);
len = bia->product_typelen & 0x1f;
ret = fwrite(&bia->product_typelen, 1, sizeof(uint8_t), f);
ret = fwrite(bia->product_data, len, 1, f);
len = bia->serial_typelen & 0x1f;
ret = fwrite(&bia->serial_typelen, 1, sizeof(uint8_t), f);
ret = fwrite(bia->serial_data, len, 1, f);
len = bia->partnum_typelen & 0x1f;
ret = fwrite(&bia->product_typelen, 1, sizeof(uint8_t), f);
ret = fwrite(bia->partnum_data, len, 1, f);
len = bia->fru_fid_typelen & 0x1f;
ret = fwrite(&bia->fru_fid_typelen, 1, sizeof(uint8_t), f);
ret = fwrite(bia->fru_fid_data, len, 1, f);
ret = fwrite(&bia->typelen_end, 1, sizeof(uint8_t), f);
for (i = 0; i < bia->pad_len; i++)
ret = fwrite(&pad, 1, sizeof(pad), f);
/* calculate checksum here */
checksum = 0;
checksum +=
bia->format +
bia->area_len +
bia->language +
bia->mfg_date0 +
bia->mfg_date1 +
bia->mfg_date2 +
bia->mfgr_typelen +
bia->product_typelen +
bia->serial_typelen +
bia->partnum_typelen +
bia->fru_fid_typelen +
bia->typelen_end;
for (i = 0; i < (bia->mfgr_typelen & 0x1f); i++)
checksum += bia->mfgr_data[i];
for (i = 0; i < (bia->product_typelen & 0x1f); i++)
checksum += bia->product_data[i];
for (i = 0; i < (bia->serial_typelen & 0x1f); i++)
checksum += bia->serial_data[i];
for (i = 0; i < (bia->partnum_typelen & 0x1f); i++)
checksum += bia->partnum_data[i];
for (i = 0; i < (bia->fru_fid_typelen & 0x1f); i++)
checksum += bia->fru_fid_data[i];
checksum = -checksum;
checksum &= 0xff;
bia->checksum = checksum;
ret = fwrite(&bia->checksum, 1, sizeof(uint8_t), f);
return 0;
}
int ipmi_dc_load_record_write(int end)
{
int ret;
struct multirecord_header head;
if (!dcl || !f)
return -1;
head.record_typeid = 0x2; /* DC load type */
head.extra = 0x2;
if (end)
head.extra |= (1 << 7);
head.record_len = sizeof(struct dc_load_record);
head.record_checksum = checksum((uint8_t *)dcl,
sizeof(struct dc_load_record));
head.header_checksum = checksum((uint8_t *)&head,
sizeof(struct multirecord_header) - 1);
ret = fwrite(&head, 1, sizeof(struct multirecord_header), f);
ret = fwrite(dcl, 1, sizeof(struct dc_load_record), f);
return 0;
}
int ipmi_dc_output_record_write(int end)
{
int ret;
struct multirecord_header head;
if (!dco || !f)
return -1;
head.record_typeid = 0x1; /* DC output type */
head.extra = 0x2;
if (end)
head.extra |= (1 << 7);
head.record_len = sizeof(struct dc_output_record);
head.record_checksum = checksum((uint8_t *)dco,
sizeof(struct dc_output_record));
head.header_checksum = checksum((uint8_t *)&head,
sizeof(struct multirecord_header) - 1);
ret = fwrite(&head, 1, sizeof(struct multirecord_header), f);
ret = fwrite(dco, 1, sizeof(struct dc_output_record), f);
return 0;
}
int ipmi_oem_record_write(int end)
{
int ret;
struct multirecord_header head;
if (!oem || !f)
return -1;
/* VITA ID: 0x0012a2 */
oem->mfg_id0 = 0x00;
oem->mfg_id1 = 0x12;
oem->mfg_id2 = 0xa2;
head.record_typeid = 0xfa; /* OEM record type */
head.extra = 0x2;
if (end)
head.extra |= (1 << 7);
head.record_len = sizeof(struct oem_record);
head.record_checksum = checksum((uint8_t *)oem,
sizeof(struct oem_record));
head.header_checksum = checksum((uint8_t *)&head,
sizeof(struct multirecord_header) - 1);
ret = fwrite(&head, 1, sizeof(struct multirecord_header), f);
ret = fwrite(oem, 1, sizeof(struct oem_record), f);
return 0;
}
int ipmi_write(void)
{
ch = malloc(sizeof(struct common_header));
memset(ch, 0, sizeof(struct common_header));
ipmi_common_header_write();
ipmi_board_info_area_write();
ipmi_dc_load_record_write(0);
ipmi_dc_output_record_write(0);
ipmi_oem_record_write(1);
return 0;
}
#ifndef IPMI_H
#define IPMI_H
#include <stdint.h>
#include <stdio.h>
/* 8 bytes */
struct common_header {
uint8_t format;
uint8_t internal_use_off;
uint8_t chassis_info_off;
uint8_t board_area_off;
uint8_t product_area_off;
uint8_t multirecord_off;
uint8_t pad;
uint8_t checksum;
};
struct board_info_area {
uint8_t format;
uint8_t area_len;
uint8_t language;
uint8_t mfg_date0;
uint8_t mfg_date1;
uint8_t mfg_date2;
uint8_t mfgr_typelen;
uint8_t *mfgr_data;
uint8_t product_typelen;
uint8_t *product_data;
uint8_t serial_typelen;
uint8_t *serial_data;
uint8_t partnum_typelen;
uint8_t *partnum_data;
uint8_t fru_fid_typelen;
uint8_t *fru_fid_data;
/* uint8_t *custom; */
uint8_t typelen_end;
uint8_t pad_len;
uint8_t checksum;
};
/* 5 bytes */
struct multirecord_header {
uint8_t record_typeid;
uint8_t extra;
uint8_t record_len;
uint8_t record_checksum;
uint8_t header_checksum;
};
/* 13 bytes */
struct dc_load_record {
uint8_t voltage_required;
uint16_t nominal_voltage;
uint16_t min_voltage;
uint16_t max_voltage;
uint16_t spec_ripple;
uint16_t min_current;
uint16_t max_current;
};
/* 13 bytes */
struct dc_output_record {
uint8_t output_info;
uint16_t nominal_voltage;
uint16_t max_neg_voltage_dev;
uint16_t max_pos_voltage_dev;
uint16_t ripple;
uint16_t min_current_draw;
uint16_t max_current_draw;
};
struct fmc_oem_data {
uint8_t subtype_version;
uint8_t other;
uint8_t p1_a_nsig;
uint8_t p1_b_nsig;
uint8_t p2_a_nsig;
uint8_t p2_b_nsig;
uint8_t p1_gbt_ntran;
uint8_t p2_gbt_ntran;
uint8_t max_clock;
};
/* 12 bytes */
struct oem_record {
uint8_t mfg_id0;
uint8_t mfg_id1;
uint8_t mfg_id2;
struct fmc_oem_data data;
};
int ipmi_file_open(const char *name);
void ipmi_file_close(void);
int ipmi_write(void);
int ipmi_common_header_write(void);
void ipmi_set_board_info_area(struct board_info_area *);
int ipmi_board_info_area_write(void);
void ipmi_set_dc_load_record(struct dc_load_record *);
int ipmi_dc_load_record_write(int);
void ipmi_set_dc_output_record(struct dc_output_record *);
int ipmi_dc_output_record_write(int);
void ipmi_set_oem_record(struct oem_record *);
int ipmi_oem_record_write(int);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment