[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Freeipmi-devel] New FreeIPMI byte-array/FIID model
From: |
Albert Chu |
Subject: |
Re: [Freeipmi-devel] New FreeIPMI byte-array/FIID model |
Date: |
Thu, 18 Dec 2003 16:18:36 -0800 |
Hey AB,
Cool. I think I need to see more code to fully digest it all, but
overall I think I can visualize how all the code hooks together. Looks
good.
BTW, I finished up coding md2/md5 algorithms. Hopefully we'll have IPMI
MD2/MD5 support soon.
Al
--
Albert Chu
address@hidden
Lawrence Livermore National Laboratory
----- Original Message -----
From: Anand Babu <address@hidden>
Date: Thursday, December 18, 2003 3:49 pm
Subject: [Freeipmi-devel] New FreeIPMI byte-array/FIID model
>
> Just finished byte-array/FIID (FreeIPMI Interface Definition) model.
> Currently porting the rest of the framework to this new interface.
> Tomorrow you will release a copy of bmc-config utility with all the
> required functionalities based on FIID model.
>
> After trying marco pre-processors, lex parsers and complex definition
> formats, Finally got a clean and easy interface to work. This new FIID
> model was jointly developed by Me and Balamurugan. Bala will soon
> be a
> full-time developer for LLNL activities.
>
> FIID Model:
>
> Let us take the most complex packet structure:
>
> typedef struct ipmi_cmd_get_dev_id_rs
> {
> u_int8_t cmd;
> u_int8_t comp_code;
> struct {
> u_int8_t dev_id;
> struct {
> u_int8_t rev:4; /* binary encoded */
> u_int8_t reserved1:3;
> u_int8_t sdr_support:1;
> } dev_rev;
> struct {
> u_int8_t major_rev:7; /* binary encoded */
> u_int8_t dev_available:1;
> } firmware_rev1;
> struct {
> u_int8_t minor_rev; /* BCD encoded */
> } firmware_rev2;
> struct {
> u_int8_t ms_bits:4;
> u_int8_t ls_bits:4;
> } ipmi_ver; /* BCD encoded */
> struct {
> u_int8_t sensor_dev:1;
> u_int8_t sdr_repo_dev:1;
> u_int8_t sel_dev:1;
> u_int8_t fru_inventory_dev:1;
> u_int8_t ipmb_evnt_receiver:1;
> u_int8_t ipmb_evnt_generator:1;
> u_int8_t bridge:1;
> u_int8_t chassis_dev:1;
> } additional_dev_support;
> struct {
> u_int32_t id:20;
> u_int8_t reserved1:4;
> } manf_id;
> u_int16_t prod_id;
> u_int32_t aux_firmware_rev_info;
> } data;
> } ipmi_cmd_get_dev_id_rs_t;
>
> This gets translated to a C array (no need of lex parsers :)
>
> fiid_obj_t fiid_cmd_get_dev_id_rs =
> {
> {8, "cmd"},
> {8, "comp_code"},
> {8, "data.dev_id"},
> {4, "data.dev_rev.rev"}, /* binary encoded */
> {3, "data.dev_rev.reserved1"},
> {1, "data.dev_rev.sdr_support"},
> {7, "data.firmware_rev1.major_rev"},
> {1, "data.firmware_rev1.dev_available"},
> {8, "data.firmware_rev2.minor_rev"}, /* BCD encoded */
> {4, "data.ipmi_ver.ms_bits"},
> {4, "data.ipmi_ver.ls_bits"},
> {1, "data.additional_dev_support.sensor_dev"},
> {1, "data.additional_dev_support.sdr_repo_dev"},
> {1, "data.additional_dev_support.sel_dev"},
> {1, "data.additional_dev_support.fru_inventory_dev"},
> {1, "data.additional_dev_support.ipmb_evnt_receiver"},
> {1, "data.additional_dev_support.ipmb_evnt_generator"},
> {1, "data.additional_dev_support.bridge"},
> {1, "data.additional_dev_support.chassis_dev"},
> {20, "data.manf_id.id"},
> {4, "data.manf_id.reserved1"},
> {16, "data.prod_id"},
> {32, "data.aux_firmware_rev_info"},
> {0, ""}
> };
>
> Then you have FIID calls to work on top of a byte-array using this
> interface definition:
>
> int32_t fiid_obj_len (fiid_obj_t obj);
> int32_t fiid_obj_len_bytes (fiid_obj_t obj);
> int32_t fiid_obj_field_start_end (fiid_obj_t obj, u_int8_t *field,
> u_int32_t *start, u_int32_t *end);
> int32_t fiid_obj_field_start (fiid_obj_t obj, u_int8_t *field);
> int32_t fiid_obj_field_end (fiid_obj_t obj, u_int8_t *field);
> int32_t fiid_obj_field_len (fiid_obj_t obj, u_int8_t *field);
> int32_t fiid_obj_field_len_bytes (fiid_obj_t obj, u_int8_t *field);
> int8_t fiid_obj_set (u_int8_t *bytes, u_int32_t len, fiid_obj_t
> obj, u_int8_t *field, u_int64_t val);
> u_int32_t fiid_obj_get (u_int8_t *bytes, u_int32_t len, fiid_obj_t
> obj, u_int8_t *field, u_int64_t *val);
> int8_t fiid_obj_dump (int fd, fiid_obj_t obj, u_int8_t *data,
> u_int32_t len)
> #define FIID_OBJ_SET(bytes, len, obj, field, val) \
> do { \
> if (fiid_obj_set (bytes, len, obj, field, val) == -1) \
> err (1, "fiid_obj_set (%p, %d, %p, \"%s\", %X) error", \
> bytes, len, obj, field, val); \
> } while (0)
>
> #define FIID_OBJ_GET(bytes, len, obj, field, val) \
> do { \
> if (fiid_obj_get (bytes, len, obj, field, val) == -1) \
> err (1, "fiid_obj_get (%p, %d, %p, \"%s\", %p) error", \
> bytes, len, obj, field, val); \
> } while (0)
>
>
> Most importantly all we care about is get, set, dump and len_bytes.
>
> We also have a whole bunch of bit manipulators.
>
> #define BIT_0 0x01
> #define BIT_1 0x02
> #define BIT_2 0x04
> #define BIT_3 0x08
> #define BIT_4 0x10
> #define BIT_5 0x20
> #define BIT_6 0x40
> #define BIT_7 0x80
> #define BIT(n) ((u_int64_t) powl(2, n))
>
> #define TOBOOL(arg) (!(!(arg)))
> #define BIT_SET(arg, posn) (arg | (1L << posn))
> #define BIT_CLR(arg, posn) (arg & ~(1L << posn))
> #define BIT_FLP(arg, posn) (arg ^ (1L << posn))
> #define BIT_TST(arg, posn) TOBOOL ((arg) & (1L << posn))
>
> #define BITS_ZERO(arg) (arg ^ arg)
> #define BITS_0(arg) (bits_extract (arg, 0 , 8))
> #define BITS_1(arg) (bits_extract (arg, 8, 16))
> #define BITS_2(arg) (bits_extract (arg, 16, 24))
> #define BITS_3(arg) (bits_extract (arg, 24, 33))
> #define BITS_4(arg) (bits_extract (arg, 32, 40))
> #define BITS_5(arg) (bits_extract (arg, 40, 48))
> #define BITS_6(arg) (bits_extract (arg, 48, 56))
> #define BITS_7(arg) (bits_extract (arg, 56, 64))
> #define BITS_SET(arg, bits) (arg | (bits))
> #define BITS_CLR(arg, bits) (arg & ~(bits))
> #define BITS_ROUND_BYTES(bits_count) ((bits_count / 8) +
> ((bits_count % 8) ? 1 : 0))
>
>
> typedef u_int8_t bitstr_t;
> #define _BITSTR_BYTE(bit) \
> #define _BITSTR_MASK(bit) \
> #define BITSTR_SIZE(nbits) \
> #define BITSTR_ALLOC(nbits) \
> #define BITSTR_DECL(name, nbits) \
> #define BITSTR_TEST(name, bit) \
> #define BITSTR_SET(name, bit) \
> #define BITSTR_CLEAR(name, bit) \
> #define BITSTR_NCLEAR(name, start, stop) { \
> #define BITSTR_NSET(name, start, stop) { \
> #define BITSTR_FFC(name, nbits, value) { \
> #define BITSTR_FFS(name, nbits, value) { \
> u_int64_t bits_extract (u_int64_t bits, u_int8_t start, u_int8_t end);
> u_int64_t bits_merge (u_int64_t bits, u_int8_t start, u_int8_t end,
> u_int64_t val);
>
> This new interface seems to work great. All the complex bit level
> manipulations are completely hidden in a portable fashion.
>
> The code seems to shrink a lot now with this new interface.
> Even for dumping the packet, just one generic function will do.
>
> fiid_obj_dump (1, fiid_cmd_get_dev_id_rs, cmd_rs, sizeof(cmd_rs))
> yields
> ================================================================
> [ VALUE TAG NAME:LENGTH ]
> ================================================================
> [ 1h] = cmd[ 8b]
> [ 0h] = comp_code[ 8b]
> [ 20h] = data.dev_id[ 8b]
> [ 1h] = data.dev_rev.rev[ 4b]
> [ 0h] = data.dev_rev.reserved1[ 3b]
> [ 1h] = data.dev_rev.sdr_support[ 1b]
> [ 0h] = data.firmware_rev1.major_rev[ 7b]
> [ 0h] = data.firmware_rev1.dev_available[ 1b]
> [ 20h] = data.firmware_rev2.minor_rev[ 8b]
> [ 1h] = data.ipmi_ver.ms_bits[ 4b]
> [ 5h] = data.ipmi_ver.ls_bits[ 4b]
> [ 1h] = data.additional_dev_support.sensor_dev[ 1b]
> [ 1h] = data.additional_dev_support.sdr_repo_dev[ 1b]
> [ 1h] = data.additional_dev_support.sel_dev[ 1b]
> [ 1h] =
> data.additional_dev_support.fru_inventory_dev[1b][
> 1h] = data.additional_dev_support.ipmb_evnt_receiver[1b]
> [ 0h] =
> data.additional_dev_support.ipmb_evnt_generator[1b][
> 0h] = data.additional_dev_support.bridge[ 1b]
> [ 1h] = data.additional_dev_support.chassis_dev[ 1b]
> [ 157h] = data.manf_id.id[20b]
> [ 0h] = data.manf_id.reserved1[ 4b]
> [ 100h] = data.prod_id[16b]
> [ 20011300h] = data.aux_firmware_rev_info[32b]
> ================================================================
>
> There are simple strategies to handle variable / optional fields in a
> packet, just the we handle them with struct. More later.
>
> I will upload the new FreeIPMI code tomorrow along with bmc-config
> utility.
>
>
> --
> Anand Babu
> CaliforniaDigital.com
> Office# +1-510-687-7045
> Cell# +1-510-396-0717
> Home# +1-510-894-0586
>
> Free as in Freedom <www.gnu.org>
>
>
> _______________________________________________
> Freeipmi-devel mailing list
> address@hidden
> http://mail.nongnu.org/mailman/listinfo/freeipmi-devel
>