All of lore.kernel.org
 help / color / mirror / Atom feed
From: Corey Minyard <cminyard@mvista.com>
To: "Cédric Le Goater" <clg@fr.ibm.com>
Cc: qemu-devel@nongnu.org, "Michael S. Tsirkin" <mst@redhat.com>
Subject: Re: [Qemu-devel] [PATCH 4/8] ipmi: add FRU support
Date: Fri, 8 Jan 2016 13:41:26 -0600	[thread overview]
Message-ID: <569010E6.6080308@mvista.com> (raw)
In-Reply-To: <1452015002-28493-5-git-send-email-clg@fr.ibm.com>

On 01/05/2016 11:29 AM, Cédric Le Goater wrote:
> This patch provides a simplistic FRU support for the IPMI BMC
> simulator.  The FRU area contains 32 entries * 256 bytes which should
> be enough to start some simulation.
>
> Signed-off-by: Cédric Le Goater <clg@fr.ibm.com>
> ---
>   hw/ipmi/ipmi_bmc_sim.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 119 insertions(+)
>
> diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
> index 5db94491b130..60586a67104e 100644
> --- a/hw/ipmi/ipmi_bmc_sim.c
> +++ b/hw/ipmi/ipmi_bmc_sim.c
> @@ -81,6 +81,9 @@
>   #define IPMI_CMD_ENTER_SDR_REP_UPD_MODE   0x2A
>   #define IPMI_CMD_EXIT_SDR_REP_UPD_MODE    0x2B
>   #define IPMI_CMD_RUN_INIT_AGENT           0x2C
> +#define IPMI_CMD_GET_FRU_AREA_INFO        0x10
> +#define IPMI_CMD_READ_FRU_DATA            0x11
> +#define IPMI_CMD_WRITE_FRU_DATA           0x12
>   #define IPMI_CMD_GET_SEL_INFO             0x40
>   #define IPMI_CMD_GET_SEL_ALLOC_INFO       0x41
>   #define IPMI_CMD_RESERVE_SEL              0x42
> @@ -123,6 +126,14 @@ typedef struct IPMISdr {
>       uint8_t overflow;
>   } IPMISdr;
>   
> +/* theoretically, the offset being 16bits, it should be 65536 */
> +#define MAX_FRU_SIZE 256
> +#define MAX_FRU_ID 32
> +
> +typedef struct IPMIFru {
> +    uint8_t data[MAX_FRU_SIZE][MAX_FRU_ID];
> +} IPMIFru;

Instead of a static table like this, I think it would be better to make 
this configurable somehow.  I say this because I've never seen a system 
with 32 FRU devices on a BMC, but I've seen plenty with FRU data larger 
than 256 bytes.  By default, 1 FRU device with 2048 bytes is pretty 
reasonable, I think.

I'm not exactly sure the best way to make it configurable.  I assume 
that you need your platform code to be able to provide that information, 
and it could be passed in as BMC configuration parameters.  The ability 
to load the FRU data at startup is probably also necessary.

-corey

