qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 7/8] ipmi: introduce an ipmi_bmc_init_sensor() API


From: Cédric Le Goater
Subject: [Qemu-devel] [PATCH 7/8] ipmi: introduce an ipmi_bmc_init_sensor() API
Date: Tue, 5 Jan 2016 18:30:01 +0100

This routine will let qemu platforms populate the sdr/sensor tables of
the IPMI BMC simulator with their customs needs.

The patch adds a compact sensor record typedef to ease definition of
sdrs. To be used in the code the following way:

    static ipmi_sdr_compact_buffer my_init_sdrs[] = {
        {   /* Firmware Progress Sensor */
            0xff, 0xff, 0x51, 0x02,   43, 0x20, 0x00, 0xff,
            0x22, 0x00, 0xff, 0x40, 0x0f, 0x6f, 0x07, 0x00,
            0x00, 0x00, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x01,
            0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0,
            'F',  'W',  ' ',  'B',  'o',  'o',  't',  ' ',
            'P',  'r',  'o',  'g',  'r',  'e',  's',  's',
        },
        ...
    };

    struct ipmi_sdr_compact *sdr =
           (struct ipmi_sdr_compact *) &my_init_sdrs[0];

    ipmi_bmc_init_sensor(IPMI_BMC(obj), my_init_sdrs[0],
                     sdr->rec_length + 5, &sdr->sensor_owner_number);

Signed-off-by: Cédric Le Goater <address@hidden>
---
 hw/ipmi/ipmi_bmc_sim.c | 61 +++++++++++++++++++++++++++++++++++++++++---------
 include/hw/ipmi/ipmi.h | 37 ++++++++++++++++++++++++++++++
 2 files changed, 87 insertions(+), 11 deletions(-)

diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
index 4f7c74da4b6b..9618db44ce69 100644
--- a/hw/ipmi/ipmi_bmc_sim.c
+++ b/hw/ipmi/ipmi_bmc_sim.c
@@ -527,6 +527,22 @@ static void sensor_set_discrete_bit(IPMIBmcSim *ibs, 
unsigned int sensor,
     }
 }
 
+static void ipmi_init_sensor(IPMISensor *sens, const uint8_t *sdr)
+{
+    IPMI_SENSOR_SET_PRESENT(sens, 1);
+    IPMI_SENSOR_SET_SCAN_ON(sens, (sdr[10] >> 6) & 1);
+    IPMI_SENSOR_SET_EVENTS_ON(sens, (sdr[10] >> 5) & 1);
+    sens->assert_suppt = sdr[14] | (sdr[15] << 8);
+    sens->deassert_suppt = sdr[16] | (sdr[17] << 8);
+    sens->states_suppt = sdr[18] | (sdr[19] << 8);
+    sens->sensor_type = sdr[12];
+    sens->evt_reading_type_code = sdr[13] & 0x7f;
+
+    /* Enable all the events that are supported. */
+    sens->assert_enable = sens->assert_suppt;
+    sens->deassert_enable = sens->deassert_suppt;
+}
+
 static void ipmi_init_sensors_from_sdrs(IPMIBmcSim *s)
 {
     unsigned int i, pos;
@@ -553,19 +569,42 @@ static void ipmi_init_sensors_from_sdrs(IPMIBmcSim *s)
         }
         sens = s->sensors + sdr[7];
 
-        IPMI_SENSOR_SET_PRESENT(sens, 1);
-        IPMI_SENSOR_SET_SCAN_ON(sens, (sdr[10] >> 6) & 1);
-        IPMI_SENSOR_SET_EVENTS_ON(sens, (sdr[10] >> 5) & 1);
-        sens->assert_suppt = sdr[14] | (sdr[15] << 8);
-        sens->deassert_suppt = sdr[16] | (sdr[17] << 8);
-        sens->states_suppt = sdr[18] | (sdr[19] << 8);
-        sens->sensor_type = sdr[12];
-        sens->evt_reading_type_code = sdr[13] & 0x7f;
+        ipmi_init_sensor(sens, sdr);
+    }
+}
+
+int ipmi_bmc_init_sensor(IPMIBmc *b, const uint8_t *sdr,
+                         unsigned int len, uint8_t *sensor_num)
+{
+    IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b);
+    int ret;
+    unsigned int i;
+    IPMISensor *sens;
 
-        /* Enable all the events that are supported. */
-        sens->assert_enable = sens->assert_suppt;
-        sens->deassert_enable = sens->deassert_suppt;
+    for (i = 0; i < MAX_SENSORS; i++) {
+        sens = ibs->sensors + i;
+        if (!IPMI_SENSOR_GET_PRESENT(sens)) {
+            break;
+        }
+    }
+
+    if (i == MAX_SENSORS) {
+        return 1;
     }
+
+    ret = sdr_add_entry(ibs, sdr, len, NULL);
+    if (ret) {
+        return ret;
+    }
+
+    ipmi_init_sensor(sens, sdr);
+    if (sensor_num) {
+        *sensor_num = i;
+    }
+
+    /* patch sensor in sdr table. This is a little hacky. */
+    ibs->sdr.sdr[ibs->sdr.next_free - len + 7] = i;
+    return 0;
 }
 
 static int ipmi_register_netfn(IPMIBmcSim *s, unsigned int netfn,
diff --git a/include/hw/ipmi/ipmi.h b/include/hw/ipmi/ipmi.h
index 32bac0fa8877..ce1f539754be 100644
--- a/include/hw/ipmi/ipmi.h
+++ b/include/hw/ipmi/ipmi.h
@@ -210,4 +210,41 @@ IPMIFwInfo *ipmi_next_fwinfo(IPMIFwInfo *current);
 #define ipmi_debug(fs, ...)
 #endif
 
+/*
+ * 43.2 SDR Type 02h. Compact Sensor Record
+ */
+struct ipmi_sdr_compact {
+    uint16_t rec_id;
+    uint8_t  sdr_version;               /* 0x51 */
+    uint8_t  rec_type;                  /* 0x02 Compact Sensor Record */
+    uint8_t  rec_length;
+    uint8_t  sensor_owner_id;
+    uint8_t  sensor_owner_lun;
+    uint8_t  sensor_owner_number;       /* byte 8 */
+    uint8_t  entity_id;
+    uint8_t  entity_instance;
+    uint8_t  sensor_init;
+    uint8_t  sensor_caps;
+    uint8_t  sensor_type;
+    uint8_t  reading_type;
+    uint8_t  assert_mask[2];            /* byte 16 */
+    uint8_t  deassert_mask[2];
+    uint8_t  discrete_mask[2];
+    uint8_t  sensor_unit1;
+    uint8_t  sensor_unit2;
+    uint8_t  sensor_unit3;
+    uint8_t  sensor_direction[2];       /* byte 24 */
+    uint8_t  positive_threshold;
+    uint8_t  negative_threshold;
+    uint8_t  reserved[3];
+    uint8_t  oem;
+    uint8_t  id_str_len;                /* byte 32 */
+    uint8_t  id_string[16];
+};
+
+typedef uint8_t ipmi_sdr_compact_buffer[sizeof(struct ipmi_sdr_compact)];
+
+int ipmi_bmc_init_sensor(IPMIBmc *b, const uint8_t *entry,
+                         unsigned int len, uint8_t *sensor_num);
+
 #endif
-- 
2.1.4




reply via email to

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