freeipmi-devel
[Top][All Lists]
Advanced

[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
> 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]