blob: c83b019eb00808b1280aa6832320aa7dd2d95b92 [file] [log] [blame]
Andrew Geissler62864f62015-02-27 14:49:28 -06001From d8c341b72aad30bff1417f1a2cec82af9cc14786 Mon Sep 17 00:00:00 2001
2From: Richard J. Knight <rjknight@us.ibm.com>
3Date: Thu, 19 Feb 2015 23:47:03 -0600
4Subject: [PATCH 2/5] Update dev tree with additional sensor information
5
6 -Add sensor type, reading type and specific offsets.
7 -Add IPMI entity ID and instance information for sensors
8 -Include IPMI Enity instance in targets which have ipmi sensors
9 attribute
10
11Change-Id: I02b0a5046c67e2e00af30a0c78cbcc182ae4c0cd
12RTC:123186
13(cherry picked from commit ff8c81ac1ab76d9835165a8dae4a0e3b1e5a0055)
14---
15 src/include/usr/ipmi/ipmisensor.H | 96 ++++++++++++++++++++
16 src/usr/devtree/bld_devtree.C | 89 ++++++++++++++-----
17 src/usr/ipmi/ipmisensor.C | 76 ++++++++++++++++
18 src/usr/targeting/common/Targets.pm | 2 +-
19 .../common/xmltohb/attribute_types_hb.xml | 73 +++++++++++++++
20 .../targeting/common/xmltohb/target_types_hb.xml | 12 ++-
21 6 files changed, 322 insertions(+), 26 deletions(-)
22
23diff --git a/src/include/usr/ipmi/ipmisensor.H b/src/include/usr/ipmi/ipmisensor.H
24index 7b4e3fa..ef00bfa 100644
25--- a/src/include/usr/ipmi/ipmisensor.H
26+++ b/src/include/usr/ipmi/ipmisensor.H
27@@ -48,6 +48,20 @@ namespace SENSOR
28 const uint8_t INVALID_TYPE = 0xFF;
29
30 /**
31+ * @enum sensorReadingTypes
32+ * Sensor specific completion codes, defined in IPMI Spec.
33+ *
34+ */
35+ enum sensorReadingType
36+ {
37+ THRESHOLD = 0x01,
38+ DIGITAL_ASSERT_DEASSERT = 0x03,
39+ DIGITAL_ENABLE_DISABLE = 0x09,
40+ SENSOR_SPECIFIC = 0x6f,
41+ };
42+
43+
44+ /**
45 * @enum procStatusSensorOffsets
46 * Sensor specific completion codes, defined in IPMI Spec.
47 *
48@@ -90,6 +104,74 @@ namespace SENSOR
49 CRITICAL_OVER_TEMP = 0x0A,
50 };
51
52+ /**
53+ * @enum firmwareBootProgressSensorOffsets
54+ * Boot progress specific offsets defined in IPMI Spec.
55+ *
56+ */
57+ enum firmwareProgressSensorOffsets
58+ {
59+ // offset 02h
60+ SYSTEM_FIRMWARE_PROGRESS = 0x02,
61+ };
62+
63+ /**
64+ * @enum discrete09_Offsets
65+ *
66+ * Offsets specific to IPMI sensor reading type 09
67+ * digital discrete senosrs. These offsets result in
68+ * Device Enabled or Device Disabled events in the
69+ * BMC event log.
70+ *
71+ */
72+ enum discrete09_Offsets
73+ {
74+ // offset 00h
75+ DEVICE_DISABLED = 0x0,
76+
77+ //offset 01h
78+ DEVICE_ENABLED = 0x1,
79+ };
80+
81+ /**
82+ * @enum discrete03_Offsets
83+ *
84+ * Offsets specific to IPMI sensor reading type 03
85+ * digital discrete senosrs. These offsets result in generic
86+ * State Asserted or State Deasserted events in the
87+ * BMC event log.
88+ *
89+ */
90+ enum discrete03_Offsets
91+ {
92+ // offset 00h
93+ DEASSERTED = 0x00,
94+
95+ //offset 01h
96+ ASSERTED = 0x01,
97+ };
98+
99+ /**
100+ * @enum acpiPowerState_Offsets
101+ *
102+ * Offsets specific to IPMI ACPI Power state
103+ * senosrs. These offsets result in power
104+ * state messages in the BMC event log.
105+ *
106+ */
107+ enum acpiPowerState_Offsets
108+ {
109+ // offset 0h
110+ S0_G0_WORKING = 0x00,
111+
112+ // offset 05h
113+ G5_SOFT_OFF = 0x05,
114+
115+ //offset 0Bh
116+ LEGACY_ON = 0x0B,
117+
118+ };
119+
120 //** Bit definition for set sensor reading cmd operation field
121 // [7:6] 10b - write given values to event data bytes let BMC handle
122 // offset in event data 1 when an external event is
123@@ -827,6 +909,20 @@ namespace SENSOR
124 errlHndl_t getAPSSChannelSensorNumbers(
125 const uint16_t (* &o_sensor_numbers)[16]);
126
127+ /**
128+ * Helper function to return a mask of the supported masks for the
129+ * sensor passed in.
130+ *
131+ * @param[i] - sensor name to determine the offset for.
132+ * @param[o] - sensor reading type, defined in IPMI spec for the
133+ * passed in sensor number.
134+ *
135+ *
136+ * @return sensor offsets
137+ */
138+ uint16_t getSensorOffsets(TARGETING::SENSOR_NAME i_name,
139+ sensorReadingType &o_readType );
140+
141
142
143 }; // end namespace
144diff --git a/src/usr/devtree/bld_devtree.C b/src/usr/devtree/bld_devtree.C
145index dd81392..f4647a3 100644
146--- a/src/usr/devtree/bld_devtree.C
147+++ b/src/usr/devtree/bld_devtree.C
148@@ -1299,17 +1299,40 @@ errlHndl_t bld_fdt_mem(devTree * i_dt, bool i_smallTree)
149 return errhdl;
150 }
151
152+
153+#ifdef CONFIG_BMC_IPMI
154+enum
155+{
156+ ENTITY_ID_MASK = 0x00FF,
157+ SENSOR_TYPE_MASK = 0xFF00,
158+};
159+
160 /* create a node for each IPMI sensor in the system, the sensor unit number
161 corresponds to the BMC assigned sensor number */
162 uint32_t bld_sensor_node(devTree * i_dt, const dtOffset_t & i_parentNode,
163- const uint16_t sensorData[] )
164+ const uint16_t sensorData[],
165+ uint32_t instance, uint32_t chipId )
166 {
167
168- const uint32_t sensorNumber = sensorData[
169+ SENSOR::sensorReadingType readType;
170+
171+ // pass in the sensor name to get back the supported offsets and the event
172+ // reading type for this sensor.
173+ uint32_t offsets = SENSOR::getSensorOffsets(
174+ static_cast<TARGETING::SENSOR_NAME>(
175+ sensorData[TARGETING::IPMI_SENSOR_ARRAY_NAME_OFFSET]),
176+ readType);
177+
178+ const uint16_t sensorNumber = sensorData[
179 TARGETING::IPMI_SENSOR_ARRAY_NUMBER_OFFSET];
180
181- const uint32_t sensorName =
182- sensorData[TARGETING::IPMI_SENSOR_ARRAY_NAME_OFFSET];
183+ // the sensor name is a combination of the sensor type + entity ID
184+ const uint16_t sensorType = (
185+ sensorData[TARGETING::IPMI_SENSOR_ARRAY_NAME_OFFSET]
186+ & SENSOR_TYPE_MASK) >> 8;
187+
188+ const uint16_t entityId =
189+ sensorData[TARGETING::IPMI_SENSOR_ARRAY_NAME_OFFSET] & ENTITY_ID_MASK;
190
191 /* Build sensor node based on sensor number */
192 dtOffset_t sensorNode = i_dt->addNode(i_parentNode, "sensor", sensorNumber);
193@@ -1317,22 +1340,35 @@ uint32_t bld_sensor_node(devTree * i_dt, const dtOffset_t & i_parentNode,
194 i_dt->addPropertyCell32(sensorNode, "reg", sensorNumber);
195
196 // add sensor type
197- i_dt->addPropertyCell32(sensorNode, "ipmi-sensor-type", sensorName);
198-
199- // @TODO RTC:113902
200- // get more info from Ben H. regarding what info he needs
201- // add the name of the sensor
202- //i_dt->addPropertyString(sensorNode, "name", sensorToString( sensorName ));
203- // i_dt->addPropertyCell32(sensorNode, "ipmi-entity-type",
204- // sensorData[ENTITY_TYPE_OFFSET]);
205- // i_dt->addPropertyCell32(sensorNode, "ipmi-reading-type",
206- // sensorData[READING_TYPE_OFFSET]);
207-
208- /* return the phandle for this sensor, might need to add it to the
209- cpus node per Ben H. proposal */
210+ i_dt->addPropertyCell32(sensorNode, "ipmi-sensor-type", sensorType);
211+ i_dt->addPropertyCell32(sensorNode, "ipmi-entity-id", entityId);
212+ i_dt->addPropertyCell32(sensorNode, "ipmi-entity-instance", instance);
213+ i_dt->addPropertyCell32(sensorNode, "ipmi-sensor-offsets", offsets);
214+ i_dt->addPropertyCell32(sensorNode, "ipmi-sensor-reading-type", readType);
215+
216+ // currently we only add the chip ID to the OCC sensor
217+ if(chipId != 0xFF )
218+ {
219+ i_dt->addPropertyCell32(sensorNode, "ibm,chip-id", chipId);
220+ }
221+
222+ /* return the phandle for this sensor */
223 return i_dt->getPhandle(sensorNode);
224 }
225
226+// return the IPMI entity instance from the SDR for this
227+// target.
228+uint32_t getInstanceNumber( TARGETING::Target * i_pTarget )
229+{
230+ AttributeTraits<ATTR_IPMI_INSTANCE>::Type l_instance;
231+
232+ l_instance = i_pTarget->getAttr<TARGETING::ATTR_IPMI_INSTANCE>();
233+
234+ return l_instance;
235+
236+}
237+
238+// build the sensor node for a given target
239 uint32_t bld_sensor_node(devTree * i_dt, const dtOffset_t & i_sensorNode,
240 TARGETING::Target * i_pTarget )
241 {
242@@ -1344,6 +1380,17 @@ uint32_t bld_sensor_node(devTree * i_dt, const dtOffset_t & i_sensorNode,
243 * for each sensor */
244 if ( i_pTarget->tryGetAttr<ATTR_IPMI_SENSORS>(l_sensors) )
245 {
246+ uint32_t chipId = 0xFF;
247+
248+ // add the chip id to the OCC sensor since OPAL needs it to figure out
249+ // which OCC it is.
250+ if( TARGETING::TYPE_OCC == i_pTarget->getAttr<TARGETING::ATTR_TYPE>())
251+ {
252+ ConstTargetHandle_t proc = getParentChip(i_pTarget);
253+
254+ chipId = getProcChipId( proc );
255+ }
256+
257 for(uint16_t i=0; i< array_rows; i++)
258 {
259 /* if the sensor number is 0xFF move on */
260@@ -1351,7 +1398,8 @@ uint32_t bld_sensor_node(devTree * i_dt, const dtOffset_t & i_sensorNode,
261 {
262 /* use this row to create the next sensor node - ignoring
263 * return value for now */
264- bld_sensor_node(i_dt, i_sensorNode, l_sensors[i] );
265+ bld_sensor_node(i_dt, i_sensorNode, l_sensors[i],
266+ getInstanceNumber(i_pTarget) , chipId );
267 }
268 else
269 {
270@@ -1394,10 +1442,6 @@ errlHndl_t bld_fdt_sensors(devTree * i_dt, const dtOffset_t & i_parentNode,
271 i_dt->addPropertyCell32(sensorNode, "#address-cells", 1);
272 i_dt->addPropertyCell32(sensorNode, "#size-cells", 0);
273
274- // pass ALL IPMI_SENSORS to opal
275- // @TODO RTC:113902 - add remaining sensor info and limit sensors
276- // and adjust the sensors passed to opal to match their requirements
277-
278 /* loop through all the targets and get the IPMI sensor data if it
279 exists */
280 for (TargetIterator itr = TARGETING::targetService().begin();
281@@ -1454,6 +1498,7 @@ errlHndl_t bld_fdt_bmc(devTree * i_dt, bool i_smallTree)
282
283 return errhdl;
284 }
285+#endif
286
287 errlHndl_t bld_fdt_vpd(devTree * i_dt, bool i_smallTree)
288 {
289diff --git a/src/usr/ipmi/ipmisensor.C b/src/usr/ipmi/ipmisensor.C
290index 3e15e91..fc7284b 100644
291--- a/src/usr/ipmi/ipmisensor.C
292+++ b/src/usr/ipmi/ipmisensor.C
293@@ -1121,4 +1121,80 @@ namespace SENSOR
294 return NULL;
295 }
296
297+ uint16_t getSensorOffsets( TARGETING::SENSOR_NAME i_name,
298+ sensorReadingType &o_readType )
299+ {
300+
301+ uint16_t offsets = 0;
302+
303+ // most of our sensors use generic sensor specific reading types
304+ // so use that as the default value
305+ o_readType = SENSOR_SPECIFIC;
306+
307+ // sensor type is lower byte of sensor name, if we dont match
308+ // based on name, then try the sensor type
309+ uint16_t t = ( i_name >> 8 ) & 0x00FF;
310+
311+ switch( i_name )
312+ {
313+ case TARGETING::SENSOR_NAME_FW_BOOT_PROGRESS:
314+ {
315+ offsets = ( 1 << SYSTEM_FIRMWARE_PROGRESS );
316+ break;
317+ }
318+ case TARGETING::SENSOR_NAME_OCC_ACTIVE:
319+ {
320+ offsets = ( 1 << DEVICE_DISABLED ) |
321+ ( 1 << DEVICE_ENABLED );
322+ o_readType = DIGITAL_ENABLE_DISABLE;
323+ break;
324+ }
325+ case TARGETING::SENSOR_NAME_HOST_STATUS:
326+ {
327+ offsets = ( 1 << S0_G0_WORKING ) |
328+ ( 1 << G5_SOFT_OFF ) |
329+ ( 1 << LEGACY_ON );
330+ break;
331+ }
332+ case TARGETING::SENSOR_NAME_PCI_ACTIVE:
333+ case TARGETING::SENSOR_NAME_OS_BOOT:
334+ {
335+ // default all offsets enabled
336+ offsets = 0x7FFF;
337+ break;
338+ }
339+
340+ default:
341+ {
342+ // try sensor type
343+ switch (t)
344+ {
345+ case TARGETING::SENSOR_TYPE_FAULT:
346+ offsets = ( 1 << ASSERTED );
347+ o_readType = DIGITAL_ASSERT_DEASSERT;
348+ break;
349+
350+ case TARGETING::SENSOR_TYPE_PROCESSOR:
351+ offsets = ( 1 << PROC_PRESENCE_DETECTED ) |
352+ ( 1 << PROC_DISABLED ) |
353+ ( 1 << IERR );
354+ break;
355+
356+ case TARGETING::SENSOR_TYPE_MEMORY:
357+ offsets = ( 1 << MEMORY_DEVICE_DISABLED ) |
358+ ( 1 << MEM_DEVICE_PRESENCE_DETECTED );
359+ break;
360+ default:
361+ offsets = 0;
362+ o_readType = THRESHOLD;
363+ break;
364+ }
365+
366+ }
367+ }
368+
369+ return offsets;
370+ }
371+
372+
373 }; // end name space
374diff --git a/src/usr/targeting/common/Targets.pm b/src/usr/targeting/common/Targets.pm
375index eb1ea1f..29f6bcb 100644
376--- a/src/usr/targeting/common/Targets.pm
377+++ b/src/usr/targeting/common/Targets.pm
378@@ -195,7 +195,7 @@ sub printAttribute
379 $filter{ENTITY_ID_LOOKUP} = 1;
380 $filter{ENTITY_INSTANCE} = 1;
381 $filter{MBA_NUM} = 1;
382- $filter{IPMI_INSTANCE} = 1;
383+ $filter{IPMI_INSTANCE} = 0;
384 $filter{IPMI_NAME} = 1;
385 $filter{INSTANCE_ID} = 1;
386 #$filter{ADC_CHANNEL_SENSOR_NUMBERS} = 1;
387diff --git a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
388index 3bb57e6..74fb492 100644
389--- a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
390+++ b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
391@@ -822,6 +822,16 @@
392 <writeable/>
393 <hbOnly/>
394 </attribute>
395+<attribute>
396+ <id>IPMI_INSTANCE</id>
397+ <description>Holds the IPMI instance number for this entity.</description>
398+ <simpleType>
399+ <uint32_t>
400+ </uint32_t>
401+ </simpleType>
402+ <persistency>non-volatile</persistency>
403+ <readable/>
404+</attribute>
405 <enumerationType>
406 <id>ENTITY_ID</id>
407 <description>Enumeration indicating the IPMI entity ID, these values are
408@@ -1003,6 +1013,69 @@
409 </enumerator>
410 </enumerationType>
411
412+<enumerationType>
413+ <id>SENSOR_TYPE</id>
414+ <description>Enumeration indicating the IPMI sensor type, these values
415+ are defined in the IPMI specification. These values will be used when
416+ sending sensor reading events to the BMC.</description>
417+ <enumerator>
418+ <name>NA</name>
419+ <value>0</value>
420+ </enumerator>
421+ <enumerator>
422+ <name>TEMPERATURE</name>
423+ <value>0x01</value>
424+ </enumerator>
425+ <enumerator>
426+ <name>PROCESSOR</name>
427+ <value>0x07</value>
428+ </enumerator>
429+ <enumerator>
430+ <name>MEMORY</name>
431+ <value>0x0c</value>
432+ </enumerator>
433+ <enumerator>
434+ <name>SYS_FW_PROGRESS</name>
435+ <value>0x0F</value>
436+ </enumerator>
437+ <enumerator>
438+ <name>SYS_EVENT</name>
439+ <value>0x12</value>
440+ </enumerator>
441+ <enumerator>
442+ <name>OS_BOOT</name>
443+ <value>0x1F</value>
444+ </enumerator>
445+ <enumerator>
446+ <name>APCI_POWER_STATE</name>
447+ <value>0x22</value>
448+ </enumerator>
449+ <enumerator>
450+ <name>FREQ</name>
451+ <value>0xC1</value>
452+ </enumerator>
453+ <enumerator>
454+ <name>POWER</name>
455+ <value>0xC2</value>
456+ </enumerator>
457+ <enumerator>
458+ <name>BOOT_COUNT</name>
459+ <value>0xC3</value>
460+ </enumerator>
461+ <enumerator>
462+ <name>PCI_LINK_PRES</name>
463+ <value>0xC4</value>
464+ </enumerator>
465+ <enumerator>
466+ <name>PWR_LIMIT_ACTIVE</name>
467+ <value>0xC4</value>
468+ </enumerator>
469+ <enumerator>
470+ <name>FAULT</name>
471+ <value>0xC7</value>
472+ </enumerator>
473+</enumerationType>
474+
475 <!-- IPMI Sensor numbers are defined in the IPMI spec as 8 bit values. However
476 in the hostboot code they will be defined as a uint16_t to allow us to add
477 additonal information. An example relates to error logs returned by the OCC,
478diff --git a/src/usr/targeting/common/xmltohb/target_types_hb.xml b/src/usr/targeting/common/xmltohb/target_types_hb.xml
479index 8255b70..bd00b87 100644
480--- a/src/usr/targeting/common/xmltohb/target_types_hb.xml
481+++ b/src/usr/targeting/common/xmltohb/target_types_hb.xml
482@@ -33,6 +33,14 @@
483 ================================================================= -->
484
485 <targetTypeExtension>
486+ <id>base</id>
487+ <attribute>
488+ <id>IPMI_INSTANCE</id>
489+ <default>0</default>
490+ </attribute>
491+</targetTypeExtension>
492+
493+<targetTypeExtension>
494 <id>sys-sys-power8</id>
495 <attribute><id>IS_MPIPL_HB</id></attribute>
496 <attribute><id>IBSCOM_ENABLE_OVERRIDE</id></attribute>
497@@ -182,9 +190,7 @@
498 <attribute>
499 <id>PSTATE_TABLE</id>
500 </attribute>
501- <attribute>
502- <id>IPMI_SENSORS</id>
503- </attribute>
504+ <attribute><id>IPMI_SENSORS</id></attribute>
505 </targetTypeExtension>
506
507 <targetTypeExtension>
508--
5091.7.4.1
510