> +
>   typedef struct IPMISensor {
>       uint8_t status;
>       uint8_t reading;
> @@ -206,6 +217,7 @@ struct IPMIBmcSim {
>   
>       IPMISel sel;
>       IPMISdr sdr;
> +    IPMIFru fru;
>       IPMISensor sensors[MAX_SENSORS];
>   
>       /* Odd netfns are for responses, so we only need the even ones. */
> @@ -1305,6 +1317,110 @@ static void get_sel_info(IPMIBmcSim *ibs,
>       return;
>   }
>   
> +static void get_fru_area_info(IPMIBmcSim *ibs,
> +                         uint8_t *cmd, unsigned int cmd_len,
> +                         uint8_t *rsp, unsigned int *rsp_len,
> +                         unsigned int max_rsp_len)
> +{
> +    uint8_t fruid;
> +    uint16_t fru_entry_size;
> +
> +    IPMI_CHECK_CMD_LEN(3);
> +
> +    fruid = cmd[2];
> +
> +    if (fruid > MAX_FRU_ID) {
> +        rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
> +        goto out;
> +    }
> +
> +    fru_entry_size = MAX_FRU_SIZE;
> +
> +    IPMI_ADD_RSP_DATA(fru_entry_size & 0xff);
> +    IPMI_ADD_RSP_DATA(fru_entry_size >> 8 & 0xff);
> +    IPMI_ADD_RSP_DATA(0x0);
> +out:
> +    return;
> +}
> +
> +#define min(x, y) ((x) < (y) ? (x) : (y))
> +#define max(x, y) ((x) > (y) ? (x) : (y))
> +
> +static void read_fru_data(IPMIBmcSim *ibs,
> +                         uint8_t *cmd, unsigned int cmd_len,
> +                         uint8_t *rsp, unsigned int *rsp_len,
> +                         unsigned int max_rsp_len)
> +{
> +    uint8_t fruid;
> +    uint16_t offset;
> +    int i;
> +    uint8_t *fru_entry;
> +    unsigned int count;
> +
> +    IPMI_CHECK_CMD_LEN(5);
> +
> +    fruid = cmd[2];
> +    offset = (cmd[3] | cmd[4] << 8);
> +
> +    if (fruid > MAX_FRU_ID) {
> +        rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
> +        goto out;
> +    }
> +
> +    if (offset >= MAX_FRU_SIZE - 1) {
> +        rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
> +        goto out;
> +    }
> +
> +    fru_entry = ibs->fru.data[fruid];
> +
> +    count = min(cmd[5], MAX_FRU_SIZE - offset);
> +
> +    IPMI_ADD_RSP_DATA(count & 0xff);
> +    for (i = 0; i < count; i++) {
> +        IPMI_ADD_RSP_DATA(fru_entry[offset + i]);
> +    }
> +
> + out:
> +    return;
> +}
> +
> +static void write_fru_data(IPMIBmcSim *ibs,
> +                         uint8_t *cmd, unsigned int cmd_len,
> +                         uint8_t *rsp, unsigned int *rsp_len,
> +                         unsigned int max_rsp_len)
> +{
> +    uint8_t fruid;
> +    uint16_t offset;
> +    uint8_t *fru_entry;
> +    unsigned int count;
> +
> +    IPMI_CHECK_CMD_LEN(5);
> +
> +    fruid = cmd[2];
> +    offset = (cmd[3] | cmd[4] << 8);
> +
> +    if (fruid > MAX_FRU_ID) {
> +        rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
> +        goto out;
> +    }
> +
> +    if (offset >= MAX_FRU_SIZE - 1) {
> +        rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
> +        goto out;
> +    }
> +
> +    fru_entry = ibs->fru.data[fruid];
> +
> +    count = min(cmd_len - 5, MAX_FRU_SIZE - offset);
> +
> +    memcpy(fru_entry + offset, cmd + 5, count);
> +
> +    IPMI_ADD_RSP_DATA(count & 0xff);
> + out:
> +    return;
> +}
> +
>   static void reserve_sel(IPMIBmcSim *ibs,
>                           uint8_t *cmd, unsigned int cmd_len,
>                           uint8_t *rsp, unsigned int *rsp_len,
> @@ -1682,6 +1798,9 @@ static const IPMINetfn app_netfn = {
>   };
>   
>   static const IPMICmdHandler storage_cmds[IPMI_NETFN_STORAGE_MAXCMD] = {
> +    [IPMI_CMD_GET_FRU_AREA_INFO] = get_fru_area_info,
> +    [IPMI_CMD_READ_FRU_DATA] = read_fru_data,
> +    [IPMI_CMD_WRITE_FRU_DATA] = write_fru_data,
>       [IPMI_CMD_GET_SDR_REP_INFO] = get_sdr_rep_info,
>       [IPMI_CMD_RESERVE_SDR_REP] = reserve_sdr_rep,
>       [IPMI_CMD_GET_SDR] = get_sdr,

  reply	other threads:[~2016-01-08 19:41 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-05 17:29 [Qemu-devel] [PATCH 4/8] ipmi: add FRU support Cédric Le Goater
2016-01-08 19:41 ` Corey Minyard [this message]
2016-01-12  7:35   ` Cédric Le Goater

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=569010E6.6080308@mvista.com \
    --to=cminyard@mvista.com \
    --cc=clg@fr.ibm.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.